pi-harness-runtime 1.1.398 → 1.1.402

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 (613) hide show
  1. package/AGENTS.md +44 -2
  2. package/CHANGELOG.md +21 -0
  3. package/RULES.md +28 -0
  4. package/harness/agent-handoff.ts +2 -3
  5. package/harness/autonomous-review.ts +1 -1
  6. package/harness/blackboard.ts +2 -3
  7. package/harness/context-compact-orchestrator.ts +1 -1
  8. package/harness/context-window-manager.ts +2 -2
  9. package/harness/e2e/playwright-runner.ts +6 -4
  10. package/harness/herdr-agents.ts +1 -1
  11. package/harness/job-state-machine.ts +1 -1
  12. package/harness/langchain/daemon.ts +3 -3
  13. package/harness/langchain/graph.ts +2 -2
  14. package/harness/langchain/ping-pong-middleware.ts +2 -2
  15. package/harness/loop-code-agent.ts +6 -4
  16. package/harness/loop-controller.ts +1 -1
  17. package/harness/loop-review-agent.ts +1 -1
  18. package/harness/loop-types.ts +1 -1
  19. package/harness/master-planner.ts +1 -1
  20. package/harness/project-detector/detector.ts +1 -2
  21. package/harness/repair-engine.ts +2 -4
  22. package/harness/service-diagnostics.ts +1 -1
  23. package/harness/skill-sync.ts +3 -3
  24. package/index.ts +276 -55
  25. package/mirror.ts +1 -1
  26. package/package.json +5 -3
  27. package/packages/a2a-adapter/dist/discovery.d.ts.map +1 -1
  28. package/packages/a2a-adapter/dist/discovery.js +0 -1
  29. package/packages/a2a-adapter/dist/discovery.js.map +1 -1
  30. package/packages/a2a-adapter/package.json +1 -1
  31. package/packages/a2a-adapter/src/discovery.ts +0 -1
  32. package/packages/agent-policy/package.json +1 -1
  33. package/packages/architecture-generator/package.json +1 -1
  34. package/packages/auth/dist/index.d.ts +9 -0
  35. package/packages/auth/dist/index.d.ts.map +1 -0
  36. package/packages/auth/dist/index.js +9 -0
  37. package/packages/auth/dist/index.js.map +1 -0
  38. package/packages/auth/package.json +1 -1
  39. package/packages/auth/src/index.ts +9 -0
  40. package/packages/autonomous-refactor/package.json +1 -1
  41. package/packages/autonomous-runtime/package.json +1 -1
  42. package/packages/cache-strategy/package.json +1 -1
  43. package/packages/capability-registry/package.json +1 -1
  44. package/packages/checkpoint/package.json +1 -1
  45. package/packages/cli-plugin-sdk/package.json +1 -1
  46. package/packages/clipboard/package.json +1 -1
  47. package/packages/clipboard-plugin/package.json +1 -1
  48. package/packages/code-generation/package.json +1 -1
  49. package/packages/code-review/package.json +1 -1
  50. package/packages/codex-adapter/package.json +1 -1
  51. package/packages/codex-watcher/package.json +1 -1
  52. package/packages/config-capture/dist/index.d.ts +52 -0
  53. package/packages/config-capture/dist/index.d.ts.map +1 -0
  54. package/packages/config-capture/dist/index.js +261 -0
  55. package/packages/config-capture/dist/index.js.map +1 -0
  56. package/packages/config-capture/package.json +1 -1
  57. package/packages/connection-runtime/package.json +1 -1
  58. package/packages/context-compiler/package.json +1 -1
  59. package/packages/context-discovery/package.json +1 -1
  60. package/packages/context-manager/package.json +1 -1
  61. package/packages/contracts/package.json +1 -1
  62. package/packages/cookie-sanitizer/package.json +1 -1
  63. package/packages/cost-optimizer/package.json +1 -1
  64. package/packages/dependency-analyzer/package.json +1 -1
  65. package/packages/django-plugin/package.json +1 -1
  66. package/packages/doc-generator/package.json +1 -1
  67. package/packages/durable-review/package.json +1 -1
  68. package/packages/e2e-tester/package.json +1 -1
  69. package/packages/evaluation-engine/package.json +1 -1
  70. package/packages/evaluation-runner/package.json +1 -1
  71. package/packages/event-bus/package.json +1 -1
  72. package/packages/event-sink/package.json +1 -1
  73. package/packages/event-store/package.json +1 -1
  74. package/packages/experience-replay/package.json +1 -1
  75. package/packages/feedback-collector/package.json +1 -1
  76. package/packages/file-copy-helper/dist/extension.d.ts +15 -0
  77. package/packages/file-copy-helper/dist/extension.d.ts.map +1 -0
  78. package/packages/file-copy-helper/dist/extension.debug.d.ts +15 -0
  79. package/packages/file-copy-helper/dist/extension.debug.d.ts.map +1 -0
  80. package/packages/file-copy-helper/dist/extension.debug.js +215 -0
  81. package/packages/file-copy-helper/dist/extension.debug.js.map +1 -0
  82. package/packages/file-copy-helper/dist/extension.js +222 -0
  83. package/packages/file-copy-helper/dist/extension.js.map +1 -0
  84. package/packages/file-copy-helper/dist/index.d.ts +3 -0
  85. package/packages/file-copy-helper/dist/index.d.ts.map +1 -0
  86. package/packages/file-copy-helper/dist/index.js +3 -0
  87. package/packages/file-copy-helper/dist/index.js.map +1 -0
  88. package/packages/file-copy-helper/dist/intent-detector.d.ts +21 -0
  89. package/packages/file-copy-helper/dist/intent-detector.d.ts.map +1 -0
  90. package/packages/file-copy-helper/dist/intent-detector.js +348 -0
  91. package/packages/file-copy-helper/dist/intent-detector.js.map +1 -0
  92. package/packages/file-copy-helper/package.json +1 -1
  93. package/packages/framework-detector/package.json +1 -1
  94. package/packages/framework-plugin-sdk/package.json +1 -1
  95. package/packages/frappe-plugin/package.json +1 -1
  96. package/packages/generic-web-plugin/package.json +1 -1
  97. package/packages/health-monitor/package.json +1 -1
  98. package/packages/intent-analyzer/package.json +1 -1
  99. package/packages/jev-judge/dist/auto-continue.d.ts +161 -2
  100. package/packages/jev-judge/dist/auto-continue.d.ts.map +1 -1
  101. package/packages/jev-judge/dist/auto-continue.js +267 -22
  102. package/packages/jev-judge/dist/auto-continue.js.map +1 -1
  103. package/packages/jev-judge/dist/index.d.ts +2 -0
  104. package/packages/jev-judge/dist/index.d.ts.map +1 -1
  105. package/packages/jev-judge/dist/index.js +2 -0
  106. package/packages/jev-judge/dist/index.js.map +1 -1
  107. package/packages/jev-judge/dist/question-risk.d.ts +50 -0
  108. package/packages/jev-judge/dist/question-risk.d.ts.map +1 -0
  109. package/packages/jev-judge/dist/question-risk.js +100 -0
  110. package/packages/jev-judge/dist/question-risk.js.map +1 -0
  111. package/packages/jev-judge/package.json +1 -1
  112. package/packages/jev-judge/src/auto-continue.ts +426 -29
  113. package/packages/jev-judge/src/index.ts +4 -0
  114. package/packages/jev-judge/src/question-risk.ts +151 -0
  115. package/packages/jev-judge/tests/auto-continue-context.test.ts +221 -0
  116. package/packages/jev-judge/tests/outcome-application.test.ts +132 -0
  117. package/packages/jev-judge/tests/question-risk.test.ts +116 -0
  118. package/packages/knowledge-graph/package.json +1 -1
  119. package/packages/knowledge-retrieval/package.json +1 -1
  120. package/packages/laravel-plugin/package.json +1 -1
  121. package/packages/learning-engine/package.json +1 -1
  122. package/packages/logging/README.md +36 -3
  123. package/packages/logging/dist/config.d.ts +7 -0
  124. package/packages/logging/dist/config.d.ts.map +1 -1
  125. package/packages/logging/dist/config.js +14 -0
  126. package/packages/logging/dist/config.js.map +1 -1
  127. package/packages/logging/dist/incidents/schema.d.ts +111 -0
  128. package/packages/logging/dist/incidents/schema.d.ts.map +1 -0
  129. package/packages/logging/dist/incidents/schema.js +0 -0
  130. package/packages/logging/dist/incidents/schema.js.map +1 -0
  131. package/packages/logging/dist/index.d.ts +2 -0
  132. package/packages/logging/dist/index.d.ts.map +1 -1
  133. package/packages/logging/dist/index.js +2 -0
  134. package/packages/logging/dist/index.js.map +1 -1
  135. package/packages/logging/dist/server/http.d.ts +4 -3
  136. package/packages/logging/dist/server/http.d.ts.map +1 -1
  137. package/packages/logging/dist/server/http.js +35 -3
  138. package/packages/logging/dist/server/http.js.map +1 -1
  139. package/packages/logging/dist/server/incident-qdrant.d.ts +83 -0
  140. package/packages/logging/dist/server/incident-qdrant.d.ts.map +1 -0
  141. package/packages/logging/dist/server/incident-qdrant.js +129 -0
  142. package/packages/logging/dist/server/incident-qdrant.js.map +1 -0
  143. package/packages/logging/dist/server/incident-store.d.ts +76 -0
  144. package/packages/logging/dist/server/incident-store.d.ts.map +1 -0
  145. package/packages/logging/dist/server/incident-store.js +157 -0
  146. package/packages/logging/dist/server/incident-store.js.map +1 -0
  147. package/packages/logging/dist/server/index.d.ts +4 -0
  148. package/packages/logging/dist/server/index.d.ts.map +1 -1
  149. package/packages/logging/dist/server/index.js +2 -0
  150. package/packages/logging/dist/server/index.js.map +1 -1
  151. package/packages/logging/dist/server/service.d.ts +33 -0
  152. package/packages/logging/dist/server/service.d.ts.map +1 -1
  153. package/packages/logging/dist/server/service.js +63 -0
  154. package/packages/logging/dist/server/service.js.map +1 -1
  155. package/packages/logging/dist/shipper.d.ts +74 -3
  156. package/packages/logging/dist/shipper.d.ts.map +1 -1
  157. package/packages/logging/dist/shipper.js +88 -5
  158. package/packages/logging/dist/shipper.js.map +1 -1
  159. package/packages/logging/dist/singleton.d.ts.map +1 -1
  160. package/packages/logging/dist/singleton.js +1 -0
  161. package/packages/logging/dist/singleton.js.map +1 -1
  162. package/packages/logging/package.json +1 -1
  163. package/packages/logging/src/config.ts +22 -0
  164. package/packages/logging/src/incidents/schema.ts +0 -0
  165. package/packages/logging/src/index.ts +17 -0
  166. package/packages/logging/src/server/http.ts +42 -3
  167. package/packages/logging/src/server/incident-qdrant.ts +177 -0
  168. package/packages/logging/src/server/incident-store.ts +192 -0
  169. package/packages/logging/src/server/index.ts +21 -0
  170. package/packages/logging/src/server/service.ts +79 -0
  171. package/packages/logging/src/shipper.ts +120 -5
  172. package/packages/logging/src/singleton.ts +1 -0
  173. package/packages/logging/test/fanout.test.ts +186 -0
  174. package/packages/logging/test/incidents.test.ts +404 -0
  175. package/packages/mcp-adapter/package.json +1 -1
  176. package/packages/memory-engine/package.json +1 -1
  177. package/packages/milestone-manager/package.json +1 -1
  178. package/packages/model-registry/package.json +1 -1
  179. package/packages/nextjs-plugin/package.json +1 -1
  180. package/packages/notification/dist/adapters/detail-format.d.ts +10 -2
  181. package/packages/notification/dist/adapters/detail-format.d.ts.map +1 -1
  182. package/packages/notification/dist/adapters/detail-format.js +39 -0
  183. package/packages/notification/dist/adapters/detail-format.js.map +1 -1
  184. package/packages/notification/dist/adapters/line-adapter.d.ts +33 -0
  185. package/packages/notification/dist/adapters/line-adapter.d.ts.map +1 -1
  186. package/packages/notification/dist/adapters/line-adapter.js +84 -7
  187. package/packages/notification/dist/adapters/line-adapter.js.map +1 -1
  188. package/packages/notification/dist/adapters/telegram-adapter.d.ts.map +1 -1
  189. package/packages/notification/dist/adapters/telegram-adapter.js +6 -2
  190. package/packages/notification/dist/adapters/telegram-adapter.js.map +1 -1
  191. package/packages/notification/dist/notification-center.d.ts.map +1 -1
  192. package/packages/notification/dist/notification-center.js +59 -7
  193. package/packages/notification/dist/notification-center.js.map +1 -1
  194. package/packages/notification/dist/pending-question.d.ts +69 -2
  195. package/packages/notification/dist/pending-question.d.ts.map +1 -1
  196. package/packages/notification/dist/pending-question.js +88 -2
  197. package/packages/notification/dist/pending-question.js.map +1 -1
  198. package/packages/notification/dist/types.d.ts +18 -0
  199. package/packages/notification/dist/types.d.ts.map +1 -1
  200. package/packages/notification/package.json +1 -1
  201. package/packages/notification/src/adapters/detail-format.ts +42 -2
  202. package/packages/notification/src/adapters/line-adapter.ts +94 -7
  203. package/packages/notification/src/adapters/telegram-adapter.ts +6 -2
  204. package/packages/notification/src/notification-center.ts +65 -8
  205. package/packages/notification/src/pending-question.ts +160 -8
  206. package/packages/notification/src/types.ts +18 -0
  207. package/packages/notification/test/approval-payload.test.ts +269 -0
  208. package/packages/notification/test/pending-question-lifecycle.test.ts +195 -0
  209. package/packages/observability/package.json +1 -1
  210. package/packages/okf-indexer/dist/index.d.ts +9 -0
  211. package/packages/okf-indexer/dist/index.d.ts.map +1 -0
  212. package/packages/okf-indexer/dist/index.js +9 -0
  213. package/packages/okf-indexer/dist/index.js.map +1 -0
  214. package/packages/okf-indexer/package.json +1 -1
  215. package/packages/okf-indexer/src/index.ts +9 -0
  216. package/packages/paperclip-integration/package.json +1 -1
  217. package/packages/performance-optimizer/package.json +1 -1
  218. package/packages/permission-mode/package.json +1 -1
  219. package/packages/privilege-broker/package.json +1 -1
  220. package/packages/project-analyzer/package.json +1 -1
  221. package/packages/project-bootstrap/package.json +1 -1
  222. package/packages/projection-engine/package.json +1 -1
  223. package/packages/prompt-compiler/package.json +1 -1
  224. package/packages/prompt-versioning/package.json +1 -1
  225. package/packages/provider-adapter-sdk/package.json +1 -1
  226. package/packages/provider-router/dist/provider-router.d.ts.map +1 -1
  227. package/packages/provider-router/dist/types.d.ts +2 -2
  228. package/packages/provider-router/dist/types.d.ts.map +1 -1
  229. package/packages/provider-router/dist/types.js +1 -1
  230. package/packages/provider-router/package.json +1 -1
  231. package/packages/provider-router/src/types.ts +2 -2
  232. package/packages/provider-selector/package.json +1 -1
  233. package/packages/providers/package.json +1 -1
  234. package/packages/qdrant-skills/package.json +1 -1
  235. package/packages/quota-manager/package.json +1 -1
  236. package/packages/rate-limiter/package.json +1 -1
  237. package/packages/react-vite-plugin/package.json +1 -1
  238. package/packages/relay/package.json +1 -1
  239. package/packages/release-manager/package.json +1 -1
  240. package/packages/requirement-compiler/package.json +1 -1
  241. package/packages/runtime/package.json +1 -1
  242. package/packages/scheduler/dist/index.d.ts +9 -0
  243. package/packages/scheduler/dist/index.d.ts.map +1 -0
  244. package/packages/scheduler/dist/index.js +9 -0
  245. package/packages/scheduler/dist/index.js.map +1 -0
  246. package/packages/scheduler/dist/scheduler.d.ts +17 -0
  247. package/packages/scheduler/dist/scheduler.d.ts.map +1 -0
  248. package/packages/scheduler/dist/scheduler.js +41 -0
  249. package/packages/scheduler/dist/scheduler.js.map +1 -0
  250. package/packages/scheduler/package.json +1 -1
  251. package/packages/scheduler/src/index.ts +9 -0
  252. package/packages/scheduler-adapter/package.json +1 -1
  253. package/packages/session/package.json +1 -1
  254. package/packages/session-api/package.json +1 -1
  255. package/packages/session-export/package.json +1 -1
  256. package/packages/shared-context/dist/index.d.ts +7 -0
  257. package/packages/shared-context/dist/index.d.ts.map +1 -0
  258. package/packages/shared-context/dist/index.js +7 -0
  259. package/packages/shared-context/dist/index.js.map +1 -0
  260. package/packages/shared-context/dist/shared-context.d.ts +12 -0
  261. package/packages/shared-context/dist/shared-context.d.ts.map +1 -0
  262. package/packages/shared-context/dist/shared-context.js +39 -0
  263. package/packages/shared-context/dist/shared-context.js.map +1 -0
  264. package/packages/shared-context/package.json +1 -1
  265. package/packages/skill-mcp-client/dist/client.d.ts +56 -0
  266. package/packages/skill-mcp-client/dist/client.d.ts.map +1 -0
  267. package/packages/skill-mcp-client/dist/client.js +101 -0
  268. package/packages/skill-mcp-client/dist/client.js.map +1 -0
  269. package/packages/skill-mcp-client/dist/errors.d.ts +44 -0
  270. package/packages/skill-mcp-client/dist/errors.d.ts.map +1 -0
  271. package/packages/skill-mcp-client/dist/errors.js +68 -0
  272. package/packages/skill-mcp-client/dist/errors.js.map +1 -0
  273. package/packages/skill-mcp-client/dist/index.d.ts +9 -0
  274. package/packages/skill-mcp-client/dist/index.d.ts.map +1 -0
  275. package/packages/skill-mcp-client/dist/index.js +9 -0
  276. package/packages/skill-mcp-client/dist/index.js.map +1 -0
  277. package/packages/skill-mcp-client/dist/types.d.ts +106 -0
  278. package/packages/skill-mcp-client/dist/types.d.ts.map +1 -0
  279. package/packages/skill-mcp-client/dist/types.js +14 -0
  280. package/packages/skill-mcp-client/dist/types.js.map +1 -0
  281. package/packages/skill-mcp-client/package.json +1 -1
  282. package/packages/skill-registry/package.json +1 -1
  283. package/packages/skills/package.json +1 -5
  284. package/packages/sprint-planner/package.json +1 -1
  285. package/packages/subscription-engine/package.json +1 -1
  286. package/packages/task-compiler/package.json +1 -1
  287. package/packages/telegram/package.json +1 -1
  288. package/packages/telegram/src/agent-messages.d.ts +28 -0
  289. package/packages/telegram/src/agent-messages.js +90 -0
  290. package/packages/telegram/src/bindings.d.ts +296 -0
  291. package/packages/telegram/src/bindings.js +1086 -0
  292. package/packages/telegram/src/bus.d.ts +759 -0
  293. package/packages/telegram/src/bus.js +2732 -0
  294. package/packages/telegram/src/commands.d.ts +761 -0
  295. package/packages/telegram/src/commands.js +2622 -0
  296. package/packages/telegram/src/config.d.ts +222 -0
  297. package/packages/telegram/src/config.js +844 -0
  298. package/packages/telegram/src/delivery.d.ts +161 -0
  299. package/packages/telegram/src/delivery.js +550 -0
  300. package/packages/telegram/src/extension.d.ts +7 -0
  301. package/packages/telegram/src/extension.js +2444 -0
  302. package/packages/telegram/src/inbound.d.ts +94 -0
  303. package/packages/telegram/src/inbound.js +478 -0
  304. package/packages/telegram/src/index.d.ts +6 -0
  305. package/packages/telegram/src/index.js +6 -0
  306. package/packages/telegram/src/keyboard.d.ts +21 -0
  307. package/packages/telegram/src/keyboard.js +37 -0
  308. package/packages/telegram/src/lifecycle.d.ts +210 -0
  309. package/packages/telegram/src/lifecycle.js +538 -0
  310. package/packages/telegram/src/pi.d.ts +76 -0
  311. package/packages/telegram/src/pi.js +130 -0
  312. package/packages/telegram/src/polling.d.ts +332 -0
  313. package/packages/telegram/src/polling.js +1219 -0
  314. package/packages/telegram/src/replies.d.ts +210 -0
  315. package/packages/telegram/src/replies.js +752 -0
  316. package/packages/telegram/src/routing.d.ts +388 -0
  317. package/packages/telegram/src/routing.js +7886 -0
  318. package/packages/telegram/src/runtime.d.ts +159 -0
  319. package/packages/telegram/src/runtime.js +351 -0
  320. package/packages/telegram/src/telegram-api.d.ts +564 -0
  321. package/packages/telegram/src/telegram-api.js +1332 -0
  322. package/packages/telegram/src/turns.d.ts +108 -0
  323. package/packages/telegram/src/turns.js +482 -0
  324. package/packages/telegram/src/updates.d.ts +1545 -0
  325. package/packages/telegram/src/updates.js +6420 -0
  326. package/packages/tencentdb-memory/package.json +1 -1
  327. package/packages/tencentdb-sync/package.json +1 -1
  328. package/packages/test-data-generator/package.json +1 -1
  329. package/packages/test-generator/package.json +1 -1
  330. package/packages/todo-bd-sync/dist/detector.d.ts +54 -0
  331. package/packages/todo-bd-sync/dist/detector.d.ts.map +1 -0
  332. package/packages/todo-bd-sync/dist/detector.js +132 -0
  333. package/packages/todo-bd-sync/dist/detector.js.map +1 -0
  334. package/packages/todo-bd-sync/dist/extension.d.ts +30 -0
  335. package/packages/todo-bd-sync/dist/extension.d.ts.map +1 -0
  336. package/packages/todo-bd-sync/dist/extension.js +35 -0
  337. package/packages/todo-bd-sync/dist/extension.js.map +1 -0
  338. package/packages/todo-bd-sync/dist/index.d.ts +87 -0
  339. package/packages/todo-bd-sync/dist/index.d.ts.map +1 -0
  340. package/packages/todo-bd-sync/dist/index.js +296 -0
  341. package/packages/todo-bd-sync/dist/index.js.map +1 -0
  342. package/packages/todo-bd-sync/dist/sync.d.ts +72 -0
  343. package/packages/todo-bd-sync/dist/sync.d.ts.map +1 -0
  344. package/packages/todo-bd-sync/dist/sync.js +290 -0
  345. package/packages/todo-bd-sync/dist/sync.js.map +1 -0
  346. package/packages/todo-bd-sync/dist/task-analyzer.d.ts +49 -0
  347. package/packages/todo-bd-sync/dist/task-analyzer.d.ts.map +1 -0
  348. package/packages/todo-bd-sync/dist/task-analyzer.js +240 -0
  349. package/packages/todo-bd-sync/dist/task-analyzer.js.map +1 -0
  350. package/packages/todo-bd-sync/dist/todo-reminder.d.ts +126 -0
  351. package/packages/todo-bd-sync/dist/todo-reminder.d.ts.map +1 -0
  352. package/packages/todo-bd-sync/dist/todo-reminder.js +329 -0
  353. package/packages/todo-bd-sync/dist/todo-reminder.js.map +1 -0
  354. package/packages/todo-bd-sync/dist/types.d.ts +65 -0
  355. package/packages/todo-bd-sync/dist/types.d.ts.map +1 -0
  356. package/packages/todo-bd-sync/dist/types.js +67 -0
  357. package/packages/todo-bd-sync/dist/types.js.map +1 -0
  358. package/packages/todo-bd-sync/package.json +1 -1
  359. package/packages/token-estimation/dist/index.d.ts +94 -0
  360. package/packages/token-estimation/dist/index.d.ts.map +1 -0
  361. package/packages/token-estimation/dist/index.js +115 -0
  362. package/packages/token-estimation/dist/index.js.map +1 -0
  363. package/packages/token-estimation/package.json +1 -1
  364. package/packages/token-optimizer/package.json +1 -1
  365. package/packages/trajectory/package.json +1 -1
  366. package/packages/tui/package.json +1 -1
  367. package/packages/types/dist/ai-providers.d.ts +36 -0
  368. package/packages/types/dist/ai-providers.d.ts.map +1 -0
  369. package/packages/types/dist/ai-providers.js +66 -0
  370. package/packages/types/dist/ai-providers.js.map +1 -0
  371. package/packages/types/dist/index.d.ts +12 -0
  372. package/packages/types/dist/index.d.ts.map +1 -0
  373. package/packages/types/dist/index.js +12 -0
  374. package/packages/types/dist/index.js.map +1 -0
  375. package/packages/types/package.json +5 -5
  376. package/packages/types/src/index.ts +12 -0
  377. package/packages/voice-api/package.json +1 -1
  378. package/packages/webmcp-tester/package.json +1 -1
  379. package/packages/wiki/package.json +1 -1
  380. package/packages/workflow-events/package.json +1 -1
  381. package/packages/workspace-scanner/package.json +1 -1
  382. package/packages/worktree/package.json +1 -1
  383. package/packages/worktree/worktree.ts +1 -1
  384. package/packages/write-review/package.json +1 -1
  385. package/renderer.ts +1 -1
  386. package/scripts/build-packages.ts +162 -0
  387. package/scripts/relay-client.ts +2 -2
  388. package/scripts/typecheck-packages.mjs +3 -3
  389. package/scripts/unified-webhook-server.ts +22 -10
  390. package/scripts/verify-package-contents.ts +345 -0
  391. package/scripts/ws-server.ts +1 -1
  392. package/tracker.ts +1 -1
  393. package/harness/browser-scrapers/base-browser-scraper.d.ts +0 -91
  394. package/harness/browser-scrapers/chrome-profile-manager.d.ts +0 -80
  395. package/harness/browser-scrapers/codex-browser-scraper.d.ts +0 -60
  396. package/harness/browser-scrapers/index.d.ts +0 -29
  397. package/harness/browser-scrapers/zai-browser-scraper.d.ts +0 -79
  398. package/harness/e2e/browser-scrapers/base-browser-scraper.d.ts +0 -92
  399. package/harness/e2e/browser-scrapers/chrome-profile-manager.d.ts +0 -81
  400. package/harness/e2e/browser-scrapers/codex-browser-scraper.d.ts +0 -61
  401. package/harness/e2e/browser-scrapers/index.d.ts +0 -30
  402. package/harness/e2e/browser-scrapers/zai-browser-scraper.d.ts +0 -80
  403. package/harness/langchain/agents.d.ts +0 -143
  404. package/harness/langchain/agents.test.d.ts +0 -2
  405. package/harness/langchain/checkpointer.d.ts +0 -48
  406. package/harness/langchain/checkpointer.test.d.ts +0 -8
  407. package/harness/langchain/cron-cli.d.ts +0 -12
  408. package/harness/langchain/daemon.d.ts +0 -161
  409. package/harness/langchain/daemon.test.d.ts +0 -11
  410. package/harness/langchain/file-tools.d.ts +0 -97
  411. package/harness/langchain/graph.d.ts +0 -706
  412. package/harness/langchain/model-router.d.ts +0 -63
  413. package/harness/langchain/model-router.test.d.ts +0 -2
  414. package/harness/langchain/models.d.ts +0 -72
  415. package/harness/langchain/ping-pong-middleware.d.ts +0 -28
  416. package/harness/langchain/ping-pong-middleware.test.d.ts +0 -2
  417. package/harness/langchain/run.d.ts +0 -15
  418. package/harness/langchain/scoreboard.test.d.ts +0 -13
  419. package/harness/langchain/status-line.d.ts +0 -91
  420. package/harness/langchain/status-line.test.d.ts +0 -8
  421. package/harness/langchain/surge.d.ts +0 -111
  422. package/harness/langchain/surge.test.d.ts +0 -10
  423. package/harness/langchain/widget.d.ts +0 -105
  424. package/harness/langchain/widget.test.d.ts +0 -8
  425. package/packages/autonomous-runtime/dist/worker.d.ts +0 -63
  426. package/packages/autonomous-runtime/dist/worker.js +0 -133
  427. package/packages/capability-registry/src/types.d.ts +0 -47
  428. package/packages/clipboard/dist/clipboard.d.ts +0 -11
  429. package/packages/clipboard/dist/clipboard.js +0 -40
  430. package/packages/clipboard/dist/index.d.ts +0 -2
  431. package/packages/clipboard/dist/index.js +0 -2
  432. package/packages/clipboard/dist/types.d.ts +0 -13
  433. package/packages/clipboard/dist/types.js +0 -5
  434. package/packages/context-discovery/dist/discover.d.ts +0 -3
  435. package/packages/context-discovery/dist/discover.js +0 -42
  436. package/packages/context-discovery/dist/discovery.d.ts +0 -28
  437. package/packages/context-discovery/dist/discovery.js +0 -21
  438. package/packages/context-discovery/dist/index.d.ts +0 -3
  439. package/packages/context-discovery/dist/index.js +0 -2
  440. package/packages/context-discovery/dist/types.d.ts +0 -16
  441. package/packages/context-discovery/dist/types.js +0 -2
  442. package/packages/event-bus/dist/bus.d.ts +0 -15
  443. package/packages/event-bus/dist/bus.js +0 -90
  444. package/packages/event-bus/dist/index.d.ts +0 -4
  445. package/packages/event-bus/dist/index.js +0 -3
  446. package/packages/event-bus/dist/test/bus.test.js +0 -52
  447. package/packages/event-bus/dist/types.d.ts +0 -27
  448. package/packages/event-bus/dist/types.js +0 -10
  449. package/packages/event-store/dist/index.d.ts +0 -3
  450. package/packages/event-store/dist/index.js +0 -2
  451. package/packages/event-store/dist/store.d.ts +0 -15
  452. package/packages/event-store/dist/store.js +0 -131
  453. package/packages/event-store/dist/test/store.test.js +0 -57
  454. package/packages/event-store/dist/types.d.ts +0 -48
  455. package/packages/event-store/dist/types.js +0 -5
  456. package/packages/event-store/src/types.d.ts +0 -48
  457. package/packages/file-copy-helper/dist/src/extension.js +0 -186
  458. package/packages/model-registry/src/types.d.ts +0 -63
  459. package/packages/notification/dist/src/adapters/email-adapter.d.ts +0 -17
  460. package/packages/notification/dist/src/adapters/email-adapter.d.ts.map +0 -1
  461. package/packages/notification/dist/src/adapters/email-adapter.js +0 -89
  462. package/packages/notification/dist/src/adapters/email-adapter.js.map +0 -1
  463. package/packages/notification/dist/src/adapters/line-adapter.d.ts +0 -17
  464. package/packages/notification/dist/src/adapters/line-adapter.d.ts.map +0 -1
  465. package/packages/notification/dist/src/adapters/line-adapter.js +0 -99
  466. package/packages/notification/dist/src/adapters/line-adapter.js.map +0 -1
  467. package/packages/notification/dist/src/adapters/ntfy-adapter.d.ts +0 -17
  468. package/packages/notification/dist/src/adapters/ntfy-adapter.d.ts.map +0 -1
  469. package/packages/notification/dist/src/adapters/ntfy-adapter.js +0 -84
  470. package/packages/notification/dist/src/adapters/ntfy-adapter.js.map +0 -1
  471. package/packages/notification/dist/src/adapters/telegram-adapter.d.ts +0 -56
  472. package/packages/notification/dist/src/adapters/telegram-adapter.d.ts.map +0 -1
  473. package/packages/notification/dist/src/adapters/telegram-adapter.js +0 -251
  474. package/packages/notification/dist/src/adapters/telegram-adapter.js.map +0 -1
  475. package/packages/notification/dist/src/adapters/webhook-adapter.d.ts +0 -15
  476. package/packages/notification/dist/src/adapters/webhook-adapter.d.ts.map +0 -1
  477. package/packages/notification/dist/src/adapters/webhook-adapter.js +0 -64
  478. package/packages/notification/dist/src/adapters/webhook-adapter.js.map +0 -1
  479. package/packages/notification/dist/src/base-adapter.d.ts +0 -36
  480. package/packages/notification/dist/src/base-adapter.d.ts.map +0 -1
  481. package/packages/notification/dist/src/base-adapter.js +0 -39
  482. package/packages/notification/dist/src/base-adapter.js.map +0 -1
  483. package/packages/notification/dist/src/index.d.ts +0 -12
  484. package/packages/notification/dist/src/index.d.ts.map +0 -1
  485. package/packages/notification/dist/src/index.js +0 -12
  486. package/packages/notification/dist/src/index.js.map +0 -1
  487. package/packages/notification/dist/src/notification-center.d.ts +0 -89
  488. package/packages/notification/dist/src/notification-center.d.ts.map +0 -1
  489. package/packages/notification/dist/src/notification-center.js +0 -356
  490. package/packages/notification/dist/src/notification-center.js.map +0 -1
  491. package/packages/notification/dist/src/notification-policy.d.ts +0 -66
  492. package/packages/notification/dist/src/notification-policy.d.ts.map +0 -1
  493. package/packages/notification/dist/src/notification-policy.js +0 -153
  494. package/packages/notification/dist/src/notification-policy.js.map +0 -1
  495. package/packages/notification/dist/src/telegram-webhook-handler.d.ts +0 -86
  496. package/packages/notification/dist/src/telegram-webhook-handler.d.ts.map +0 -1
  497. package/packages/notification/dist/src/telegram-webhook-handler.js +0 -149
  498. package/packages/notification/dist/src/telegram-webhook-handler.js.map +0 -1
  499. package/packages/notification/dist/src/types.d.ts +0 -106
  500. package/packages/notification/dist/src/types.d.ts.map +0 -1
  501. package/packages/notification/dist/src/types.js +0 -7
  502. package/packages/notification/dist/src/types.js.map +0 -1
  503. package/packages/projection-engine/dist/engine.d.ts +0 -61
  504. package/packages/projection-engine/dist/engine.js +0 -76
  505. package/packages/projection-engine/dist/index.d.ts +0 -2
  506. package/packages/projection-engine/dist/index.js +0 -2
  507. package/packages/projection-engine/dist/project.d.ts +0 -3
  508. package/packages/projection-engine/dist/project.js +0 -24
  509. package/packages/projection-engine/dist/types.d.ts +0 -55
  510. package/packages/projection-engine/dist/types.js +0 -5
  511. package/packages/projection-engine/src/types.d.ts +0 -55
  512. package/packages/provider-adapter-sdk/dist/src/builder.d.ts +0 -140
  513. package/packages/provider-adapter-sdk/dist/src/builder.d.ts.map +0 -1
  514. package/packages/provider-adapter-sdk/dist/src/builder.js +0 -332
  515. package/packages/provider-adapter-sdk/dist/src/builder.js.map +0 -1
  516. package/packages/provider-adapter-sdk/dist/src/errors.d.ts +0 -71
  517. package/packages/provider-adapter-sdk/dist/src/errors.d.ts.map +0 -1
  518. package/packages/provider-adapter-sdk/dist/src/errors.js +0 -111
  519. package/packages/provider-adapter-sdk/dist/src/errors.js.map +0 -1
  520. package/packages/provider-adapter-sdk/dist/src/index.d.ts +0 -15
  521. package/packages/provider-adapter-sdk/dist/src/index.d.ts.map +0 -1
  522. package/packages/provider-adapter-sdk/dist/src/index.js +0 -19
  523. package/packages/provider-adapter-sdk/dist/src/index.js.map +0 -1
  524. package/packages/provider-adapter-sdk/dist/src/registry.d.ts +0 -108
  525. package/packages/provider-adapter-sdk/dist/src/registry.d.ts.map +0 -1
  526. package/packages/provider-adapter-sdk/dist/src/registry.js +0 -301
  527. package/packages/provider-adapter-sdk/dist/src/registry.js.map +0 -1
  528. package/packages/provider-adapter-sdk/dist/src/tester.d.ts +0 -71
  529. package/packages/provider-adapter-sdk/dist/src/tester.d.ts.map +0 -1
  530. package/packages/provider-adapter-sdk/dist/src/tester.js +0 -392
  531. package/packages/provider-adapter-sdk/dist/src/tester.js.map +0 -1
  532. package/packages/provider-adapter-sdk/dist/src/types.d.ts +0 -182
  533. package/packages/provider-adapter-sdk/dist/src/types.d.ts.map +0 -1
  534. package/packages/provider-adapter-sdk/dist/src/types.js +0 -11
  535. package/packages/provider-adapter-sdk/dist/src/types.js.map +0 -1
  536. package/packages/provider-router/dist/capability-registry/src/types.d.ts +0 -47
  537. package/packages/provider-router/dist/capability-registry/src/types.d.ts.map +0 -1
  538. package/packages/provider-router/dist/capability-registry/src/types.js +0 -10
  539. package/packages/provider-router/dist/capability-registry/src/types.js.map +0 -1
  540. package/packages/provider-router/dist/provider-router/src/index.d.ts +0 -23
  541. package/packages/provider-router/dist/provider-router/src/index.d.ts.map +0 -1
  542. package/packages/provider-router/dist/provider-router/src/index.js +0 -25
  543. package/packages/provider-router/dist/provider-router/src/index.js.map +0 -1
  544. package/packages/provider-router/dist/provider-router/src/policy.d.ts +0 -10
  545. package/packages/provider-router/dist/provider-router/src/policy.d.ts.map +0 -1
  546. package/packages/provider-router/dist/provider-router/src/policy.js +0 -45
  547. package/packages/provider-router/dist/provider-router/src/policy.js.map +0 -1
  548. package/packages/provider-router/dist/provider-router/src/provider-router.d.ts +0 -56
  549. package/packages/provider-router/dist/provider-router/src/provider-router.d.ts.map +0 -1
  550. package/packages/provider-router/dist/provider-router/src/provider-router.js +0 -222
  551. package/packages/provider-router/dist/provider-router/src/provider-router.js.map +0 -1
  552. package/packages/provider-router/dist/provider-router/src/strategies.d.ts +0 -19
  553. package/packages/provider-router/dist/provider-router/src/strategies.d.ts.map +0 -1
  554. package/packages/provider-router/dist/provider-router/src/strategies.js +0 -110
  555. package/packages/provider-router/dist/provider-router/src/strategies.js.map +0 -1
  556. package/packages/provider-router/dist/provider-router/src/types.d.ts +0 -91
  557. package/packages/provider-router/dist/provider-router/src/types.d.ts.map +0 -1
  558. package/packages/provider-router/dist/provider-router/src/types.js +0 -10
  559. package/packages/provider-router/dist/provider-router/src/types.js.map +0 -1
  560. package/packages/provider-router/dist/src/index.d.ts +0 -23
  561. package/packages/provider-router/dist/src/index.d.ts.map +0 -1
  562. package/packages/provider-router/dist/src/index.js +0 -25
  563. package/packages/provider-router/dist/src/index.js.map +0 -1
  564. package/packages/provider-router/dist/src/policy.d.ts +0 -10
  565. package/packages/provider-router/dist/src/policy.d.ts.map +0 -1
  566. package/packages/provider-router/dist/src/policy.js +0 -45
  567. package/packages/provider-router/dist/src/policy.js.map +0 -1
  568. package/packages/provider-router/dist/src/provider-router.d.ts +0 -56
  569. package/packages/provider-router/dist/src/provider-router.d.ts.map +0 -1
  570. package/packages/provider-router/dist/src/provider-router.js +0 -222
  571. package/packages/provider-router/dist/src/provider-router.js.map +0 -1
  572. package/packages/provider-router/dist/src/strategies.d.ts +0 -19
  573. package/packages/provider-router/dist/src/strategies.d.ts.map +0 -1
  574. package/packages/provider-router/dist/src/strategies.js +0 -110
  575. package/packages/provider-router/dist/src/strategies.js.map +0 -1
  576. package/packages/provider-router/dist/src/types.d.ts +0 -91
  577. package/packages/provider-router/dist/src/types.d.ts.map +0 -1
  578. package/packages/provider-router/dist/src/types.js +0 -10
  579. package/packages/provider-router/dist/src/types.js.map +0 -1
  580. package/packages/provider-router/dist/types/src/runtime-types.d.ts +0 -412
  581. package/packages/provider-router/dist/types/src/runtime-types.d.ts.map +0 -1
  582. package/packages/provider-router/dist/types/src/runtime-types.js +0 -2
  583. package/packages/provider-router/dist/types/src/runtime-types.js.map +0 -1
  584. package/packages/session-api/dist/api.d.ts +0 -83
  585. package/packages/session-api/dist/api.js +0 -35
  586. package/packages/session-api/dist/index.d.ts +0 -2
  587. package/packages/session-api/dist/index.js +0 -2
  588. package/packages/session-api/dist/types.d.ts +0 -22
  589. package/packages/session-api/dist/types.js +0 -5
  590. package/packages/session-export/dist/exporter.d.ts +0 -28
  591. package/packages/session-export/dist/exporter.js +0 -38
  592. package/packages/session-export/dist/index.d.ts +0 -2
  593. package/packages/session-export/dist/index.js +0 -2
  594. package/packages/session-export/dist/types.d.ts +0 -20
  595. package/packages/session-export/dist/types.js +0 -5
  596. package/packages/subscription-engine/dist/engine.d.ts +0 -13
  597. package/packages/subscription-engine/dist/engine.js +0 -40
  598. package/packages/subscription-engine/dist/index.d.ts +0 -2
  599. package/packages/subscription-engine/dist/index.js +0 -2
  600. package/packages/subscription-engine/dist/subscriptions.d.ts +0 -19
  601. package/packages/subscription-engine/dist/subscriptions.js +0 -32
  602. package/packages/subscription-engine/dist/types.d.ts +0 -24
  603. package/packages/subscription-engine/dist/types.js +0 -5
  604. package/packages/trajectory/test/store.test.d.ts +0 -2
  605. package/packages/workflow-events/dist/events.d.ts +0 -38
  606. package/packages/workflow-events/dist/events.js +0 -46
  607. package/packages/workflow-events/dist/index.d.ts +0 -2
  608. package/packages/workflow-events/dist/index.js +0 -2
  609. package/packages/workflow-events/dist/pipeline.d.ts +0 -21
  610. package/packages/workflow-events/dist/pipeline.js +0 -27
  611. package/packages/workflow-events/dist/types.d.ts +0 -110
  612. package/packages/workflow-events/dist/types.js +0 -5
  613. package/packages/workflow-events/src/types.d.ts +0 -110
