@openacp/cli 0.6.10 → 2026.326.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/dist/{action-detect-P7ZE4NEM.js → action-detect-QPA775HB.js} +2 -2
  2. package/dist/adapter-6ANPBSVU.js +16 -0
  3. package/dist/{discord-OMC52Y54.js → adapter-77ZCVABT.js} +520 -365
  4. package/dist/adapter-77ZCVABT.js.map +1 -0
  5. package/dist/{adapter-ZOANORGM.js → adapter-PQGHVG4K.js} +300 -93
  6. package/dist/adapter-PQGHVG4K.js.map +1 -0
  7. package/dist/{admin-6SYB6XCZ.js → admin-GBPZFFAU.js} +3 -3
  8. package/dist/agent-catalog-YHBFERYO.js +11 -0
  9. package/dist/{agent-dependencies-4OWBMZWZ.js → agent-dependencies-WS7Z2DFW.js} +2 -2
  10. package/dist/agent-registry-5LZT7CUB.js +9 -0
  11. package/dist/agent-store-VSHNY5GT.js +9 -0
  12. package/dist/{agents-QO7DKARJ.js → agents-BWU4MRRD.js} +3 -3
  13. package/dist/{api-client-CFQT5U7D.js → api-client-AQPNKXI2.js} +2 -2
  14. package/dist/api-server-3PYLRBCN.js +8 -0
  15. package/dist/api-server-CHVSUDBX.js +11 -0
  16. package/dist/{autostart-X33OGMX6.js → autostart-6JS565RY.js} +3 -3
  17. package/dist/chunk-2CX4IEEC.js +124 -0
  18. package/dist/chunk-2CX4IEEC.js.map +1 -0
  19. package/dist/{chunk-O7CPGUAI.js → chunk-4KGLKKQK.js} +4 -4
  20. package/dist/chunk-4KGLKKQK.js.map +1 -0
  21. package/dist/{chunk-W3EYKZNQ.js → chunk-4WXALZA3.js} +2 -2
  22. package/dist/chunk-4WXALZA3.js.map +1 -0
  23. package/dist/chunk-5OCGO27U.js +125 -0
  24. package/dist/chunk-5OCGO27U.js.map +1 -0
  25. package/dist/{chunk-OWP7RZ62.js → chunk-5ZOFBTOR.js} +118 -262
  26. package/dist/chunk-5ZOFBTOR.js.map +1 -0
  27. package/dist/chunk-6RXVEXF3.js +23 -0
  28. package/dist/chunk-6RXVEXF3.js.map +1 -0
  29. package/dist/{chunk-34M4OS5P.js → chunk-A6Y4GZM3.js} +3 -3
  30. package/dist/chunk-A6Y4GZM3.js.map +1 -0
  31. package/dist/chunk-AD3X6DGK.js +166 -0
  32. package/dist/chunk-AD3X6DGK.js.map +1 -0
  33. package/dist/{chunk-7QJS2XBD.js → chunk-AFKX424Q.js} +2 -2
  34. package/dist/chunk-AFKX424Q.js.map +1 -0
  35. package/dist/chunk-APS6UEFU.js +259 -0
  36. package/dist/chunk-APS6UEFU.js.map +1 -0
  37. package/dist/chunk-BLQUXO7S.js +113 -0
  38. package/dist/chunk-BLQUXO7S.js.map +1 -0
  39. package/dist/{chunk-WTZDAYZX.js → chunk-BQ6FR32N.js} +3 -3
  40. package/dist/chunk-BQ6FR32N.js.map +1 -0
  41. package/dist/chunk-FNRSWA2K.js +1 -0
  42. package/dist/chunk-FQEBWOZR.js +3557 -0
  43. package/dist/chunk-FQEBWOZR.js.map +1 -0
  44. package/dist/{chunk-4CTX774K.js → chunk-GJOY37U7.js} +4 -4
  45. package/dist/chunk-GJOY37U7.js.map +1 -0
  46. package/dist/{chunk-I7WC6E5S.js → chunk-HVBNCPAY.js} +2 -2
  47. package/dist/chunk-HVBNCPAY.js.map +1 -0
  48. package/dist/{chunk-2HMQOC7N.js → chunk-I3CGU5W7.js} +4 -4
  49. package/dist/chunk-I3CGU5W7.js.map +1 -0
  50. package/dist/{chunk-NVPG6JCL.js → chunk-L7YNNBI5.js} +3 -3
  51. package/dist/chunk-L7YNNBI5.js.map +1 -0
  52. package/dist/chunk-LGFWH3AE.js +26 -0
  53. package/dist/chunk-LGFWH3AE.js.map +1 -0
  54. package/dist/chunk-MLF4W5R6.js +101 -0
  55. package/dist/chunk-MLF4W5R6.js.map +1 -0
  56. package/dist/{chunk-KIRH7TUJ.js → chunk-MTSDOSXS.js} +3 -3
  57. package/dist/chunk-MTSDOSXS.js.map +1 -0
  58. package/dist/{chunk-J4SJTKIK.js → chunk-NAM4ERUW.js} +3 -3
  59. package/dist/chunk-NAM4ERUW.js.map +1 -0
  60. package/dist/{chunk-MKHUZLII.js → chunk-NBFIBGAT.js} +39 -25
  61. package/dist/chunk-NBFIBGAT.js.map +1 -0
  62. package/dist/{chunk-BNLGTZ34.js → chunk-O5RG4YZY.js} +3 -3
  63. package/dist/chunk-O5RG4YZY.js.map +1 -0
  64. package/dist/{chunk-JHYXKVV2.js → chunk-ODUM3D6X.js} +2 -2
  65. package/dist/chunk-ODUM3D6X.js.map +1 -0
  66. package/dist/chunk-OYSAN7UX.js +15 -0
  67. package/dist/chunk-OYSAN7UX.js.map +1 -0
  68. package/dist/chunk-P4SNGQNI.js +158 -0
  69. package/dist/chunk-P4SNGQNI.js.map +1 -0
  70. package/dist/{chunk-2CJ46J3C.js → chunk-PPSMUECX.js} +3 -3
  71. package/dist/chunk-PPSMUECX.js.map +1 -0
  72. package/dist/chunk-Q6ZXJTZB.js +56 -0
  73. package/dist/chunk-Q6ZXJTZB.js.map +1 -0
  74. package/dist/{chunk-XANPHG7W.js → chunk-QSDZDHNS.js} +7 -7
  75. package/dist/chunk-QSDZDHNS.js.map +1 -0
  76. package/dist/{chunk-33RP6K2O.js → chunk-QVMEF6FB.js} +6 -6
  77. package/dist/chunk-QVMEF6FB.js.map +1 -0
  78. package/dist/chunk-QWP76EBW.js +536 -0
  79. package/dist/chunk-QWP76EBW.js.map +1 -0
  80. package/dist/{chunk-V5GZQEIY.js → chunk-RBYBSSGO.js} +4 -4
  81. package/dist/chunk-RBYBSSGO.js.map +1 -0
  82. package/dist/{chunk-CS3KCJ5D.js → chunk-RKB2ZK6S.js} +555 -383
  83. package/dist/chunk-RKB2ZK6S.js.map +1 -0
  84. package/dist/{chunk-UKT3G5IA.js → chunk-SHTGQGAU.js} +7 -7
  85. package/dist/chunk-SHTGQGAU.js.map +1 -0
  86. package/dist/chunk-SNPYTMPR.js +51 -0
  87. package/dist/chunk-SNPYTMPR.js.map +1 -0
  88. package/dist/chunk-UB2QB6DE.js +124 -0
  89. package/dist/chunk-UB2QB6DE.js.map +1 -0
  90. package/dist/chunk-UNJUWWQO.js +1108 -0
  91. package/dist/chunk-UNJUWWQO.js.map +1 -0
  92. package/dist/chunk-V2M243KZ.js +445 -0
  93. package/dist/chunk-V2M243KZ.js.map +1 -0
  94. package/dist/chunk-V5JT5TPD.js +97 -0
  95. package/dist/chunk-V5JT5TPD.js.map +1 -0
  96. package/dist/chunk-W26AUH5B.js +61 -0
  97. package/dist/chunk-W26AUH5B.js.map +1 -0
  98. package/dist/chunk-WAAD23KY.js +222 -0
  99. package/dist/chunk-WAAD23KY.js.map +1 -0
  100. package/dist/chunk-WIIZNPCR.js +150 -0
  101. package/dist/chunk-WIIZNPCR.js.map +1 -0
  102. package/dist/chunk-WQCJTU2C.js +84 -0
  103. package/dist/chunk-WQCJTU2C.js.map +1 -0
  104. package/dist/chunk-WVLDNYOJ.js +150 -0
  105. package/dist/chunk-WVLDNYOJ.js.map +1 -0
  106. package/dist/chunk-WXVT3AOY.js +22 -0
  107. package/dist/chunk-WXVT3AOY.js.map +1 -0
  108. package/dist/{chunk-GAK6PIBW.js → chunk-XMMAGAT4.js} +2 -2
  109. package/dist/chunk-XMMAGAT4.js.map +1 -0
  110. package/dist/chunk-Y64XWMJ4.js +212 -0
  111. package/dist/chunk-Y64XWMJ4.js.map +1 -0
  112. package/dist/chunk-YEULD3SG.js +62 -0
  113. package/dist/chunk-YEULD3SG.js.map +1 -0
  114. package/dist/chunk-ZHGPZBS4.js +49 -0
  115. package/dist/chunk-ZHGPZBS4.js.map +1 -0
  116. package/dist/{chunk-JKBFUAJK.js → chunk-ZSLHHQPQ.js} +2 -2
  117. package/dist/chunk-ZSLHHQPQ.js.map +1 -0
  118. package/dist/cli.js +496 -150
  119. package/dist/cli.js.map +1 -1
  120. package/dist/{config-6S355X75.js → config-I4FMCJGZ.js} +3 -3
  121. package/dist/config-editor-HNEKXRLQ.js +11 -0
  122. package/dist/{config-registry-AHYI4MYL.js → config-registry-CUMNXFGK.js} +2 -2
  123. package/dist/context-XM6E22LM.js +10 -0
  124. package/dist/core-plugins-VEUNFTMB.js +27 -0
  125. package/dist/{daemon-4CS6HMB5.js → daemon-PXO5QPCR.js} +4 -4
  126. package/dist/dev-loader-RDC5E2CW.js +50 -0
  127. package/dist/dev-loader-RDC5E2CW.js.map +1 -0
  128. package/dist/discord-NOJQ5PZO.js +8 -0
  129. package/dist/doctor-H72BZOPA.js +10 -0
  130. package/dist/{doctor-OLYBO3V3.js → doctor-RF6BHMCC.js} +5 -5
  131. package/dist/file-service-EUODJAIT.js +9 -0
  132. package/dist/file-service-EUODJAIT.js.map +1 -0
  133. package/dist/index.d.ts +1293 -188
  134. package/dist/index.js +387 -48
  135. package/dist/index.js.map +1 -1
  136. package/dist/{install-cloudflared-Z7VCGOVG.js → install-cloudflared-AN24L4DP.js} +5 -5
  137. package/dist/install-cloudflared-AN24L4DP.js.map +1 -0
  138. package/dist/install-context-XPWTFT3J.js +78 -0
  139. package/dist/install-context-XPWTFT3J.js.map +1 -0
  140. package/dist/{install-jq-HUYSQWKR.js → install-jq-CRVDJGF3.js} +5 -5
  141. package/dist/install-jq-CRVDJGF3.js.map +1 -0
  142. package/dist/{integrate-PNEHRY2I.js → integrate-5C6KSU6D.js} +2 -2
  143. package/dist/integrate-5C6KSU6D.js.map +1 -0
  144. package/dist/{log-NXABYJTT.js → log-LZ7FTRKG.js} +2 -2
  145. package/dist/log-LZ7FTRKG.js.map +1 -0
  146. package/dist/main-T5WVCCFN.js +715 -0
  147. package/dist/main-T5WVCCFN.js.map +1 -0
  148. package/dist/{menu-YY5MKHEK.js → menu-YDQ2LWAR.js} +2 -2
  149. package/dist/menu-YDQ2LWAR.js.map +1 -0
  150. package/dist/{new-session-FEO4J4VU.js → new-session-AVQCNXRG.js} +5 -5
  151. package/dist/new-session-AVQCNXRG.js.map +1 -0
  152. package/dist/notifications-D5BRDNSU.js +9 -0
  153. package/dist/notifications-D5BRDNSU.js.map +1 -0
  154. package/dist/plugin-create-JVCVUG6V.js +331 -0
  155. package/dist/plugin-create-JVCVUG6V.js.map +1 -0
  156. package/dist/plugin-registry-WB3DR67H.js +8 -0
  157. package/dist/plugin-registry-WB3DR67H.js.map +1 -0
  158. package/dist/{post-upgrade-CJG5I7M2.js → post-upgrade-XLHZ6ZB7.js} +8 -8
  159. package/dist/post-upgrade-XLHZ6ZB7.js.map +1 -0
  160. package/dist/read-text-file-IRZM3QLM.js +8 -0
  161. package/dist/read-text-file-IRZM3QLM.js.map +1 -0
  162. package/dist/security-YNRBW6S7.js +9 -0
  163. package/dist/security-YNRBW6S7.js.map +1 -0
  164. package/dist/{session-IUSI7P5S.js → session-KZFA6Z26.js} +4 -4
  165. package/dist/session-KZFA6Z26.js.map +1 -0
  166. package/dist/{settings-RQPAM4KC.js → settings-MFYM7CZO.js} +4 -4
  167. package/dist/settings-MFYM7CZO.js.map +1 -0
  168. package/dist/settings-manager-MD2U4ZV2.js +8 -0
  169. package/dist/settings-manager-MD2U4ZV2.js.map +1 -0
  170. package/dist/{chunk-LCRLAV4G.js → setup-BAI2F24H.js} +154 -492
  171. package/dist/setup-BAI2F24H.js.map +1 -0
  172. package/dist/slack-KH7E3VBS.js +8 -0
  173. package/dist/slack-KH7E3VBS.js.map +1 -0
  174. package/dist/speech-2GHQNRIO.js +9 -0
  175. package/dist/speech-2GHQNRIO.js.map +1 -0
  176. package/dist/telegram-ZDC3JQF2.js +8 -0
  177. package/dist/telegram-ZDC3JQF2.js.map +1 -0
  178. package/dist/tunnel-M47I7H4B.js +8 -0
  179. package/dist/tunnel-M47I7H4B.js.map +1 -0
  180. package/dist/{tunnel-service-CJLUH6SZ.js → tunnel-service-WADYHREX.js} +17 -17
  181. package/dist/tunnel-service-WADYHREX.js.map +1 -0
  182. package/dist/usage-WYNK6ZC5.js +10 -0
  183. package/dist/usage-WYNK6ZC5.js.map +1 -0
  184. package/dist/validators-6CLEZUBD.js +8 -0
  185. package/dist/validators-6CLEZUBD.js.map +1 -0
  186. package/dist/validators-WSTBNKRW.js +12 -0
  187. package/dist/validators-WSTBNKRW.js.map +1 -0
  188. package/package.json +1 -1
  189. package/dist/adapter-ZOANORGM.js.map +0 -1
  190. package/dist/agent-catalog-FC3HGDEQ.js +0 -11
  191. package/dist/agent-registry-WT4NXPYG.js +0 -9
  192. package/dist/agent-store-VZLFPTZU.js +0 -9
  193. package/dist/chunk-2CJ46J3C.js.map +0 -1
  194. package/dist/chunk-2HMQOC7N.js.map +0 -1
  195. package/dist/chunk-33RP6K2O.js.map +0 -1
  196. package/dist/chunk-34M4OS5P.js.map +0 -1
  197. package/dist/chunk-4CTX774K.js.map +0 -1
  198. package/dist/chunk-7QJS2XBD.js.map +0 -1
  199. package/dist/chunk-BNLGTZ34.js.map +0 -1
  200. package/dist/chunk-CS3KCJ5D.js.map +0 -1
  201. package/dist/chunk-GAK6PIBW.js.map +0 -1
  202. package/dist/chunk-I7WC6E5S.js.map +0 -1
  203. package/dist/chunk-J4SJTKIK.js.map +0 -1
  204. package/dist/chunk-JHYXKVV2.js.map +0 -1
  205. package/dist/chunk-JKBFUAJK.js.map +0 -1
  206. package/dist/chunk-KIRH7TUJ.js.map +0 -1
  207. package/dist/chunk-LBIKITQT.js +0 -22
  208. package/dist/chunk-LBIKITQT.js.map +0 -1
  209. package/dist/chunk-LCRLAV4G.js.map +0 -1
  210. package/dist/chunk-LGP2YGRL.js +0 -4880
  211. package/dist/chunk-LGP2YGRL.js.map +0 -1
  212. package/dist/chunk-MKHUZLII.js.map +0 -1
  213. package/dist/chunk-NAMYZIS5.js +0 -1
  214. package/dist/chunk-NVPG6JCL.js.map +0 -1
  215. package/dist/chunk-O7CPGUAI.js.map +0 -1
  216. package/dist/chunk-OWP7RZ62.js.map +0 -1
  217. package/dist/chunk-UKT3G5IA.js.map +0 -1
  218. package/dist/chunk-V5GZQEIY.js.map +0 -1
  219. package/dist/chunk-VOIJ6OY4.js +0 -63
  220. package/dist/chunk-VOIJ6OY4.js.map +0 -1
  221. package/dist/chunk-W3EYKZNQ.js.map +0 -1
  222. package/dist/chunk-WTZDAYZX.js.map +0 -1
  223. package/dist/chunk-XANPHG7W.js.map +0 -1
  224. package/dist/config-editor-QQTZMWGD.js +0 -13
  225. package/dist/discord-OMC52Y54.js.map +0 -1
  226. package/dist/doctor-HZZ5BSHB.js +0 -10
  227. package/dist/install-cloudflared-Z7VCGOVG.js.map +0 -1
  228. package/dist/install-jq-HUYSQWKR.js.map +0 -1
  229. package/dist/integrate-PNEHRY2I.js.map +0 -1
  230. package/dist/main-XOZCLFUK.js +0 -238
  231. package/dist/main-XOZCLFUK.js.map +0 -1
  232. package/dist/post-upgrade-CJG5I7M2.js.map +0 -1
  233. package/dist/setup-XHS4OMPM.js +0 -37
  234. package/dist/tunnel-service-CJLUH6SZ.js.map +0 -1
  235. /package/dist/{action-detect-P7ZE4NEM.js.map → action-detect-QPA775HB.js.map} +0 -0
  236. /package/dist/{admin-6SYB6XCZ.js.map → adapter-6ANPBSVU.js.map} +0 -0
  237. /package/dist/{agent-catalog-FC3HGDEQ.js.map → admin-GBPZFFAU.js.map} +0 -0
  238. /package/dist/{agent-dependencies-4OWBMZWZ.js.map → agent-catalog-YHBFERYO.js.map} +0 -0
  239. /package/dist/{agent-registry-WT4NXPYG.js.map → agent-dependencies-WS7Z2DFW.js.map} +0 -0
  240. /package/dist/{agent-store-VZLFPTZU.js.map → agent-registry-5LZT7CUB.js.map} +0 -0
  241. /package/dist/{agents-QO7DKARJ.js.map → agent-store-VSHNY5GT.js.map} +0 -0
  242. /package/dist/{api-client-CFQT5U7D.js.map → agents-BWU4MRRD.js.map} +0 -0
  243. /package/dist/{autostart-X33OGMX6.js.map → api-client-AQPNKXI2.js.map} +0 -0
  244. /package/dist/{chunk-NAMYZIS5.js.map → api-server-3PYLRBCN.js.map} +0 -0
  245. /package/dist/{config-6S355X75.js.map → api-server-CHVSUDBX.js.map} +0 -0
  246. /package/dist/{config-editor-QQTZMWGD.js.map → autostart-6JS565RY.js.map} +0 -0
  247. /package/dist/{config-registry-AHYI4MYL.js.map → chunk-FNRSWA2K.js.map} +0 -0
  248. /package/dist/{daemon-4CS6HMB5.js.map → config-I4FMCJGZ.js.map} +0 -0
  249. /package/dist/{doctor-HZZ5BSHB.js.map → config-editor-HNEKXRLQ.js.map} +0 -0
  250. /package/dist/{doctor-OLYBO3V3.js.map → config-registry-CUMNXFGK.js.map} +0 -0
  251. /package/dist/{log-NXABYJTT.js.map → context-XM6E22LM.js.map} +0 -0
  252. /package/dist/{menu-YY5MKHEK.js.map → core-plugins-VEUNFTMB.js.map} +0 -0
  253. /package/dist/{new-session-FEO4J4VU.js.map → daemon-PXO5QPCR.js.map} +0 -0
  254. /package/dist/{session-IUSI7P5S.js.map → discord-NOJQ5PZO.js.map} +0 -0
  255. /package/dist/{settings-RQPAM4KC.js.map → doctor-H72BZOPA.js.map} +0 -0
  256. /package/dist/{setup-XHS4OMPM.js.map → doctor-RF6BHMCC.js.map} +0 -0
