beecork 1.2.0 → 1.3.1

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 (390) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -0
  3. package/dist/capabilities/index.d.ts +0 -1
  4. package/dist/capabilities/index.js +0 -1
  5. package/dist/capabilities/manager.d.ts +0 -1
  6. package/dist/capabilities/manager.js +0 -1
  7. package/dist/capabilities/packs.d.ts +0 -1
  8. package/dist/capabilities/packs.js +7 -8
  9. package/dist/capabilities/types.d.ts +0 -1
  10. package/dist/capabilities/types.js +0 -1
  11. package/dist/channels/command-handler.d.ts +0 -1
  12. package/dist/channels/command-handler.js +26 -1
  13. package/dist/channels/discord.d.ts +1 -1
  14. package/dist/channels/discord.js +36 -47
  15. package/dist/channels/index.d.ts +0 -1
  16. package/dist/channels/index.js +0 -1
  17. package/dist/channels/loader.d.ts +0 -1
  18. package/dist/channels/loader.js +6 -1
  19. package/dist/channels/pipeline.d.ts +50 -0
  20. package/dist/channels/pipeline.js +83 -0
  21. package/dist/channels/registry.d.ts +0 -1
  22. package/dist/channels/registry.js +0 -1
  23. package/dist/channels/telegram.d.ts +1 -1
  24. package/dist/channels/telegram.js +99 -60
  25. package/dist/channels/types.d.ts +0 -1
  26. package/dist/channels/types.js +0 -1
  27. package/dist/channels/webhook.d.ts +0 -1
  28. package/dist/channels/webhook.js +0 -1
  29. package/dist/channels/whatsapp.d.ts +1 -1
  30. package/dist/channels/whatsapp.js +26 -52
  31. package/dist/cli/capabilities.d.ts +0 -1
  32. package/dist/cli/capabilities.js +0 -1
  33. package/dist/cli/channel.d.ts +0 -1
  34. package/dist/cli/channel.js +1 -2
  35. package/dist/cli/commands.d.ts +2 -1
  36. package/dist/cli/commands.js +49 -15
  37. package/dist/cli/doctor.d.ts +0 -1
  38. package/dist/cli/doctor.js +2 -2
  39. package/dist/cli/handoff.d.ts +0 -1
  40. package/dist/cli/handoff.js +0 -1
  41. package/dist/cli/helpers.d.ts +0 -1
  42. package/dist/cli/helpers.js +0 -1
  43. package/dist/cli/mcp.d.ts +0 -1
  44. package/dist/cli/mcp.js +0 -1
  45. package/dist/cli/media.d.ts +0 -1
  46. package/dist/cli/media.js +0 -1
  47. package/dist/cli/setup.d.ts +0 -1
  48. package/dist/cli/setup.js +13 -12
  49. package/dist/cli/store.d.ts +3 -0
  50. package/dist/cli/store.js +91 -0
  51. package/dist/config.d.ts +0 -1
  52. package/dist/config.js +0 -1
  53. package/dist/daemon.d.ts +0 -1
  54. package/dist/daemon.js +21 -11
  55. package/dist/dashboard/html.d.ts +0 -1
  56. package/dist/dashboard/html.js +169 -42
  57. package/dist/dashboard/server.d.ts +0 -1
  58. package/dist/dashboard/server.js +166 -35
  59. package/dist/db/index.d.ts +11 -1
  60. package/dist/db/index.js +12 -1
  61. package/dist/db/migrations.d.ts +0 -1
  62. package/dist/db/migrations.js +44 -1
  63. package/dist/delegation/manager.d.ts +0 -3
  64. package/dist/delegation/manager.js +0 -5
  65. package/dist/index.d.ts +0 -1
  66. package/dist/index.js +124 -6
  67. package/dist/knowledge/index.d.ts +2 -0
  68. package/dist/knowledge/index.js +1 -0
  69. package/dist/knowledge/manager.d.ts +17 -0
  70. package/dist/knowledge/manager.js +146 -0
  71. package/dist/knowledge/types.d.ts +7 -0
  72. package/dist/knowledge/types.js +1 -0
  73. package/dist/machines/index.d.ts +1 -3
  74. package/dist/machines/index.js +1 -3
  75. package/dist/machines/registry.d.ts +0 -7
  76. package/dist/machines/registry.js +0 -25
  77. package/dist/mcp/server.d.ts +0 -1
  78. package/dist/mcp/server.js +275 -80
  79. package/dist/media/factory.d.ts +0 -1
  80. package/dist/media/factory.js +0 -1
  81. package/dist/media/generators/dall-e.d.ts +0 -1
  82. package/dist/media/generators/dall-e.js +0 -1
  83. package/dist/media/generators/elevenlabs-music.d.ts +0 -1
  84. package/dist/media/generators/elevenlabs-music.js +0 -1
  85. package/dist/media/generators/elevenlabs-sfx.d.ts +0 -1
  86. package/dist/media/generators/elevenlabs-sfx.js +0 -1
  87. package/dist/media/generators/kling.d.ts +0 -1
  88. package/dist/media/generators/kling.js +14 -20
  89. package/dist/media/generators/lyria.d.ts +0 -1
  90. package/dist/media/generators/lyria.js +0 -1
  91. package/dist/media/generators/nano-banana.d.ts +0 -1
  92. package/dist/media/generators/nano-banana.js +0 -1
  93. package/dist/media/generators/poll-util.d.ts +12 -0
  94. package/dist/media/generators/poll-util.js +22 -0
  95. package/dist/media/generators/recraft.d.ts +0 -1
  96. package/dist/media/generators/recraft.js +0 -1
  97. package/dist/media/generators/runway.d.ts +0 -1
  98. package/dist/media/generators/runway.js +14 -23
  99. package/dist/media/generators/stable-diffusion.d.ts +0 -1
  100. package/dist/media/generators/stable-diffusion.js +0 -1
  101. package/dist/media/generators/veo.d.ts +0 -1
  102. package/dist/media/generators/veo.js +0 -1
  103. package/dist/media/index.d.ts +0 -2
  104. package/dist/media/index.js +0 -2
  105. package/dist/media/store.d.ts +0 -1
  106. package/dist/media/store.js +0 -1
  107. package/dist/media/types.d.ts +0 -1
  108. package/dist/media/types.js +0 -1
  109. package/dist/memory/extractor.d.ts +0 -1
  110. package/dist/memory/extractor.js +8 -3
  111. package/dist/notifications/index.d.ts +0 -1
  112. package/dist/notifications/index.js +0 -1
  113. package/dist/notifications/ntfy.d.ts +0 -1
  114. package/dist/notifications/ntfy.js +0 -1
  115. package/dist/notifications/pushover.d.ts +0 -1
  116. package/dist/notifications/pushover.js +0 -1
  117. package/dist/notifications/types.d.ts +0 -1
  118. package/dist/notifications/types.js +0 -1
  119. package/dist/notifications/webhook-provider.d.ts +0 -1
  120. package/dist/notifications/webhook-provider.js +0 -1
  121. package/dist/observability/analytics.d.ts +0 -1
  122. package/dist/observability/analytics.js +1 -2
  123. package/dist/pipe/anthropic-client.d.ts +0 -1
  124. package/dist/pipe/anthropic-client.js +5 -3
  125. package/dist/pipe/brain.d.ts +0 -1
  126. package/dist/pipe/brain.js +0 -1
  127. package/dist/pipe/memory-store.d.ts +0 -1
  128. package/dist/pipe/memory-store.js +0 -1
  129. package/dist/pipe/project-scanner.d.ts +5 -3
  130. package/dist/pipe/project-scanner.js +21 -90
  131. package/dist/pipe/types.d.ts +0 -11
  132. package/dist/pipe/types.js +0 -1
  133. package/dist/projects/index.d.ts +0 -1
  134. package/dist/projects/index.js +0 -1
  135. package/dist/projects/manager.d.ts +0 -1
  136. package/dist/projects/manager.js +0 -1
  137. package/dist/projects/router.d.ts +0 -1
  138. package/dist/projects/router.js +1 -2
  139. package/dist/projects/types.d.ts +0 -7
  140. package/dist/projects/types.js +0 -1
  141. package/dist/service/install.d.ts +0 -1
  142. package/dist/service/install.js +0 -1
  143. package/dist/service/templates.d.ts +0 -1
  144. package/dist/service/templates.js +0 -1
  145. package/dist/service/windows.d.ts +0 -3
  146. package/dist/service/windows.js +0 -11
  147. package/dist/session/circuit-breaker.d.ts +0 -1
  148. package/dist/session/circuit-breaker.js +0 -1
  149. package/dist/session/context-monitor.d.ts +0 -1
  150. package/dist/session/context-monitor.js +0 -1
  151. package/dist/session/manager.d.ts +0 -1
  152. package/dist/session/manager.js +18 -6
  153. package/dist/session/subprocess.d.ts +0 -1
  154. package/dist/session/subprocess.js +0 -1
  155. package/dist/session/tool-classifier.d.ts +0 -1
  156. package/dist/session/tool-classifier.js +0 -1
  157. package/dist/{cron → tasks}/scheduler.d.ts +5 -4
  158. package/dist/{cron → tasks}/scheduler.js +31 -29
  159. package/dist/tasks/store.d.ts +11 -0
  160. package/dist/{cron → tasks}/store.js +12 -13
  161. package/dist/timeline/index.d.ts +3 -0
  162. package/dist/timeline/index.js +2 -0
  163. package/dist/timeline/logger.d.ts +8 -0
  164. package/dist/timeline/logger.js +9 -0
  165. package/dist/timeline/query.d.ts +11 -0
  166. package/dist/timeline/query.js +57 -0
  167. package/dist/timeline/types.d.ts +12 -0
  168. package/dist/timeline/types.js +1 -0
  169. package/dist/types.d.ts +6 -6
  170. package/dist/types.js +0 -1
  171. package/dist/users/index.d.ts +1 -2
  172. package/dist/users/index.js +1 -2
  173. package/dist/users/service.d.ts +0 -8
  174. package/dist/users/service.js +0 -19
  175. package/dist/util/logger.d.ts +0 -1
  176. package/dist/util/logger.js +0 -1
  177. package/dist/util/paths.d.ts +0 -1
  178. package/dist/util/paths.js +0 -1
  179. package/dist/util/platform.d.ts +0 -1
  180. package/dist/util/platform.js +0 -1
  181. package/dist/util/progress.d.ts +0 -1
  182. package/dist/util/progress.js +0 -1
  183. package/dist/util/rate-limiter.d.ts +0 -1
  184. package/dist/util/rate-limiter.js +0 -1
  185. package/dist/util/retry.d.ts +0 -1
  186. package/dist/util/retry.js +1 -2
  187. package/dist/util/text.d.ts +0 -1
  188. package/dist/util/text.js +0 -1
  189. package/dist/version.d.ts +0 -1
  190. package/dist/version.js +0 -1
  191. package/dist/voice/index.d.ts +8 -1
  192. package/dist/voice/index.js +23 -1
  193. package/dist/voice/stt.d.ts +2 -1
  194. package/dist/voice/stt.js +10 -1
  195. package/dist/voice/tts.d.ts +0 -1
  196. package/dist/voice/tts.js +0 -1
  197. package/dist/watchers/evaluator.d.ts +5 -0
  198. package/dist/watchers/evaluator.js +45 -0
  199. package/dist/watchers/index.d.ts +4 -0
  200. package/dist/watchers/index.js +3 -0
  201. package/dist/watchers/scheduler.d.ts +13 -0
  202. package/dist/watchers/scheduler.js +133 -0
  203. package/dist/watchers/store.d.ts +10 -0
  204. package/dist/watchers/store.js +56 -0
  205. package/dist/watchers/types.d.ts +15 -0
  206. package/dist/watchers/types.js +1 -0
  207. package/package.json +25 -2
  208. package/dist/capabilities/index.d.ts.map +0 -1
  209. package/dist/capabilities/index.js.map +0 -1
  210. package/dist/capabilities/manager.d.ts.map +0 -1
  211. package/dist/capabilities/manager.js.map +0 -1
  212. package/dist/capabilities/packs.d.ts.map +0 -1
  213. package/dist/capabilities/packs.js.map +0 -1
  214. package/dist/capabilities/types.d.ts.map +0 -1
  215. package/dist/capabilities/types.js.map +0 -1
  216. package/dist/channels/command-handler.d.ts.map +0 -1
  217. package/dist/channels/command-handler.js.map +0 -1
  218. package/dist/channels/discord.d.ts.map +0 -1
  219. package/dist/channels/discord.js.map +0 -1
  220. package/dist/channels/index.d.ts.map +0 -1
  221. package/dist/channels/index.js.map +0 -1
  222. package/dist/channels/loader.d.ts.map +0 -1
  223. package/dist/channels/loader.js.map +0 -1
  224. package/dist/channels/registry.d.ts.map +0 -1
  225. package/dist/channels/registry.js.map +0 -1
  226. package/dist/channels/telegram.d.ts.map +0 -1
  227. package/dist/channels/telegram.js.map +0 -1
  228. package/dist/channels/types.d.ts.map +0 -1
  229. package/dist/channels/types.js.map +0 -1
  230. package/dist/channels/webhook.d.ts.map +0 -1
  231. package/dist/channels/webhook.js.map +0 -1
  232. package/dist/channels/whatsapp.d.ts.map +0 -1
  233. package/dist/channels/whatsapp.js.map +0 -1
  234. package/dist/cli/capabilities.d.ts.map +0 -1
  235. package/dist/cli/capabilities.js.map +0 -1
  236. package/dist/cli/channel.d.ts.map +0 -1
  237. package/dist/cli/channel.js.map +0 -1
  238. package/dist/cli/commands.d.ts.map +0 -1
  239. package/dist/cli/commands.js.map +0 -1
  240. package/dist/cli/doctor.d.ts.map +0 -1
  241. package/dist/cli/doctor.js.map +0 -1
  242. package/dist/cli/handoff.d.ts.map +0 -1
  243. package/dist/cli/handoff.js.map +0 -1
  244. package/dist/cli/helpers.d.ts.map +0 -1
  245. package/dist/cli/helpers.js.map +0 -1
  246. package/dist/cli/mcp.d.ts.map +0 -1
  247. package/dist/cli/mcp.js.map +0 -1
  248. package/dist/cli/media.d.ts.map +0 -1
  249. package/dist/cli/media.js.map +0 -1
  250. package/dist/cli/setup.d.ts.map +0 -1
  251. package/dist/cli/setup.js.map +0 -1
  252. package/dist/config.d.ts.map +0 -1
  253. package/dist/config.js.map +0 -1
  254. package/dist/cron/scheduler.d.ts.map +0 -1
  255. package/dist/cron/scheduler.js.map +0 -1
  256. package/dist/cron/store.d.ts +0 -12
  257. package/dist/cron/store.d.ts.map +0 -1
  258. package/dist/cron/store.js.map +0 -1
  259. package/dist/daemon.d.ts.map +0 -1
  260. package/dist/daemon.js.map +0 -1
  261. package/dist/dashboard/html.d.ts.map +0 -1
  262. package/dist/dashboard/html.js.map +0 -1
  263. package/dist/dashboard/server.d.ts.map +0 -1
  264. package/dist/dashboard/server.js.map +0 -1
  265. package/dist/db/index.d.ts.map +0 -1
  266. package/dist/db/index.js.map +0 -1
  267. package/dist/db/migrations.d.ts.map +0 -1
  268. package/dist/db/migrations.js.map +0 -1
  269. package/dist/delegation/manager.d.ts.map +0 -1
  270. package/dist/delegation/manager.js.map +0 -1
  271. package/dist/index.d.ts.map +0 -1
  272. package/dist/index.js.map +0 -1
  273. package/dist/machines/forwarder.d.ts +0 -7
  274. package/dist/machines/forwarder.d.ts.map +0 -1
  275. package/dist/machines/forwarder.js +0 -35
  276. package/dist/machines/forwarder.js.map +0 -1
  277. package/dist/machines/index.d.ts.map +0 -1
  278. package/dist/machines/index.js.map +0 -1
  279. package/dist/machines/registry.d.ts.map +0 -1
  280. package/dist/machines/registry.js.map +0 -1
  281. package/dist/mcp/server.d.ts.map +0 -1
  282. package/dist/mcp/server.js.map +0 -1
  283. package/dist/media/factory.d.ts.map +0 -1
  284. package/dist/media/factory.js.map +0 -1
  285. package/dist/media/generators/dall-e.d.ts.map +0 -1
  286. package/dist/media/generators/dall-e.js.map +0 -1
  287. package/dist/media/generators/elevenlabs-music.d.ts.map +0 -1
  288. package/dist/media/generators/elevenlabs-music.js.map +0 -1
  289. package/dist/media/generators/elevenlabs-sfx.d.ts.map +0 -1
  290. package/dist/media/generators/elevenlabs-sfx.js.map +0 -1
  291. package/dist/media/generators/kling.d.ts.map +0 -1
  292. package/dist/media/generators/kling.js.map +0 -1
  293. package/dist/media/generators/lyria.d.ts.map +0 -1
  294. package/dist/media/generators/lyria.js.map +0 -1
  295. package/dist/media/generators/nano-banana.d.ts.map +0 -1
  296. package/dist/media/generators/nano-banana.js.map +0 -1
  297. package/dist/media/generators/recraft.d.ts.map +0 -1
  298. package/dist/media/generators/recraft.js.map +0 -1
  299. package/dist/media/generators/runway.d.ts.map +0 -1
  300. package/dist/media/generators/runway.js.map +0 -1
  301. package/dist/media/generators/stable-diffusion.d.ts.map +0 -1
  302. package/dist/media/generators/stable-diffusion.js.map +0 -1
  303. package/dist/media/generators/veo.d.ts.map +0 -1
  304. package/dist/media/generators/veo.js.map +0 -1
  305. package/dist/media/index.d.ts.map +0 -1
  306. package/dist/media/index.js.map +0 -1
  307. package/dist/media/loader.d.ts +0 -8
  308. package/dist/media/loader.d.ts.map +0 -1
  309. package/dist/media/loader.js +0 -46
  310. package/dist/media/loader.js.map +0 -1
  311. package/dist/media/store.d.ts.map +0 -1
  312. package/dist/media/store.js.map +0 -1
  313. package/dist/media/types.d.ts.map +0 -1
  314. package/dist/media/types.js.map +0 -1
  315. package/dist/memory/extractor.d.ts.map +0 -1
  316. package/dist/memory/extractor.js.map +0 -1
  317. package/dist/notifications/index.d.ts.map +0 -1
  318. package/dist/notifications/index.js.map +0 -1
  319. package/dist/notifications/ntfy.d.ts.map +0 -1
  320. package/dist/notifications/ntfy.js.map +0 -1
  321. package/dist/notifications/pushover.d.ts.map +0 -1
  322. package/dist/notifications/pushover.js.map +0 -1
  323. package/dist/notifications/types.d.ts.map +0 -1
  324. package/dist/notifications/types.js.map +0 -1
  325. package/dist/notifications/webhook-provider.d.ts.map +0 -1
  326. package/dist/notifications/webhook-provider.js.map +0 -1
  327. package/dist/observability/analytics.d.ts.map +0 -1
  328. package/dist/observability/analytics.js.map +0 -1
  329. package/dist/pipe/anthropic-client.d.ts.map +0 -1
  330. package/dist/pipe/anthropic-client.js.map +0 -1
  331. package/dist/pipe/brain.d.ts.map +0 -1
  332. package/dist/pipe/brain.js.map +0 -1
  333. package/dist/pipe/memory-store.d.ts.map +0 -1
  334. package/dist/pipe/memory-store.js.map +0 -1
  335. package/dist/pipe/project-scanner.d.ts.map +0 -1
  336. package/dist/pipe/project-scanner.js.map +0 -1
  337. package/dist/pipe/types.d.ts.map +0 -1
  338. package/dist/pipe/types.js.map +0 -1
  339. package/dist/projects/index.d.ts.map +0 -1
  340. package/dist/projects/index.js.map +0 -1
  341. package/dist/projects/manager.d.ts.map +0 -1
  342. package/dist/projects/manager.js.map +0 -1
  343. package/dist/projects/router.d.ts.map +0 -1
  344. package/dist/projects/router.js.map +0 -1
  345. package/dist/projects/types.d.ts.map +0 -1
  346. package/dist/projects/types.js.map +0 -1
  347. package/dist/service/install.d.ts.map +0 -1
  348. package/dist/service/install.js.map +0 -1
  349. package/dist/service/templates.d.ts.map +0 -1
  350. package/dist/service/templates.js.map +0 -1
  351. package/dist/service/windows.d.ts.map +0 -1
  352. package/dist/service/windows.js.map +0 -1
  353. package/dist/session/circuit-breaker.d.ts.map +0 -1
  354. package/dist/session/circuit-breaker.js.map +0 -1
  355. package/dist/session/context-monitor.d.ts.map +0 -1
  356. package/dist/session/context-monitor.js.map +0 -1
  357. package/dist/session/manager.d.ts.map +0 -1
  358. package/dist/session/manager.js.map +0 -1
  359. package/dist/session/subprocess.d.ts.map +0 -1
  360. package/dist/session/subprocess.js.map +0 -1
  361. package/dist/session/tool-classifier.d.ts.map +0 -1
  362. package/dist/session/tool-classifier.js.map +0 -1
  363. package/dist/types.d.ts.map +0 -1
  364. package/dist/types.js.map +0 -1
  365. package/dist/users/index.d.ts.map +0 -1
  366. package/dist/users/index.js.map +0 -1
  367. package/dist/users/service.d.ts.map +0 -1
  368. package/dist/users/service.js.map +0 -1
  369. package/dist/util/logger.d.ts.map +0 -1
  370. package/dist/util/logger.js.map +0 -1
  371. package/dist/util/paths.d.ts.map +0 -1
  372. package/dist/util/paths.js.map +0 -1
  373. package/dist/util/platform.d.ts.map +0 -1
  374. package/dist/util/platform.js.map +0 -1
  375. package/dist/util/progress.d.ts.map +0 -1
  376. package/dist/util/progress.js.map +0 -1
  377. package/dist/util/rate-limiter.d.ts.map +0 -1
  378. package/dist/util/rate-limiter.js.map +0 -1
  379. package/dist/util/retry.d.ts.map +0 -1
  380. package/dist/util/retry.js.map +0 -1
  381. package/dist/util/text.d.ts.map +0 -1
  382. package/dist/util/text.js.map +0 -1
  383. package/dist/version.d.ts.map +0 -1
  384. package/dist/version.js.map +0 -1
  385. package/dist/voice/index.d.ts.map +0 -1
  386. package/dist/voice/index.js.map +0 -1
  387. package/dist/voice/stt.d.ts.map +0 -1
  388. package/dist/voice/stt.js.map +0 -1
  389. package/dist/voice/tts.d.ts.map +0 -1
  390. package/dist/voice/tts.js.map +0 -1