@@ -0,0 +1,844 @@
1
+ /**
2
+ * Telegram bridge config and pairing helpers
3
+ * Zones: telegram config, pairing, filesystem
4
+ * Owns persisted bot/session pairing state, local config storage, live config controls, authorization policy, and first-user pairing side effects
5
+ */
6
+ import { createHash, randomUUID } from "node:crypto";
7
+ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
8
+ import { withTelegramFileTransaction } from "./locks.js";
9
+ import { resolveAgentDir, resolveTelegramConfigPath, TELEGRAM_DEFAULT_PROFILE_NAME, } from "./paths.js";
10
+ import { isPiStaleContextError } from "./pi.js";
11
+ import { isWireRecord as isPlainConfigRecord } from "./wire.js";
12
+ export { TELEGRAM_DEFAULT_PROFILE_NAME } from "./paths.js";
13
+ const CONFIG_REPLACE_RETRY_ATTEMPTS = 5;
14
+ const CONFIG_REPLACE_RETRY_DELAY_MS = 25;
15
+ function isRetryableConfigReplaceError(error) {
16
+ const code = error?.code;
17
+ return code === "EPERM" || code === "EACCES" || code === "EBUSY";
18
+ }
19
+ function sleepConfigReplaceRetry(ms) {
20
+ if (ms <= 0)
21
+ return;
22
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
23
+ }
24
+ function replaceTelegramConfigFile(tempPath, configPath) {
25
+ for (let attempt = 0; attempt < CONFIG_REPLACE_RETRY_ATTEMPTS; attempt += 1) {
26
+ try {
27
+ renameSync(tempPath, configPath);
28
+ return;
29
+ }
30
+ catch (error) {
31
+ if (!isRetryableConfigReplaceError(error) ||
32
+ attempt === CONFIG_REPLACE_RETRY_ATTEMPTS - 1) {
33
+ throw error;
34
+ }
35
+ sleepConfigReplaceRetry(CONFIG_REPLACE_RETRY_DELAY_MS * (attempt + 1));
36
+ }
37
+ }
38
+ }
39
+ function getConfigPath() {
40
+ return resolveTelegramConfigPath();
41
+ }
42
+ const TELEGRAM_BOT_TOKEN_ENV_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
43
+ /**
44
+ * Parse a persisted bot-token value. `$NAME` and `${NAME}` are exact
45
+ * environment-variable references. Any other `$`-prefixed value is malformed
46
+ * rather than a literal secret so a broken reference fails closed.
47
+ */
48
+ function getTelegramBotTokenReference(value) {
49
+ const trimmed = value?.trim();
50
+ if (!trimmed)
51
+ return undefined;
52
+ if (!trimmed.startsWith("$"))
53
+ return { kind: "literal", token: trimmed };
54
+ const body = trimmed.startsWith("${") && trimmed.endsWith("}")
55
+ ? trimmed.slice(2, -1)
56
+ : trimmed.slice(1);
57
+ return TELEGRAM_BOT_TOKEN_ENV_NAME_PATTERN.test(body)
58
+ ? { kind: "environment", variable: body }
59
+ : { kind: "malformed" };
60
+ }
61
+ /** Resolve a persisted token at a validation/activation boundary. */
62
+ export function resolveTelegramBotToken(value, env = process.env) {
63
+ const reference = getTelegramBotTokenReference(value);
64
+ if (reference?.kind === "literal")
65
+ return reference.token;
66
+ if (reference?.kind !== "environment")
67
+ return undefined;
68
+ return env[reference.variable]?.trim() || undefined;
69
+ }
70
+ /** Redacted diagnostic for an unresolved or malformed token reference. */
71
+ export function getTelegramBotTokenDiagnostic(value, env = process.env) {
72
+ const reference = getTelegramBotTokenReference(value);
73
+ if (reference?.kind === "malformed") {
74
+ return "Telegram bot token environment reference is malformed; use $NAME or ${NAME}.";
75
+ }
76
+ if (reference?.kind !== "environment")
77
+ return undefined;
78
+ if (resolveTelegramBotToken(value, env))
79
+ return undefined;
80
+ return `Telegram bot token environment variable ${reference.variable} is not set.`;
81
+ }
82
+ const TELEGRAM_THREAD_DISPLAY_MODES = [
83
+ "letters",
84
+ "names",
85
+ "directory-snake",
86
+ "directory-title",
87
+ ];
88
+ export function resolveTelegramThreadDisplayMode(config) {
89
+ return TELEGRAM_THREAD_DISPLAY_MODES.includes(config.threadDisplayMode)
90
+ ? config.threadDisplayMode
91
+ : "letters";
92
+ }
93
+ export async function setTelegramThreadDisplayMode(store, mode, isCurrent) {
94
+ if (!TELEGRAM_THREAD_DISPLAY_MODES.includes(mode)) {
95
+ throw new Error("Invalid Telegram Thread display mode.");
96
+ }
97
+ const profile = store.getActiveProfileName();
98
+ const current = () => isCurrent() && store.getActiveProfileName() === profile;
99
+ if (!current())
100
+ throw new Error("Telegram Thread display setting lost authority.");
101
+ await store.load();
102
+ if (!current() || !store.hasBotToken()) {
103
+ throw new Error("Telegram Thread display setting lost its configured profile.");
104
+ }
105
+ await store.persist({ ...store.get(), threadDisplayMode: mode }, { isCurrent: current });
106
+ if (!current())
107
+ throw new Error("Telegram Thread display setting changed during persistence.");
108
+ }
109
+ /** Profile names must contain only lowercase ASCII letters and digits; max 32 chars. */
110
+ const TELEGRAM_PROFILE_NAME_PATTERN = /^[a-z0-9]{1,32}$/;
111
+ const TELEGRAM_RESERVED_PROFILE_NAMES = new Set([
112
+ "main",
113
+ "active",
114
+ ]);
115
+ export function isValidTelegramProfileName(name) {
116
+ return (TELEGRAM_PROFILE_NAME_PATTERN.test(name) &&
117
+ !TELEGRAM_RESERVED_PROFILE_NAMES.has(name));
118
+ }
119
+ /** List defined profile names. */
120
+ export function getTelegramProfileNames(config) {
121
+ return Object.keys(config.profiles ?? {}).sort();
122
+ }
123
+ export function createTelegramConfigBotIdGetter(store) {
124
+ return () => store.get().botId;
125
+ }
126
+ export function createTelegramActiveProfileKeyGetter(store) {
127
+ return () => store.getActiveProfileName() ?? TELEGRAM_DEFAULT_PROFILE_NAME;
128
+ }
129
+ function isEmptyTelegramConfig(config) {
130
+ return Object.keys(config).length === 0;
131
+ }
132
+ async function loadLatestTelegramConfig(configStore) {
133
+ if (!configStore.load)
134
+ return;
135
+ const before = configStore.get();
136
+ await configStore.load();
137
+ if (!isEmptyTelegramConfig(before) &&
138
+ isEmptyTelegramConfig(configStore.get())) {
139
+ configStore.set(before);
140
+ }
141
+ }
142
+ function getInvalidTelegramConfigRecoveryPath(configPath) {
143
+ return `${configPath}.invalid-${process.pid}-${Date.now()}`;
144
+ }
145
+ export async function readTelegramConfig(configPath, options = {}) {
146
+ if (!existsSync(configPath))
147
+ return {};
148
+ const content = readFileSync(configPath, "utf8");
149
+ try {
150
+ return JSON.parse(content);
151
+ }
152
+ catch {
153
+ // Atomic config publication makes ordinary reads safe without serialization.
154
+ // Acquire the transaction only before destructive invalid-file recovery.
155
+ return withTelegramFileTransaction(`${configPath}.transaction`, () => {
156
+ if (!existsSync(configPath))
157
+ return {};
158
+ const identity = statSync(configPath);
159
+ const currentContent = readFileSync(configPath, "utf8");
160
+ try {
161
+ return JSON.parse(currentContent);
162
+ }
163
+ catch (error) {
164
+ const currentIdentity = statSync(configPath);
165
+ if (currentIdentity.dev !== identity.dev ||
166
+ currentIdentity.ino !== identity.ino ||
167
+ currentIdentity.size !== identity.size ||
168
+ currentIdentity.mtimeMs !== identity.mtimeMs) {
169
+ throw new Error(`Telegram config changed while validating invalid content: ${configPath}`, { cause: error });
170
+ }
171
+ const recoveryPath = getInvalidTelegramConfigRecoveryPath(configPath);
172
+ renameSync(configPath, recoveryPath);
173
+ options.onInvalidConfig?.({ configPath, recoveryPath, error });
174
+ return {};
175
+ }
176
+ });
177
+ }
178
+ }
179
+ function cloneTelegramConfig(value) {
180
+ return structuredClone(value);
181
+ }
182
+ function configValuesEqual(left, right) {
183
+ return JSON.stringify(left) === JSON.stringify(right);
184
+ }
185
+ function mergeTelegramConfigDelta(base, desired, latest) {
186
+ const merged = cloneTelegramConfig(latest);
187
+ for (const key of new Set([...Object.keys(base), ...Object.keys(desired)])) {
188
+ const baseHas = Object.hasOwn(base, key);
189
+ const desiredHas = Object.hasOwn(desired, key);
190
+ const baseValue = base[key];
191
+ const desiredValue = desired[key];
192
+ if (baseHas === desiredHas && configValuesEqual(baseValue, desiredValue)) {
193
+ continue;
194
+ }
195
+ if (!desiredHas) {
196
+ delete merged[key];
197
+ continue;
198
+ }
199
+ if (isPlainConfigRecord(desiredValue) &&
200
+ (!baseHas || isPlainConfigRecord(baseValue))) {
201
+ merged[key] = mergeTelegramConfigDelta(isPlainConfigRecord(baseValue) ? baseValue : {}, desiredValue, isPlainConfigRecord(merged[key]) ? merged[key] : {});
202
+ continue;
203
+ }
204
+ merged[key] = cloneTelegramConfig(desiredValue);
205
+ }
206
+ return merged;
207
+ }
208
+ function readTelegramConfigForTransaction(configPath) {
209
+ if (!existsSync(configPath))
210
+ return {};
211
+ const parsed = JSON.parse(readFileSync(configPath, "utf8"));
212
+ if (!isPlainConfigRecord(parsed)) {
213
+ throw new Error(`Invalid Telegram config object: ${configPath}`);
214
+ }
215
+ return parsed;
216
+ }
217
+ function writeTelegramConfigInTransaction(agentDir, configPath, config) {
218
+ mkdirSync(agentDir, { recursive: true, mode: 0o700 });
219
+ const tempConfigPath = `${configPath}.tmp-${process.pid}-${randomUUID()}`;
220
+ writeFileSync(tempConfigPath, `${JSON.stringify(config, null, "\t")}\n`, {
221
+ encoding: "utf8",
222
+ mode: 0o600,
223
+ });
224
+ chmodSync(tempConfigPath, 0o600);
225
+ try {
226
+ replaceTelegramConfigFile(tempConfigPath, configPath);
227
+ chmodSync(configPath, 0o600);
228
+ }
229
+ finally {
230
+ try {
231
+ unlinkSync(tempConfigPath);
232
+ }
233
+ catch {
234
+ /* rename consumed the temp file or cleanup is best effort */
235
+ }
236
+ }
237
+ }
238
+ export function getTelegramProfileFields(config) {
239
+ const token = config.botToken?.trim();
240
+ if (!token)
241
+ return undefined;
242
+ return { botToken: token, ...pickTelegramRootProfileFields(config) };
243
+ }
244
+ /** Root-level profile fields other than the token, including the retired legacy cursor. */
245
+ function pickTelegramRootProfileFields(config) {
246
+ const legacyCursor = config
247
+ .lastUpdateId;
248
+ return {
249
+ ...(config.botUsername !== undefined
250
+ ? { botUsername: config.botUsername }
251
+ : {}),
252
+ ...(config.botId !== undefined ? { botId: config.botId } : {}),
253
+ ...(config.allowedUserId !== undefined
254
+ ? { allowedUserId: config.allowedUserId }
255
+ : {}),
256
+ ...(config.threadDisplayMode !== undefined
257
+ ? { threadDisplayMode: config.threadDisplayMode }
258
+ : {}),
259
+ ...(legacyCursor !== undefined ? { lastUpdateId: legacyCursor } : {}),
260
+ };
261
+ }
262
+ function omitTelegramRootProfileFields(config) {
263
+ const { botToken: _botToken, botUsername: _botUsername, botId: _botId, allowedUserId: _allowedUserId, threadDisplayMode: _threadDisplayMode, lastUpdateId: _lastUpdateId, ...sharedConfig } = config;
264
+ return sharedConfig;
265
+ }
266
+ function omitRetiredProactivePush(config) {
267
+ const assistant = config.assistant;
268
+ if (!assistant || !Object.hasOwn(assistant, "proactivePush")) {
269
+ return { config, changed: false };
270
+ }
271
+ const { proactivePush: _proactivePush, ...remainingAssistant } = assistant;
272
+ const next = { ...config };
273
+ if (Object.keys(remainingAssistant).length > 0) {
274
+ next.assistant = remainingAssistant;
275
+ }
276
+ else {
277
+ delete next.assistant;
278
+ }
279
+ return { config: next, changed: true };
280
+ }
281
+ export function normalizeTelegramDefaultProfileConfig(config) {
282
+ const retiredProactivePush = omitRetiredProactivePush(config);
283
+ config = retiredProactivePush.config;
284
+ const hasLegacyRootProfile = [
285
+ "botToken",
286
+ "botUsername",
287
+ "botId",
288
+ "allowedUserId",
289
+ "threadDisplayMode",
290
+ "lastUpdateId",
291
+ ].some((field) => Object.hasOwn(config, field));
292
+ if (!hasLegacyRootProfile) {
293
+ return { config, changed: retiredProactivePush.changed };
294
+ }
295
+ const canonicalProfile = config.profiles?.[TELEGRAM_DEFAULT_PROFILE_NAME];
296
+ const legacyToken = config.botToken?.trim();
297
+ if (Object.hasOwn(config, "botToken") && !legacyToken) {
298
+ throw new Error("Legacy Telegram default profile has no bot token");
299
+ }
300
+ const legacyProfile = {
301
+ ...(legacyToken ? { botToken: legacyToken } : {}),
302
+ ...pickTelegramRootProfileFields(config),
303
+ };
304
+ if (!canonicalProfile && !legacyToken) {
305
+ throw new Error("Legacy Telegram default profile has no bot token");
306
+ }
307
+ const hasConflict = canonicalProfile
308
+ ? Object.entries(legacyProfile).some(([field, value]) => Object.hasOwn(canonicalProfile, field) &&
309
+ !configValuesEqual(canonicalProfile[field], value))
310
+ : false;
311
+ if (hasConflict) {
312
+ throw new Error("Conflicting Telegram default profile identity at root and profiles.default");
313
+ }
314
+ const normalizedProfile = canonicalProfile
315
+ ? { ...legacyProfile, ...canonicalProfile }
316
+ : legacyProfile;
317
+ return {
318
+ config: {
319
+ ...omitTelegramRootProfileFields(config),
320
+ profiles: {
321
+ ...(config.profiles ?? {}),
322
+ [TELEGRAM_DEFAULT_PROFILE_NAME]: normalizedProfile,
323
+ },
324
+ },
325
+ changed: true,
326
+ };
327
+ }
328
+ function applyTelegramProfile(config, profileName) {
329
+ const effectiveProfileName = profileName ?? TELEGRAM_DEFAULT_PROFILE_NAME;
330
+ const profile = config.profiles?.[effectiveProfileName];
331
+ if (!profile)
332
+ return omitTelegramRootProfileFields(config);
333
+ return {
334
+ ...omitTelegramRootProfileFields(config),
335
+ ...profile,
336
+ };
337
+ }
338
+ function storeTelegramEffectiveConfig(baseConfig, nextConfig, profileName) {
339
+ const effectiveProfileName = profileName ?? TELEGRAM_DEFAULT_PROFILE_NAME;
340
+ const profile = getTelegramProfileFields(nextConfig);
341
+ const profiles = { ...(baseConfig.profiles ?? {}) };
342
+ if (profile)
343
+ profiles[effectiveProfileName] = profile;
344
+ else
345
+ delete profiles[effectiveProfileName];
346
+ return {
347
+ ...omitTelegramRootProfileFields(nextConfig),
348
+ profiles: Object.keys(profiles).length > 0 ? profiles : undefined,
349
+ };
350
+ }
351
+ export function createTelegramConfigStore(options = {}) {
352
+ let config = normalizeTelegramDefaultProfileConfig(cloneTelegramConfig(options.initialConfig ?? {})).config;
353
+ let persistedConfig = {};
354
+ let mutationVersion = 0;
355
+ let persistQueue = Promise.resolve();
356
+ let activeProfileName;
357
+ let lastLoadRecoveredInvalidConfig = false;
358
+ const agentDir = options.agentDir ?? resolveAgentDir();
359
+ const configPath = options.configPath ?? getConfigPath();
360
+ const env = options.env ?? process.env;
361
+ const getEffectiveConfig = () => applyTelegramProfile(config, activeProfileName);
362
+ const setEffectiveConfig = (nextConfig) => {
363
+ config = storeTelegramEffectiveConfig(config, nextConfig, activeProfileName);
364
+ mutationVersion += 1;
365
+ };
366
+ const adoptPersistedConfig = (merged, preserveLocalChanges) => {
367
+ // Local edits are relative to the latest observation, not a queued write's older request baseline.
368
+ const nextConfig = preserveLocalChanges
369
+ ? mergeTelegramConfigDelta(persistedConfig, config, merged)
370
+ : cloneTelegramConfig(merged);
371
+ persistedConfig = cloneTelegramConfig(merged);
372
+ config = nextConfig;
373
+ };
374
+ const withPersistedPairingProfile = (profileName, tokenSha256, observe) => {
375
+ if ((profileName !== TELEGRAM_DEFAULT_PROFILE_NAME &&
376
+ !isValidTelegramProfileName(profileName)) ||
377
+ !/^[a-f0-9]{64}$/u.test(tokenSha256)) {
378
+ throw new Error("Invalid Telegram pairing admission identity.");
379
+ }
380
+ return withTelegramFileTransaction(`${configPath}.transaction`, () => {
381
+ const latest = readTelegramConfigForTransaction(configPath);
382
+ const profile = latest.profiles?.[profileName];
383
+ const resolvedToken = typeof profile?.botToken === "string"
384
+ ? resolveTelegramBotToken(profile.botToken, env)
385
+ : undefined;
386
+ if (!profile ||
387
+ !resolvedToken ||
388
+ createHash("sha256").update(resolvedToken).digest("hex") !==
389
+ tokenSha256 ||
390
+ (profile.allowedUserId !== undefined &&
391
+ (!Number.isSafeInteger(profile.allowedUserId) ||
392
+ profile.allowedUserId <= 0))) {
393
+ throw new Error("Telegram pairing admission authority is unavailable or changed.");
394
+ }
395
+ return observe(latest, profile);
396
+ });
397
+ };
398
+ return {
399
+ get: getEffectiveConfig,
400
+ getStoredConfig: () => config,
401
+ set: setEffectiveConfig,
402
+ setProfile: (profileName, profile) => {
403
+ config = {
404
+ ...omitTelegramRootProfileFields(config),
405
+ profiles: {
406
+ ...(config.profiles ?? {}),
407
+ [profileName]: cloneTelegramConfig(profile),
408
+ },
409
+ };
410
+ mutationVersion += 1;
411
+ },
412
+ update: (mutate) => {
413
+ const nextConfig = getEffectiveConfig();
414
+ mutate(nextConfig);
415
+ setEffectiveConfig(nextConfig);
416
+ },
417
+ activateProfile: (profileName) => {
418
+ const normalizedProfileName = !profileName || profileName === TELEGRAM_DEFAULT_PROFILE_NAME
419
+ ? undefined
420
+ : profileName;
421
+ if (normalizedProfileName && !config.profiles?.[normalizedProfileName]) {
422
+ return false;
423
+ }
424
+ activeProfileName = normalizedProfileName;
425
+ return true;
426
+ },
427
+ getActiveProfileName: () => activeProfileName,
428
+ getBotToken: () => resolveTelegramBotToken(getEffectiveConfig().botToken, env),
429
+ getBotTokenDiagnostic: () => getTelegramBotTokenDiagnostic(getEffectiveConfig().botToken, env),
430
+ hasBotToken: () => !!resolveTelegramBotToken(getEffectiveConfig().botToken, env),
431
+ getAllowedUserId: () => getEffectiveConfig().allowedUserId,
432
+ getLegacyPollingCursor: () => getEffectiveConfig()
433
+ .lastUpdateId,
434
+ removeLegacyPollingCursor: () => {
435
+ const next = {
436
+ ...getEffectiveConfig(),
437
+ };
438
+ delete next.lastUpdateId;
439
+ setEffectiveConfig(next);
440
+ },
441
+ getInboundHandlers: () => [
442
+ ...(config.inboundHandlers ?? []),
443
+ ...(config.attachmentHandlers ?? []),
444
+ ],
445
+ getAttachmentHandlers: () => config.attachmentHandlers,
446
+ getOutboundHandlers: () => config.outboundHandlers,
447
+ setAllowedUserId: (userId) => {
448
+ const nextConfig = getEffectiveConfig();
449
+ nextConfig.allowedUserId = userId;
450
+ setEffectiveConfig(nextConfig);
451
+ },
452
+ withPairingAdmission: (profileName, tokenSha256, publish) => withPersistedPairingProfile(profileName, tokenSha256, (_latest, profile) => publish(profile.allowedUserId === undefined)),
453
+ withPairedUserAdmission: (profileName, tokenSha256, userId, publish, assertExecutionCurrent) => {
454
+ if (!Number.isSafeInteger(userId) || userId <= 0)
455
+ return { admitted: false };
456
+ assertExecutionCurrent?.();
457
+ return withPersistedPairingProfile(profileName, tokenSha256, (latest, profile) => {
458
+ if (profile.allowedUserId !== userId)
459
+ return { admitted: false };
460
+ assertExecutionCurrent?.();
461
+ const current = getEffectiveConfig();
462
+ const previousOwner = persistedConfig.profiles?.[profileName]?.allowedUserId;
463
+ if ((activeProfileName ?? TELEGRAM_DEFAULT_PROFILE_NAME) !==
464
+ profileName ||
465
+ current.botToken !== profile.botToken ||
466
+ (current.allowedUserId !== undefined &&
467
+ current.allowedUserId !== userId) ||
468
+ (current.allowedUserId === undefined && previousOwner !== undefined)) {
469
+ throw new Error("Telegram paired admission lost local profile authority.");
470
+ }
471
+ // Observation is not a local edit; queued persistence still adopts its own fresh disk result.
472
+ adoptPersistedConfig(latest, true);
473
+ return { admitted: true, value: publish() };
474
+ });
475
+ },
476
+ persistAllowedUserId: (userId, assertExecutionCurrent, commitIfOwned) => {
477
+ const profileName = activeProfileName;
478
+ const profileKey = profileName ?? TELEGRAM_DEFAULT_PROFILE_NAME;
479
+ const botToken = getEffectiveConfig().botToken;
480
+ const previousOwner = getEffectiveConfig().allowedUserId;
481
+ const assertCurrent = () => {
482
+ assertExecutionCurrent?.();
483
+ if (activeProfileName !== profileName ||
484
+ getEffectiveConfig().botToken !== botToken ||
485
+ getEffectiveConfig().allowedUserId !== previousOwner) {
486
+ throw new Error("Telegram pairing lost its originating profile authority.");
487
+ }
488
+ };
489
+ const pairing = persistQueue.then(() => {
490
+ assertCurrent();
491
+ if (!Number.isSafeInteger(userId) || userId <= 0)
492
+ throw new Error("Invalid Telegram pairing user ID.");
493
+ let merged;
494
+ const publish = () => {
495
+ merged = withTelegramFileTransaction(`${configPath}.transaction`, () => {
496
+ const latest = readTelegramConfigForTransaction(configPath);
497
+ const profile = latest.profiles?.[profileKey];
498
+ if (!botToken || profile?.botToken !== botToken) {
499
+ throw new Error("Telegram pairing profile is unavailable or changed.");
500
+ }
501
+ assertCurrent();
502
+ if (profile.allowedUserId !== undefined)
503
+ return latest;
504
+ const next = {
505
+ ...latest,
506
+ profiles: {
507
+ ...latest.profiles,
508
+ [profileKey]: { ...profile, allowedUserId: userId },
509
+ },
510
+ };
511
+ writeTelegramConfigInTransaction(agentDir, configPath, next);
512
+ return next;
513
+ });
514
+ };
515
+ if (commitIfOwned) {
516
+ if (!commitIfOwned(publish))
517
+ throw new Error("Telegram pairing lost transport ownership before publication.");
518
+ }
519
+ else {
520
+ publish();
521
+ }
522
+ if (!merged)
523
+ throw new Error("Telegram pairing publication did not execute.");
524
+ adoptPersistedConfig(merged, true);
525
+ return merged.profiles?.[profileKey]?.allowedUserId === userId;
526
+ });
527
+ persistQueue = pairing.then(() => undefined, () => undefined);
528
+ return pairing;
529
+ },
530
+ load: async () => {
531
+ lastLoadRecoveredInvalidConfig = false;
532
+ const loadedConfig = await readTelegramConfig(configPath, {
533
+ onInvalidConfig: (recovery) => {
534
+ lastLoadRecoveredInvalidConfig = true;
535
+ options.recordRuntimeEvent?.("config", recovery.error, {
536
+ phase: "load",
537
+ configPath: recovery.configPath,
538
+ recoveryPath: recovery.recoveryPath,
539
+ });
540
+ },
541
+ });
542
+ let normalized;
543
+ try {
544
+ normalized = normalizeTelegramDefaultProfileConfig(loadedConfig);
545
+ }
546
+ catch (error) {
547
+ options.recordRuntimeEvent?.("config", error, {
548
+ phase: "default-profile-normalize",
549
+ configPath,
550
+ });
551
+ throw error;
552
+ }
553
+ config = normalized.changed
554
+ ? withTelegramFileTransaction(`${configPath}.transaction`, () => {
555
+ const latestConfig = readTelegramConfigForTransaction(configPath);
556
+ const latestNormalized = normalizeTelegramDefaultProfileConfig(latestConfig);
557
+ if (latestNormalized.changed) {
558
+ writeTelegramConfigInTransaction(agentDir, configPath, latestNormalized.config);
559
+ }
560
+ return latestNormalized.config;
561
+ })
562
+ : normalized.config;
563
+ persistedConfig = cloneTelegramConfig(config);
564
+ mutationVersion += 1;
565
+ },
566
+ didLastLoadRecoverInvalidConfig: () => lastLoadRecoveredInvalidConfig,
567
+ persist: (nextConfig = getEffectiveConfig(), options) => {
568
+ const profileName = activeProfileName;
569
+ const desiredConfig = storeTelegramEffectiveConfig(config, cloneTelegramConfig(nextConfig), profileName);
570
+ const baseConfig = cloneTelegramConfig(persistedConfig);
571
+ const capturedMutationVersion = mutationVersion;
572
+ const persist = persistQueue.then(() => {
573
+ const mergedConfig = withTelegramFileTransaction(`${configPath}.transaction`, () => {
574
+ if (options?.isCurrent && !options.isCurrent()) {
575
+ throw new Error("Telegram config update lost its originating authority.");
576
+ }
577
+ const latestConfig = readTelegramConfigForTransaction(configPath);
578
+ const merged = mergeTelegramConfigDelta(baseConfig, desiredConfig, latestConfig);
579
+ if (!configValuesEqual(latestConfig, merged)) {
580
+ writeTelegramConfigInTransaction(agentDir, configPath, merged);
581
+ }
582
+ return merged;
583
+ });
584
+ adoptPersistedConfig(mergedConfig, mutationVersion !== capturedMutationVersion);
585
+ });
586
+ persistQueue = persist.catch(() => undefined);
587
+ return persist;
588
+ },
589
+ };
590
+ }
591
+ function createTelegramDraftPreviewsChecker(configStore) {
592
+ return () => {
593
+ const config = configStore.get();
594
+ return (config.assistant?.draftPreviews ??
595
+ config.draftPreviews ??
596
+ config.richDraftPreviews ??
597
+ true);
598
+ };
599
+ }
600
+ function createTelegramDraftPreviewsSetter(configStore) {
601
+ return async (enabled) => {
602
+ await loadLatestTelegramConfig(configStore);
603
+ const { draftPreviews: _legacyDraftPreviews, richDraftPreviews: _legacyRichDraftPreviews, ...current } = configStore.get();
604
+ const config = {
605
+ ...current,
606
+ assistant: { ...current.assistant, draftPreviews: enabled },
607
+ };
608
+ configStore.set(config);
609
+ await configStore.persist(config);
610
+ };
611
+ }
612
+ function createTelegramAssistantRenderingModeGetter(configStore) {
613
+ return () => {
614
+ const config = configStore.get();
615
+ const mode = config.assistant?.rendering ?? config.assistantRendering;
616
+ return mode === "html" ? "html" : "rich";
617
+ };
618
+ }
619
+ function createTelegramAssistantRenderingModeSetter(configStore) {
620
+ return async (mode) => {
621
+ await loadLatestTelegramConfig(configStore);
622
+ const { assistantRendering: _legacyAssistantRendering, ...current } = configStore.get();
623
+ const config = {
624
+ ...current,
625
+ assistant: { ...current.assistant, rendering: mode },
626
+ };
627
+ configStore.set(config);
628
+ await configStore.persist(config);
629
+ };
630
+ }
631
+ function createTelegramActivityVerbosityGetter(configStore) {
632
+ return () => {
633
+ const assistant = configStore.get().assistant;
634
+ if (assistant?.activity !== undefined) {
635
+ if (assistant.activity === "thinking" ||
636
+ assistant.activity === "tools" ||
637
+ assistant.activity === "verbose") {
638
+ return assistant.activity;
639
+ }
640
+ return "quiet";
641
+ }
642
+ if (assistant?.activityVerbosity !== undefined) {
643
+ return assistant.activityVerbosity === "verbose" ? "verbose" : "quiet";
644
+ }
645
+ return "verbose";
646
+ };
647
+ }
648
+ function createTelegramActivityVerbosityRefresher(configStore) {
649
+ return () => loadLatestTelegramConfig(configStore);
650
+ }
651
+ function createTelegramActivityVerbositySetter(configStore) {
652
+ return async (verbosity) => {
653
+ await loadLatestTelegramConfig(configStore);
654
+ const current = configStore.get();
655
+ const { activityVerbosity: _legacyActivityVerbosity, ...assistant } = current.assistant ?? {};
656
+ const config = {
657
+ ...current,
658
+ assistant: {
659
+ ...assistant,
660
+ activity: verbosity,
661
+ },
662
+ };
663
+ configStore.set(config);
664
+ await configStore.persist(config);
665
+ };
666
+ }
667
+ export function createTelegramVoiceReplyModeGetter(configStore) {
668
+ return () => {
669
+ const mode = configStore.get().voice?.replyMode;
670
+ return mode === "mirror" || mode === "always" ? mode : "manual";
671
+ };
672
+ }
673
+ export function createTelegramVoiceReplyModeConfiguredChecker(configStore) {
674
+ return () => {
675
+ const mode = configStore.get().voice?.replyMode;
676
+ return mode === "mirror" || mode === "always";
677
+ };
678
+ }
679
+ export function createTelegramVoiceReplyModeSetter(configStore) {
680
+ return async (replyMode) => {
681
+ await loadLatestTelegramConfig(configStore);
682
+ const current = configStore.get();
683
+ if (replyMode === undefined ||
684
+ replyMode === "manual" ||
685
+ replyMode === "hidden") {
686
+ const { replyMode: _replyMode, ...remainingVoice } = current.voice ?? {};
687
+ const next = { ...current };
688
+ if (Object.keys(remainingVoice).length > 0)
689
+ next.voice = remainingVoice;
690
+ else
691
+ delete next.voice;
692
+ configStore.set(next);
693
+ await configStore.persist(next);
694
+ return;
695
+ }
696
+ const next = { ...current, voice: { ...(current.voice ?? {}), replyMode } };
697
+ configStore.set(next);
698
+ await configStore.persist(next);
699
+ };
700
+ }
701
+ function getSystemTimezone() {
702
+ try {
703
+ const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
704
+ return tz && tz.length > 0 ? tz : "UTC";
705
+ }
706
+ catch {
707
+ return "UTC";
708
+ }
709
+ }
710
+ export function resolveTelegramTimeConfig(raw, timeInjection = undefined) {
711
+ const injectionMode = timeInjection === undefined
712
+ ? "interval"
713
+ : timeInjection === "always" || timeInjection === "interval"
714
+ ? timeInjection
715
+ : "hidden";
716
+ const interval = typeof raw?.interval === "number" && raw.interval > 0
717
+ ? raw.interval
718
+ : 60 * 60 * 1000;
719
+ const timezone = getSystemTimezone();
720
+ return { injectionMode, interval, timezone };
721
+ }
722
+ export function createTelegramTimeConfigGetter(configStore) {
723
+ return () => {
724
+ const config = configStore.get();
725
+ return resolveTelegramTimeConfig(config.time, config.assistant?.timeInjection);
726
+ };
727
+ }
728
+ export function createTelegramTimeInjectionModeGetter(configStore) {
729
+ return () => {
730
+ const config = configStore.get();
731
+ return resolveTelegramTimeConfig(config.time, config.assistant?.timeInjection).injectionMode;
732
+ };
733
+ }
734
+ export function createTelegramTimeInjectionModeSetter(configStore) {
735
+ return async (injectionMode) => {
736
+ await loadLatestTelegramConfig(configStore);
737
+ const current = configStore.get();
738
+ const next = {
739
+ ...current,
740
+ assistant: {
741
+ ...(current.assistant ?? {}),
742
+ timeInjection: injectionMode,
743
+ },
744
+ };
745
+ configStore.set(next);
746
+ await configStore.persist(next);
747
+ };
748
+ }
749
+ export function createTelegramProactivePushChatIdGetter(getTarget) {
750
+ return () => getTarget()?.chatId;
751
+ }
752
+ export function createTelegramProactivePushTargetGetter(deps) {
753
+ return () => {
754
+ const activeTarget = deps.getActiveTurnTarget();
755
+ if (activeTarget)
756
+ return activeTarget;
757
+ const assignedTarget = deps.getAssignedTarget();
758
+ if (assignedTarget)
759
+ return assignedTarget;
760
+ const chatId = deps.getAllowedUserId();
761
+ return typeof chatId === "number" ? { chatId } : undefined;
762
+ };
763
+ }
764
+ function createTelegramAutomaticThreadCleanupChecker(configStore) {
765
+ return () => configStore.get().threads?.automaticCleanup ?? true;
766
+ }
767
+ function createTelegramAutomaticThreadCleanupResolver(configStore) {
768
+ return async () => {
769
+ await loadLatestTelegramConfig(configStore);
770
+ if (configStore.didLastLoadRecoverInvalidConfig?.()) {
771
+ throw new Error("Thread cleanup setting is unavailable after invalid Telegram config recovery.");
772
+ }
773
+ return createTelegramAutomaticThreadCleanupChecker(configStore)();
774
+ };
775
+ }
776
+ function createTelegramAutomaticThreadCleanupSetter(configStore) {
777
+ return async (enabled) => {
778
+ await loadLatestTelegramConfig(configStore);
779
+ const current = configStore.get();
780
+ const config = {
781
+ ...current,
782
+ threads: { ...current.threads, automaticCleanup: enabled },
783
+ };
784
+ configStore.set(config);
785
+ await configStore.persist(config);
786
+ };
787
+ }
788
+ export function createTelegramConfigControls(configStore) {
789
+ return {
790
+ areDraftPreviewsEnabled: createTelegramDraftPreviewsChecker(configStore),
791
+ setDraftPreviewsEnabled: createTelegramDraftPreviewsSetter(configStore),
792
+ getAssistantRenderingMode: createTelegramAssistantRenderingModeGetter(configStore),
793
+ setAssistantRenderingMode: createTelegramAssistantRenderingModeSetter(configStore),
794
+ getActivityVerbosity: createTelegramActivityVerbosityGetter(configStore),
795
+ refreshActivityVerbosity: createTelegramActivityVerbosityRefresher(configStore),
796
+ setActivityVerbosity: createTelegramActivityVerbositySetter(configStore),
797
+ getVoiceReplyMode: createTelegramVoiceReplyModeGetter(configStore),
798
+ isVoiceReplyModeConfigured: createTelegramVoiceReplyModeConfiguredChecker(configStore),
799
+ setVoiceReplyMode: createTelegramVoiceReplyModeSetter(configStore),
800
+ getTimeInjectionMode: createTelegramTimeInjectionModeGetter(configStore),
801
+ setTimeInjectionMode: createTelegramTimeInjectionModeSetter(configStore),
802
+ isAutomaticThreadCleanupEnabled: createTelegramAutomaticThreadCleanupChecker(configStore),
803
+ resolveAutomaticThreadCleanupEnabled: createTelegramAutomaticThreadCleanupResolver(configStore),
804
+ setAutomaticThreadCleanupEnabled: createTelegramAutomaticThreadCleanupSetter(configStore),
805
+ };
806
+ }
807
+ export function getTelegramAuthorizationState(userId, allowedUserId) {
808
+ if (allowedUserId === undefined) {
809
+ return { kind: "pair", userId };
810
+ }
811
+ if (userId === allowedUserId) {
812
+ return { kind: "allow" };
813
+ }
814
+ return { kind: "deny" };
815
+ }
816
+ export async function pairTelegramUserIfNeeded(userId, deps) {
817
+ const authorization = getTelegramAuthorizationState(userId, deps.allowedUserId);
818
+ if (authorization.kind !== "pair")
819
+ return authorization.kind === "allow";
820
+ deps.assertExecutionCurrent?.();
821
+ const allowed = await deps.persistAllowedUserId(authorization.userId, deps.assertExecutionCurrent);
822
+ deps.assertExecutionCurrent?.();
823
+ if (!allowed)
824
+ return false;
825
+ try {
826
+ deps.updateStatus(deps.ctx);
827
+ }
828
+ catch (error) {
829
+ if (!isPiStaleContextError(error))
830
+ throw error;
831
+ }
832
+ return true;
833
+ }
834
+ export function createTelegramUserPairingRuntime(deps) {
835
+ return {
836
+ pairIfNeeded: (userId, ctx, assertExecutionCurrent) => pairTelegramUserIfNeeded(userId, {
837
+ allowedUserId: deps.getAllowedUserId(),
838
+ ctx,
839
+ persistAllowedUserId: deps.persistAllowedUserId,
840
+ updateStatus: deps.updateStatus,
841
+ assertExecutionCurrent,
842
+ }),
843
+ };
844
+ }