@@ -0,0 +1,166 @@
1
+ import {
2
+ EdgeTTS,
3
+ GroqSTT,
4
+ SpeechService
5
+ } from "./chunk-WIIZNPCR.js";
6
+
7
+ // src/plugins/speech/index.ts
8
+ var speechPlugin = {
9
+ name: "@openacp/speech",
10
+ version: "1.0.0",
11
+ description: "Text-to-speech and speech-to-text with pluggable providers",
12
+ essential: false,
13
+ optionalPluginDependencies: { "@openacp/file-service": "^1.0.0" },
14
+ permissions: ["services:register", "commands:register"],
15
+ async install(ctx) {
16
+ const { terminal, settings, legacyConfig } = ctx;
17
+ if (legacyConfig) {
18
+ const speechCfg = legacyConfig.speech;
19
+ if (speechCfg) {
20
+ const stt = speechCfg.stt;
21
+ const tts = speechCfg.tts;
22
+ const groqProviders = stt?.providers;
23
+ const groqConfig = groqProviders?.groq;
24
+ await settings.setAll({
25
+ sttProvider: stt?.provider ?? null,
26
+ groqApiKey: groqConfig?.apiKey ?? "",
27
+ ttsProvider: tts?.provider ?? "edge-tts",
28
+ ttsVoice: ""
29
+ });
30
+ terminal.log.success("Speech settings migrated from legacy config");
31
+ return;
32
+ }
33
+ }
34
+ const enableStt = await terminal.confirm({
35
+ message: "Enable speech-to-text (STT)?",
36
+ initialValue: false
37
+ });
38
+ let sttProvider = null;
39
+ let groqApiKey = "";
40
+ if (enableStt) {
41
+ sttProvider = await terminal.select({
42
+ message: "STT provider:",
43
+ options: [{ value: "groq", label: "Groq (Whisper)", hint: "Fast and affordable" }]
44
+ });
45
+ if (sttProvider === "groq") {
46
+ groqApiKey = await terminal.text({
47
+ message: "Groq API key:",
48
+ validate: (v) => !v.trim() ? "API key cannot be empty" : void 0
49
+ });
50
+ groqApiKey = groqApiKey.trim();
51
+ }
52
+ }
53
+ const ttsProvider = await terminal.select({
54
+ message: "TTS provider:",
55
+ options: [
56
+ { value: "edge-tts", label: "Edge TTS", hint: "Free, good quality" },
57
+ { value: "none", label: "None (disable TTS)" }
58
+ ]
59
+ });
60
+ let ttsVoice = "";
61
+ if (ttsProvider === "edge-tts") {
62
+ ttsVoice = await terminal.text({
63
+ message: "TTS voice (leave blank for default):",
64
+ placeholder: "e.g. en-US-AriaNeural"
65
+ });
66
+ ttsVoice = ttsVoice.trim();
67
+ }
68
+ await settings.setAll({
69
+ sttProvider,
70
+ groqApiKey,
71
+ ttsProvider: ttsProvider === "none" ? null : ttsProvider,
72
+ ttsVoice
73
+ });
74
+ terminal.log.success("Speech settings saved");
75
+ },
76
+ async configure(ctx) {
77
+ const { terminal, settings } = ctx;
78
+ const current = await settings.getAll();
79
+ const choice = await terminal.select({
80
+ message: "What to configure?",
81
+ options: [
82
+ { value: "stt", label: "Change STT provider/key" },
83
+ { value: "tts", label: "Change TTS provider/voice" },
84
+ { value: "done", label: "Done" }
85
+ ]
86
+ });
87
+ if (choice === "stt") {
88
+ const key = await terminal.text({
89
+ message: "Groq API key (leave blank to disable STT):",
90
+ defaultValue: current.groqApiKey ?? ""
91
+ });
92
+ const trimmed = key.trim();
93
+ await settings.set("sttProvider", trimmed ? "groq" : null);
94
+ await settings.set("groqApiKey", trimmed);
95
+ terminal.log.success("STT settings updated");
96
+ } else if (choice === "tts") {
97
+ const voice = await terminal.text({
98
+ message: "TTS voice (leave blank for default):",
99
+ defaultValue: current.ttsVoice ?? ""
100
+ });
101
+ await settings.set("ttsVoice", voice.trim());
102
+ terminal.log.success("TTS settings updated");
103
+ }
104
+ },
105
+ async uninstall(ctx, opts) {
106
+ if (opts.purge) {
107
+ await ctx.settings.clear();
108
+ ctx.terminal.log.success("Speech settings cleared");
109
+ }
110
+ },
111
+ async setup(ctx) {
112
+ const config = ctx.pluginConfig;
113
+ const groqApiKey = config.groqApiKey;
114
+ const ttsVoice = config.ttsVoice;
115
+ const sttProvider = groqApiKey ? "groq" : null;
116
+ const speechConfig = {
117
+ stt: {
118
+ provider: sttProvider,
119
+ providers: groqApiKey ? { groq: { apiKey: groqApiKey } } : {}
120
+ },
121
+ tts: {
122
+ provider: "edge-tts",
123
+ providers: {}
124
+ }
125
+ };
126
+ const service = new SpeechService(speechConfig);
127
+ if (groqApiKey) {
128
+ service.registerSTTProvider("groq", new GroqSTT(groqApiKey));
129
+ }
130
+ service.registerTTSProvider("edge-tts", new EdgeTTS(ttsVoice));
131
+ service.setProviderFactory((cfg) => {
132
+ const sttMap = /* @__PURE__ */ new Map();
133
+ const ttsMap = /* @__PURE__ */ new Map();
134
+ const groqCfg = cfg.stt?.providers?.groq;
135
+ if (groqCfg?.apiKey) {
136
+ sttMap.set("groq", new GroqSTT(groqCfg.apiKey, groqCfg.model));
137
+ }
138
+ const edgeVoice = cfg.tts?.providers?.["edge-tts"]?.voice;
139
+ ttsMap.set("edge-tts", new EdgeTTS(edgeVoice));
140
+ return { stt: sttMap, tts: ttsMap };
141
+ });
142
+ ctx.registerService("speech", service);
143
+ ctx.registerCommand({
144
+ name: "tts",
145
+ description: "Toggle text-to-speech",
146
+ usage: "on|off",
147
+ category: "plugin",
148
+ handler: async (args) => {
149
+ const mode = args.raw.trim().toLowerCase();
150
+ if (mode === "on") return { type: "text", text: "Text-to-speech enabled" };
151
+ if (mode === "off") return { type: "text", text: "Text-to-speech disabled" };
152
+ return { type: "menu", title: "Text to Speech", options: [
153
+ { label: "Enable", command: "/tts on" },
154
+ { label: "Disable", command: "/tts off" }
155
+ ] };
156
+ }
157
+ });
158
+ ctx.log.info("Speech service ready");
159
+ }
160
+ };
161
+ var speech_default = speechPlugin;
162
+
163
+ export {
164
+ speech_default
165
+ };
166
+ //# sourceMappingURL=chunk-AD3X6DGK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plugins/speech/index.ts"],"sourcesContent":["import type { OpenACPPlugin, InstallContext } from '../../core/plugin/types.js'\nimport { SpeechService, GroqSTT, EdgeTTS } from './exports.js'\nimport type { SpeechServiceConfig } from './exports.js'\n\nconst speechPlugin: OpenACPPlugin = {\n name: '@openacp/speech',\n version: '1.0.0',\n description: 'Text-to-speech and speech-to-text with pluggable providers',\n essential: false,\n optionalPluginDependencies: { '@openacp/file-service': '^1.0.0' },\n permissions: ['services:register', 'commands:register'],\n\n async install(ctx: InstallContext) {\n const { terminal, settings, legacyConfig } = ctx\n\n // Migrate from legacy config if present\n if (legacyConfig) {\n const speechCfg = legacyConfig.speech as Record<string, unknown> | undefined\n if (speechCfg) {\n const stt = speechCfg.stt as Record<string, unknown> | undefined\n const tts = speechCfg.tts as Record<string, unknown> | undefined\n const groqProviders = stt?.providers as Record<string, unknown> | undefined\n const groqConfig = groqProviders?.groq as Record<string, unknown> | undefined\n await settings.setAll({\n sttProvider: stt?.provider ?? null,\n groqApiKey: groqConfig?.apiKey ?? '',\n ttsProvider: tts?.provider ?? 'edge-tts',\n ttsVoice: '',\n })\n terminal.log.success('Speech settings migrated from legacy config')\n return\n }\n }\n\n // Interactive setup\n const enableStt = await terminal.confirm({\n message: 'Enable speech-to-text (STT)?',\n initialValue: false,\n })\n\n let sttProvider: string | null = null\n let groqApiKey = ''\n\n if (enableStt) {\n sttProvider = await terminal.select({\n message: 'STT provider:',\n options: [{ value: 'groq', label: 'Groq (Whisper)', hint: 'Fast and affordable' }],\n })\n\n if (sttProvider === 'groq') {\n groqApiKey = await terminal.text({\n message: 'Groq API key:',\n validate: (v) => (!v.trim() ? 'API key cannot be empty' : undefined),\n })\n groqApiKey = groqApiKey.trim()\n }\n }\n\n const ttsProvider = await terminal.select({\n message: 'TTS provider:',\n options: [\n { value: 'edge-tts', label: 'Edge TTS', hint: 'Free, good quality' },\n { value: 'none', label: 'None (disable TTS)' },\n ],\n })\n\n let ttsVoice = ''\n if (ttsProvider === 'edge-tts') {\n ttsVoice = await terminal.text({\n message: 'TTS voice (leave blank for default):',\n placeholder: 'e.g. en-US-AriaNeural',\n })\n ttsVoice = ttsVoice.trim()\n }\n\n await settings.setAll({\n sttProvider,\n groqApiKey,\n ttsProvider: ttsProvider === 'none' ? null : ttsProvider,\n ttsVoice,\n })\n terminal.log.success('Speech settings saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const choice = await terminal.select({\n message: 'What to configure?',\n options: [\n { value: 'stt', label: 'Change STT provider/key' },\n { value: 'tts', label: 'Change TTS provider/voice' },\n { value: 'done', label: 'Done' },\n ],\n })\n\n if (choice === 'stt') {\n const key = await terminal.text({\n message: 'Groq API key (leave blank to disable STT):',\n defaultValue: (current.groqApiKey as string) ?? '',\n })\n const trimmed = key.trim()\n await settings.set('sttProvider', trimmed ? 'groq' : null)\n await settings.set('groqApiKey', trimmed)\n terminal.log.success('STT settings updated')\n } else if (choice === 'tts') {\n const voice = await terminal.text({\n message: 'TTS voice (leave blank for default):',\n defaultValue: (current.ttsVoice as string) ?? '',\n })\n await settings.set('ttsVoice', voice.trim())\n terminal.log.success('TTS settings updated')\n }\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('Speech settings cleared')\n }\n },\n\n async setup(ctx) {\n const config = ctx.pluginConfig as Record<string, unknown>\n const groqApiKey = config.groqApiKey as string | undefined\n const ttsVoice = config.ttsVoice as string | undefined\n\n const sttProvider = groqApiKey ? 'groq' : null\n const speechConfig: SpeechServiceConfig = {\n stt: {\n provider: sttProvider,\n providers: groqApiKey ? { groq: { apiKey: groqApiKey } } : {},\n },\n tts: {\n provider: 'edge-tts',\n providers: {},\n },\n }\n\n const service = new SpeechService(speechConfig)\n\n if (groqApiKey) {\n service.registerSTTProvider('groq', new GroqSTT(groqApiKey))\n }\n service.registerTTSProvider('edge-tts', new EdgeTTS(ttsVoice))\n\n // Register provider factory for hot-reload (core calls refreshProviders on config change)\n service.setProviderFactory((cfg) => {\n const sttMap = new Map<string, InstanceType<typeof GroqSTT>>()\n const ttsMap = new Map<string, InstanceType<typeof EdgeTTS>>()\n const groqCfg = cfg.stt?.providers?.groq\n if (groqCfg?.apiKey) {\n sttMap.set('groq', new GroqSTT(groqCfg.apiKey, groqCfg.model))\n }\n const edgeVoice = cfg.tts?.providers?.['edge-tts']?.voice as string | undefined\n ttsMap.set('edge-tts', new EdgeTTS(edgeVoice))\n return { stt: sttMap, tts: ttsMap }\n })\n\n ctx.registerService('speech', service)\n\n ctx.registerCommand({\n name: 'tts',\n description: 'Toggle text-to-speech',\n usage: 'on|off',\n category: 'plugin',\n handler: async (args) => {\n const mode = args.raw.trim().toLowerCase()\n if (mode === 'on') return { type: 'text', text: 'Text-to-speech enabled' }\n if (mode === 'off') return { type: 'text', text: 'Text-to-speech disabled' }\n return { type: 'menu', title: 'Text to Speech', options: [\n { label: 'Enable', command: '/tts on' },\n { label: 'Disable', command: '/tts off' },\n ]}\n },\n })\n\n ctx.log.info('Speech service ready')\n },\n}\n\nexport default speechPlugin\n"],"mappings":"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","names":[]}
@@ -1,4 +1,4 @@
1
- // src/adapters/telegram/commands/menu.ts
1
+ // src/plugins/telegram/commands/menu.ts
2
2
  import { InlineKeyboard } from "grammy";