@@ -49,4 +49,3 @@ export class ChannelRegistry {
49
49
  await Promise.all(Array.from(this.channels.values()).map(channel => channel.sendNotification(text, urgent).catch(err => logger.warn(`${channel.name} notify failed:`, err))));
50
50
  }
51
51
  }
52
- //# sourceMappingURL=registry.js.map
@@ -20,6 +20,7 @@ export declare class TelegramChannel implements Channel {
20
20
  private botUsername;
21
21
  private mutedGroups;
22
22
  private welcomeSent;
23
+ private sttWarmedUp;
23
24
  constructor(ctx: ChannelContext);
24
25
  start(): Promise<void>;
25
26
  stop(): void;
@@ -37,4 +38,3 @@ export declare class TelegramChannel implements Channel {
37
38
  private isAdmin;
38
39
  private setReaction;
39
40
  }
40
- //# sourceMappingURL=telegram.d.ts.map
@@ -1,14 +1,14 @@
1
1
  import TelegramBot from 'node-telegram-bot-api';
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
- import { chunkText, timeAgo, parseTabMessage, buildMediaPrompt } from '../util/text.js';
4
+ import { chunkText, timeAgo, parseTabMessage } from '../util/text.js';
5
5
  import { logger } from '../util/logger.js';
6
6
  import { retryWithBackoff } from '../util/retry.js';
7
7
  import { getAdminUserId } from '../config.js';
8
8
  import { getLogsDir } from '../util/paths.js';
9
9
  import { saveMedia, isOversized } from '../media/store.js';
10
10
  import { inboundLimiter, groupLimiter } from '../util/rate-limiter.js';
11
- import { ProgressTracker } from '../util/progress.js';
11
+ import { processInboundMessage } from './pipeline.js';
12
12
  import { initVoiceProviders } from '../voice/index.js';
13
13
  const DEFAULT_GROUP_CONFIG = { activationMode: 'mention', maxResponsesPerMinute: 3, tabPerGroup: true };
14
14
  /** Format tab status for Telegram display */
@@ -35,6 +35,7 @@ export class TelegramChannel {
35
35
  botUsername = null;
36
36
  mutedGroups = new Set();
37
37
  welcomeSent = new Set();
38
+ sttWarmedUp = false;
38
39
  constructor(ctx) {
39
40
  this.ctx = ctx;
40
41
  this.bot = new TelegramBot(ctx.config.telegram.token, {
@@ -193,6 +194,8 @@ export class TelegramChannel {
193
194
  text = text.replace(new RegExp(`@${this.botUsername}`, 'gi'), '').trim();
194
195
  }
195
196
  }
197
+ // Track voice pipeline timing
198
+ const voicePipelineStart = msg.voice ? Date.now() : null;
196
199
  // Download media if present (in parallel)
197
200
  const downloadTasks = [];
198
201
  if (msg.photo) {
@@ -228,17 +231,8 @@ export class TelegramChannel {
228
231
  .map(r => r.value);
229
232
  // Transcribe voice messages if STT is configured
230
233
  if (this.sttProvider) {
231
- for (const m of media) {
232
- if (m.type === 'voice' && m.filePath) {
233
- try {
234
- const transcription = await this.sttProvider.transcribe(m.filePath);
235
- m.caption = `[Transcribed from voice message]: ${transcription}`;
236
- }
237
- catch (err) {
238
- logger.warn('Voice transcription failed, passing file path instead:', err);
239
- }
240
- }
241
- }
234
+ const { transcribeVoiceMessages } = await import('../voice/index.js');
235
+ this.sttWarmedUp = await transcribeVoiceMessages(media, this.sttProvider, 'telegram', this.sttWarmedUp);
242
236
  }
243
237
  // Skip if no text AND no media
244
238
  if (!text && media.length === 0)
@@ -255,6 +249,9 @@ export class TelegramChannel {
255
249
  });
256
250
  logger.info(`[telegram] Message received from ${msg.from?.id}, sending typing`);
257
251
  await this.handleMessage(chatId, text, msg.message_id, media, isGroup);
252
+ if (voicePipelineStart) {
253
+ logger.info(`[telegram] Voice-to-response total: ${Date.now() - voicePipelineStart}ms`);
254
+ }
258
255
  }
259
256
  catch (err) {
260
257
  logger.error('Telegram: error handling message:', err);
@@ -274,6 +271,34 @@ export class TelegramChannel {
274
271
  await this.bot.sendMessage(chatId, 'Beecork unmuted in this group.');
275
272
  return;
276
273
  }
274
+ if (text === '/history' || text.startsWith('/history ')) {
275
+ const dateArg = text.slice(9).trim();
276
+ const { getTimeline, formatTimeline } = await import('../timeline/index.js');
277
+ let date;
278
+ if (dateArg === 'yesterday') {
279
+ date = new Date(Date.now() - 86400000).toISOString().slice(0, 10);
280
+ }
281
+ else if (dateArg) {
282
+ date = dateArg;
283
+ }
284
+ else {
285
+ date = new Date().toISOString().slice(0, 10);
286
+ }
287
+ const events = getTimeline({ date, limit: 30 });
288
+ await this.sendResponse(chatId, formatTimeline(events));
289
+ return;
290
+ }
291
+ if (text === '/knowledge') {
292
+ const { getAllKnowledge, formatKnowledgeForContext } = await import('../knowledge/index.js');
293
+ const entries = getAllKnowledge();
294
+ if (entries.length === 0) {
295
+ await this.bot.sendMessage(chatId, 'No knowledge stored yet. Beecork learns from your conversations.');
296
+ return;
297
+ }
298
+ const formatted = formatKnowledgeForContext(entries);
299
+ await this.sendResponse(chatId, formatted.slice(0, 4000));
300
+ return;
301
+ }
277
302
  // Shared command handler (covers /tabs, /stop, /tab, /projects, /project, /newproject, /close, /fresh, /register, /link, /users, /cost, /activity, /handoff, /machines)
278
303
  const { handleSharedCommand } = await import('./command-handler.js');
279
304
  const result = await handleSharedCommand({
@@ -296,28 +321,17 @@ export class TelegramChannel {
296
321
  await this.handleMessage(chatId, text, messageId);
297
322
  }
298
323
  async handleMessage(chatId, text, messageId, media = [], isGroup = false) {
299
- let { tabName, prompt: rawPrompt } = parseTabMessage(text);
300
- if (!rawPrompt && media.length === 0)
324
+ const { tabName } = parseTabMessage(text);
325
+ if (!tabName && !text && media.length === 0)
301
326
  return;
302
- // Group tab routing: use a dedicated tab per group unless /tab is explicit
327
+ // Telegram-specific: group tab routing
328
+ let overrideTabName;
303
329
  if (isGroup) {
304
330
  const groupConfig = this.ctx.config.groups || DEFAULT_GROUP_CONFIG;
305
331
  if (groupConfig.tabPerGroup && !text.startsWith('/tab ')) {
306
- tabName = `group-tg-${Math.abs(chatId)}`;
332
+ overrideTabName = `group-tg-${Math.abs(chatId)}`;
307
333
  }
308
334
  }
309
- // Smart project routing (shared across all channels)
310
- const { resolveProjectRoute } = await import('./command-handler.js');
311
- const route = await resolveProjectRoute(rawPrompt, tabName, text, String(chatId));
312
- if (route.confirmationMessage) {
313
- await this.bot.sendMessage(chatId, route.confirmationMessage);
314
- return;
315
- }
316
- let effectiveTabName = route.effectiveTabName;
317
- let projectPath = route.projectPath;
318
- // Build prompt with media references
319
- const prompt = buildMediaPrompt(media, rawPrompt);
320
- logger.info(`[telegram] Handling message for tab "${effectiveTabName}" (chat: ${chatId}, msg: ${messageId})`);
321
335
  // React with ⏳
322
336
  await this.setReaction(chatId, messageId, '⏳');
323
337
  // Typing indicator — keep refreshing every 4s
@@ -328,13 +342,14 @@ export class TelegramChannel {
328
342
  const typingInterval = setInterval(sendTyping, 4000);
329
343
  // "Still working" timeout
330
344
  const stillWorkingTimeout = setTimeout(() => {
331
- this.bot.sendMessage(chatId, `Still working on your request in tab "${effectiveTabName}"...`).catch(() => { });
345
+ this.bot.sendMessage(chatId, `Still working on your request...`).catch(() => { });
332
346
  }, 120000);
333
347
  try {
334
348
  let responseText;
335
349
  let responseError;
336
- let responseTab = effectiveTabName;
350
+ let responseTab;
337
351
  if (this.ctx.pipeBrain) {
352
+ // PipeBrain path is Telegram-specific (not shared in pipeline)
338
353
  const pipeResult = await this.ctx.pipeBrain.process(text, { chatId, userId: 0, messageId });
339
354
  responseText = pipeResult.response.text || '(empty response)';
340
355
  responseError = pipeResult.response.error;
@@ -345,9 +360,13 @@ export class TelegramChannel {
345
360
  }
346
361
  }
347
362
  else {
363
+ // Telegram-specific: streaming message edits
348
364
  let streamMsgId = null;
349
365
  let streamBuffer = '';
350
366
  let lastEditTime = 0;
367
+ // We need the effective tab name for the stream prefix, but it's determined
368
+ // inside the pipeline. Use a mutable ref that the pipeline result will fill.
369
+ let effectiveTabForStream = overrideTabName || tabName;
351
370
  const onTextChunk = async (chunk) => {
352
371
  streamBuffer += chunk;
353
372
  const now = Date.now();
@@ -355,7 +374,7 @@ export class TelegramChannel {
355
374
  return;
356
375
  lastEditTime = now;
357
376
  try {
358
- const prefix = effectiveTabName !== 'default' ? `[${effectiveTabName}] ` : '';
377
+ const prefix = effectiveTabForStream !== 'default' ? `[${effectiveTabForStream}] ` : '';
359
378
  const preview = prefix + streamBuffer.slice(0, 4000) + (streamBuffer.length > 4000 ? '...' : '');
360
379
  if (!streamMsgId) {
361
380
  const sent = await this.bot.sendMessage(chatId, preview);
@@ -367,59 +386,80 @@ export class TelegramChannel {
367
386
  }
368
387
  catch { /* edit failures are non-critical */ }
369
388
  };
370
- // Progress updates for long tasks (every 30 seconds)
371
- const progressTracker = new ProgressTracker(effectiveTabName, (msg) => {
372
- this.bot.sendMessage(chatId, msg).catch(() => { });
373
- });
374
- const result = await this.ctx.tabManager.sendMessage(effectiveTabName, prompt, {
389
+ // Shared pipeline handles: routing, media prompt, progress, sendMessage, TTS
390
+ const pipelineResult = await processInboundMessage({
391
+ text,
392
+ media,
393
+ channelId: 'telegram',
394
+ tabManager: this.ctx.tabManager,
395
+ voiceReplyMode: this.ctx.config.voice?.replyMode,
396
+ ttsProvider: this.ttsProvider,
397
+ userId: String(chatId),
398
+ sendProgress: (msg) => {
399
+ this.bot.sendMessage(chatId, msg).catch(() => { });
400
+ },
401
+ overrideTabName,
375
402
  onTextChunk,
376
- onToolUse: (name, input) => progressTracker.record(name, input),
377
- projectPath,
378
403
  });
379
- progressTracker.stop();
380
- responseText = result.text || '(empty response)';
381
- responseError = result.error;
404
+ // Empty result means no prompt and no media
405
+ if (!pipelineResult.responseText) {
406
+ clearInterval(typingInterval);
407
+ clearTimeout(stillWorkingTimeout);
408
+ return;
409
+ }
410
+ // Update the effective tab for stream prefix (now known)
411
+ effectiveTabForStream = pipelineResult.tabName;
412
+ responseText = pipelineResult.responseText;
413
+ responseError = pipelineResult.isError;
414
+ responseTab = pipelineResult.tabName;
415
+ // Telegram-specific: if streaming was active and no error, edit the final message
382
416
  if (streamMsgId && !responseError) {
383
417
  clearInterval(typingInterval);
384
418
  clearTimeout(stillWorkingTimeout);
385
419
  await this.setReaction(chatId, messageId, '✅');
420
+ // Send voice if available (even with streaming)
421
+ if (pipelineResult.audioPath) {
422
+ await this.bot.sendVoice(chatId, pipelineResult.audioPath);
423
+ if (pipelineResult.voiceOnly)
424
+ return;
425
+ }
386
426
  try {
387
- const prefix = effectiveTabName !== 'default' ? `[${effectiveTabName}] ` : '';
427
+ const prefix = responseTab !== 'default' ? `[${responseTab}] ` : '';
388
428
  const finalText = prefix + responseText;
389
429
  if (finalText.length <= 4096) {
390
430
  await this.bot.editMessageText(finalText, { chat_id: chatId, message_id: streamMsgId });
391
431
  }
392
432
  else {
393
- await this.sendResponse(chatId, responseText, effectiveTabName);
433
+ await this.sendResponse(chatId, responseText, responseTab);
394
434
  }
395
435
  }
396
436
  catch {
397
- await this.sendResponse(chatId, responseText, effectiveTabName);
437
+ await this.sendResponse(chatId, responseText, responseTab);
398
438
  }
399
439
  return;
400
440
  }
441
+ // Send voice reply if TTS generated audio (non-streaming path)
442
+ if (pipelineResult.audioPath) {
443
+ clearInterval(typingInterval);
444
+ clearTimeout(stillWorkingTimeout);
445
+ await this.setReaction(chatId, messageId, responseError ? '❌' : '✅');
446
+ await this.bot.sendVoice(chatId, pipelineResult.audioPath);
447
+ if (pipelineResult.voiceOnly)
448
+ return;
449
+ if (!responseError) {
450
+ await this.sendResponse(chatId, responseText, responseTab);
451
+ return;
452
+ }
453
+ }
401
454
  }
402
455
  clearInterval(typingInterval);
403
456
  clearTimeout(stillWorkingTimeout);
404
457
  if (responseError) {
405
458
  await this.setReaction(chatId, messageId, '❌');
406
- await this.sendResponse(chatId, `Error: ${responseText}`, responseTab);
459
+ await this.sendResponse(chatId, responseText, responseTab);
407
460
  return;
408
461
  }
409
462
  await this.setReaction(chatId, messageId, '✅');
410
- // TTS: send voice reply if configured
411
- const voiceReplyMode = this.ctx.config.voice?.replyMode;
412
- if (this.ttsProvider && (voiceReplyMode === 'voice' || voiceReplyMode === 'both')) {
413
- try {
414
- const audioPath = await this.ttsProvider.synthesize(responseText);
415
- await this.bot.sendVoice(chatId, audioPath);
416
- if (voiceReplyMode === 'voice')
417
- return; // Don't send text
418
- }
419
- catch (err) {
420
- logger.warn('TTS failed, sending text reply:', err);
421
- }
422
- }
423
463
  await this.sendResponse(chatId, responseText, responseTab);
424
464
  }
425
465
  catch (err) {
@@ -510,4 +550,3 @@ export class TelegramChannel {
510
550
  }
511
551
  }
512
552
  }
513
- //# sourceMappingURL=telegram.js.map
@@ -66,4 +66,3 @@ export interface ChannelContext {
66
66
  /** Broadcast notification to all channels + notification providers */
67
67
  notifyCallback?: (message: string) => Promise<void>;
68
68
  }
69
- //# sourceMappingURL=types.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=types.js.map
@@ -17,4 +17,3 @@ export declare class WebhookChannel implements Channel {
17
17
  private authenticate;
18
18
  private getConfig;
19
19
  }
20
- //# sourceMappingURL=webhook.d.ts.map
@@ -161,4 +161,3 @@ export class WebhookChannel {
161
161
  return this.ctx.config.webhook;
162
162
  }
163
163
  }
164
- //# sourceMappingURL=webhook.js.map
@@ -13,6 +13,7 @@ export declare class WhatsAppChannel implements Channel {
13
13
  private readonly backoffDelays;
14
14
  private sttProvider;
15
15
  private ttsProvider;
16
+ private sttWarmedUp;
16
17
  constructor(ctx: ChannelContext);
17
18
  start(): Promise<void>;
18
19
  stop(): void;
@@ -23,4 +24,3 @@ export declare class WhatsAppChannel implements Channel {
23
24
  private sendResponse;
24
25
  private isAllowed;
25
26
  }
26
- //# sourceMappingURL=whatsapp.d.ts.map
@@ -2,9 +2,9 @@ import fs from 'node:fs';
2
2
  import { logger } from '../util/logger.js';
3
3
  import { saveMedia, isOversized } from '../media/store.js';
4
4
  import { retryWithBackoff } from '../util/retry.js';
5
- import { chunkText, parseTabMessage, buildMediaPrompt } from '../util/text.js';
5
+ import { chunkText } from '../util/text.js';
6
6
  import { inboundLimiter } from '../util/rate-limiter.js';
7
- import { ProgressTracker } from '../util/progress.js';
7
+ import { processInboundMessage } from './pipeline.js';
8
8
  import { initVoiceProviders } from '../voice/index.js';
9
9
  const WHATSAPP_MAX_LENGTH = 8192;
10
10
  export class WhatsAppChannel {
@@ -21,6 +21,7 @@ export class WhatsAppChannel {
21
21
  backoffDelays = [1000, 5000, 15000, 30000, 60000];
22
22
  sttProvider = null;
23
23
  ttsProvider = null;
24
+ sttWarmedUp = false;
24
25
  constructor(ctx) {
25
26
  this.ctx = ctx;
26
27
  this.allowedNumbers = new Set(ctx.config.whatsapp?.allowedNumbers ?? []);
@@ -146,17 +147,8 @@ export class WhatsAppChannel {
146
147
  .map(r => r.value);
147
148
  // Transcribe voice messages if STT is configured
148
149
  if (this.sttProvider) {
149
- for (const att of media) {
150
- if (att.type === 'voice' && att.filePath) {
151
- try {
152
- const transcription = await this.sttProvider.transcribe(att.filePath);
153
- att.caption = `[Transcribed from voice message]: ${transcription}`;
154
- }
155
- catch (err) {
156
- logger.warn('Voice transcription failed, passing file path instead:', err);
157
- }
158
- }
159
- }
150
+ const { transcribeVoiceMessages } = await import('../voice/index.js');
151
+ this.sttWarmedUp = await transcribeVoiceMessages(media, this.sttProvider, 'whatsapp', this.sttWarmedUp);
160
152
  }
161
153
  if (!text && media.length === 0)
162
154
  return;
@@ -177,48 +169,31 @@ export class WhatsAppChannel {
177
169
  return;
178
170
  }
179
171
  }
180
- const { tabName, prompt: rawPrompt } = parseTabMessage(text);
181
- if (!rawPrompt && media.length === 0)
182
- return;
183
- // Build prompt with media references
184
- const prompt = buildMediaPrompt(media, rawPrompt);
185
- // Smart project routing (shared across all channels)
186
- const { resolveProjectRoute } = await import('./command-handler.js');
187
- const route = await resolveProjectRoute(rawPrompt, tabName, text, waUserId);
188
- if (route.confirmationMessage) {
189
- await sock.sendMessage(sender, { text: route.confirmationMessage });
190
- return;
191
- }
192
- let effectiveTabName = route.effectiveTabName;
193
- let projectPath = route.projectPath;
194
172
  await sock.sendPresenceUpdate('composing', sender).catch(() => { });
195
- // Progress updates for long tasks (every 30 seconds)
196
- const progressTracker = new ProgressTracker(effectiveTabName, (msg) => {
197
- sock.sendMessage(sender, { text: msg }).catch(() => { });
173
+ // Shared message pipeline
174
+ const pipelineResult = await processInboundMessage({
175
+ text,
176
+ media,
177
+ channelId: 'whatsapp',
178
+ tabManager: this.ctx.tabManager,
179
+ voiceReplyMode: this.ctx.config.voice?.replyMode,
180
+ ttsProvider: this.ttsProvider,
181
+ userId: waUserId,
182
+ sendProgress: (msg) => {
183
+ sock.sendMessage(sender, { text: msg }).catch(() => { });
184
+ },
198
185
  });
199
- const result = await this.ctx.tabManager.sendMessage(effectiveTabName, prompt, {
200
- onToolUse: (name, input) => progressTracker.record(name, input),
201
- projectPath,
202
- });
203
- progressTracker.stop();
204
- const responseText = result.error
205
- ? `Error: ${result.text}`
206
- : result.text || '(empty response)';
207
186
  await sock.sendPresenceUpdate('paused', sender).catch(() => { });
208
- // TTS: send voice reply if configured
209
- const voiceReplyMode = this.ctx.config.voice?.replyMode;
210
- if (this.ttsProvider && (voiceReplyMode === 'voice' || voiceReplyMode === 'both')) {
211
- try {
212
- const audioPath = await this.ttsProvider.synthesize(responseText);
213
- await sock.sendMessage(sender, { audio: { url: audioPath }, mimetype: 'audio/ogg; codecs=opus', ptt: true });
214
- if (voiceReplyMode === 'voice')
215
- return; // Don't send text
216
- }
217
- catch (err) {
218
- logger.warn('TTS failed, sending text reply:', err);
219
- }
187
+ // Empty result means no prompt and no media
188
+ if (!pipelineResult.responseText)
189
+ return;
190
+ // Send voice reply if TTS generated audio
191
+ if (pipelineResult.audioPath) {
192
+ await sock.sendMessage(sender, { audio: { url: pipelineResult.audioPath }, mimetype: 'audio/ogg; codecs=opus', ptt: true });
193
+ if (pipelineResult.voiceOnly)
194
+ return;
220
195
  }
221
- await this.sendResponse(sender, responseText, effectiveTabName);
196
+ await this.sendResponse(sender, pipelineResult.responseText, pipelineResult.tabName);
222
197
  }
223
198
  catch (err) {
224
199
  logger.error('WhatsApp message handler error:', err);
@@ -292,4 +267,3 @@ export class WhatsAppChannel {
292
267
  return this.allowedNumbers.has(number);
293
268
  }
294
269
  }
295
- //# sourceMappingURL=whatsapp.js.map
@@ -1,4 +1,3 @@
1
1
  export declare function enableCapability(packId: string): Promise<void>;
2
2
  export declare function listCapabilities(): Promise<void>;
3
3
  export declare function disableCapability(packId: string): Promise<void>;
4
- //# sourceMappingURL=capabilities.d.ts.map
@@ -70,4 +70,3 @@ export async function disableCapability(packId) {
70
70
  console.log(`\n✓ ${packId} disabled.`);
71
71
  console.log(' Restart daemon to apply: beecork stop && beecork start\n');
72
72
  }
73
- //# sourceMappingURL=capabilities.js.map
@@ -1,4 +1,3 @@
1
1
  export declare function channelInstall(packageName: string): void;
2
2
  export declare function channelCreate(name: string): void;
3
3
  export declare function channelList(): void;
4
- //# sourceMappingURL=channel.d.ts.map
@@ -174,7 +174,7 @@ npm publish
174
174
  }
175
175
  export function channelList() {
176
176
  try {
177
- const output = execSync('npm list -g --depth=0 2>/dev/null', { encoding: 'utf-8' });
177
+ const output = execSync('npm list -g --depth=0', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
178
178
  const lines = output.split('\n').filter(line => line.includes(CHANNEL_PREFIX));
179
179
  if (lines.length === 0) {
180
180
  console.log('No community channels installed.');
@@ -191,4 +191,3 @@ export function channelList() {
191
191
  console.log('No community channels installed.');
192
192
  }
193
193
  }
194
- //# sourceMappingURL=channel.js.map
@@ -5,10 +5,11 @@ export declare function listTabs(): Promise<void>;
5
5
  export declare function tailLogs(tabName?: string): Promise<void>;
6
6
  export declare function listCrons(): Promise<void>;
7
7
  export declare function deleteCron(id: string): Promise<void>;
8
+ export declare function listWatchers(): Promise<void>;
9
+ export declare function deleteWatcher(id: string): Promise<void>;
8
10
  export declare function listMemories(): Promise<void>;
9
11
  export declare function deleteMemory(id: string): Promise<void>;
10
12
  export declare function updateBeecork(options: {
11
13
  check?: boolean;
12
14
  }): Promise<void>;
13
15
  export declare function sendMessage(message: string): Promise<void>;
14
- //# sourceMappingURL=commands.d.ts.map
@@ -3,7 +3,7 @@ import path from 'node:path';
3
3
  import { spawn, execSync } from 'node:child_process';
4
4
  import { getDb, closeDb } from '../db/index.js';
5
5
  import { getConfig } from '../config.js';
6
- import { CronStore } from '../cron/store.js';
6
+ import { TaskStore } from '../tasks/store.js';
7
7
  import { getDaemonPid, timeAgo } from './helpers.js';
8
8
  import { startService, stopService } from '../service/install.js';
9
9
  import { getPidPath, getLogsDir } from '../util/paths.js';
@@ -79,10 +79,10 @@ export async function showStatus() {
79
79
  const pidInfo = tab.pid ? ` (PID ${tab.pid})` : '';
80
80
  console.log(` ${tab.name.padEnd(20)} ${tab.status.padEnd(12)} last active: ${ago}${pidInfo}`);
81
81
  }
82
- const store = new CronStore();
82
+ const store = new TaskStore();
83
83
  const jobs = store.list();
84
84
  const activeJobs = jobs.filter(j => j.enabled);
85
- console.log(`\nCron jobs: ${activeJobs.length} active (${jobs.length} total)`);
85
+ console.log(`\nTasks: ${activeJobs.length} active (${jobs.length} total)`);
86
86
  if (activeJobs.length > 0) {
87
87
  for (const job of activeJobs.slice(0, 5)) {
88
88
  const lastRun = job.lastRunAt ? `last: ${timeAgo(job.lastRunAt)}` : 'never run';
@@ -119,34 +119,69 @@ export async function tailLogs(tabName) {
119
119
  console.log(`No log file found: ${logFile}`);
120
120
  return;
121
121
  }
122
- const child = spawn('tail', ['-f', '-n', '50', logFile], { stdio: 'inherit' });
123
- process.on('SIGINT', () => child.kill());
122
+ if (process.platform === 'win32') {
123
+ // Windows: use PowerShell Get-Content -Wait
124
+ const child = spawn('powershell', ['-Command', `Get-Content -Path '${logFile}' -Tail 50 -Wait`], { stdio: 'inherit' });
125
+ process.on('SIGINT', () => child.kill());
126
+ }
127
+ else {
128
+ const child = spawn('tail', ['-f', '-n', '50', logFile], { stdio: 'inherit' });
129
+ process.on('SIGINT', () => child.kill());
130
+ }
124
131
  }
125
132
  export async function listCrons() {
126
- requireDb(); // Ensure DB exists before CronStore tries to access it
127
- const store = new CronStore();
133
+ requireDb();
134
+ const store = new TaskStore();
128
135
  const jobs = store.list();
129
136
  if (jobs.length === 0) {
130
- console.log('No cron jobs.');
137
+ console.log('No tasks.');
131
138
  return;
132
139
  }
133
- console.log(`\nCron jobs (${jobs.length}):\n`);
140
+ console.log(`\nTasks (${jobs.length}):\n`);
134
141
  for (const job of jobs) {
135
142
  const status = job.enabled ? 'enabled' : 'disabled';
136
143
  const lastRun = job.lastRunAt ? timeAgo(job.lastRunAt) : 'never';
137
144
  console.log(` ${job.name.padEnd(20)} [${status}] ${job.scheduleType}:${job.schedule}`);
138
- console.log(` tab:${job.tabName} | last: ${lastRun} | ID: ${job.id}`);
145
+ console.log(` -> tab:${job.tabName} | last: ${lastRun} | ID: ${job.id}`);
139
146
  }
140
147
  console.log('');
141
148
  }
142
149
  export async function deleteCron(id) {
143
- requireDb(); // Ensure DB exists before CronStore tries to access it
144
- const store = new CronStore();
150
+ requireDb();
151
+ const store = new TaskStore();
145
152
  if (store.delete(id)) {
146
- console.log(`Deleted cron job: ${id}`);
153
+ console.log(`Deleted task: ${id}`);
154
+ }
155
+ else {
156
+ console.log(`No task found with ID: ${id}`);
157
+ }
158
+ }
159
+ export async function listWatchers() {
160
+ const db = requireDb();
161
+ const watchers = db.prepare('SELECT * FROM watchers ORDER BY created_at').all();
162
+ closeDb();
163
+ if (watchers.length === 0) {
164
+ console.log('No watchers.');
165
+ return;
166
+ }
167
+ console.log(`\nWatchers (${watchers.length}):\n`);
168
+ for (const w of watchers) {
169
+ const status = w.enabled ? 'enabled' : 'disabled';
170
+ const lastCheck = w.last_check_at ? timeAgo(w.last_check_at) : 'never';
171
+ console.log(` ${w.name.padEnd(20)} [${status}] ${w.schedule}`);
172
+ console.log(` condition: ${w.condition} | action: ${w.action} | triggers: ${w.trigger_count} | last: ${lastCheck} | ID: ${w.id}`);
173
+ }
174
+ console.log('');
175
+ }
176
+ export async function deleteWatcher(id) {
177
+ const db = requireDb();
178
+ const result = db.prepare('DELETE FROM watchers WHERE id = ?').run(id);
179
+ closeDb();
180
+ if (result.changes > 0) {
181
+ console.log(`Deleted watcher: ${id}`);
147
182
  }
148
183
  else {
149
- console.log(`No cron job found with ID: ${id}`);
184
+ console.log(`No watcher found with ID: ${id}`);
150
185
  }
151
186
  }
152
187
  export async function listMemories() {
@@ -232,4 +267,3 @@ export async function sendMessage(message) {
232
267
  }
233
268
  closeDb();
234
269
  }
235
- //# sourceMappingURL=commands.js.map
@@ -1,2 +1 @@
1
1
  export declare function runDoctor(): Promise<void>;
2
- //# sourceMappingURL=doctor.d.ts.map
@@ -8,7 +8,8 @@ export async function runDoctor() {
8
8
  try {
9
9
  const config = getConfig();
10
10
  const bin = config.claudeCode?.bin || 'claude';
11
- execSync(`which ${bin}`, { encoding: 'utf-8' });
11
+ const whichCmd = process.platform === 'win32' ? 'where' : 'which';
12
+ execSync(`${whichCmd} ${bin}`, { encoding: 'utf-8' });
12
13
  try {
13
14
  const version = execSync(`${bin} --version 2>&1`, { encoding: 'utf-8' }).trim();
14
15
  checks.push({ name: 'Claude Code', status: 'pass', message: `Found: ${version}` });
@@ -147,4 +148,3 @@ export async function runDoctor() {
147
148
  if (fails > 0)
148
149
  process.exit(1);
149
150
  }
150
- //# sourceMappingURL=doctor.js.map
@@ -13,4 +13,3 @@ export declare function exportTab(tabName: string): TabInfo | null;
13
13
  export declare function attachTab(tabName: string): void;
14
14
  export declare function formatHandoffInfo(info: TabInfo): string;
15
15
  export {};
16
- //# sourceMappingURL=handoff.d.ts.map
@@ -66,4 +66,3 @@ export function formatHandoffInfo(info) {
66
66
  }
67
67
  return lines.join('\n');
68
68
  }
69
- //# sourceMappingURL=handoff.js.map
@@ -1,3 +1,2 @@
1
1
  export { timeAgo } from '../util/text.js';
2
2
  export declare function getDaemonPid(): number | null;
3
- //# sourceMappingURL=helpers.d.ts.map