3
3
  function buildMenuKeyboard() {
4
4
  return new InlineKeyboard().text("\u{1F195} New Session", "m:new").text("\u{1F4CB} Sessions", "m:topics").row().text("\u{1F4CA} Status", "m:status").text("\u{1F916} Agents", "m:agents").row().text("\u2699\uFE0F Settings", "m:settings").text("\u{1F517} Integrate", "m:integrate").row().text("\u{1F504} Restart", "m:restart").text("\u2B06\uFE0F Update", "m:update").row().text("\u2753 Help", "m:help").text("\u{1FA7A} Doctor", "m:doctor");
@@ -89,4 +89,4 @@ export {
89
89
  handleClear,
90
90
  buildSkillMessages
91
91
  };
92
- //# sourceMappingURL=chunk-7QJS2XBD.js.map
92
+ //# sourceMappingURL=chunk-AFKX424Q.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plugins/telegram/commands/menu.ts"],"sourcesContent":["import type { Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { AgentCommand } from \"../../../core/index.js\";\nimport type { CommandsAssistantContext } from \"../types.js\";\n\nexport function buildMenuKeyboard(): InlineKeyboard {\n return new InlineKeyboard()\n .text(\"🆕 New Session\", \"m:new\")\n .text(\"📋 Sessions\", \"m:topics\")\n .row()\n .text(\"📊 Status\", \"m:status\")\n .text(\"🤖 Agents\", \"m:agents\")\n .row()\n .text(\"⚙️ Settings\", \"m:settings\")\n .text(\"🔗 Integrate\", \"m:integrate\")\n .row()\n .text(\"🔄 Restart\", \"m:restart\")\n .text(\"⬆️ Update\", \"m:update\")\n .row()\n .text(\"❓ Help\", \"m:help\")\n .text(\"🩺 Doctor\", \"m:doctor\");\n}\n\nexport async function handleMenu(ctx: Context): Promise<void> {\n await ctx.reply(`<b>OpenACP Menu</b>\\nChoose an action:`, {\n parse_mode: \"HTML\",\n reply_markup: buildMenuKeyboard(),\n });\n}\n\nexport async function handleHelp(ctx: Context): Promise<void> {\n await ctx.reply(\n `📖 <b>OpenACP Help</b>\\n\\n` +\n `🚀 <b>Getting Started</b>\\n` +\n `Tap 🆕 New Session to start coding with AI.\\n` +\n `Each session gets its own topic — chat there to work with the agent.\\n\\n` +\n `💡 <b>Common Tasks</b>\\n` +\n `/new [agent] [workspace] — Create new session\\n` +\n `/cancel — Cancel session (in session topic)\\n` +\n `/status — Show session or system status\\n` +\n `/sessions — List all sessions\\n` +\n `/agents — Browse & install agents\\n` +\n `/install <name> — Install an agent\\n\\n` +\n `⚙️ <b>System</b>\\n` +\n `/restart — Restart OpenACP\\n` +\n `/update — Update to latest version\\n` +\n `/integrate — Manage agent integrations\\n` +\n `/menu — Show action menu\\n\\n` +\n `🔒 <b>Session Options</b>\\n` +\n `/enable_dangerous — Auto-approve permissions\\n` +\n `/disable_dangerous — Restore permission prompts\\n` +\n `/handoff — Continue session in terminal\\n` +\n `/archive — Archive session topic\\n` +\n `/clear — Clear assistant history\\n\\n` +\n `💬 Need help? Just ask me in this topic!`,\n { parse_mode: \"HTML\" },\n );\n}\n\nexport async function handleClear(ctx: Context, assistant?: CommandsAssistantContext): Promise<void> {\n if (!assistant) {\n await ctx.reply(\"⚠️ Assistant is not available.\", { parse_mode: \"HTML\" });\n return;\n }\n\n const threadId = ctx.message?.message_thread_id;\n if (threadId !== assistant.topicId) {\n await ctx.reply(\"ℹ️ /clear only works in the Assistant topic.\", { parse_mode: \"HTML\" });\n return;\n }\n\n await ctx.reply(\"🔄 Clearing assistant history...\", { parse_mode: \"HTML\" });\n\n try {\n await assistant.respawn();\n await ctx.reply(\"✅ Assistant history cleared.\", { parse_mode: \"HTML\" });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.reply(`❌ Failed to clear: <code>${message}</code>`, { parse_mode: \"HTML\" });\n }\n}\n\nconst TELEGRAM_MSG_LIMIT = 4096;\n\n/**\n * Build plain-text skill command messages. Each command is on its own line\n * wrapped in <code> for tap-to-copy. If the list exceeds Telegram's message\n * limit, it is split into multiple messages (cut at line boundaries).\n */\nexport function buildSkillMessages(commands: AgentCommand[]): string[] {\n const sorted = [...commands].sort((a, b) => a.name.localeCompare(b.name));\n const header = \"🛠 <b>Available Skills</b>\\n\";\n const lines = sorted.map((c) => `<code>/${c.name}</code>`);\n\n const messages: string[] = [];\n let current = header;\n\n for (const line of lines) {\n const candidate = current + \"\\n\" + line;\n if (candidate.length > TELEGRAM_MSG_LIMIT) {\n messages.push(current);\n current = line;\n } else {\n current = candidate;\n }\n }\n if (current) messages.push(current);\n return messages;\n}\n"],"mappings":";AACA,SAAS,sBAAsB;AAIxB,SAAS,oBAAoC;AAClD,SAAO,IAAI,eAAe,EACvB,KAAK,yBAAkB,OAAO,EAC9B,KAAK,sBAAe,UAAU,EAC9B,IAAI,EACJ,KAAK,oBAAa,UAAU,EAC5B,KAAK,oBAAa,UAAU,EAC5B,IAAI,EACJ,KAAK,yBAAe,YAAY,EAChC,KAAK,uBAAgB,aAAa,EAClC,IAAI,EACJ,KAAK,qBAAc,WAAW,EAC9B,KAAK,uBAAa,UAAU,EAC5B,IAAI,EACJ,KAAK,eAAU,QAAQ,EACvB,KAAK,oBAAa,UAAU;AACjC;AAEA,eAAsB,WAAW,KAA6B;AAC5D,QAAM,IAAI,MAAM;AAAA,oBAA0C;AAAA,IACxD,YAAY;AAAA,IACZ,cAAc,kBAAkB;AAAA,EAClC,CAAC;AACH;AAEA,eAAsB,WAAW,KAA6B;AAC5D,QAAM,IAAI;AAAA,IACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAuBA,EAAE,YAAY,OAAO;AAAA,EACvB;AACF;AAEA,eAAsB,YAAY,KAAc,WAAqD;AACnG,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,4CAAkC,EAAE,YAAY,OAAO,CAAC;AACxE;AAAA,EACF;AAEA,QAAM,WAAW,IAAI,SAAS;AAC9B,MAAI,aAAa,UAAU,SAAS;AAClC,UAAM,IAAI,MAAM,0DAAgD,EAAE,YAAY,OAAO,CAAC;AACtF;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,2CAAoC,EAAE,YAAY,OAAO,CAAC;AAE1E,MAAI;AACF,UAAM,UAAU,QAAQ;AACxB,UAAM,IAAI,MAAM,qCAAgC,EAAE,YAAY,OAAO,CAAC;AAAA,EACxE,SAAS,KAAK;AACZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,UAAM,IAAI,MAAM,iCAA4B,OAAO,WAAW,EAAE,YAAY,OAAO,CAAC;AAAA,EACtF;AACF;AAEA,IAAM,qBAAqB;AAOpB,SAAS,mBAAmB,UAAoC;AACrE,QAAM,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AACxE,QAAM,SAAS;AACf,QAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,UAAU,EAAE,IAAI,SAAS;AAEzD,QAAM,WAAqB,CAAC;AAC5B,MAAI,UAAU;AAEd,aAAW,QAAQ,OAAO;AACxB,UAAM,YAAY,UAAU,OAAO;AACnC,QAAI,UAAU,SAAS,oBAAoB;AACzC,eAAS,KAAK,OAAO;AACrB,gBAAU;AAAA,IACZ,OAAO;AACL,gBAAU;AAAA,IACZ;AAAA,EACF;AACA,MAAI,QAAS,UAAS,KAAK,OAAO;AAClC,SAAO;AACT;","names":[]}
@@ -0,0 +1,259 @@
1
+ // src/plugins/context/context-provider.ts
2
+ var DEFAULT_MAX_TOKENS = 3e4;
3
+ var TOKENS_PER_TURN_ESTIMATE = 400;
4
+
5
+ // src/plugins/context/entire/checkpoint-reader.ts
6
+ import { execFileSync } from "child_process";
7
+ var ENTIRE_BRANCH = "origin/entire/checkpoints/v1";
8
+ var CHECKPOINT_ID_RE = /^[0-9a-f]{12}$/;
9
+ var SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
10
+ var CheckpointReader = class _CheckpointReader {
11
+ constructor(repoPath) {
12
+ this.repoPath = repoPath;
13
+ }
14
+ // ─── Git execution ───────────────────────────────────────────────────────────
15
+ /**
16
+ * Run a git command in the repo directory.
17
+ * Returns trimmed stdout on success, empty string on failure.
18
+ */
19
+ git(...args) {
20
+ try {
21
+ return execFileSync("git", ["-C", this.repoPath, ...args], {
22
+ encoding: "utf-8"
23
+ }).trim();
24
+ } catch {
25
+ return "";
26
+ }
27
+ }
28
+ // ─── Static helpers ──────────────────────────────────────────────────────────
29
+ /**
30
+ * Convert a 12-char checkpoint ID to its shard path: "f634acf05138" → "f6/34acf05138"
31
+ */
32
+ static shardPath(cpId) {
33
+ return `${cpId.slice(0, 2)}/${cpId.slice(2)}`;
34
+ }
35
+ /**
36
+ * Returns true when value looks like a 12-char lowercase hex checkpoint ID.
37
+ */
38
+ static isCheckpointId(value) {
39
+ return CHECKPOINT_ID_RE.test(value);
40
+ }
41
+ /**
42
+ * Returns true when value looks like a UUID (session ID).
43
+ */
44
+ static isSessionId(value) {
45
+ return SESSION_ID_RE.test(value);
46
+ }
47
+ /**
48
+ * Parse checkpoint-level metadata JSON. Returns null on error.
49
+ */
50
+ static parseCheckpointMeta(json) {
51
+ try {
52
+ const parsed = JSON.parse(json);
53
+ if (!parsed || typeof parsed !== "object") return null;
54
+ if (!Array.isArray(parsed.sessions)) return null;
55
+ return parsed;
56
+ } catch {
57
+ return null;
58
+ }
59
+ }
60
+ /**
61
+ * Extract Entire-Checkpoint trailer IDs from `git log --format="%H|%(trailers:...)"` output.
62
+ * Each line is: `<hash>|<trailer_value_or_empty>`. Returns only non-empty trailer values.
63
+ * Uses the last pipe on each line to locate the trailer value, to be robust against
64
+ * subject lines that contain pipes.
65
+ */
66
+ static parseCheckpointTrailers(output) {
67
+ const ids = [];
68
+ for (const line of output.split("\n")) {
69
+ const pipe = line.lastIndexOf("|");
70
+ if (pipe === -1) continue;
71
+ const trailerId = line.slice(pipe + 1).trim();
72
+ if (trailerId) ids.push(trailerId);
73
+ }
74
+ return ids;
75
+ }
76
+ // ─── Branch check ────────────────────────────────────────────────────────────
77
+ async hasEntireBranch() {
78
+ const out = this.git("branch", "-r");
79
+ return out.includes("entire/checkpoints/v1");
80
+ }
81
+ // ─── Core session fetching ───────────────────────────────────────────────────
82
+ listAllCheckpointIds() {
83
+ const out = this.git(
84
+ "ls-tree",
85
+ "-r",
86
+ ENTIRE_BRANCH,
87
+ "--name-only"
88
+ );
89
+ if (!out) return [];
90
+ const ids = /* @__PURE__ */ new Set();
91
+ for (const file of out.split("\n")) {
92
+ const parts = file.split("/");
93
+ if (parts.length === 3 && parts[2] === "metadata.json") {
94
+ ids.add(parts[0] + parts[1]);
95
+ }
96
+ }
97
+ return [...ids];
98
+ }
99
+ fetchCheckpointMeta(cpId) {
100
+ const shard = _CheckpointReader.shardPath(cpId);
101
+ const raw = this.git("show", `${ENTIRE_BRANCH}:${shard}/metadata.json`);
102
+ if (!raw) return null;
103
+ return _CheckpointReader.parseCheckpointMeta(raw);
104
+ }
105
+ fetchSessionMeta(metaPath) {
106
+ const normalized = metaPath.startsWith("/") ? metaPath.slice(1) : metaPath;
107
+ const raw = this.git("show", `${ENTIRE_BRANCH}:${normalized}`);
108
+ if (!raw) return {};
109
+ try {
110
+ return JSON.parse(raw);
111
+ } catch {
112
+ return {};
113
+ }
114
+ }
115
+ /**
116
+ * Build SessionInfo[] from a single checkpoint's metadata.
117
+ */
118
+ buildSessionsForCheckpoint(cpId, cpMeta) {
119
+ const sessions = [];
120
+ for (let idx = 0; idx < cpMeta.sessions.length; idx++) {
121
+ const sess = cpMeta.sessions[idx];
122
+ const transcriptPath = (sess.transcript ?? "").replace(/^\//, "");
123
+ const metaPath = sess.metadata ?? "";
124
+ const smeta = this.fetchSessionMeta(metaPath);
125
+ const createdAt = smeta.created_at ?? "";
126
+ sessions.push({
127
+ checkpointId: cpId,
128
+ sessionIndex: String(idx),
129
+ transcriptPath,
130
+ createdAt,
131
+ endedAt: createdAt,
132
+ // will be filled from JSONL by conversation builder
133
+ branch: smeta.branch ?? cpMeta.branch ?? "",
134
+ agent: smeta.agent ?? "",
135
+ turnCount: smeta.session_metrics?.turn_count ?? 0,
136
+ filesTouched: smeta.files_touched ?? cpMeta.files_touched ?? [],
137
+ sessionId: smeta.session_id ?? ""
138
+ });
139
+ }
140
+ return sessions;
141
+ }
142
+ getSessionsForCheckpoint(cpId) {
143
+ const meta = this.fetchCheckpointMeta(cpId);
144
+ if (!meta) return [];
145
+ return this.buildSessionsForCheckpoint(cpId, meta);
146
+ }
147
+ // ─── Public resolvers ────────────────────────────────────────────────────────
148
+ /**
149
+ * All sessions recorded on a given branch, sorted by createdAt ascending.
150
+ */
151
+ async resolveByBranch(branchName) {
152
+ const cpIds = this.listAllCheckpointIds();
153
+ const sessions = [];
154
+ for (const cpId of cpIds) {
155
+ const meta = this.fetchCheckpointMeta(cpId);
156
+ if (!meta) continue;
157
+ if (meta.branch !== branchName) continue;
158
+ sessions.push(...this.buildSessionsForCheckpoint(cpId, meta));
159
+ }
160
+ sessions.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
161
+ return sessions;
162
+ }
163
+ /**
164
+ * Sessions linked to a specific commit via the Entire-Checkpoint git trailer.
165
+ */
166
+ async resolveByCommit(commitHash) {
167
+ const fullHash = this.git("rev-parse", commitHash);
168
+ if (!fullHash) return [];
169
+ const cpId = this.git(
170
+ "log",
171
+ "-1",
172
+ "--format=%(trailers:key=Entire-Checkpoint,valueonly)",
173
+ fullHash
174
+ );
175
+ if (!cpId) return [];
176
+ return this.getSessionsForCheckpoint(cpId.trim());
177
+ }
178
+ /**
179
+ * All sessions from a merged PR (by number or GitHub URL).
180
+ */
181
+ async resolveByPr(prInput) {
182
+ let prNumber;
183
+ if (/^\d+$/.test(prInput)) {
184
+ prNumber = prInput;
185
+ } else {
186
+ const m = /\/pull\/(\d+)/.exec(prInput);
187
+ if (!m) return [];
188
+ prNumber = m[1];
189
+ }
190
+ const mergeOut = this.git(
191
+ "log",
192
+ "--all",
193
+ "--oneline",
194
+ "--grep",
195
+ `Merge pull request #${prNumber}`
196
+ );
197
+ if (!mergeOut) return [];
198
+ const mergeCommit = mergeOut.split("\n")[0].split(" ")[0];
199
+ const logOut = this.git(
200
+ "log",
201
+ "--format=%H|%(trailers:key=Entire-Checkpoint,valueonly)",
202
+ `${mergeCommit}^2`,
203
+ "--not",
204
+ `${mergeCommit}^1`
205
+ );
206
+ if (!logOut) return [];
207
+ const cpIds = _CheckpointReader.parseCheckpointTrailers(logOut);
208
+ const sessions = [];
209
+ for (const cpId of cpIds) {
210
+ sessions.push(...this.getSessionsForCheckpoint(cpId));
211
+ }
212
+ sessions.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
213
+ return sessions;
214
+ }
215
+ /**
216
+ * Sessions matching a specific checkpoint ID.
217
+ */
218
+ async resolveByCheckpoint(checkpointId) {
219
+ return this.getSessionsForCheckpoint(checkpointId);
220
+ }
221
+ /**
222
+ * Find a session by its UUID.
223
+ */
224
+ async resolveBySessionId(sessionId) {
225
+ const cpIds = this.listAllCheckpointIds();
226
+ for (const cpId of cpIds) {
227
+ const sessions = this.getSessionsForCheckpoint(cpId);
228
+ const match = sessions.find((s) => s.sessionId === sessionId);
229
+ if (match) return [match];
230
+ }
231
+ return [];
232
+ }
233
+ /**
234
+ * Latest N sessions across all checkpoints, sorted by createdAt descending.
235
+ */
236
+ async resolveLatest(count) {
237
+ const cpIds = this.listAllCheckpointIds();
238
+ const all = [];
239
+ for (const cpId of cpIds) {
240
+ all.push(...this.getSessionsForCheckpoint(cpId));
241
+ }
242
+ all.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
243
+ return all.slice(0, count);
244
+ }
245
+ /**
246
+ * Read the full JSONL transcript content from the entire branch.
247
+ */
248
+ getTranscript(transcriptPath) {
249
+ const normalized = transcriptPath.startsWith("/") ? transcriptPath.slice(1) : transcriptPath;
250
+ return this.git("show", `${ENTIRE_BRANCH}:${normalized}`);
251
+ }
252
+ };
253
+
254
+ export {
255
+ DEFAULT_MAX_TOKENS,
256
+ TOKENS_PER_TURN_ESTIMATE,
257
+ CheckpointReader
258
+ };
259
+ //# sourceMappingURL=chunk-APS6UEFU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plugins/context/context-provider.ts","../../src/plugins/context/entire/checkpoint-reader.ts"],"sourcesContent":["// NOTE: This interface is designed around Entire as the first provider.\n// It may evolve when additional providers (Cursor history, Zed, etc.) are added.\n// Providers may only support a subset of query types and should return empty results\n// for unsupported types rather than throwing.\n\nexport interface ContextProvider {\n readonly name: string;\n isAvailable(repoPath: string): Promise<boolean>;\n listSessions(query: ContextQuery): Promise<SessionListResult>;\n buildContext(query: ContextQuery, options?: ContextOptions): Promise<ContextResult>;\n}\n\nexport interface ContextQuery {\n repoPath: string;\n type: \"branch\" | \"commit\" | \"pr\" | \"latest\" | \"checkpoint\" | \"session\";\n value: string;\n}\n\nexport interface ContextOptions {\n maxTokens?: number;\n limit?: number;\n}\n\nexport interface SessionInfo {\n checkpointId: string;\n sessionIndex: string;\n transcriptPath: string;\n createdAt: string;\n endedAt: string;\n branch: string;\n agent: string;\n turnCount: number;\n filesTouched: string[];\n sessionId: string;\n}\n\nexport interface SessionListResult {\n sessions: SessionInfo[];\n estimatedTokens: number;\n}\n\nexport type ContextMode = \"full\" | \"balanced\" | \"compact\";\n\nexport interface ContextResult {\n markdown: string;\n tokenEstimate: number;\n sessionCount: number;\n totalTurns: number;\n mode: ContextMode;\n truncated: boolean;\n timeRange: { start: string; end: string };\n}\n\nexport const DEFAULT_MAX_TOKENS = 30_000;\nexport const TOKENS_PER_TURN_ESTIMATE = 400;\n","import { execFileSync } from \"child_process\";\nimport type { SessionInfo } from \"../context-provider.js\";\n\n// ─── Internal types ────────────────────────────────────────────────────────────\n\ninterface CheckpointMeta {\n checkpoint_id?: string;\n branch?: string;\n files_touched?: string[];\n sessions: Array<{\n metadata: string;\n transcript: string;\n }>;\n}\n\ninterface SessionMeta {\n session_id?: string;\n created_at?: string;\n branch?: string;\n agent?: string;\n files_touched?: string[];\n session_metrics?: {\n turn_count?: number;\n };\n}\n\n// ─── CheckpointReader ─────────────────────────────────────────────────────────\n\nconst ENTIRE_BRANCH = \"origin/entire/checkpoints/v1\";\nconst CHECKPOINT_ID_RE = /^[0-9a-f]{12}$/;\nconst SESSION_ID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\nexport class CheckpointReader {\n constructor(private readonly repoPath: string) {}\n\n // ─── Git execution ───────────────────────────────────────────────────────────\n\n /**\n * Run a git command in the repo directory.\n * Returns trimmed stdout on success, empty string on failure.\n */\n private git(...args: string[]): string {\n try {\n return execFileSync(\"git\", [\"-C\", this.repoPath, ...args], {\n encoding: \"utf-8\",\n }).trim();\n } catch {\n return \"\";\n }\n }\n\n // ─── Static helpers ──────────────────────────────────────────────────────────\n\n /**\n * Convert a 12-char checkpoint ID to its shard path: \"f634acf05138\" → \"f6/34acf05138\"\n */\n static shardPath(cpId: string): string {\n return `${cpId.slice(0, 2)}/${cpId.slice(2)}`;\n }\n\n /**\n * Returns true when value looks like a 12-char lowercase hex checkpoint ID.\n */\n static isCheckpointId(value: string): boolean {\n return CHECKPOINT_ID_RE.test(value);\n }\n\n /**\n * Returns true when value looks like a UUID (session ID).\n */\n static isSessionId(value: string): boolean {\n return SESSION_ID_RE.test(value);\n }\n\n /**\n * Parse checkpoint-level metadata JSON. Returns null on error.\n */\n static parseCheckpointMeta(json: string): CheckpointMeta | null {\n try {\n const parsed = JSON.parse(json) as CheckpointMeta;\n if (!parsed || typeof parsed !== \"object\") return null;\n if (!Array.isArray(parsed.sessions)) return null;\n return parsed;\n } catch {\n return null;\n }\n }\n\n /**\n * Extract Entire-Checkpoint trailer IDs from `git log --format=\"%H|%(trailers:...)\"` output.\n * Each line is: `<hash>|<trailer_value_or_empty>`. Returns only non-empty trailer values.\n * Uses the last pipe on each line to locate the trailer value, to be robust against\n * subject lines that contain pipes.\n */\n static parseCheckpointTrailers(output: string): string[] {\n const ids: string[] = [];\n for (const line of output.split(\"\\n\")) {\n const pipe = line.lastIndexOf(\"|\");\n if (pipe === -1) continue;\n const trailerId = line.slice(pipe + 1).trim();\n if (trailerId) ids.push(trailerId);\n }\n return ids;\n }\n\n // ─── Branch check ────────────────────────────────────────────────────────────\n\n async hasEntireBranch(): Promise<boolean> {\n const out = this.git(\"branch\", \"-r\");\n return out.includes(\"entire/checkpoints/v1\");\n }\n\n // ─── Core session fetching ───────────────────────────────────────────────────\n\n private listAllCheckpointIds(): string[] {\n const out = this.git(\n \"ls-tree\",\n \"-r\",\n ENTIRE_BRANCH,\n \"--name-only\"\n );\n if (!out) return [];\n\n const ids = new Set<string>();\n for (const file of out.split(\"\\n\")) {\n const parts = file.split(\"/\");\n // Checkpoint-level metadata: XX/YYYYYYYYYY/metadata.json (3 parts)\n if (parts.length === 3 && parts[2] === \"metadata.json\") {\n ids.add(parts[0] + parts[1]);\n }\n }\n return [...ids];\n }\n\n private fetchCheckpointMeta(cpId: string): CheckpointMeta | null {\n const shard = CheckpointReader.shardPath(cpId);\n const raw = this.git(\"show\", `${ENTIRE_BRANCH}:${shard}/metadata.json`);\n if (!raw) return null;\n return CheckpointReader.parseCheckpointMeta(raw);\n }\n\n private fetchSessionMeta(metaPath: string): SessionMeta {\n const normalized = metaPath.startsWith(\"/\") ? metaPath.slice(1) : metaPath;\n const raw = this.git(\"show\", `${ENTIRE_BRANCH}:${normalized}`);\n if (!raw) return {};\n try {\n return JSON.parse(raw) as SessionMeta;\n } catch {\n return {};\n }\n }\n\n /**\n * Build SessionInfo[] from a single checkpoint's metadata.\n */\n private buildSessionsForCheckpoint(\n cpId: string,\n cpMeta: CheckpointMeta\n ): SessionInfo[] {\n const sessions: SessionInfo[] = [];\n\n for (let idx = 0; idx < cpMeta.sessions.length; idx++) {\n const sess = cpMeta.sessions[idx];\n const transcriptPath = (sess.transcript ?? \"\").replace(/^\\//, \"\");\n const metaPath = sess.metadata ?? \"\";\n\n const smeta = this.fetchSessionMeta(metaPath);\n const createdAt = smeta.created_at ?? \"\";\n\n sessions.push({\n checkpointId: cpId,\n sessionIndex: String(idx),\n transcriptPath,\n createdAt,\n endedAt: createdAt, // will be filled from JSONL by conversation builder\n branch: smeta.branch ?? cpMeta.branch ?? \"\",\n agent: smeta.agent ?? \"\",\n turnCount: smeta.session_metrics?.turn_count ?? 0,\n filesTouched: smeta.files_touched ?? cpMeta.files_touched ?? [],\n sessionId: smeta.session_id ?? \"\",\n });\n }\n\n return sessions;\n }\n\n private getSessionsForCheckpoint(cpId: string): SessionInfo[] {\n const meta = this.fetchCheckpointMeta(cpId);\n if (!meta) return [];\n return this.buildSessionsForCheckpoint(cpId, meta);\n }\n\n // ─── Public resolvers ────────────────────────────────────────────────────────\n\n /**\n * All sessions recorded on a given branch, sorted by createdAt ascending.\n */\n async resolveByBranch(branchName: string): Promise<SessionInfo[]> {\n const cpIds = this.listAllCheckpointIds();\n const sessions: SessionInfo[] = [];\n\n for (const cpId of cpIds) {\n const meta = this.fetchCheckpointMeta(cpId);\n if (!meta) continue;\n if (meta.branch !== branchName) continue;\n sessions.push(...this.buildSessionsForCheckpoint(cpId, meta));\n }\n\n sessions.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n return sessions;\n }\n\n /**\n * Sessions linked to a specific commit via the Entire-Checkpoint git trailer.\n */\n async resolveByCommit(commitHash: string): Promise<SessionInfo[]> {\n const fullHash = this.git(\"rev-parse\", commitHash);\n if (!fullHash) return [];\n\n const cpId = this.git(\n \"log\",\n \"-1\",\n \"--format=%(trailers:key=Entire-Checkpoint,valueonly)\",\n fullHash\n );\n if (!cpId) return [];\n\n return this.getSessionsForCheckpoint(cpId.trim());\n }\n\n /**\n * All sessions from a merged PR (by number or GitHub URL).\n */\n async resolveByPr(prInput: string): Promise<SessionInfo[]> {\n let prNumber: string;\n\n if (/^\\d+$/.test(prInput)) {\n prNumber = prInput;\n } else {\n const m = /\\/pull\\/(\\d+)/.exec(prInput);\n if (!m) return [];\n prNumber = m[1];\n }\n\n const mergeOut = this.git(\n \"log\",\n \"--all\",\n \"--oneline\",\n \"--grep\",\n `Merge pull request #${prNumber}`\n );\n if (!mergeOut) return [];\n\n const mergeCommit = mergeOut.split(\"\\n\")[0].split(\" \")[0];\n\n const logOut = this.git(\n \"log\",\n \"--format=%H|%(trailers:key=Entire-Checkpoint,valueonly)\",\n `${mergeCommit}^2`,\n \"--not\",\n `${mergeCommit}^1`\n );\n if (!logOut) return [];\n\n const cpIds = CheckpointReader.parseCheckpointTrailers(logOut);\n const sessions: SessionInfo[] = [];\n\n for (const cpId of cpIds) {\n sessions.push(...this.getSessionsForCheckpoint(cpId));\n }\n\n sessions.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n return sessions;\n }\n\n /**\n * Sessions matching a specific checkpoint ID.\n */\n async resolveByCheckpoint(checkpointId: string): Promise<SessionInfo[]> {\n return this.getSessionsForCheckpoint(checkpointId);\n }\n\n /**\n * Find a session by its UUID.\n */\n async resolveBySessionId(sessionId: string): Promise<SessionInfo[]> {\n const cpIds = this.listAllCheckpointIds();\n\n for (const cpId of cpIds) {\n const sessions = this.getSessionsForCheckpoint(cpId);\n const match = sessions.find((s) => s.sessionId === sessionId);\n if (match) return [match];\n }\n\n return [];\n }\n\n /**\n * Latest N sessions across all checkpoints, sorted by createdAt descending.\n */\n async resolveLatest(count: number): Promise<SessionInfo[]> {\n const cpIds = this.listAllCheckpointIds();\n const all: SessionInfo[] = [];\n\n for (const cpId of cpIds) {\n all.push(...this.getSessionsForCheckpoint(cpId));\n }\n\n all.sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n return all.slice(0, count);\n }\n\n /**\n * Read the full JSONL transcript content from the entire branch.\n */\n getTranscript(transcriptPath: string): string {\n const normalized = transcriptPath.startsWith(\"/\")\n ? transcriptPath.slice(1)\n : transcriptPath;\n return this.git(\"show\", `${ENTIRE_BRANCH}:${normalized}`);\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,113 @@
1
+ // src/plugins/file-service/file-service.ts
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import { OggOpusDecoder } from "ogg-opus-decoder";
5
+ import wav from "node-wav";
6
+ var MIME_TO_EXT = {
7
+ "image/jpeg": ".jpg",
8
+ "image/png": ".png",
9
+ "image/gif": ".gif",
10
+ "image/webp": ".webp",
11
+ "image/svg+xml": ".svg",
12
+ "audio/ogg": ".ogg",
13
+ "audio/mpeg": ".mp3",
14
+ "audio/wav": ".wav",
15
+ "audio/webm": ".webm",
16
+ "audio/mp4": ".m4a",
17
+ "video/mp4": ".mp4",
18
+ "video/webm": ".webm",
19
+ "application/pdf": ".pdf",
20
+ "text/plain": ".txt"
21
+ };
22
+ var EXT_TO_MIME = {
23
+ ".jpg": "image/jpeg",
24
+ ".jpeg": "image/jpeg",
25
+ ".png": "image/png",
26
+ ".gif": "image/gif",
27
+ ".webp": "image/webp",
28
+ ".svg": "image/svg+xml",
29
+ ".ogg": "audio/ogg",
30
+ ".oga": "audio/ogg",
31
+ ".mp3": "audio/mpeg",
32
+ ".wav": "audio/wav",
33
+ ".m4a": "audio/mp4",
34
+ ".mp4": "video/mp4",
35
+ ".pdf": "application/pdf",
36
+ ".txt": "text/plain"
37
+ };
38
+ function classifyMime(mimeType) {
39
+ if (mimeType.startsWith("image/")) return "image";
40
+ if (mimeType.startsWith("audio/")) return "audio";
41
+ return "file";
42
+ }
43
+ var FileService = class _FileService {
44
+ constructor(baseDir) {
45
+ this.baseDir = baseDir;
46
+ }
47
+ async saveFile(sessionId, fileName, data, mimeType) {
48
+ const sessionDir = path.join(this.baseDir, sessionId);
49
+ await fs.promises.mkdir(sessionDir, { recursive: true });
50
+ const safeName = `${Date.now()}-${fileName.replace(/[^a-zA-Z0-9._-]/g, "_")}`;
51
+ const filePath = path.join(sessionDir, safeName);
52
+ await fs.promises.writeFile(filePath, data);
53
+ return {
54
+ type: classifyMime(mimeType),
55
+ filePath,
56
+ fileName,
57
+ mimeType,
58
+ size: data.length
59
+ };
60
+ }
61
+ async resolveFile(filePath) {
62
+ try {
63
+ const stat = await fs.promises.stat(filePath);
64
+ if (!stat.isFile()) return null;
65
+ const ext = path.extname(filePath).toLowerCase();
66
+ const mimeType = EXT_TO_MIME[ext] || "application/octet-stream";
67
+ return {
68
+ type: classifyMime(mimeType),
69
+ filePath,
70
+ fileName: path.basename(filePath),
71
+ mimeType,
72
+ size: stat.size
73
+ };
74
+ } catch {
75
+ return null;
76
+ }
77
+ }
78
+ /**
79
+ * Convert OGG Opus audio to WAV format.
80
+ * Telegram voice messages use OGG Opus which many AI agents can't read.
81
+ */
82
+ async convertOggToWav(oggData) {
83
+ const decoder = new OggOpusDecoder();
84
+ await decoder.ready;
85
+ try {
86
+ const { channelData, sampleRate } = await decoder.decode(new Uint8Array(oggData));
87
+ const wavData = wav.encode(channelData, { sampleRate, float: true, bitDepth: 32 });
88
+ return Buffer.from(wavData);
89
+ } finally {
90
+ decoder.free();
91
+ }
92
+ }
93
+ /** Instance method — delegates to static for FileServiceInterface compliance */
94
+ async readTextFileWithRange(filePath, options) {
95
+ return _FileService.readTextFileWithRange(filePath, options);
96
+ }
97
+ static async readTextFileWithRange(filePath, options) {
98
+ const { readTextFileWithRange } = await import("./read-text-file-IRZM3QLM.js");
99
+ return readTextFileWithRange(filePath, options);
100
+ }
101
+ /** Instance method — delegates to static for FileServiceInterface compliance */
102
+ extensionFromMime(mimeType) {
103
+ return _FileService.extensionFromMime(mimeType);
104
+ }
105
+ static extensionFromMime(mimeType) {
106
+ return MIME_TO_EXT[mimeType] || ".bin";
107
+ }
108
+ };
109
+
110
+ export {
111
+ FileService
112
+ };
113
+ //# sourceMappingURL=chunk-BLQUXO7S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plugins/file-service/file-service.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { OggOpusDecoder } from \"ogg-opus-decoder\";\nimport wav from \"node-wav\";\nimport type { Attachment } from \"../../core/types.js\";\n\nconst MIME_TO_EXT: Record<string, string> = {\n \"image/jpeg\": \".jpg\",\n \"image/png\": \".png\",\n \"image/gif\": \".gif\",\n \"image/webp\": \".webp\",\n \"image/svg+xml\": \".svg\",\n \"audio/ogg\": \".ogg\",\n \"audio/mpeg\": \".mp3\",\n \"audio/wav\": \".wav\",\n \"audio/webm\": \".webm\",\n \"audio/mp4\": \".m4a\",\n \"video/mp4\": \".mp4\",\n \"video/webm\": \".webm\",\n \"application/pdf\": \".pdf\",\n \"text/plain\": \".txt\",\n};\n\nconst EXT_TO_MIME: Record<string, string> = {\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".png\": \"image/png\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".ogg\": \"audio/ogg\",\n \".oga\": \"audio/ogg\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".m4a\": \"audio/mp4\",\n \".mp4\": \"video/mp4\",\n \".pdf\": \"application/pdf\",\n \".txt\": \"text/plain\",\n};\n\nfunction classifyMime(mimeType: string): Attachment[\"type\"] {\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n return \"file\";\n}\n\nexport class FileService {\n constructor(private baseDir: string) {}\n\n async saveFile(\n sessionId: string,\n fileName: string,\n data: Buffer,\n mimeType: string,\n ): Promise<Attachment> {\n const sessionDir = path.join(this.baseDir, sessionId);\n await fs.promises.mkdir(sessionDir, { recursive: true });\n\n const safeName = `${Date.now()}-${fileName.replace(/[^a-zA-Z0-9._-]/g, \"_\")}`;\n const filePath = path.join(sessionDir, safeName);\n await fs.promises.writeFile(filePath, data);\n\n return {\n type: classifyMime(mimeType),\n filePath,\n fileName,\n mimeType,\n size: data.length,\n };\n }\n\n async resolveFile(filePath: string): Promise<Attachment | null> {\n try {\n const stat = await fs.promises.stat(filePath);\n if (!stat.isFile()) return null;\n\n const ext = path.extname(filePath).toLowerCase();\n const mimeType = EXT_TO_MIME[ext] || \"application/octet-stream\";\n\n return {\n type: classifyMime(mimeType),\n filePath,\n fileName: path.basename(filePath),\n mimeType,\n size: stat.size,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Convert OGG Opus audio to WAV format.\n * Telegram voice messages use OGG Opus which many AI agents can't read.\n */\n async convertOggToWav(oggData: Buffer): Promise<Buffer> {\n const decoder = new OggOpusDecoder();\n await decoder.ready;\n try {\n const { channelData, sampleRate } = await decoder.decode(new Uint8Array(oggData));\n const wavData = wav.encode(channelData, { sampleRate, float: true, bitDepth: 32 });\n return Buffer.from(wavData);\n } finally {\n decoder.free();\n }\n }\n\n /** Instance method — delegates to static for FileServiceInterface compliance */\n async readTextFileWithRange(\n filePath: string,\n options?: { line?: number; limit?: number },\n ): Promise<string> {\n return FileService.readTextFileWithRange(filePath, options);\n }\n\n static async readTextFileWithRange(\n filePath: string,\n options?: { line?: number; limit?: number },\n ): Promise<string> {\n // Delegate to core utility (canonical implementation)\n const { readTextFileWithRange } = await import(\"../../core/utils/read-text-file.js\");\n return readTextFileWithRange(filePath, options);\n }\n\n /** Instance method — delegates to static for FileServiceInterface compliance */\n extensionFromMime(mimeType: string): string {\n return FileService.extensionFromMime(mimeType);\n }\n\n static extensionFromMime(mimeType: string): string {\n return MIME_TO_EXT[mimeType] || \".bin\";\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  expandHome
3
- } from "./chunk-33RP6K2O.js";
3
+ } from "./chunk-QVMEF6FB.js";
4
4
 
5
- // src/core/daemon.ts
5
+ // src/cli/daemon.ts
6
6
  import { spawn } from "child_process";
7
7
  import * as fs from "fs";
8
8
  import * as path from "path";
@@ -169,4 +169,4 @@ export {
169
169
  clearRunning,
170
170
  shouldAutoStart
171
171
  };
172
- //# sourceMappingURL=chunk-WTZDAYZX.js.map
172
+ //# sourceMappingURL=chunk-BQ6FR32N.js.map