abtars 0.3.4-alpha.7 → 0.3.4

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 (348) hide show
  1. package/bundle/{_registry.generated-WGR4WOPT.js → _registry.generated-AVR7DK2A.js} +17 -14
  2. package/bundle/{_registry.generated-WGR4WOPT.js.map → _registry.generated-AVR7DK2A.js.map} +1 -1
  3. package/bundle/{abmind-lazy-7Z44NODV.js → abmind-lazy-E3YCFKQ5.js} +15 -5
  4. package/bundle/abtars-browser.js +4 -4
  5. package/bundle/abtars-cli.js +23 -13
  6. package/bundle/abtars-cli.js.map +2 -2
  7. package/bundle/abtars-restart.js +3 -3
  8. package/bundle/abtars-task.js +3 -3
  9. package/bundle/abtars-task.js.map +2 -2
  10. package/bundle/abtars.js +610 -455
  11. package/bundle/abtars.js.map +4 -4
  12. package/bundle/{acp-raw-client-E6FM45NC.js → acp-raw-client-UCNK3OTU.js} +2 -2
  13. package/bundle/{action-gate-G2V47NHW.js → action-gate-V4FCBHFB.js} +2 -2
  14. package/bundle/{agent-api-adapter-YAHKQMMZ.js → agent-api-adapter-7HEPYSIN.js} +3 -3
  15. package/bundle/{agent-api-rate-limit-WCFXJMGY.js → agent-api-rate-limit-RZSAM3SW.js} +4 -4
  16. package/bundle/{agent-registry-GI6CLT3Z.js → agent-registry-46A2R5KP.js} +7 -7
  17. package/bundle/{bootstrap-X2QYIZIJ.js → bootstrap-MIHJJSWU.js} +2 -2
  18. package/bundle/{bridge-lock-transport-4ZH7QTJP.js → bridge-lock-transport-7RSN7OLJ.js} +4 -4
  19. package/bundle/{browser-DMARZJIN.js → browser-F6BCWJWW.js} +6 -6
  20. package/bundle/{budget-45QOBDWA.js → budget-WUM3SPKW.js} +3 -3
  21. package/bundle/{capability-JFWX3IQF.js → capability-QVRKGRFC.js} +5 -5
  22. package/bundle/{chunk-YSKCQH6E.js → chunk-2IYJ4I66.js} +2 -2
  23. package/bundle/{chunk-KTYGKPYM.js → chunk-2NLUT5S2.js} +6 -6
  24. package/bundle/chunk-3BG3AIDP.js +191 -0
  25. package/bundle/chunk-3BG3AIDP.js.map +7 -0
  26. package/bundle/{chunk-OKAQICWY.js → chunk-3GQX34S2.js} +3 -3
  27. package/bundle/{chunk-QROWBWLL.js → chunk-3XZ773BS.js} +2 -2
  28. package/bundle/{chunk-DYBW4XXL.js → chunk-467SRLLR.js} +2 -2
  29. package/bundle/{chunk-LGP6TYFI.js → chunk-4AILRHUI.js} +97 -8
  30. package/bundle/chunk-4AILRHUI.js.map +7 -0
  31. package/bundle/{chunk-GPZNXY2U.js → chunk-4S3H4OK7.js} +4 -4
  32. package/bundle/{chunk-NDCRWEEJ.js → chunk-4Y5MJQRE.js} +6 -6
  33. package/bundle/{chunk-FRKW6LWB.js → chunk-55UWKI5C.js} +3 -3
  34. package/bundle/{chunk-4UL3KINB.js → chunk-5PNJFDSW.js} +8 -8
  35. package/bundle/{chunk-LUNA6PM5.js → chunk-5RVOEFGT.js} +4 -2
  36. package/bundle/{chunk-LUNA6PM5.js.map → chunk-5RVOEFGT.js.map} +2 -2
  37. package/bundle/{chunk-OXTSWQCX.js → chunk-5Y3FJ2Y7.js} +2 -2
  38. package/bundle/{chunk-TMUYFERL.js → chunk-6B5ZFUPD.js} +2 -2
  39. package/bundle/{chunk-65VCEC32.js → chunk-6PA5JBUU.js} +2 -2
  40. package/bundle/chunk-BNXV7SZI.js +195 -0
  41. package/bundle/chunk-BNXV7SZI.js.map +7 -0
  42. package/bundle/{chunk-AFREM7FX.js → chunk-CK7YTA2F.js} +2 -2
  43. package/bundle/{chunk-NRUSRJXR.js → chunk-DZJ5QZFD.js} +2 -2
  44. package/bundle/{chunk-YRSMGJFP.js → chunk-E67KESEG.js} +2 -2
  45. package/bundle/{chunk-ZV4IWKDJ.js → chunk-E7XD5UGB.js} +3 -3
  46. package/bundle/{chunk-GXL7HJPT.js → chunk-EAX5ZZUL.js} +63 -39
  47. package/bundle/chunk-EAX5ZZUL.js.map +7 -0
  48. package/bundle/{chunk-PEDX56EL.js → chunk-EFGBM555.js} +2 -2
  49. package/bundle/{chunk-EQSG2CRM.js → chunk-FGYDIX54.js} +22 -15
  50. package/bundle/chunk-FGYDIX54.js.map +7 -0
  51. package/bundle/{chunk-XWRADSXO.js → chunk-GF6NVNA7.js} +15 -5
  52. package/bundle/chunk-GF6NVNA7.js.map +7 -0
  53. package/bundle/{chunk-SIFPBTI4.js → chunk-HGSHCQ5F.js} +113 -73
  54. package/bundle/chunk-HGSHCQ5F.js.map +7 -0
  55. package/bundle/{chunk-YRU2K3O6.js → chunk-IMIGG5EO.js} +39 -39
  56. package/bundle/chunk-IMIGG5EO.js.map +7 -0
  57. package/bundle/{chunk-W4EA4GCA.js → chunk-ITOFPJAV.js} +43 -31
  58. package/bundle/chunk-ITOFPJAV.js.map +7 -0
  59. package/bundle/{chunk-UPRZDU6T.js → chunk-IY6UKLPS.js} +3 -3
  60. package/bundle/{chunk-EUZDKV3C.js → chunk-J4RUFAPK.js} +3 -3
  61. package/bundle/{chunk-HZDLFLRP.js → chunk-J7DRPVMU.js} +35 -5
  62. package/bundle/chunk-J7DRPVMU.js.map +7 -0
  63. package/bundle/{chunk-EGL6UMAO.js → chunk-JG4BKXBN.js} +7 -1
  64. package/bundle/chunk-JG4BKXBN.js.map +7 -0
  65. package/bundle/{chunk-5B5B6EHL.js → chunk-JLWYPGWI.js} +5 -5
  66. package/bundle/{chunk-5QUTMUIK.js → chunk-JXYWDAHD.js} +12 -12
  67. package/bundle/{chunk-GRVWZO4C.js → chunk-KOSFXW2S.js} +24 -3
  68. package/bundle/{chunk-GRVWZO4C.js.map → chunk-KOSFXW2S.js.map} +1 -1
  69. package/bundle/{chunk-ONBF5DDU.js → chunk-L72RIPEC.js} +248 -182
  70. package/bundle/chunk-L72RIPEC.js.map +7 -0
  71. package/bundle/{chunk-TEFZ4JA4.js → chunk-NHPLD3C7.js} +2 -2
  72. package/bundle/{chunk-2KC5G3EA.js → chunk-OWUO5RS3.js} +5 -5
  73. package/bundle/{chunk-4MULJ5SS.js → chunk-OY4Q6AMY.js} +71 -49
  74. package/bundle/chunk-OY4Q6AMY.js.map +7 -0
  75. package/bundle/{chunk-WBTJ2E62.js → chunk-P3NODAHF.js} +2 -5
  76. package/bundle/{chunk-WBTJ2E62.js.map → chunk-P3NODAHF.js.map} +2 -2
  77. package/bundle/{chunk-BROFMHC2.js → chunk-PB5GF4FG.js} +334 -237
  78. package/bundle/chunk-PB5GF4FG.js.map +7 -0
  79. package/bundle/{chunk-WYHGNI56.js → chunk-PMD5BLFS.js} +6 -6
  80. package/bundle/{chunk-URQPDCK5.js → chunk-Q66LQMMZ.js} +3 -3
  81. package/bundle/{chunk-HKRSMUXJ.js → chunk-SC2Y5NR2.js} +71 -132
  82. package/bundle/chunk-SC2Y5NR2.js.map +7 -0
  83. package/bundle/chunk-SFL4EPCZ.js +555 -0
  84. package/bundle/chunk-SFL4EPCZ.js.map +7 -0
  85. package/bundle/{chunk-LDUOOKQY.js → chunk-SJPUNDZ3.js} +5 -5
  86. package/bundle/{chunk-LDUOOKQY.js.map → chunk-SJPUNDZ3.js.map} +1 -1
  87. package/bundle/{chunk-JQDJPUHM.js → chunk-TWB2ZGVH.js} +2 -2
  88. package/bundle/{chunk-IJT4KWXT.js → chunk-U4U47YE7.js} +2 -2
  89. package/bundle/{chunk-2FAZIA37.js → chunk-W546CU3A.js} +3 -3
  90. package/bundle/chunk-WC5O5KOE.js +211 -0
  91. package/bundle/chunk-WC5O5KOE.js.map +7 -0
  92. package/bundle/{chunk-JNIHEDKF.js → chunk-XPWYDNWL.js} +2 -2
  93. package/bundle/{chunk-GWILHZPT.js → chunk-XRTXYN66.js} +10 -7
  94. package/bundle/{chunk-GWILHZPT.js.map → chunk-XRTXYN66.js.map} +2 -2
  95. package/bundle/{chunk-EFJVUJBE.js → chunk-Y5FEFKGM.js} +6 -6
  96. package/bundle/chunk-YJZE4OK3.js +169 -0
  97. package/bundle/chunk-YJZE4OK3.js.map +7 -0
  98. package/bundle/{chunk-GVM5YU5I.js → chunk-Z4FZPB42.js} +2 -2
  99. package/bundle/{chunk-7BSQ5UQO.js → chunk-ZSIDQ66D.js} +3 -3
  100. package/bundle/{chunk-XX6BGTPO.js → chunk-ZZZCJJEO.js} +4 -4
  101. package/bundle/{commands-XYEGVUZF.js → commands-2ZW6CMLC.js} +17 -16
  102. package/bundle/{config-M3P5IOAI.js → config-YMY5YHKN.js} +6 -6
  103. package/bundle/{context-2RJHC2LE.js → context-CL2RSLII.js} +7 -5
  104. package/bundle/context-CL2RSLII.js.map +7 -0
  105. package/bundle/{daemon-TB23FFWY.js → daemon-D7SU63OY.js} +3 -3
  106. package/bundle/{delegation-tools-QKNYQGTQ.js → delegation-tools-WS7Z56KZ.js} +12 -12
  107. package/bundle/{deploy-EPDWNHJU.js → deploy-AMTVKIMU.js} +2 -2
  108. package/bundle/{deps-WVK553KF.js → deps-T63AVJKJ.js} +3 -3
  109. package/bundle/{direct-api-transport-E3LNDBJT.js → direct-api-transport-QNNY2WWP.js} +56 -33
  110. package/bundle/direct-api-transport-QNNY2WWP.js.map +7 -0
  111. package/bundle/{discord-adapter-IT3KP3VB.js → discord-adapter-ABAD56Y2.js} +21 -20
  112. package/bundle/{discord-adapter-IT3KP3VB.js.map → discord-adapter-ABAD56Y2.js.map} +1 -1
  113. package/bundle/{dns-wakeup-IDOJIXBX.js → dns-wakeup-V3LEFXPE.js} +9 -33
  114. package/bundle/dns-wakeup-V3LEFXPE.js.map +7 -0
  115. package/bundle/{doctor-probes-B54JFIW3.js → doctor-probes-O6YI6XSZ.js} +6 -2
  116. package/bundle/{env-schema-4JXQUOH4.js → env-schema-B5RB32DC.js} +3 -3
  117. package/bundle/{gossip-3C3BSNPN.js → gossip-SKRCPOBS.js} +9 -5
  118. package/bundle/{guardrails-DL7ZSWVN.js → guardrails-64GQ5Y5K.js} +4 -4
  119. package/bundle/{heartbeat-system-MVTRS4GP.js → heartbeat-system-X4MUTKJD.js} +6 -6
  120. package/bundle/{heartbeat-tier3-ABWL3P7M.js → heartbeat-tier3-2PTPWEQQ.js} +53 -76
  121. package/bundle/heartbeat-tier3-2PTPWEQQ.js.map +7 -0
  122. package/bundle/{hook-system-M3POLUIB.js → hook-system-YB635OC4.js} +3 -3
  123. package/bundle/{hotskills-FWX4QI7V.js → hotskills-Q75D2DK3.js} +5 -5
  124. package/bundle/{install-OS3CU7NF.js → install-RFKKFSGS.js} +17 -30
  125. package/bundle/install-RFKKFSGS.js.map +7 -0
  126. package/bundle/{install-manifest-5PPWMD2W.js → install-manifest-J7ICPCJN.js} +2 -2
  127. package/bundle/{irc-adapter-PTTZD32W.js → irc-adapter-TVEV4R6H.js} +3 -3
  128. package/bundle/{irc-config-CP7ZMUOX.js → irc-config-M676FOFI.js} +4 -4
  129. package/bundle/{kanban-board-M326B2XJ.js → kanban-board-DLEJUCNN.js} +9 -7
  130. package/bundle/{kanban-channel-IJ52OMNA.js → kanban-channel-XOLUHJZJ.js} +6 -6
  131. package/bundle/kanban-delivery-C4QPBNPX.js +45 -0
  132. package/bundle/kanban-delivery-C4QPBNPX.js.map +7 -0
  133. package/bundle/{lazy-require-KCRVT4SI.js → lazy-require-JKQSALXN.js} +3 -3
  134. package/bundle/{logger-OWCSNYCA.js → logger-3EGHBD4R.js} +2 -2
  135. package/bundle/{main-chat-ZNUZCTNS.js → main-chat-3H63REKK.js} +4 -4
  136. package/bundle/{master-user-HSKM4ZFN.js → master-user-MUBUP3KD.js} +5 -5
  137. package/bundle/{media-utils-3ZYOD7SK.js → media-utils-HUUIALAJ.js} +3 -3
  138. package/bundle/{message-pipeline-P5GAQU4Z.js → message-pipeline-GRDRWONR.js} +17 -16
  139. package/bundle/meta.json +3699 -3138
  140. package/bundle/{metrics-collector-L3VPEHII.js → metrics-collector-YMUGY3PI.js} +31 -2
  141. package/bundle/metrics-collector-YMUGY3PI.js.map +7 -0
  142. package/bundle/{model-health-registry-MLEIZSTV.js → model-health-registry-QADMFQFQ.js} +2 -2
  143. package/bundle/{nerve-IGSXBKZZ.js → nerve-QPAEBRKX.js} +3 -3
  144. package/bundle/{notification-BFSIEECG.js → notification-3JICGXWU.js} +6 -6
  145. package/bundle/{openrouter-credits-NTVZDRYM.js → openrouter-credits-7NEIPYJN.js} +3 -3
  146. package/bundle/{orc-tools-4CHEFWSN.js → orc-tools-UZVPONKY.js} +5 -3
  147. package/bundle/{peer-auth-QC4EF2PM.js → peer-auth-RI43DKJE.js} +24 -15
  148. package/bundle/{peer-client-RGEU5HOK.js → peer-client-UITTMWJ2.js} +34 -29
  149. package/bundle/peer-client-UITTMWJ2.js.map +7 -0
  150. package/bundle/{peer-config-TN55LFDC.js → peer-config-URM7DCW6.js} +9 -4
  151. package/bundle/{peer-transport-I6JPLFZ2.js → peer-transport-SI7I72DB.js} +12 -10
  152. package/bundle/{phase-transport-PGKU2KD4.js → phase-transport-ESWWACZI.js} +17 -17
  153. package/bundle/{reconcile-CTFCLQRN.js → reconcile-GFDQYNBD.js} +3 -3
  154. package/bundle/{reconciler-EBKH3JNU.js → reconciler-IEUJXJN2.js} +12 -12
  155. package/bundle/{restore-IFHPI7I7.js → restore-FARTGLQQ.js} +3 -3
  156. package/bundle/{rollback-ANRI3T5Z.js → rollback-GEWPZABG.js} +2 -2
  157. package/bundle/{sandbox-runtime-QROWHDCS.js → sandbox-runtime-DV6E25J6.js} +2 -2
  158. package/bundle/{self-healer-utils-IFAYOQO2.js → self-healer-utils-P4SKNNEM.js} +3 -3
  159. package/bundle/{sha-tracker-ZWBP6CIJ.js → sha-tracker-77SHLYNY.js} +3 -3
  160. package/bundle/{skill-session-BMSRQSHV.js → skill-session-5HSMXY54.js} +3 -3
  161. package/bundle/{skill-stats-JORH5DGM.js → skill-stats-MI3RSWWL.js} +4 -4
  162. package/bundle/{skill-watcher-E4MGLKLS.js → skill-watcher-5L7JE6TN.js} +4 -4
  163. package/bundle/{sleep-36XS6MHJ.js → sleep-I4JFASCY.js} +11 -8
  164. package/bundle/{soul-bundle-VWAVHCZ6.js → soul-bundle-522C3IRH.js} +9 -8
  165. package/bundle/{spin-TI3TSVVT.js → spin-VHNGNWTD.js} +11 -11
  166. package/bundle/{spin-notifications-SE2HVZI7.js → spin-notifications-7NC5XZEM.js} +5 -5
  167. package/bundle/{spin-types-BLPYAETA.js → spin-types-C5KOQOPD.js} +7 -3
  168. package/bundle/{sse-parser-anthropic-A6R4Z2TB.js → sse-parser-anthropic-MMTVWHLI.js} +3 -3
  169. package/bundle/{sse-parser-responses-HSZY3QGJ.js → sse-parser-responses-3AOFN64C.js} +3 -3
  170. package/bundle/{ssrf-guard-O6SHIK6Q.js → ssrf-guard-U2JA72TC.js} +3 -3
  171. package/bundle/{start-7QZIWO3S.js → start-H5IUFAWF.js} +4 -2
  172. package/bundle/{start-7QZIWO3S.js.map → start-H5IUFAWF.js.map} +2 -2
  173. package/bundle/{stt-LGVPXMVR.js → stt-PSOPPBV4.js} +4 -4
  174. package/bundle/{system-status-JZU5FO7B.js → system-status-4LYGOFNO.js} +38 -24
  175. package/bundle/system-status-4LYGOFNO.js.map +7 -0
  176. package/bundle/{task-store-W5BFIAIH.js → task-store-MNCW42BW.js} +4 -4
  177. package/bundle/{telegram-adapter-H6PMFPMB.js → telegram-adapter-O6KIZDY6.js} +69 -46
  178. package/bundle/telegram-adapter-O6KIZDY6.js.map +7 -0
  179. package/bundle/{tool-registry-IZX2IOBM.js → tool-registry-JJMWCQKZ.js} +26 -24
  180. package/bundle/{tool-sandbox-4UC6GAKA.js → tool-sandbox-CNL6V6IH.js} +4 -4
  181. package/bundle/{transport-config-KBF5W2DP.js → transport-config-6MB2K2XC.js} +7 -7
  182. package/bundle/tribe-GDTFYJTK.js +111 -0
  183. package/bundle/tribe-GDTFYJTK.js.map +7 -0
  184. package/bundle/{update-MESYO4LO.js → update-HGQAOC5L.js} +3 -3
  185. package/bundle/{usage-tracker-NXD364VX.js → usage-tracker-SR4BI6ZT.js} +2 -2
  186. package/bundle/{user-registry-35BW4XKM.js → user-registry-4PACZJIJ.js} +4 -4
  187. package/bundle/wire-platform-KKPWNNNQ.js +88 -0
  188. package/bundle/wire-platform-KKPWNNNQ.js.map +7 -0
  189. package/bundle/ws-peer-client-U3NNPOK7.js +370 -0
  190. package/bundle/ws-peer-client-U3NNPOK7.js.map +7 -0
  191. package/package.json +1 -1
  192. package/scripts/abtars-watchdog.service +2 -1
  193. package/scripts/abtars-watchdog.sh +1 -5
  194. package/scripts/emergency-deploy.sh +2 -2
  195. package/scripts/emergency-update.sh +88 -41
  196. package/bundle/chunk-3AAENI2K.js +0 -210
  197. package/bundle/chunk-3AAENI2K.js.map +0 -7
  198. package/bundle/chunk-4MULJ5SS.js.map +0 -7
  199. package/bundle/chunk-4S554KLW.js +0 -105
  200. package/bundle/chunk-4S554KLW.js.map +0 -7
  201. package/bundle/chunk-5GCLBUBS.js +0 -257
  202. package/bundle/chunk-5GCLBUBS.js.map +0 -7
  203. package/bundle/chunk-BROFMHC2.js.map +0 -7
  204. package/bundle/chunk-EGL6UMAO.js.map +0 -7
  205. package/bundle/chunk-EQSG2CRM.js.map +0 -7
  206. package/bundle/chunk-GXL7HJPT.js.map +0 -7
  207. package/bundle/chunk-HKRSMUXJ.js.map +0 -7
  208. package/bundle/chunk-HT2BPTZY.js +0 -241
  209. package/bundle/chunk-HT2BPTZY.js.map +0 -7
  210. package/bundle/chunk-HZDLFLRP.js.map +0 -7
  211. package/bundle/chunk-IKUZPMVA.js +0 -82
  212. package/bundle/chunk-IKUZPMVA.js.map +0 -7
  213. package/bundle/chunk-LGP6TYFI.js.map +0 -7
  214. package/bundle/chunk-ONBF5DDU.js.map +0 -7
  215. package/bundle/chunk-RWRRGE4U.js +0 -72
  216. package/bundle/chunk-RWRRGE4U.js.map +0 -7
  217. package/bundle/chunk-SIFPBTI4.js.map +0 -7
  218. package/bundle/chunk-VUIX5AGB.js +0 -65
  219. package/bundle/chunk-VUIX5AGB.js.map +0 -7
  220. package/bundle/chunk-W4EA4GCA.js.map +0 -7
  221. package/bundle/chunk-XWRADSXO.js.map +0 -7
  222. package/bundle/chunk-Y76VUJSF.js +0 -75
  223. package/bundle/chunk-Y76VUJSF.js.map +0 -7
  224. package/bundle/chunk-YRU2K3O6.js.map +0 -7
  225. package/bundle/context-2RJHC2LE.js.map +0 -7
  226. package/bundle/direct-api-transport-E3LNDBJT.js.map +0 -7
  227. package/bundle/dns-wakeup-IDOJIXBX.js.map +0 -7
  228. package/bundle/heartbeat-tier3-ABWL3P7M.js.map +0 -7
  229. package/bundle/install-OS3CU7NF.js.map +0 -7
  230. package/bundle/metrics-collector-L3VPEHII.js.map +0 -7
  231. package/bundle/peer-client-RGEU5HOK.js.map +0 -7
  232. package/bundle/peer-jwt-NCCPXJRX.js +0 -18
  233. package/bundle/public/css/dashboard.css +0 -542
  234. package/bundle/public/index.html +0 -180
  235. package/bundle/public/js/app.js +0 -437
  236. package/bundle/public/memory-universe.js +0 -384
  237. package/bundle/stream-single-RFJNUTL6.js +0 -34
  238. package/bundle/stream-single-RFJNUTL6.js.map +0 -7
  239. package/bundle/subagent-runtime-5QUVES3W.js +0 -14
  240. package/bundle/system-status-JZU5FO7B.js.map +0 -7
  241. package/bundle/telegram-adapter-H6PMFPMB.js.map +0 -7
  242. package/bundle/usage-tracker-NXD364VX.js.map +0 -7
  243. package/bundle/user-registry-35BW4XKM.js.map +0 -7
  244. package/bundle/ws-peer-client-AIXCXF7V.js +0 -173
  245. package/bundle/ws-peer-client-AIXCXF7V.js.map +0 -7
  246. /package/bundle/{abmind-lazy-7Z44NODV.js.map → abmind-lazy-E3YCFKQ5.js.map} +0 -0
  247. /package/bundle/{acp-raw-client-E6FM45NC.js.map → acp-raw-client-UCNK3OTU.js.map} +0 -0
  248. /package/bundle/{action-gate-G2V47NHW.js.map → action-gate-V4FCBHFB.js.map} +0 -0
  249. /package/bundle/{agent-api-adapter-YAHKQMMZ.js.map → agent-api-adapter-7HEPYSIN.js.map} +0 -0
  250. /package/bundle/{agent-api-rate-limit-WCFXJMGY.js.map → agent-api-rate-limit-RZSAM3SW.js.map} +0 -0
  251. /package/bundle/{agent-registry-GI6CLT3Z.js.map → agent-registry-46A2R5KP.js.map} +0 -0
  252. /package/bundle/{bootstrap-X2QYIZIJ.js.map → bootstrap-MIHJJSWU.js.map} +0 -0
  253. /package/bundle/{bridge-lock-transport-4ZH7QTJP.js.map → bridge-lock-transport-7RSN7OLJ.js.map} +0 -0
  254. /package/bundle/{browser-DMARZJIN.js.map → browser-F6BCWJWW.js.map} +0 -0
  255. /package/bundle/{budget-45QOBDWA.js.map → budget-WUM3SPKW.js.map} +0 -0
  256. /package/bundle/{capability-JFWX3IQF.js.map → capability-QVRKGRFC.js.map} +0 -0
  257. /package/bundle/{chunk-YSKCQH6E.js.map → chunk-2IYJ4I66.js.map} +0 -0
  258. /package/bundle/{chunk-KTYGKPYM.js.map → chunk-2NLUT5S2.js.map} +0 -0
  259. /package/bundle/{chunk-OKAQICWY.js.map → chunk-3GQX34S2.js.map} +0 -0
  260. /package/bundle/{chunk-QROWBWLL.js.map → chunk-3XZ773BS.js.map} +0 -0
  261. /package/bundle/{chunk-DYBW4XXL.js.map → chunk-467SRLLR.js.map} +0 -0
  262. /package/bundle/{chunk-GPZNXY2U.js.map → chunk-4S3H4OK7.js.map} +0 -0
  263. /package/bundle/{chunk-NDCRWEEJ.js.map → chunk-4Y5MJQRE.js.map} +0 -0
  264. /package/bundle/{chunk-FRKW6LWB.js.map → chunk-55UWKI5C.js.map} +0 -0
  265. /package/bundle/{chunk-4UL3KINB.js.map → chunk-5PNJFDSW.js.map} +0 -0
  266. /package/bundle/{chunk-OXTSWQCX.js.map → chunk-5Y3FJ2Y7.js.map} +0 -0
  267. /package/bundle/{chunk-TMUYFERL.js.map → chunk-6B5ZFUPD.js.map} +0 -0
  268. /package/bundle/{chunk-65VCEC32.js.map → chunk-6PA5JBUU.js.map} +0 -0
  269. /package/bundle/{chunk-AFREM7FX.js.map → chunk-CK7YTA2F.js.map} +0 -0
  270. /package/bundle/{chunk-NRUSRJXR.js.map → chunk-DZJ5QZFD.js.map} +0 -0
  271. /package/bundle/{chunk-YRSMGJFP.js.map → chunk-E67KESEG.js.map} +0 -0
  272. /package/bundle/{chunk-ZV4IWKDJ.js.map → chunk-E7XD5UGB.js.map} +0 -0
  273. /package/bundle/{chunk-PEDX56EL.js.map → chunk-EFGBM555.js.map} +0 -0
  274. /package/bundle/{chunk-UPRZDU6T.js.map → chunk-IY6UKLPS.js.map} +0 -0
  275. /package/bundle/{chunk-EUZDKV3C.js.map → chunk-J4RUFAPK.js.map} +0 -0
  276. /package/bundle/{chunk-5B5B6EHL.js.map → chunk-JLWYPGWI.js.map} +0 -0
  277. /package/bundle/{chunk-5QUTMUIK.js.map → chunk-JXYWDAHD.js.map} +0 -0
  278. /package/bundle/{chunk-TEFZ4JA4.js.map → chunk-NHPLD3C7.js.map} +0 -0
  279. /package/bundle/{chunk-2KC5G3EA.js.map → chunk-OWUO5RS3.js.map} +0 -0
  280. /package/bundle/{chunk-WYHGNI56.js.map → chunk-PMD5BLFS.js.map} +0 -0
  281. /package/bundle/{chunk-URQPDCK5.js.map → chunk-Q66LQMMZ.js.map} +0 -0
  282. /package/bundle/{chunk-JQDJPUHM.js.map → chunk-TWB2ZGVH.js.map} +0 -0
  283. /package/bundle/{chunk-IJT4KWXT.js.map → chunk-U4U47YE7.js.map} +0 -0
  284. /package/bundle/{chunk-2FAZIA37.js.map → chunk-W546CU3A.js.map} +0 -0
  285. /package/bundle/{chunk-JNIHEDKF.js.map → chunk-XPWYDNWL.js.map} +0 -0
  286. /package/bundle/{chunk-EFJVUJBE.js.map → chunk-Y5FEFKGM.js.map} +0 -0
  287. /package/bundle/{chunk-GVM5YU5I.js.map → chunk-Z4FZPB42.js.map} +0 -0
  288. /package/bundle/{chunk-7BSQ5UQO.js.map → chunk-ZSIDQ66D.js.map} +0 -0
  289. /package/bundle/{chunk-XX6BGTPO.js.map → chunk-ZZZCJJEO.js.map} +0 -0
  290. /package/bundle/{commands-XYEGVUZF.js.map → commands-2ZW6CMLC.js.map} +0 -0
  291. /package/bundle/{config-M3P5IOAI.js.map → config-YMY5YHKN.js.map} +0 -0
  292. /package/bundle/{daemon-TB23FFWY.js.map → daemon-D7SU63OY.js.map} +0 -0
  293. /package/bundle/{delegation-tools-QKNYQGTQ.js.map → delegation-tools-WS7Z56KZ.js.map} +0 -0
  294. /package/bundle/{deploy-EPDWNHJU.js.map → deploy-AMTVKIMU.js.map} +0 -0
  295. /package/bundle/{deps-WVK553KF.js.map → deps-T63AVJKJ.js.map} +0 -0
  296. /package/bundle/{doctor-probes-B54JFIW3.js.map → doctor-probes-O6YI6XSZ.js.map} +0 -0
  297. /package/bundle/{env-schema-4JXQUOH4.js.map → env-schema-B5RB32DC.js.map} +0 -0
  298. /package/bundle/{gossip-3C3BSNPN.js.map → gossip-SKRCPOBS.js.map} +0 -0
  299. /package/bundle/{guardrails-DL7ZSWVN.js.map → guardrails-64GQ5Y5K.js.map} +0 -0
  300. /package/bundle/{heartbeat-system-MVTRS4GP.js.map → heartbeat-system-X4MUTKJD.js.map} +0 -0
  301. /package/bundle/{hook-system-M3POLUIB.js.map → hook-system-YB635OC4.js.map} +0 -0
  302. /package/bundle/{hotskills-FWX4QI7V.js.map → hotskills-Q75D2DK3.js.map} +0 -0
  303. /package/bundle/{install-manifest-5PPWMD2W.js.map → install-manifest-J7ICPCJN.js.map} +0 -0
  304. /package/bundle/{irc-adapter-PTTZD32W.js.map → irc-adapter-TVEV4R6H.js.map} +0 -0
  305. /package/bundle/{irc-config-CP7ZMUOX.js.map → irc-config-M676FOFI.js.map} +0 -0
  306. /package/bundle/{kanban-board-M326B2XJ.js.map → kanban-board-DLEJUCNN.js.map} +0 -0
  307. /package/bundle/{kanban-channel-IJ52OMNA.js.map → kanban-channel-XOLUHJZJ.js.map} +0 -0
  308. /package/bundle/{lazy-require-KCRVT4SI.js.map → lazy-require-JKQSALXN.js.map} +0 -0
  309. /package/bundle/{logger-OWCSNYCA.js.map → logger-3EGHBD4R.js.map} +0 -0
  310. /package/bundle/{main-chat-ZNUZCTNS.js.map → main-chat-3H63REKK.js.map} +0 -0
  311. /package/bundle/{master-user-HSKM4ZFN.js.map → master-user-MUBUP3KD.js.map} +0 -0
  312. /package/bundle/{media-utils-3ZYOD7SK.js.map → media-utils-HUUIALAJ.js.map} +0 -0
  313. /package/bundle/{message-pipeline-P5GAQU4Z.js.map → message-pipeline-GRDRWONR.js.map} +0 -0
  314. /package/bundle/{model-health-registry-MLEIZSTV.js.map → model-health-registry-QADMFQFQ.js.map} +0 -0
  315. /package/bundle/{nerve-IGSXBKZZ.js.map → nerve-QPAEBRKX.js.map} +0 -0
  316. /package/bundle/{notification-BFSIEECG.js.map → notification-3JICGXWU.js.map} +0 -0
  317. /package/bundle/{openrouter-credits-NTVZDRYM.js.map → openrouter-credits-7NEIPYJN.js.map} +0 -0
  318. /package/bundle/{orc-tools-4CHEFWSN.js.map → orc-tools-UZVPONKY.js.map} +0 -0
  319. /package/bundle/{peer-auth-QC4EF2PM.js.map → peer-auth-RI43DKJE.js.map} +0 -0
  320. /package/bundle/{peer-config-TN55LFDC.js.map → peer-config-URM7DCW6.js.map} +0 -0
  321. /package/bundle/{peer-jwt-NCCPXJRX.js.map → peer-transport-SI7I72DB.js.map} +0 -0
  322. /package/bundle/{peer-transport-I6JPLFZ2.js.map → phase-transport-ESWWACZI.js.map} +0 -0
  323. /package/bundle/{phase-transport-PGKU2KD4.js.map → reconcile-GFDQYNBD.js.map} +0 -0
  324. /package/bundle/{reconciler-EBKH3JNU.js.map → reconciler-IEUJXJN2.js.map} +0 -0
  325. /package/bundle/{restore-IFHPI7I7.js.map → restore-FARTGLQQ.js.map} +0 -0
  326. /package/bundle/{reconcile-CTFCLQRN.js.map → rollback-GEWPZABG.js.map} +0 -0
  327. /package/bundle/{sandbox-runtime-QROWHDCS.js.map → sandbox-runtime-DV6E25J6.js.map} +0 -0
  328. /package/bundle/{self-healer-utils-IFAYOQO2.js.map → self-healer-utils-P4SKNNEM.js.map} +0 -0
  329. /package/bundle/{rollback-ANRI3T5Z.js.map → sha-tracker-77SHLYNY.js.map} +0 -0
  330. /package/bundle/{skill-session-BMSRQSHV.js.map → skill-session-5HSMXY54.js.map} +0 -0
  331. /package/bundle/{sha-tracker-ZWBP6CIJ.js.map → skill-stats-MI3RSWWL.js.map} +0 -0
  332. /package/bundle/{skill-stats-JORH5DGM.js.map → skill-watcher-5L7JE6TN.js.map} +0 -0
  333. /package/bundle/{skill-watcher-E4MGLKLS.js.map → sleep-I4JFASCY.js.map} +0 -0
  334. /package/bundle/{sleep-36XS6MHJ.js.map → soul-bundle-522C3IRH.js.map} +0 -0
  335. /package/bundle/{soul-bundle-VWAVHCZ6.js.map → spin-VHNGNWTD.js.map} +0 -0
  336. /package/bundle/{spin-notifications-SE2HVZI7.js.map → spin-notifications-7NC5XZEM.js.map} +0 -0
  337. /package/bundle/{spin-TI3TSVVT.js.map → spin-types-C5KOQOPD.js.map} +0 -0
  338. /package/bundle/{sse-parser-anthropic-A6R4Z2TB.js.map → sse-parser-anthropic-MMTVWHLI.js.map} +0 -0
  339. /package/bundle/{sse-parser-responses-HSZY3QGJ.js.map → sse-parser-responses-3AOFN64C.js.map} +0 -0
  340. /package/bundle/{ssrf-guard-O6SHIK6Q.js.map → ssrf-guard-U2JA72TC.js.map} +0 -0
  341. /package/bundle/{spin-types-BLPYAETA.js.map → stt-PSOPPBV4.js.map} +0 -0
  342. /package/bundle/{stt-LGVPXMVR.js.map → task-store-MNCW42BW.js.map} +0 -0
  343. /package/bundle/{subagent-runtime-5QUVES3W.js.map → tool-registry-JJMWCQKZ.js.map} +0 -0
  344. /package/bundle/{task-store-W5BFIAIH.js.map → tool-sandbox-CNL6V6IH.js.map} +0 -0
  345. /package/bundle/{tool-registry-IZX2IOBM.js.map → transport-config-6MB2K2XC.js.map} +0 -0
  346. /package/bundle/{tool-sandbox-4UC6GAKA.js.map → update-HGQAOC5L.js.map} +0 -0
  347. /package/bundle/{transport-config-KBF5W2DP.js.map → usage-tracker-SR4BI6ZT.js.map} +0 -0
  348. /package/bundle/{update-MESYO4LO.js.map → user-registry-4PACZJIJ.js.map} +0 -0
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/components/transport/model-health-registry.ts"],
4
- "sourcesContent": ["/**\n * ModelHealthRegistry \u2014 shared per-model error tracking.\n * Leaky-bucket algorithm: fills on errors, drains over time. Full = skip.\n * One instance per bridge process, shared across all FallbackPolicy instances.\n *\n * All tuning constants configurable via transport.json `healthPolicy` key.\n * Missing fields fall back to hardcoded defaults.\n */\n\nexport type ErrorKind = \"rate_limit\" | \"credits\" | \"auth\" | \"transient\" | \"weak\" | \"empty\" | \"truncated\";\nexport type ModelStatus = \"healthy\" | \"degraded\" | \"exhausted\" | \"auth_failed\";\n\nexport interface HealthPolicyConfig {\n /** Bucket level (0-1) above which model is skipped. Default: 0.7 */\n skipThreshold?: number;\n /** Drain rate per minute (0-1). Default: 0.03 */\n leakPerMinute?: number;\n /** Auth error: fill amount (0-1). Default: 1.0 (instant full) */\n authFill?: number;\n /** Auth errors are sticky (never auto-drain). Default: true */\n authSticky?: boolean;\n /** Rate-limit fill per hit. Default: 0.5 */\n rateLimitFill?: number;\n /** Weak-model fill per hit. Default: 0.05 */\n weakFill?: number;\n /** Empty response (0 tokens) fill per hit. Default: 0.25 */\n emptyFill?: number;\n /** Truncated response (finish_reason=length) fill per hit. Default: 0 (disabled) */\n truncatedFill?: number;\n /** Transient progressive fill array. Default: [0.1, 0.2, 0.4, 0.8] */\n transientProgressive?: number[];\n /** Consecutive errors before cooldown kicks in. Default: 3 */\n transientCooldownAfter?: number;\n /** Max cooldown seconds for transient errors. Default: 300 */\n transientMaxCooldownSec?: number;\n}\n\ninterface Bucket {\n level: number;\n lastUpdate: number;\n consecutiveErrors: number;\n cooldownUntil?: number;\n authFailed?: boolean;\n demoted?: boolean;\n}\n\n// Defaults (unchanged from pre-config behavior)\nconst D_SKIP_THRESHOLD = 0.7;\nconst D_LEAK_PER_MIN = 0.03;\nconst D_AUTH_STICKY = true;\nconst D_RATE_LIMIT_FILL = 0.5;\nconst D_WEAK_FILL = 0.35;\nconst D_EMPTY_FILL = 0.25;\nconst D_TRUNCATED_FILL = 0;\nconst D_TRANSIENT_PROGRESSIVE = [0.1, 0.2, 0.4, 0.8];\nconst D_TRANSIENT_COOLDOWN_AFTER = 3;\nconst D_TRANSIENT_MAX_COOLDOWN_SEC = 300;\n\nexport class ModelHealthRegistry {\n private readonly buckets = new Map<string, Bucket>();\n private readonly skipThreshold: number;\n private readonly leakPerMs: number;\n private readonly authSticky: boolean;\n private readonly rateLimitFill: number;\n private readonly weakFill: number;\n private readonly emptyFill: number;\n private readonly truncatedFill: number;\n private readonly transientProgressive: number[];\n private readonly transientCooldownAfter: number;\n private readonly transientMaxCooldownMs: number;\n\n /** Fired when a model crosses the demotion threshold. Wired at boot. */\n onDemote?: (model: string, endpoint: string, reason: \"auth\" | \"timeout\") => void;\n\n constructor(config?: HealthPolicyConfig) {\n this.skipThreshold = config?.skipThreshold ?? D_SKIP_THRESHOLD;\n this.leakPerMs = (config?.leakPerMinute ?? D_LEAK_PER_MIN) / 60000;\n this.authSticky = config?.authSticky ?? D_AUTH_STICKY;\n this.rateLimitFill = config?.rateLimitFill ?? D_RATE_LIMIT_FILL;\n this.weakFill = config?.weakFill ?? D_WEAK_FILL;\n this.emptyFill = config?.emptyFill ?? D_EMPTY_FILL;\n this.truncatedFill = config?.truncatedFill ?? D_TRUNCATED_FILL;\n this.transientProgressive = config?.transientProgressive ?? D_TRANSIENT_PROGRESSIVE;\n this.transientCooldownAfter = config?.transientCooldownAfter ?? D_TRANSIENT_COOLDOWN_AFTER;\n this.transientMaxCooldownMs = (config?.transientMaxCooldownSec ?? D_TRANSIENT_MAX_COOLDOWN_SEC) * 1000;\n }\n\n private drain(b: Bucket, now: number): void {\n if (this.authSticky && b.authFailed) return;\n const elapsed = now - b.lastUpdate;\n b.level = Math.max(0, b.level - elapsed * this.leakPerMs);\n b.lastUpdate = now;\n }\n\n shouldSkip(model: string, endpoint: string): boolean {\n const b = this.buckets.get(`${endpoint}|${model}`);\n if (!b) return false;\n const now = Date.now();\n if (b.cooldownUntil && now < b.cooldownUntil) return true;\n if (b.cooldownUntil && now >= b.cooldownUntil) b.cooldownUntil = undefined;\n this.drain(b, now);\n return b.level > this.skipThreshold;\n }\n\n recordSuccess(model: string, endpoint: string): void {\n const b = this.buckets.get(`${endpoint}|${model}`);\n if (!b) return;\n b.consecutiveErrors = 0;\n b.cooldownUntil = undefined;\n b.authFailed = false;\n }\n\n recordError(model: string, endpoint: string, kind: ErrorKind, retryAfterMs?: number): void {\n const key = `${endpoint}|${model}`;\n const now = Date.now();\n const b = this.buckets.get(key) ?? { level: 0, lastUpdate: now, consecutiveErrors: 0 };\n this.drain(b, now);\n\n switch (kind) {\n case \"auth\":\n b.level = 1.0;\n b.authFailed = true;\n if (this.onDemote && !b.demoted) {\n b.demoted = true;\n this.onDemote(model, endpoint, \"auth\");\n }\n break;\n case \"transient\": {\n const idx = Math.min(b.consecutiveErrors, this.transientProgressive.length - 1);\n b.level = Math.min(1.0, b.level + this.transientProgressive[idx]!);\n if (b.consecutiveErrors >= this.transientCooldownAfter) {\n b.cooldownUntil = now + Math.min((b.consecutiveErrors + 1) * 60_000, this.transientMaxCooldownMs);\n }\n break;\n }\n case \"rate_limit\":\n case \"credits\":\n b.level = Math.min(1.0, b.level + this.rateLimitFill);\n if (retryAfterMs && retryAfterMs > 0) b.cooldownUntil = now + retryAfterMs;\n break;\n case \"weak\":\n b.level = Math.min(1.0, b.level + this.weakFill);\n break;\n case \"empty\":\n b.level = Math.min(1.0, b.level + this.emptyFill);\n break;\n case \"truncated\":\n if (this.truncatedFill > 0) b.level = Math.min(1.0, b.level + this.truncatedFill);\n break;\n }\n\n b.consecutiveErrors++;\n b.lastUpdate = now;\n this.buckets.set(key, b);\n }\n\n getHealth(): Map<string, { level: number; consecutiveErrors: number; cooldownUntil?: number; status: ModelStatus }> {\n const now = Date.now();\n const result = new Map<string, { level: number; consecutiveErrors: number; cooldownUntil?: number; status: ModelStatus }>();\n for (const [key, b] of this.buckets) {\n this.drain(b, now);\n let status: ModelStatus = \"healthy\";\n if (b.authFailed) status = \"auth_failed\";\n else if (b.level > this.skipThreshold) status = \"exhausted\";\n else if (b.level > 0.3) status = \"degraded\";\n result.set(key, { level: Math.round(b.level * 100), consecutiveErrors: b.consecutiveErrors, cooldownUntil: b.cooldownUntil, status });\n }\n return result;\n }\n\n /** Get bucket level for a specific model (0-100%). */\n getBucketLevel(model: string, endpoint: string): number {\n const b = this.buckets.get(`${endpoint}|${model}`);\n if (!b) return 0;\n this.drain(b, Date.now());\n return Math.round(b.level * 100);\n }\n\n resetAll(): void {\n this.buckets.clear();\n }\n}\n\n/** Classify HTTP status to error kind. */\nexport function classifyError(status: number, message?: string): ErrorKind {\n if (status === 402 && message?.includes(\"credits\")) return \"credits\";\n if (status === 429 || status === 402) return \"rate_limit\";\n if (status === 404 && message && /image input|No endpoints found/i.test(message)) return \"transient\";\n if (status === 401 || status === 403 || status === 404) return \"auth\";\n return \"transient\";\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/components/tasks/kanban-board.ts"],
4
- "sourcesContent": ["/**\n * kanban-board.ts \u2014 Local Kanban board backed by SQLite.\n *\n * Workers write completion; main agent polls and delivers.\n * DB lives at ~/.abtars/kanban/kanban.db\n */\n\nimport { join } from \"node:path\";\nimport { mkdirSync } from \"node:fs\";\nimport { abtarsHome } from \"../../paths.js\";\nimport { resolveNativeDep } from \"../../utils/lazy-require.js\";\nimport { logWarn } from \"../logger.js\";\n\n// better-sqlite3 is external (native module, resolved from ~/.local/lib/node_modules/)\ntype SqliteDb = { prepare(sql: string): any; exec(sql: string): void; pragma(s: string): void };\n\nexport interface KanbanCard {\n id: number;\n title: string;\n source: string;\n source_id: string | null;\n assignee: string;\n priority: string;\n status: string;\n type: string | null;\n notes: string | null;\n result_summary: string | null;\n result_path: string | null;\n error: string | null;\n delivery_attempts: number;\n approval: string | null;\n due_at: string | null;\n labels: string | null;\n parent_id: number | null;\n blocked_by: string | null;\n created_at: string;\n updated_at: string;\n completed_at: string | null;\n delivered_at: string | null;\n max_tokens: number | null;\n tokens_used: number | null;\n delivery_mode: string;\n chat_id: string | null;\n source_peer: string | null;\n}\n\nlet _db: SqliteDb | null = null;\nlet _dbAttempted = false;\n\nfunction db(): SqliteDb | null {\n if (_dbAttempted) return _db;\n _dbAttempted = true;\n const dir = join(abtarsHome(), \"kanban\");\n mkdirSync(dir, { recursive: true });\n try {\n const Database = resolveNativeDep(\"better-sqlite3\");\n _db = new Database(join(dir, \"kanban.db\")) as SqliteDb;\n _db.pragma(\"journal_mode = WAL\");\n _db.exec(`CREATE TABLE IF NOT EXISTS kanban_board (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n title TEXT NOT NULL,\n source TEXT NOT NULL,\n source_id TEXT,\n assignee TEXT DEFAULT 'local',\n priority TEXT NOT NULL DEFAULT 'MEDIUM' CHECK(priority IN ('CRITICAL','HIGH','MEDIUM','LOW')),\n status TEXT NOT NULL DEFAULT 'queued' CHECK(status IN ('queued','running','done','failed','delivering','delivered')),\n type TEXT,\n notes TEXT,\n result_summary TEXT,\n result_path TEXT,\n error TEXT,\n delivery_attempts INTEGER DEFAULT 0,\n approval TEXT CHECK(approval IS NULL OR approval IN ('pending','approved','rejected')),\n due_at TEXT,\n labels TEXT,\n parent_id INTEGER REFERENCES kanban_board(id),\n blocked_by TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n completed_at TEXT,\n delivered_at TEXT\n )`);\n // Migrations \u2014 safe to re-run (silently skip if column exists)\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN max_tokens INTEGER`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN tokens_used INTEGER DEFAULT 0`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN progress TEXT`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN delivery_mode TEXT DEFAULT 'deliver'`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN retry_count INTEGER DEFAULT 0`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN next_retry_at TEXT`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN chat_id TEXT`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN source_peer TEXT`); } catch {}\n } catch {\n logWarn(\"kanban\", \"better-sqlite3 not available \u2014 kanban features disabled (run: abtars deps install)\");\n _db = null;\n }\n return _db;\n}\n\nimport { nerve } from \"../nerve.js\";\n\n/** Return db or null (with warning logged once). */\nfunction dbOrNull(): SqliteDb | null {\n return db();\n}\n\nexport function kanbanEnqueue(title: string, source: string, sourceId?: string, opts?: { priority?: string; type?: string; labels?: string; due_at?: string; parent_id?: number; notes?: string; deliveryMode?: \"silent\" | \"deliver\" | \"announce\"; blocked_by?: string; chatId?: string; sourcePeer?: string }): number {\n const d = dbOrNull();\n if (!d) return 0;\n const deliveryMode = opts?.deliveryMode ?? \"deliver\";\n const stmt = d.prepare(\n `INSERT INTO kanban_board (title, source, source_id, priority, type, labels, due_at, parent_id, notes, delivery_mode, blocked_by, chat_id, source_peer)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n );\n const result = stmt.run(title, source, sourceId ?? null, opts?.priority ?? \"MEDIUM\", opts?.type ?? null, opts?.labels ?? null, opts?.due_at ?? null, opts?.parent_id ?? null, opts?.notes ?? null, deliveryMode, opts?.blocked_by ?? null, opts?.chatId ?? null, opts?.sourcePeer ?? null);\n const id = Number(result.lastInsertRowid);\n nerve.fire(\"card:queued\", id);\n return id;\n}\n\nexport function kanbanRunning(id: number): void {\n const d = dbOrNull();\n if (!d) return;\n d.prepare(`UPDATE kanban_board SET status = 'running', updated_at = datetime('now') WHERE id = ?`).run(id);\n nerve.fire(\"card:running\", id);\n}\n\nexport function kanbanComplete(id: number, resultPath: string | null, summary: string): void {\n const d = dbOrNull();\n if (!d) return;\n d.prepare(\n `UPDATE kanban_board SET status = 'done', result_path = ?, result_summary = ?, completed_at = datetime('now'), updated_at = datetime('now') WHERE id = ?`\n ).run(resultPath, summary.slice(0, 4000), id);\n nerve.fire(\"card:done\", id);\n}\n\nexport function kanbanFail(id: number, error: string): void {\n const d = dbOrNull();\n if (!d) return;\n d.prepare(\n `UPDATE kanban_board SET status = 'failed', error = ?, completed_at = datetime('now'), updated_at = datetime('now') WHERE id = ?`\n ).run(error.slice(0, 1000), id);\n nerve.fire(\"card:failed\", id);\n}\n\nconst MAX_RETRIES = 3;\n\n/** Fail with retry logic \u2014 exponential backoff (10s\u219220s\u219240s, cap 5min). After MAX_RETRIES \u2192 permanent fail. */\nexport function kanbanRetryOrFail(id: number, error: string): \"retrying\" | \"failed\" {\n const d = dbOrNull();\n if (!d) return \"failed\";\n const card = d.prepare(\"SELECT retry_count FROM kanban_board WHERE id = ?\").get(id) as { retry_count: number } | undefined;\n const retryCount = (card?.retry_count ?? 0) + 1;\n if (retryCount > MAX_RETRIES) {\n kanbanFail(id, `${error} (after ${MAX_RETRIES} retries)`);\n return \"failed\";\n }\n const backoffMs = Math.min(10_000 * Math.pow(2, retryCount - 1), 300_000);\n const nextRetryAt = new Date(Date.now() + backoffMs).toISOString();\n d.prepare(\n `UPDATE kanban_board SET status = 'queued', retry_count = ?, next_retry_at = ?, error = ?, updated_at = datetime('now') WHERE id = ?`\n ).run(retryCount, nextRetryAt, error.slice(0, 1000), id);\n nerve.fire(\"card:queued\", id);\n return \"retrying\";\n}\n\nexport function kanbanPending(): KanbanCard[] {\n const d = dbOrNull();\n if (!d) return [];\n return d.prepare(\n `SELECT * FROM kanban_board WHERE status = 'done' AND delivery_attempts < 3 ORDER BY priority = 'CRITICAL' DESC, priority = 'HIGH' DESC, created_at ASC`\n ).all() as KanbanCard[];\n}\n\nexport function kanbanSetDelivering(id: number): void {\n const d = dbOrNull();\n if (!d) return;\n d.prepare(`UPDATE kanban_board SET status = 'delivering', updated_at = datetime('now') WHERE id = ?`).run(id);\n}\n\nexport function kanbanMarkDelivered(id: number): void {\n const d = dbOrNull();\n if (!d) return;\n d.prepare(\n `UPDATE kanban_board SET status = 'delivered', delivered_at = datetime('now'), updated_at = datetime('now') WHERE id = ?`\n ).run(id);\n nerve.fire(\"card:delivered\", id);\n}\n\nexport function kanbanDeliveryFailed(id: number): void {\n const d = dbOrNull();\n if (!d) return;\n const card = d.prepare(`SELECT delivery_attempts FROM kanban_board WHERE id = ?`).get(id) as { delivery_attempts: number } | undefined;\n const attempts = (card?.delivery_attempts ?? 0) + 1;\n if (attempts >= 3) {\n d.prepare(`UPDATE kanban_board SET status = 'failed', error = 'delivery failed after 3 attempts', delivery_attempts = ?, updated_at = datetime('now') WHERE id = ?`).run(attempts, id);\n } else {\n d.prepare(`UPDATE kanban_board SET status = 'done', delivery_attempts = ?, updated_at = datetime('now') WHERE id = ?`).run(attempts, id);\n }\n}\n\nexport function kanbanList(filter?: string, filterKey?: string): KanbanCard[] {\n const d = dbOrNull();\n if (!d) return [];\n if (filter === \"*\") {\n return d.prepare(`SELECT * FROM kanban_board ORDER BY created_at DESC LIMIT 50`).all() as KanbanCard[];\n }\n if (filter && filterKey) {\n if (filterKey === \"labels\") {\n return d.prepare(`SELECT * FROM kanban_board WHERE labels LIKE ? ORDER BY created_at DESC LIMIT 50`).all(`%${filter}%`) as KanbanCard[];\n }\n const allowed = new Set([\"status\", \"source\", \"priority\", \"type\"]);\n if (allowed.has(filterKey)) {\n return d.prepare(`SELECT * FROM kanban_board WHERE ${filterKey} = ? ORDER BY created_at DESC LIMIT 50`).all(filter) as KanbanCard[];\n }\n }\n if (filter) {\n return d.prepare(`SELECT * FROM kanban_board WHERE status = ? ORDER BY created_at DESC LIMIT 50`).all(filter) as KanbanCard[];\n }\n return d.prepare(`SELECT * FROM kanban_board WHERE status NOT IN ('delivered') ORDER BY status = 'running' DESC, priority = 'CRITICAL' DESC, created_at DESC LIMIT 50`).all() as KanbanCard[];\n}\n\nexport function kanbanUpdate(id: number, fields: Partial<Pick<KanbanCard, \"title\" | \"status\" | \"priority\" | \"type\" | \"labels\" | \"due_at\" | \"notes\" | \"parent_id\" | \"approval\">>): void {\n const d = dbOrNull();\n if (!d) return;\n const sets: string[] = [\"updated_at = datetime('now')\"];\n const vals: unknown[] = [];\n for (const [k, v] of Object.entries(fields)) {\n if (v !== undefined) { sets.push(`${k} = ?`); vals.push(v); }\n }\n vals.push(id);\n d.prepare(`UPDATE kanban_board SET ${sets.join(\", \")} WHERE id = ?`).run(...vals);\n}\n\nexport function kanbanCleanup(olderThanDays = 7): number {\n const d = dbOrNull();\n if (!d) return 0;\n const result = d.prepare(\n `DELETE FROM kanban_board WHERE status = 'delivered' AND delivered_at < datetime('now', '-' || ? || ' days')`\n ).run(olderThanDays);\n return result.changes;\n}\n\nexport function kanbanGetCard(id: number): KanbanCard | undefined {\n const d = dbOrNull();\n if (!d) return undefined;\n return d.prepare(`SELECT * FROM kanban_board WHERE id = ?`).get(id) as KanbanCard | undefined;\n}\n\nexport function kanbanGetChildren(parentId: number): KanbanCard[] {\n const d = dbOrNull();\n if (!d) return [];\n return d.prepare(`SELECT * FROM kanban_board WHERE parent_id = ? ORDER BY id`).all(parentId) as KanbanCard[];\n}\n\nexport function kanbanAddTokens(id: number, tokens: number): void {\n const d = dbOrNull();\n if (!d) return;\n d.prepare(`UPDATE kanban_board SET tokens_used = COALESCE(tokens_used, 0) + ?, updated_at = datetime('now') WHERE id = ?`).run(tokens, id);\n const card = kanbanGetCard(id);\n if (card?.parent_id) {\n d.prepare(`UPDATE kanban_board SET tokens_used = COALESCE(tokens_used, 0) + ?, updated_at = datetime('now') WHERE id = ?`).run(tokens, card.parent_id);\n }\n}\n\n// #907: Worker progress \u2014 30s debounce per card\nconst _progressTimers = new Map<number, ReturnType<typeof setTimeout>>();\nconst _progressPending = new Map<number, Record<string, unknown>>();\n\nexport function kanbanProgress(id: number, data: { toolUseCount?: number; tokenCount?: number; lastTool?: string; summary?: string }): void {\n _progressPending.set(id, data);\n if (_progressTimers.has(id)) return;\n _progressTimers.set(id, setTimeout(() => {\n _progressTimers.delete(id);\n const pending = _progressPending.get(id);\n if (pending) {\n const d = dbOrNull();\n if (d) d.prepare(`UPDATE kanban_board SET progress = ?, updated_at = datetime('now') WHERE id = ?`).run(JSON.stringify(pending), id);\n _progressPending.delete(id);\n }\n }, 30_000));\n}\n\n// \u2500\u2500 DAG orchestration (#677) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Check if all dependencies of a card are satisfied. */\nexport function isUnblocked(card: KanbanCard): boolean {\n if (!card.blocked_by) return true;\n if (card.blocked_by === \"children\") {\n const kids = kanbanGetChildren(card.id);\n return kids.length > 0 && kids.every(k => k.status === \"done\" || k.status === \"delivered\");\n }\n const depIds = card.blocked_by.split(\",\").map(Number).filter(n => !isNaN(n));\n if (depIds.length === 0) return true;\n return depIds.every(id => {\n const dep = kanbanGetCard(id);\n return dep?.status === \"done\" || dep?.status === \"delivered\";\n });\n}\n\n/** Cascade-fail all cards depending (transitively) on a failed card. */\nexport function cascadeFail(failedId: number, projectCards: KanbanCard[]): void {\n for (const card of projectCards) {\n if (card.status !== \"queued\") continue;\n if (!card.blocked_by) continue;\n const deps = card.blocked_by.split(\",\").map(Number).filter(n => !isNaN(n));\n if (deps.includes(failedId)) {\n kanbanFail(card.id, `upstream #${failedId} failed`);\n cascadeFail(card.id, projectCards);\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/components/agent-registry.ts"],
4
- "sourcesContent": ["import { getEnv } from \"./env-schema.js\";\n/**\n * agent-registry.ts \u2014 Centralized agent role configuration.\n * Single factory for all agent transports. Transport-agnostic.\n */\n\nimport { AcpTransport } from \"./transport/acp-transport.js\";\nimport { logInfo, logWarn } from \"./logger.js\";\nimport type { IKiroTransport } from \"./transport/kiro-transport.js\";\n\nexport type AgentRole = \"professor\" | \"dreamy\" | \"browsie\" | \"coding\" | \"task\";\n\nexport interface AgentRoleConfig {\n agent: string | null;\n model: string | null;\n autoReinit: boolean;\n tag: string;\n trust: number;\n}\n\nconst AGENT_ROLES: Record<AgentRole, AgentRoleConfig> = {\n professor: { agent: \"professor\", model: null, autoReinit: true, tag: \"acp-main\", trust: 3 },\n dreamy: { agent: \"dreamy\", model: null, autoReinit: false, tag: \"acp-sleep\", trust: 2 },\n coding: { agent: \"coding-agent\", model: null, autoReinit: true, tag: \"acp-coding\", trust: 2 },\n browsie: { agent: \"browsie\", model: null, autoReinit: false, tag: \"acp-browsie\", trust: 1 },\n task: { agent: \"professor\", model: null, autoReinit: false, tag: \"acp-task\", trust: 2 },\n};\n\nfunction resolveModel(role: AgentRole): string | undefined {\n switch (role) {\n case \"dreamy\": return getEnv().sleepModel;\n case \"browsie\": return getEnv().browsingAgent;\n case \"coding\": return getEnv().codingModel;\n default: return undefined;\n }\n}\n\nexport interface TransportConfig {\n cliPath: string;\n workingDir: string;\n agentCli?: string;\n model?: string;\n}\n\nexport function createAgentTransport(\n role: AgentRole,\n tc: TransportConfig,\n overrides?: Partial<AgentRoleConfig>,\n): AcpTransport {\n const cfg = { ...AGENT_ROLES[role], ...overrides };\n const cliArgs = tc.agentCli === \"gemini\" ? [\"--acp\", \"-y\"] : undefined;\n const model = tc.model ?? resolveModel(role);\n\n return new AcpTransport(tc.cliPath, tc.workingDir, {\n agent: cfg.agent ?? undefined,\n model,\n autoReinit: cfg.autoReinit,\n tag: cfg.tag,\n cliArgs,\n });\n}\n\nexport type SubagentRole = \"sleep\" | \"browse\" | \"coding\" | \"task\";\n\nconst SUBAGENT_TO_AGENT: Record<SubagentRole, string> = {\n sleep: \"dreamy\",\n browse: \"browsie\",\n coding: \"coding\",\n task: \"professor\",\n};\n\nconst SUBAGENT_ACP_ROLE: Record<SubagentRole, AgentRole> = {\n sleep: \"dreamy\",\n browse: \"browsie\",\n coding: \"coding\",\n task: \"task\",\n};\n\n/** Unified transport factory for all subagents. Reads from transport.json + models.json. */\n/** @internal Used only by SubagentRuntime. Do not call directly. */\nexport async function createSubagentTransport(role: SubagentRole, registry?: import(\"./transport/model-health-registry.js\").ModelHealthRegistry, currentModel?: string): Promise<{ transport: IKiroTransport; model: string }> {\n const { resolveAgent, getEnvFallback, loadTransport } = await import(\"./transport-config.js\");\n const tc = loadTransport();\n const agentName = SUBAGENT_TO_AGENT[role];\n const resolved = tc ? resolveAgent(agentName, tc) : null;\n\n // Fallback: use professor's config. If that also fails, use .env defaults.\n const profResolved = resolved ?? (tc ? resolveAgent(\"professor\", tc) : null);\n const agent = profResolved ?? (() => {\n const fb = getEnvFallback();\n return { model: fb.model, provider: fb.provider, providerName: fb.providerName, contextWindow: fb.contextWindow, maxOutput: fb.maxOutput, fallbacks: [] };\n })();\n\n if (agent.provider.transport === \"api\") {\n const { DirectApiTransport } = await import(\"./transport/direct-api-transport.js\");\n const { FallbackPolicy } = await import(\"./transport/fallback-policy.js\");\n const apiKey = getEnv().getApiKey(agent.provider.apiKeyEnv ?? \"API_KEY\");\n\n // Use main transport's active model if available, else static config\n const startModel = currentModel ?? agent.model;\n\n // Build per-agent candidate list\n const candidates: Array<{ model: string; endpoint: string; apiKey?: string; maxContext: number }> = [\n { endpoint: agent.provider.endpoint ?? \"http://localhost:11434/v1\", apiKey, model: startModel, maxContext: agent.contextWindow },\n ];\n\n // Add static config model if different from startModel\n if (agent.model !== startModel && !candidates.some(c => c.model === agent.model)) {\n candidates.push({ endpoint: agent.provider.endpoint ?? \"http://localhost:11434/v1\", apiKey, model: agent.model, maxContext: agent.contextWindow });\n }\n\n // Add professor's model as fallback if different and transport-compatible\n const profAgent = tc ? resolveAgent(\"professor\", tc) : null;\n const agentTransport = agent.provider.transport ?? \"api\";\n if (profAgent && profAgent.model !== startModel && !candidates.some(c => c.model === profAgent.model)) {\n const profTransport = profAgent.provider.transport ?? \"api\";\n if (profTransport === agentTransport && profAgent.provider.endpoint) {\n candidates.push({\n endpoint: profAgent.provider.endpoint,\n apiKey: profAgent.provider.apiKeyEnv ? getEnv().getApiKey(profAgent.provider.apiKeyEnv) : apiKey,\n model: profAgent.model,\n maxContext: profAgent.contextWindow,\n });\n }\n }\n\n // Inherit professor's full fallback chain (fb1\u2192fb2\u2192fb3)\n if (profAgent) {\n for (const fb of profAgent.fallbacks ?? []) {\n if (candidates.some(c => c.model === fb.model)) continue;\n const fbProvider = tc?.providers[fb.provider];\n const fbEndpoint = fbProvider?.endpoint ?? profAgent.provider.endpoint;\n if (!fbEndpoint) { logWarn(\"subagent\", `Skipping fallback ${fb.model} \u2014 no endpoint configured`); continue; }\n const fbApiKey = fbProvider?.apiKeyEnv ? getEnv().getApiKey(fbProvider.apiKeyEnv) : apiKey;\n candidates.push({ endpoint: fbEndpoint, apiKey: fbApiKey, model: fb.model, maxContext: profAgent.contextWindow });\n }\n for (const chainModel of profAgent.provider.fallbackChain ?? []) {\n if (candidates.some(c => c.model === chainModel)) continue;\n if (!profAgent.provider.endpoint) { logWarn(\"subagent\", `Skipping chain model ${chainModel} \u2014 no endpoint configured`); continue; }\n candidates.push({ endpoint: profAgent.provider.endpoint, apiKey, model: chainModel, maxContext: profAgent.contextWindow });\n }\n }\n\n // Append agent-level cross-provider fallbacks\n for (const fb of agent.fallbacks) {\n if (candidates.some(c => c.model === fb.model)) continue;\n const fbProvider = tc?.providers[fb.provider];\n const fbEndpoint = fbProvider?.endpoint ?? agent.provider.endpoint;\n if (!fbEndpoint) { logWarn(\"subagent\", `Skipping fallback ${fb.model} \u2014 no endpoint configured`); continue; }\n const fbApiKey = fbProvider?.apiKeyEnv ? getEnv().getApiKey(fbProvider.apiKeyEnv) : apiKey;\n candidates.push({ endpoint: fbEndpoint, apiKey: fbApiKey, model: fb.model, maxContext: agent.contextWindow });\n }\n\n // Append fallbackChain entries as last-resort candidates\n const chain = agent.provider.fallbackChain ?? [];\n for (const chainModel of chain) {\n if (!candidates.some(c => c.model === chainModel)) {\n if (!agent.provider.endpoint) { logWarn(\"subagent\", `Skipping chain model ${chainModel} \u2014 no endpoint configured`); continue; }\n candidates.push({\n endpoint: agent.provider.endpoint,\n apiKey, model: chainModel, maxContext: agent.contextWindow,\n });\n }\n }\n\n // Use shared registry if provided, otherwise create isolated one\n const { ModelHealthRegistry } = await import(\"./transport/model-health-registry.js\");\n const policy = new FallbackPolicy(candidates, registry ?? new ModelHealthRegistry());\n\n const transport = new DirectApiTransport({\n endpoint: agent.provider.endpoint ?? \"http://localhost:11434/v1\",\n apiKey, model: startModel,\n maxContext: agent.contextWindow, maxOutput: agent.maxOutput,\n maxTurns: tc?.maxTurns ?? 50,\n maxToolRounds: tc?.maxToolRounds ?? 25,\n }, policy);\n await transport.initialize();\n logInfo(\"subagent\", `${role} transport: DirectAPI ${agent.providerName} (model=${startModel}, ${candidates.length} candidates, shared registry: ${!!registry})`);\n return { transport, model: agent.model };\n }\n\n // ACP path \u2014 try configured model, then fallbackChain on failure\n const { loadAndValidateConfig } = await import(\"./config.js\");\n const config = await loadAndValidateConfig();\n const chain = agent.provider.fallbackChain ?? [];\n const modelsToTry = [agent.model, ...chain.filter(m => m !== agent.model)];\n\n for (let i = 0; i < modelsToTry.length; i++) {\n const model = modelsToTry[i]!;\n const transport = createAgentTransport(SUBAGENT_ACP_ROLE[role], {\n cliPath: agent.provider.cli ?? config.transport.agentCliPath,\n workingDir: config.transport.workingDir,\n agentCli: agent.provider.cli ?? \"kiro-cli\",\n model,\n });\n try {\n await transport.initialize();\n if (i > 0) logWarn(\"subagent\", `${role}: configured model failed, fell back to ${model}`);\n logInfo(\"subagent\", `${role} transport: ACP ${agent.providerName} (model=${model}${i > 0 ? \", fallback\" : \"\"})`);\n return { transport, model };\n } catch (err) {\n if (i < modelsToTry.length - 1) {\n logWarn(\"subagent\", `${role}: model ${model} init failed (${err instanceof Error ? err.message : String(err)}), trying ${modelsToTry[i + 1]}`);\n continue;\n }\n throw err;\n }\n }\n throw new Error(`${role}: all models exhausted (tried ${modelsToTry.join(\", \")})`);\n}\n"],
5
- "mappings": "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",
6
- "names": ["chain"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/components/tasks/task-checker.ts", "../src/components/heartbeat-tasks.ts", "../src/components/daily-cycle.ts", "../src/components/safe-json.ts", "../src/components/tasks/task-queue.ts", "../src/components/idle-save.ts", "../src/boot/phase-pipeline-deps.ts"],
4
- "sourcesContent": ["/**\n * cron-checker \u2014 heartbeat task that fires due cron entries.\n *\n * Reminders \u2192 pending_reminders.json (picked up by main.ts message loop)\n * Tasks \u2192 spawns kiro-cli subprocess, calls onTaskComplete callback\n */\n\nimport { logAndSwallow } from \"../log-and-swallow.js\";\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { abtarsHome } from \"../../paths.js\";\nimport { logInfo } from \"../logger.js\";\nimport { CronExpressionParser } from \"cron-parser\";\nimport { readEntries as dbReadEntries, writeEntry, removeEntry as dbRemoveEntry } from \"./task-store.js\";\nimport type { CronEntry } from \"../../cli/abtars-task.js\";\n\nconst TAG = \"cron-checker\";\nconst memoryDir = (): string => join(abtarsHome(), \"state\");\nconst remindersPath = (): string => join(memoryDir(), \"pending_reminders.json\");\n\nexport interface PendingReminder {\n chatId: number;\n message: string;\n createdAt: number;\n threadId?: number;\n}\n\nexport function readPendingReminders(): PendingReminder[] {\n if (!existsSync(remindersPath())) return [];\n try { return JSON.parse(readFileSync(remindersPath(), \"utf-8\")) as PendingReminder[]; }\n catch (err) { logAndSwallow(TAG, \"readPendingReminders\", err); return []; }\n}\n\nexport function clearPendingReminders(): void {\n if (existsSync(remindersPath())) writeFileSync(remindersPath(), \"[]\", \"utf-8\");\n}\n\nexport function appendReminder(r: PendingReminder): void {\n mkdirSync(memoryDir(), { recursive: true });\n const existing = readPendingReminders();\n existing.push(r);\n writeFileSync(remindersPath(), JSON.stringify(existing, null, 2), \"utf-8\");\n}\n\nconst MAX_HISTORY = 10;\nconst GC_AGE_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\n/** Record a run in the entry's history (keeps last MAX_HISTORY). */\nexport function recordRun(entry: CronEntry, exitCode?: number): void {\n if (!entry.history) entry.history = [];\n entry.history.push({ ts: Date.now(), ...(exitCode !== undefined ? { exitCode } : {}) });\n if (entry.history.length > MAX_HISTORY) entry.history = entry.history.slice(-MAX_HISTORY);\n}\n\n\n/**\n * Scan tasks.json for due entries. Fires reminders directly.\n * Returns due task entries (script + agent) for the CronQueue to process.\n * Advances fireAt and writes tasks.json.\n */\nexport function checkCron(): CronEntry[] {\n let entries = dbReadEntries();\n const now = Date.now();\n const dueTasks: CronEntry[] = [];\n\n // GC: remove fired one-shots older than 7 days\n for (const e of entries) {\n if (e.fired && !e.schedule && now - e.createdAt > GC_AGE_MS) {\n dbRemoveEntry(e.id);\n logInfo(TAG, `\uD83D\uDDD1\uFE0F GC: pruned old fired entry ${e.id}`);\n }\n }\n entries = entries.filter(e => !(e.fired && !e.schedule && now - e.createdAt > GC_AGE_MS));\n\n for (const entry of entries) {\n if (entry.fired || entry.paused || entry.fireAt > now) continue;\n\n // #692: daily rate limit \u2014 skip if maxRunsPerDay reached (count only successful runs)\n if (entry.maxRunsPerDay && entry.history) {\n const todayStart = new Date().setHours(0, 0, 0, 0);\n const todaySuccesses = entry.history.filter(h => h.ts >= todayStart && h.exitCode !== 1).length;\n if (todaySuccesses >= entry.maxRunsPerDay) {\n // Advance to next occurrence without running\n if (entry.schedule) {\n try {\n const expr = CronExpressionParser.parse(entry.schedule);\n entry.fireAt = expr.next().getTime();\n writeEntry(entry);\n } catch (err) { logAndSwallow(\"cron_checker\", \"op\", err); }\n }\n continue;\n }\n }\n\n // #327: stale detection \u2014 if past the catch-up window, advance to next occurrence\n if (entry.schedule && entry.fireAt <= now) {\n const maxDelay = (entry.catchUp ?? 0) * 3600_000;\n // Only consider stale if missed by more than one full interval (at minimum 5 min)\n const MIN_STALE_MS = 5 * 60_000;\n const staleThreshold = Math.max(maxDelay, MIN_STALE_MS);\n if (now - entry.fireAt > staleThreshold) {\n try {\n const expr = CronExpressionParser.parse(entry.schedule);\n entry.fireAt = expr.next().getTime();\n writeEntry(entry);\n logInfo(TAG, `\u23ED\uFE0F Stale \"${entry.id}\" \u2014 advanced to next occurrence`);\n } catch (err) { logAndSwallow(\"cron_checker\", \"op\", err); }\n continue;\n }\n }\n\n entry.lastRanAt = now;\n const wasRetry = !!entry._retrying;\n if (entry.schedule) {\n try {\n const expr = CronExpressionParser.parse(entry.schedule);\n entry.fireAt = expr.next().getTime();\n } catch (err) { logAndSwallow(TAG, \"cron parse next\", err); entry.fired = true; }\n } else {\n entry.fired = true;\n }\n delete entry._retrying;\n\n if (entry.type === \"reminder\") {\n appendReminder({ chatId: entry.chatId, message: entry.message, createdAt: now });\n recordRun(entry);\n logInfo(TAG, `\u23F0 Reminder fired: \"${entry.message}\" \u2192 chat ${entry.chatId}`);\n } else {\n dueTasks.push({ ...entry, _retrying: wasRetry || undefined });\n }\n\n writeEntry(entry);\n }\n\n return dueTasks;\n}\n", "/**\n * Heartbeat tasks extracted from bridge-app.ts \u2014 complex periodic operations\n * that benefit from being independently readable and testable.\n */\n\nimport { logAndSwallow } from \"./log-and-swallow.js\";\nimport { logInfo, logError } from \"./logger.js\";\nimport { setIdleCompactReset } from \"./message-pipeline.js\";\nimport type { IKiroTransport } from \"./transport/kiro-transport.js\";\nimport type { MemoryManager } from \"abmind\";\nimport type { HeartbeatTask } from \"../types/index.js\";\nimport { isDailyCycleDue, type DailyCycleDeps } from \"./daily-cycle.js\";\n\nconst TAG = \"heartbeat_tasks\";\nexport interface IdleCompactDeps {\n transport: IKiroTransport;\n memory: MemoryManager | null;\n memoryDir: string;\n allowedUserIds: Set<number>;\n isSleepActive: () => boolean;\n}\n\n/** Idle compaction removed \u2014 context engine handles compaction automatically via buildContext(). */\nexport function createIdleCompactTask(_deps: IdleCompactDeps): HeartbeatTask {\n setIdleCompactReset(() => {});\n return {\n name: \"idle-compact\",\n heavy: false,\n execute: async () => false,\n };\n}\n\nexport type AgeCheckDeps = DailyCycleDeps & { startSleep?: () => void; checkHwSleep?: () => void; checkStaleSleep?: () => void; cronBusy?: () => boolean };\n\n/** Daily cycle \u2014 spawn Dreamy after BED_TIME + quiet ticks, then hw sleep after more quiet ticks. */\nexport function createAgeCheckTask(deps: AgeCheckDeps): HeartbeatTask {\n let counter = 0;\n return {\n name: \"age-check\",\n execute: async () => {\n counter++;\n if (counter % 5 !== 0) return; // every 5 ticks (~5 min)\n if (deps.checkStaleSleep) deps.checkStaleSleep();\n if (deps.checkHwSleep && !deps.cronBusy?.()) deps.checkHwSleep();\n if (!isDailyCycleDue(deps)) return;\n logInfo(\"age-check\", `\uD83D\uDE34 BED_TIME (${deps.sleepHour}:${String(deps.sleepMinute).padStart(2, \"0\")}) \u2014 spawning Dreamy`);\n try { import(\"../cli/commands/doctor-probes.js\").then(m => m.runFixes()).catch(() => {}); } catch (err) { logAndSwallow(\"heartbeat_tasks\", \"op\", err); }\n if (deps.startSleep) { deps.startSleep(); }\n },\n };\n}\n\n/** DB integrity check \u2014 runs every ~1 hour (time-based, independent of tick interval). */\nexport function createDbIntegrityTask(memory: MemoryManager | null): HeartbeatTask {\n let lastCheckAt = 0;\n const INTERVAL_MS = 60 * 60 * 1000;\n const MAX_FAILURES = 5;\n let consecutiveFailures = 0;\n let escalated = false;\n return {\n name: \"db-integrity\",\n execute: async () => {\n if (escalated) return;\n if (Date.now() - lastCheckAt < INTERVAL_MS) return;\n lastCheckAt = Date.now();\n if (!memory) return;\n const result = memory.maintenance.checkIntegrity();\n if (result !== \"ok\") {\n logError(\"db-integrity\", `Memory DB integrity check failed: ${result}`);\n const { rebuilt } = memory.rebuildFtsIndexes();\n if (rebuilt.length > 0) {\n logInfo(\"db-integrity\", `Auto-rebuilt FTS indexes: ${rebuilt.join(\", \")}`);\n consecutiveFailures = 0;\n } else {\n consecutiveFailures++;\n if (consecutiveFailures >= MAX_FAILURES) {\n escalated = true;\n const msg = `\u26A0\uFE0F FTS corruption persists after ${MAX_FAILURES} rebuild attempts. Needs manual fix.`;\n logError(\"db-integrity\", msg);\n const { bufferSystemEvent } = await import(\"./system-event-buffer.js\");\n bufferSystemEvent(msg);\n }\n }\n } else {\n consecutiveFailures = 0;\n }\n },\n };\n}\n\n/** #440: Check for updates on npm, notify if newer version available. */\nexport function createUpdateCheckTask(notify: (msg: string) => void): HeartbeatTask {\n return {\n name: \"update-check\",\n async execute() {\n if (process.env[\"UPDATES_CHECK_ENABLED\"] === \"false\") return;\n const { checkForUpdate } = await import(\"./update-check.js\");\n const { readFileSync } = await import(\"node:fs\");\n const { join } = await import(\"node:path\");\n const { abtarsHome } = await import(\"../paths.js\");\n let version = \"0.0.0\";\n let source = \"npm\";\n try {\n const m = JSON.parse(readFileSync(join(abtarsHome(), \"manifest.json\"), \"utf-8\"));\n version = m.version ?? \"0.0.0\";\n source = m.source ?? \"npm\";\n } catch (err) { logAndSwallow(TAG, \"read manifest.json\", err); }\n if (source === \"local\") return; // git deploys are always ahead of npm\n const result = checkForUpdate(\"abtars\", version);\n if (result?.shouldNotify) {\n notify(`\u26A1 Update available: ${result.current} \u2192 ${result.latest}. Run: abtars update`);\n }\n },\n };\n}\n\n/** #613: Flush skill usage stats to disk every 3 hours. */\nexport function createSkillStatsFlushTask(): HeartbeatTask {\n let lastFlushAt = 0;\n const INTERVAL_MS = 3 * 60 * 60 * 1000;\n return {\n name: \"skill-stats-flush\",\n execute: async () => {\n if (Date.now() - lastFlushAt < INTERVAL_MS) return;\n lastFlushAt = Date.now();\n const { flush } = await import(\"./skill-stats.js\");\n flush();\n },\n };\n}\n\n/** #1114: Reload skills catalog every 10 minutes if skill files changed. */\nexport function createSkillReloadTask(): HeartbeatTask {\n let lastCheckAt = 0;\n let lastMtime = 0;\n const INTERVAL_MS = 10 * 60 * 1000;\n return {\n name: \"skill-reload\",\n execute: async () => {\n if (Date.now() - lastCheckAt < INTERVAL_MS) return;\n lastCheckAt = Date.now();\n const { statSync } = await import(\"node:fs\");\n const { join } = await import(\"node:path\");\n const { abtarsHome } = await import(\"../paths.js\");\n const skillsDir = join(abtarsHome(), \"skills\");\n try {\n const mtime = statSync(skillsDir).mtimeMs;\n if (mtime === lastMtime) return;\n lastMtime = mtime;\n const { reloadCatalog } = await import(\"../capabilities/hotskills/index.js\");\n const count = reloadCatalog();\n logInfo(\"skill-reload\", `Catalog regenerated: ${count} skills`);\n } catch { /* skills dir missing \u2014 skip */ }\n },\n };\n}\n\nexport interface KanbanDeliveryDeps {\n sendSystemMessage: (prompt: string) => Promise<void>;\n sendMessage: (chatId: string, text: string) => Promise<void>;\n sendDocument: (chatId: string, filePath: string, caption: string) => Promise<void>;\n chatId: () => string;\n}\n\n/** #857/#934: Kanban delivery \u2014 routes based on delivery_mode. */\nexport function createKanbanDeliveryTask(deps: KanbanDeliveryDeps): HeartbeatTask {\n return {\n name: \"kanban-delivery\",\n execute: async () => {\n try {\n const { kanbanPending, kanbanSetDelivering, kanbanMarkDelivered, kanbanDeliveryFailed } = await import(\"./tasks/kanban-board.js\");\n const pending = kanbanPending();\n if (pending.length === 0) return;\n\n for (const card of pending) {\n if (card.delivery_mode === \"silent\") {\n kanbanMarkDelivered(card.id);\n continue;\n }\n kanbanSetDelivering(card.id);\n try {\n if (card.delivery_mode === \"deliver\") {\n if (card.result_path) await deps.sendDocument(deps.chatId(), card.result_path, card.title);\n await deps.sendSystemMessage(`[SYSTEM] Task \"${card.title}\" complete. File delivered: ${card.result_path ?? \"(no file)\"}`);\n } else {\n // \"announce\"\n await deps.sendSystemMessage(\n `[TASK COMPLETE] \"${card.title}\" done.\\nResult:\\n${card.result_summary ?? \"(no output)\"}\\n\\nDeliver this to the user naturally.`\n );\n }\n kanbanMarkDelivered(card.id);\n } catch (err) {\n kanbanDeliveryFailed(card.id);\n logError(TAG, `Kanban delivery failed for card ${card.id}: ${err}`);\n }\n }\n } catch (err) { logAndSwallow(TAG, \"kanban-delivery\", err); }\n },\n };\n}\n\n/** #936: Expire idle user sessions managed by Spin. */\nexport function createUserSessionExpiryTask(): HeartbeatTask {\n return {\n name: \"user-session-expiry\",\n execute: async () => {\n const { spin } = await import(\"./spin.js\");\n const sessions = spin.listAllSessions();\n if (!sessions.length) return;\n const now = Date.now();\n for (const session of sessions) {\n if (session.idleTimeoutMs === Infinity) continue;\n if (session.status !== \"ready\") continue;\n if (!session.transport) continue;\n if (now - session.lastActiveAt > session.idleTimeoutMs) {\n spin.destroySession(session.userId, session.id);\n }\n }\n },\n };\n}\n\n/** #857: Kanban cleanup \u2014 purge delivered cards older than 7 days. */\nexport function createKanbanCleanupTask(): HeartbeatTask {\n let counter = 0;\n return {\n name: \"kanban-cleanup\",\n execute: async () => {\n counter++;\n if (counter % 72 !== 0) return; // ~hourly\n try {\n const { kanbanCleanup } = await import(\"./tasks/kanban-board.js\");\n const purged = kanbanCleanup(7);\n if (purged > 0) logInfo(TAG, `Kanban: purged ${purged} delivered cards > 7d`);\n } catch (err) { logAndSwallow(TAG, \"kanban-cleanup\", err); }\n },\n };\n}\n\n/** #832: Metrics flush (every 5min) + prune (daily). */\nexport function createMetricsTask(cronQueueDepth: () => number): HeartbeatTask {\n let flushCounter = 0;\n let pruneCounter = 0;\n return {\n name: \"metrics\",\n execute: async () => {\n try {\n const { recordCronDepth, flushToFile, pruneMetricsFile } = await import(\"./metrics-collector.js\");\n recordCronDepth(cronQueueDepth());\n flushCounter++;\n if (flushCounter % 6 === 0) flushToFile(); // ~5min (6 ticks \u00D7 50s)\n pruneCounter++;\n if (pruneCounter % 1728 === 0) pruneMetricsFile(); // ~daily (1728 ticks \u00D7 50s)\n } catch (err) { logAndSwallow(TAG, \"metrics\", err); }\n },\n };\n}\n", "import { getEnv } from \"./env-schema.js\";\nimport { spin } from \"./spin.js\";\n/**\n * Daily cycle check \u2014 shared by standby handler and age-check heartbeat task.\n *\n * After BED_TIME, counts quiet ticks (no new messages). After 6 quiet ticks\n * (~30min at 5min heartbeat), triggers sleep. Any new message resets the counter.\n */\nimport type { IMemorySystem } from \"abmind\";\nimport { logInfo } from \"./logger.js\";\nimport { logAndSwallow } from \"./log-and-swallow.js\";\nimport { safeReadJson } from \"./safe-json.js\";\nimport { abmind } from \"../utils/abmind-lazy.js\";\nimport { readBridgeLockField } from \"./transport/bridge-lock-transport.js\";\n\n\nexport interface DailyCycleDeps {\n sleepHour: number;\n sleepMinute: number;\n bridgeLockPath: string;\n sleepAuditDir: string;\n memory: IMemorySystem | null;\n isSleepActive: () => boolean;\n}\n\n\n\nlet quietTickCount = 0;\nlet lastSeenMsgTs = 0;\n\n/** Reset the quiet tick counter (call when user sends a message). */\nexport function resetBedtimeCounter(): void {\n quietTickCount = 0;\n}\n\n/** Returns true if conditions are met for the daily restart + sleep cycle. */\nexport function isDailyCycleDue(deps: DailyCycleDeps): boolean {\n // User-protection guards \u2014 NEVER bypass, even when forced.\n if (spin.listAllSessions().some(s => s.busy) || deps.isSleepActive()) return false;\n\n // Force-sleep request in bridge.lock \u2014 short-circuit time/audit/startedAt guards.\n // Peek-only here; spawnSleep() clears the field via readAndClearForceSleep().\n const forceSleep = readBridgeLockField<string>(\"forceSleep\");\n if (forceSleep) {\n logInfo(\"bedtime\", `\u26A1 forceSleep=${forceSleep} \u2014 bypassing bedtime/audit/startedAt guards`);\n return true;\n }\n\n const now = new Date();\n const nowMinutes = now.getHours() * 60 + now.getMinutes();\n const sleepMinutes = deps.sleepHour * 60 + deps.sleepMinute;\n if (nowMinutes < sleepMinutes) {\n quietTickCount = 0; // not bedtime yet, reset\n return false;\n }\n\n // Midnight wraparound: BED_TIME 0:30 means \"after midnight\", not \"all day\".\n // If more than 7 hours have passed since BED_TIME, it's daytime \u2014 not bedtime.\n if (nowMinutes - sleepMinutes > 7 * 60) {\n quietTickCount = 0;\n return false;\n }\n\n // Single source of truth: lock file status\n if (abmind()?.hasSleepAuditToday(deps.sleepAuditDir)) return false;\n\n const lockData = safeReadJson<{ startedAt?: number; lastHeartbeat?: number }>(deps.bridgeLockPath, {});\n if (!lockData.startedAt) return false; // fail-closed on missing/corrupt lock\n if (!lockData.lastHeartbeat) return false; // no successful tick yet \u2014 dark wake guard\n\n // Check for new messages since last tick \u2014 only Main (A) sessions count (#510)\n let currentMsgTs = 0;\n try {\n const row = deps.memory?.getLastMessageTimestamp(true, \"A\");\n currentMsgTs = row ?? 0;\n } catch (err) { logAndSwallow(\"daily_cycle\", \"getLastMessageTimestamp\", err); return false; }\n\n if (currentMsgTs > lastSeenMsgTs) {\n // New message arrived \u2014 reset counter\n lastSeenMsgTs = currentMsgTs;\n quietTickCount = 0;\n logInfo(\"bedtime\", `Message received \u2014 quiet counter reset (BED_TIME ${deps.sleepHour}:${String(deps.sleepMinute).padStart(2, \"0\")})`);\n return false;\n }\n\n // No new messages this tick \u2014 increment quiet counter\n quietTickCount++;\n const hbSec = parseInt(process.env[\"HEARTBEAT_INTERVAL_SEC\"] ?? \"60\", 10);\n const threshold = Math.ceil(getEnv().bedQuietMin * 60 / hbSec);\n logInfo(\"bedtime\", `Quiet tick ${quietTickCount}/${threshold} (BED_TIME ${deps.sleepHour}:${String(deps.sleepMinute).padStart(2, \"0\")})`);\n\n if (quietTickCount >= threshold) {\n quietTickCount = 0; // reset after triggering \u2014 prevents re-spawn on next tick\n return true;\n }\n return false;\n}\n", "/**\n * safe-json.ts \u2014 Defensive JSON file reader.\n * Returns fallback on any error (missing file, invalid JSON, wrong schema).\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { logAndSwallow } from \"./log-and-swallow.js\";\n\nconst TAG = \"safe_json\";\n\n/** Read and parse a JSON file. Returns fallback on any error. */\nexport function safeReadJson<T>(path: string, fallback: T): T {\n try {\n const raw = readFileSync(path, \"utf-8\");\n const parsed = JSON.parse(raw);\n if (parsed === null || typeof parsed !== \"object\") return fallback;\n return parsed as T;\n } catch (err) {\n logAndSwallow(TAG, `safeReadJson ${path}`, err);\n return fallback;\n }\n}\n", "/**\n * CronQueue \u2014 sequential job processor for cron tasks.\n *\n * Heartbeat enqueues due tasks. Queue runs them one at a time:\n * scripts sequentially, agents sequentially, never concurrent.\n * Priority-sorted: high jobs jump ahead of pending medium/low.\n * Duplicate prevention: same entry ID can't be queued or running twice.\n */\n\nimport { logAndSwallow } from \"../log-and-swallow.js\";\nimport { addTaskFailure } from \"./task-failure-buffer.js\";\nimport { spawn } from \"node:child_process\";\nimport { existsSync, readFileSync, readdirSync, statSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { resolve, join, dirname, basename } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { abtarsHome } from \"../../paths.js\";\nimport { logInfo, logWarn } from \"../logger.js\";\nimport { readLastPromptAt, readBridgeLockField } from \"../transport/bridge-lock-transport.js\";\nimport { recordRun as dbRecordRun, readEntry, writeEntry } from \"./task-store.js\";\nimport { recordRun } from \"./task-checker.js\";\nimport { kanbanComplete, kanbanFail } from \"./kanban-board.js\";\nimport type { CronEntry } from \"../../cli/abtars-task.js\";\nimport { localDate } from \"../../utils/date.js\";\n\nconst TAG = \"cron-queue\";\nconst AGENT_TIMEOUT_MS = 30 * 60 * 1000;\nconst RETRY_DELAY_MS = 10 * 60 * 1000; // skip 1 cycle (2 \u00D7 5min)\nconst PRIO_RANK: Record<string, number> = { high: 0, medium: 1, low: 2 };\nconst STATE_FILE = join(homedir(), \".abtars\", \"state\", \"task-queue-state.json\");\n\ninterface PersistedState {\n pid: number;\n currentJob: { entryId: string; message: string; startedAt: number; type: string } | null;\n queue: Array<{ entryId: string; message: string; priority: string; manual: boolean }>;\n}\n\nfunction persistState(current: RunningJob | null, queue: QueuedJob[]): void {\n try {\n const state: PersistedState = {\n pid: process.pid,\n currentJob: current ? { entryId: current.entryId, message: current.message, startedAt: current.startedAt, type: current.type } : null,\n queue: queue.map(j => ({ entryId: j.entry.id, message: j.entry.message, priority: j.entry.priority ?? \"medium\", manual: j.manual ?? false })),\n };\n writeFileSync(STATE_FILE, JSON.stringify(state), \"utf-8\");\n } catch (err) { logAndSwallow(\"cron_queue\", \"op\", err); }\n}\n\nfunction loadStaleState(): PersistedState | null {\n try {\n if (!existsSync(STATE_FILE)) return null;\n const raw = JSON.parse(readFileSync(STATE_FILE, \"utf-8\")) as PersistedState;\n // If PID matches current process, state is ours (not stale)\n if (raw.pid === process.pid) return null;\n // If bridge was in hw_sleep, don't mark as failed (watchdog-aware)\n const sleepStatus = readBridgeLockField(\"sleepStatus\");\n if (sleepStatus === \"hw_sleep\") return null;\n return raw;\n } catch (err) { logAndSwallow(TAG, \"loadStaleState\", err); return null; }\n}\n\nfunction recordRunToFile(entryId: string, exitCode?: number): void {\n dbRecordRun(entryId, exitCode);\n}\n\nfunction writeResultFile(entryId: string, content: string): string | null {\n try {\n const dir = join(abtarsHome(), \"workspace\", entryId);\n mkdirSync(dir, { recursive: true });\n const file = join(dir, `${entryId}-${localDate()}.md`);\n writeFileSync(file, content, \"utf-8\");\n return file;\n } catch (err) { logAndSwallow(TAG, \"writeResultFile\", err); return null; }\n}\n\nconst DOD_MIN_BYTES = 100;\n\nfunction todayStr(): string {\n return localDate();\n}\n\n/** Read task file, substitute {today}, glob associated _* files, return { prompt, dodPaths }. */\nfunction readTaskFile(taskFile: string): { prompt: string; dodPaths: string[] } | null {\n const filePath = resolve(taskFile.replace(/^~/, homedir()));\n if (!existsSync(filePath)) { logWarn(TAG, `Task file not found: ${filePath}`); return null; }\n const raw = readFileSync(filePath, \"utf-8\");\n const today = todayStr();\n const content = raw.replace(/\\{today\\}/g, today);\n\n const dodIdx = content.indexOf(\"## Definition of Done\");\n let prompt: string;\n let dodPaths: string[] = [];\n if (dodIdx === -1) {\n prompt = content.trim();\n } else {\n prompt = content.slice(0, dodIdx).trim();\n const dodSection = content.slice(dodIdx);\n dodPaths = dodSection.split(\"\\n\")\n .filter(l => l.match(/^- /))\n .map(l => l.replace(/^- /, \"\").trim())\n .map(p => resolve(p.replace(/^~/, homedir())));\n }\n\n // Glob associated files: {taskname}_* in same directory (cap 10k chars total)\n const dir = dirname(filePath);\n const base = basename(filePath, \".md\");\n const associated = readdirSync(dir).filter(f => f !== base + \".md\" && !f.startsWith(\".\")).sort();\n if (associated.length > 0) {\n let injected = \"\\n\\n---\\n## Associated files\\n\";\n let totalChars = 0;\n const CAP = 10_000;\n for (const f of associated) {\n const fc = readFileSync(join(dir, f), \"utf-8\");\n if (totalChars + fc.length > CAP) {\n injected += `\\n[${f}]: (truncated \u2014 full file at ${join(dir, f)})\\n`;\n break;\n }\n injected += `\\n### ${f}\\n\\`\\`\\`\\n${fc}\\n\\`\\`\\`\\n`;\n totalChars += fc.length;\n }\n prompt += injected;\n }\n\n return { prompt, dodPaths };\n}\n\n/** Check DoD: each path must exist and be >= DOD_MIN_BYTES. Returns pass/fail + details. */\nfunction checkDoD(paths: string[]): { passed: boolean; details: string } {\n if (paths.length === 0) return { passed: true, details: \"no DoD defined\" };\n const results: string[] = [];\n let allPassed = true;\n for (const p of paths) {\n if (!existsSync(p)) {\n results.push(`\u2717 missing: ${p}`);\n allPassed = false;\n } else {\n const size = statSync(p).size;\n if (size < DOD_MIN_BYTES) {\n results.push(`\u2717 too small (${size}B): ${p}`);\n allPassed = false;\n } else {\n results.push(`\u2713 ${p} (${size}B)`);\n }\n }\n }\n return { passed: allPassed, details: results.join(\"\\n\") };\n}\n\n/** Schedule a one-time retry after 1 skipped cycle. */\nfunction scheduleRetry(entry: CronEntry, isRetry: boolean): void {\n if (!entry.schedule || isRetry) return;\n try {\n const target = readEntry(entry.id);\n if (target) {\n target.fireAt = Date.now() + RETRY_DELAY_MS;\n target.fired = false;\n target._retrying = true;\n writeEntry(target);\n logInfo(TAG, `Scheduled retry for \"${entry.id}\" in ${RETRY_DELAY_MS / 60000}min`);\n }\n } catch (err) {\n logWarn(TAG, `Failed to schedule retry: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nexport type TaskCompleteCallback = (chatId: number, message: string, result: string, dodFiles?: string[]) => void;\nexport type FailInjectCallback = (entryId: string, command: string, result: string) => void;\nexport type TaskPausedCallback = (chatId: number, title: string, reason: string) => void;\n\ninterface QueuedJob {\n entry: CronEntry;\n onComplete?: TaskCompleteCallback;\n manual?: boolean;\n}\n\nexport interface RunningJob {\n entryId: string;\n message: string;\n pid: number;\n startedAt: number;\n type: \"script\" | \"agent\";\n}\n\nexport class CronQueue {\n private queue: QueuedJob[] = [];\n private _current: RunningJob | null = null;\n private timeout: ReturnType<typeof setTimeout> | null = null;\n private readonly onFailInject?: FailInjectCallback;\n private readonly onTaskPaused?: TaskPausedCallback;\n private readonly failCounts = new Map<string, { date: string; count: number }>();\n\n constructor(_cliPath: string, _workingDir: string, onFailInject?: FailInjectCallback, onTaskPaused?: TaskPausedCallback) {\n this.onFailInject = onFailInject;\n this.onTaskPaused = onTaskPaused;\n // #267: recover stale state from previous process\n const stale = loadStaleState();\n if (stale) {\n if (stale.currentJob) {\n logWarn(TAG, `Stale in-flight job detected: \"${stale.currentJob.entryId}\" (PID ${stale.pid} dead) \u2014 marking failed`);\n recordRunToFile(stale.currentJob.entryId, 1);\n }\n if (stale.queue.length > 0) {\n logWarn(TAG, `${stale.queue.length} stale queued job(s) from previous process \u2014 dropped`);\n }\n // Clear stale state\n persistState(null, []);\n }\n }\n\n /** Currently running job, or null. */\n get currentJob(): RunningJob | null { return this._current; }\n\n /** Number of jobs waiting. */\n get pending(): number { return this.queue.length; }\n\n /** Enqueue a task. Returns null on success, error string on failure. */\n enqueue(entry: CronEntry, onComplete?: TaskCompleteCallback, manual?: boolean): string | null {\n if (this._current?.entryId === entry.id) {\n return `\u23F3 Already running: \"${entry.message.slice(0, 60)}\"`;\n }\n if (this.queue.some(j => j.entry.id === entry.id)) {\n return `\u23F3 Already queued: \"${entry.message.slice(0, 60)}\"`;\n }\n\n // Priority-sorted insert\n const rank = PRIO_RANK[entry.priority ?? \"medium\"] ?? 1;\n let i = 0;\n while (i < this.queue.length) {\n const qRank = PRIO_RANK[this.queue[i]!.entry.priority ?? \"medium\"] ?? 1;\n if (rank < qRank) break;\n i++;\n }\n this.queue.splice(i, 0, { entry, onComplete, manual });\n logInfo(TAG, `Enqueued \"${entry.id}\" (${entry.executor ?? \"agent\"}, ${entry.priority ?? \"medium\"}${manual ? \", manual\" : \"\"}) \u2014 ${this.queue.length} pending`);\n persistState(this._current, this.queue);\n\n if (!this._current) this.processNext();\n return null;\n }\n\n private processNext(): void {\n if (this.queue.length === 0) return;\n\n // Skip all tasks during hardware sleep (dark wakes are too brief)\n if (readBridgeLockField(\"sleepStatus\") === \"hw_sleep\") {\n logInfo(TAG, `\u23F8 Hardware sleep \u2014 deferring ${this.queue.length} task(s)`);\n return;\n }\n\n const job = this.queue.shift()!;\n const { entry } = job;\n\n if (entry.executor === \"script\") {\n this.runScript(entry, job.onComplete);\n } else if (entry.executor === \"orc\") {\n this.runOrc(entry);\n } else {\n this.runAgent(entry, job.onComplete, job.manual);\n }\n }\n\n private setCurrent(entry: CronEntry, pid: number, type: \"script\" | \"agent\"): void {\n this._current = {\n entryId: entry.id,\n message: entry.message.slice(0, 80),\n pid,\n startedAt: Date.now(),\n type,\n };\n persistState(this._current, this.queue);\n }\n\n private clearCurrent(): void {\n if (this.timeout) { clearTimeout(this.timeout); this.timeout = null; }\n this._current = null;\n persistState(this._current, this.queue);\n }\n\n private tryInjectFailure(entry: CronEntry, result: string): void {\n if (!this.onFailInject) return;\n const today = localDate();\n const key = entry.id;\n const fc = this.failCounts.get(key);\n if (fc && fc.date === today && fc.count >= 2) {\n logInfo(TAG, `Skip auto-fix for \"${key}\" \u2014 already 2 attempts today`);\n return;\n }\n const count = (fc?.date === today ? fc.count : 0) + 1;\n this.failCounts.set(key, { date: today, count });\n logInfo(TAG, `Injecting failure to agent for \"${key}\" (attempt ${count}/2)`);\n this.onFailInject(entry.id, entry.message, result);\n }\n\n private checkAutoPause(entry: CronEntry, exitCode: number, lastError: string): boolean {\n if (!entry.schedule) return false;\n if (exitCode === 0) {\n if (entry.consecutiveFails) { entry.consecutiveFails = 0; writeEntry(entry); }\n return false;\n }\n entry.consecutiveFails = (entry.consecutiveFails ?? 0) + 1;\n if (entry.consecutiveFails >= 3) {\n entry.paused = true;\n logWarn(TAG, `\u23F8 Auto-paused \"${entry.id}\" after ${entry.consecutiveFails} consecutive failures`);\n this.onTaskPaused?.(entry.chatId, entry.title ?? entry.message.slice(0, 60), lastError.slice(0, 200));\n writeEntry(entry);\n return true;\n }\n writeEntry(entry);\n return false;\n }\n\n private runOrc(entry: CronEntry): void {\n logInfo(TAG, `\u25B6 Orc: \"${entry.message.slice(0, 60)}\"`);\n import(\"../spin.js\").then(({ spin }) => {\n spin.dispatch({ type: \"O\", goal: entry.message, source: \"task\", priority: entry.priority ?? \"MEDIUM\", deliveryMode: entry.deliveryMode });\n this.clearCurrent();\n this.processNext();\n }).catch((err) => {\n logWarn(TAG, `Orc dispatch failed: ${err instanceof Error ? err.message : String(err)}`);\n this.clearCurrent();\n this.processNext();\n });\n }\n\n private runScript(entry: CronEntry, onComplete?: TaskCompleteCallback): void {\n logInfo(TAG, `\u25B6 Script: \"${entry.message.slice(0, 60)}\"`);\n try {\n const child = spawn(\"bash\", [\"-c\", entry.message], { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n \n this.setCurrent(entry, child.pid ?? 0, \"script\");\n\n let output = \"\";\n child.stdout?.on(\"data\", (d: Buffer) => { output += d.toString(); });\n child.stderr?.on(\"data\", (d: Buffer) => { output += d.toString(); });\n\n child.on(\"exit\", (code) => {\n const status = code === 0 ? \"\u2713\" : `\u274C (exit ${code})`;\n logInfo(TAG, `\u25A0 Script ${status}: \"${entry.message.slice(0, 60)}\"`);\n recordRunToFile(entry.id, code ?? undefined);\n if (code === 0) recordRun(entry, 0); // #694: count toward maxRunsPerDay only on success\n const paused = this.checkAutoPause(entry, code ?? 1, (output || \"(no output)\").slice(0, 200));\n if (code === 0 && output.trim() && entry.agentFollowUp && entry.agentMessage) {\n logInfo(TAG, `\u25A0 Gate triggered \u2192 enqueuing agent follow-up for \"${entry.id}\"`);\n const agentEntry: CronEntry = { ...entry, executor: \"agent\", message: entry.agentMessage.replace(\"{{GATE_OUTPUT}}\", output.trim()), agentFollowUp: undefined };\n this.clearCurrent();\n this.enqueue(agentEntry, onComplete);\n return;\n }\n if (code !== 0) {\n scheduleRetry(entry, !!entry._retrying);\n if (!paused && code !== 2) this.tryInjectFailure(entry, `${status}\\n${(output || \"(no output)\").slice(0, 500)}`);\n addTaskFailure({ taskName: entry.title ?? entry.message.slice(0, 60), exitCode: code ?? 1, error: (output || \"\").slice(0, 100), timestamp: Date.now(), consecutiveFailures: entry.consecutiveFails ?? 1 });\n }\n if (!paused) {\n // Silent success: don't notify user when script exits 0 with no output\n if (code !== 0 || output.trim()) {\n onComplete?.(entry.chatId, entry.message, `${status}\\n${(output || \"(no output)\").slice(0, 500)}`);\n }\n }\n this.clearCurrent();\n this.processNext();\n });\n\n child.on(\"error\", (err) => {\n logWarn(TAG, `Script spawn failed: ${err.message}`);\n onComplete?.(entry.chatId, entry.message, `\u274C Failed: ${err.message}`);\n this.clearCurrent();\n this.processNext();\n });\n } catch (err) {\n logWarn(TAG, `Script error: ${err instanceof Error ? err.message : String(err)}`);\n this.clearCurrent();\n this.processNext();\n }\n }\n\n private async runAgent(entry: CronEntry, onComplete?: TaskCompleteCallback, manual?: boolean): Promise<void> {\n // Idle gate: defer agent tasks if user was active in last 90s (skip for manual triggers)\n if (!manual) {\n const idleMs = Date.now() - readLastPromptAt();\n if (idleMs < 90_000) {\n logInfo(TAG, `\u23F8 Deferring agent task \"${entry.id}\" \u2014 user active ${Math.round(idleMs / 1000)}s ago`);\n return;\n }\n }\n\n // Read task file if specified, otherwise use inline message\n let prompt = entry.message;\n let dodPaths: string[] = [];\n if (entry.taskFile) {\n const task = readTaskFile(entry.taskFile);\n if (task) {\n prompt = task.prompt;\n dodPaths = task.dodPaths;\n } else {\n logWarn(TAG, `Falling back to inline message for \"${entry.id}\"`);\n }\n }\n\n // #1141: Inject task-scoped persistent context if it exists\n const contextFile = join(abtarsHome(), \"workspace\", entry.id, \"CONTEXT.md\");\n if (existsSync(contextFile)) {\n const raw = readFileSync(contextFile, \"utf-8\").trim();\n if (raw) {\n const ctx = raw.length > 30000 ? (logWarn(TAG, `Task context truncated (${raw.length} > 30000)`), raw.slice(0, 30000)) : raw;\n prompt = `[TASK CONTEXT \u2014 your notes from previous runs]\\n${ctx}\\n\\n[TASK]\\n${prompt}`;\n logInfo(TAG, `Injected task context (${ctx.length} chars)`);\n }\n }\n\n logInfo(TAG, `\u25B6 Agent: \"${entry.message.slice(0, 60)}\"`);\n\n // #936 Phase 2: Route to user session via injectGreeting if targetUserId is set\n if (entry.targetUserId) {\n this.setCurrent(entry, 0, \"agent\");\n try {\n const { spin } = await import(\"../spin.js\");\n const response = await spin.injectGreeting(entry.targetUserId, prompt);\n if (response) {\n recordRunToFile(entry.id, 0);\n recordRun(entry, 0);\n logInfo(TAG, `\u2713 Greeting delivered to ${entry.targetUserId}`);\n } else {\n recordRunToFile(entry.id, 1);\n logWarn(TAG, `Greeting failed for ${entry.targetUserId}`);\n }\n } catch (err) {\n recordRunToFile(entry.id, 1);\n logWarn(TAG, `Greeting error: ${err instanceof Error ? err.message : String(err)}`);\n } finally {\n this.clearCurrent();\n this.processNext();\n }\n return;\n }\n\n // Set current BEFORE any await \u2014 prevents race where enqueue() sees _current=null\n // and calls processNext() again while we're awaiting the dynamic import.\n this.setCurrent(entry, 0, \"agent\");\n\n // #1141: Skill-trigger task \u2014 delegate to launchSkill()\n if ((entry as any).skill) {\n const { launchSkill } = await import(\"../skill-session.js\");\n const userId = entry.targetUserId ?? String(entry.chatId);\n const err = await launchSkill((entry as any).skill, userId, String(entry.chatId), prompt);\n if (err) logWarn(TAG, `Skill launch failed for \"${entry.id}\": ${err}`);\n else logInfo(TAG, `\u25A0 Skill \"${(entry as any).skill}\" launched for \"${entry.id}\"`);\n recordRunToFile(entry.id, err ? 1 : 0);\n if (!err) recordRun(entry, 0);\n this.clearCurrent();\n this.processNext();\n return;\n }\n\n // Kanban board: track this task (Spin handles card lifecycle)\n // Set $WORKSPACE for agent tool execution \u2014 all output goes here\n const workspace = join(abtarsHome(), \"workspace\", entry.id);\n mkdirSync(workspace, { recursive: true });\n process.env[\"WORKSPACE\"] = workspace;\n\n const { spin } = await import(\"../spin.js\");\n\n // 30-min hard timeout\n this.timeout = setTimeout(() => {\n logWarn(TAG, `\u23F1\uFE0F Agent \"${entry.id}\" timed out (30min)`);\n }, AGENT_TIMEOUT_MS);\n\n // #935: map agent field to session type (canonical task routing \u2014 distinct from TYPE_AGENT in spin-types which maps type\u2192model-role)\n const AGENT_SESSION: Record<string, string> = { professor: \"A\", browsie: \"B\", coding: \"C\", dreamy: \"D\" };\n const sessionType = (AGENT_SESSION[entry.agent ?? \"\"] ?? \"T\") as import(\"../spin-types.js\").SessionType;\n\n spin.dispatchAwait({ type: sessionType, title: entry.title ?? entry.message.slice(0, 80), goal: prompt, source: \"task\", priority: entry.priority ?? \"MEDIUM\", chatId: String(entry.chatId), deliveryMode: entry.deliveryMode })\n .then(({ cardId: boardId, result: response }) => {\n // Guard: if model returned raw JSON tool output ({\"stdout\":...,\"exit_code\":...}),\n // extract just the meaningful content. This happens when the model echoes its last\n // tool result instead of synthesizing a human-readable response.\n let cleaned = response || \"(no output)\";\n try {\n const parsed = JSON.parse(cleaned);\n if (parsed && typeof parsed === \"object\" && \"exit_code\" in parsed) {\n cleaned = parsed.stdout || parsed.stderr || \"(task completed)\";\n }\n } catch (err) { logAndSwallow(TAG, \"JSON.parse task output\", err); }\n const summary = cleaned.slice(0, 500);\n let exitCode = 0;\n let dodResult = \"\";\n if (dodPaths.length > 0) {\n const dod = checkDoD(dodPaths);\n // If DoD paths missing but model produced substantial output, accept it\n if (!dod.passed && cleaned.length > 200) {\n dod.passed = true;\n dod.details += \"\\n\u2713 accepted: model output written to result file\";\n }\n exitCode = dod.passed ? 0 : 1;\n dodResult = `\\nDoD: ${dod.passed ? \"PASSED\" : \"FAILED\"}\\n${dod.details}`;\n logInfo(TAG, `\u25A0 Agent DoD ${dod.passed ? \"\u2713\" : \"\u274C\"}: \"${entry.message.slice(0, 60)}\"\\n${dod.details}`);\n } else {\n logInfo(TAG, `\u25A0 Agent completed: \"${entry.message.slice(0, 60)}\"`);\n }\n\n // Write result file \u2014 skip if DoD files exist (they ARE the result)\n // #1118: inline tasks skip file writing \u2014 deliver text directly via kanban\n const producedFiles = dodPaths.filter(p => existsSync(p));\n const isReport = entry.deliveryMethod === \"report\";\n const resultPath = producedFiles.length > 0 ? producedFiles[0] : (isReport ? writeResultFile(entry.id, cleaned) : null);\n if (resultPath) logInfo(TAG, `\u25A0 Result: ${resultPath}`);\n\n // Kanban board: mark complete or failed\n if (exitCode === 0) {\n // #1118: inline tasks store full response as summary (delivered as chat message)\n const kanbanSummary = isReport ? summary : cleaned;\n kanbanComplete(boardId, resultPath ?? null, kanbanSummary);\n } else {\n kanbanFail(boardId, `${summary}${dodResult}`);\n }\n\n recordRunToFile(entry.id, exitCode);\n if (exitCode === 0) recordRun(entry, 0); // #694: count toward maxRunsPerDay only on success\n const paused = this.checkAutoPause(entry, exitCode, `${summary}${dodResult}`);\n const icon = exitCode === 0 ? \"\u2713\" : \"\u274C\";\n if (exitCode !== 0) {\n scheduleRetry(entry, !!entry._retrying);\n if (!paused) this.tryInjectFailure(entry, `${icon} ${summary}${dodResult}`);\n }\n if (!paused) {\n const producedFiles = dodPaths.filter(p => existsSync(p));\n onComplete?.(entry.chatId, entry.message, `${icon} ${summary}${dodResult}`, producedFiles.length > 0 ? producedFiles : undefined);\n }\n })\n .catch((err: unknown) => {\n const boardId = 0; // card already tracked by Spin\n logWarn(TAG, `Agent failed: ${err instanceof Error ? err.message : String(err)}`);\n kanbanFail(boardId, err instanceof Error ? err.message : String(err));\n recordRunToFile(entry.id, 1);\n const paused = this.checkAutoPause(entry, 1, err instanceof Error ? err.message : String(err));\n scheduleRetry(entry, !!entry._retrying);\n if (!paused) {\n const errMsg = `\u274C Failed: ${err instanceof Error ? err.message : String(err)}`;\n this.tryInjectFailure(entry, errMsg);\n onComplete?.(entry.chatId, entry.message, errMsg);\n }\n })\n .finally(() => {\n this.clearCurrent();\n this.processNext();\n });\n }\n}\n", "import { mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { logInfo, logWarn, logDebug } from \"./logger.js\";\nimport type { IKiroTransport } from \"./transport/kiro-transport.js\";\nimport { localDate } from \"../utils/date.js\";\n\nconst CHAT_SAVE_IDLE_MS = 10 * 60 * 1000;\n\n/**\n * Manages idle-save timers: after 10 min of inactivity per session,\n * saves the kiro-cli conversation transcript to the working directory.\n */\nexport class IdleSave {\n private readonly timers = new Map<string, ReturnType<typeof setTimeout>>();\n private readonly transport: IKiroTransport;\n private readonly memoryDir: string;\n private readonly enabled: boolean;\n\n constructor(transport: IKiroTransport, memoryDir: string, memoryEnabled: boolean) {\n this.transport = transport;\n this.memoryDir = memoryDir;\n this.enabled = memoryEnabled;\n }\n\n getTimers(): Map<string, ReturnType<typeof setTimeout>> {\n return this.timers;\n }\n\n reset(sessionKey: string, chatId: number): void {\n const existing = this.timers.get(sessionKey);\n if (existing) clearTimeout(existing);\n this.timers.set(sessionKey, setTimeout(() => {\n this.timers.delete(sessionKey);\n this.save(sessionKey, chatId);\n }, CHAT_SAVE_IDLE_MS));\n }\n\n async save(sessionKey: string, chatId: number): Promise<void> {\n if (!this.enabled || !this.memoryDir) return;\n // /chat save only works on tmux transport, not ACP\n if (!(\"sendKeys\" in this.transport)) return;\n const today = localDate();\n const dir = join(this.memoryDir, \"working\", today);\n try { mkdirSync(dir, { recursive: true }); } catch { logDebug(\"idle-save\", `Cannot create ${dir} \u2014 skipping`); return; }\n const dest = join(dir, `transcript_${chatId}.chat`);\n try {\n await this.transport.sendPrompt(sessionKey, `/chat save ${dest}`);\n logInfo(\"idle-save\", `Chat saved to ${dest}`);\n } catch (e) {\n logWarn(\"idle-save\", `Chat save failed: ${e instanceof Error ? e.message : JSON.stringify(e)}`);\n }\n }\n\n clearAll(): void {\n for (const timer of this.timers.values()) clearTimeout(timer);\n this.timers.clear();\n }\n}\n", "/**\n * phase-pipeline-deps \u2014 boot phase 5: construct CronQueue + pipelineDeps object.\n *\n * Must run after phase-transport (uses ctx.transport). Runs before\n * phase-platforms (platforms' adapters close over ctx.pipelineDeps).\n *\n * - Constructs CodingMode, IdleSave, CronQueue\n * - Wires setEnqueueCron singleton (tool-registry)\n * - Builds the PipelineDeps object \u2014 closes over ctx fields so later phases\n * can populate sleepHandle, selfHealerTask, loadedCapabilities via ctx\n * mutation without rewiring\n * - cronCallback closes over ctx so it reads telegramAdapter when fired\n *\n * Owns singleton: tool-registry._enqueueCron (via setEnqueueCron).\n *\n * Populates ctx: cronQueue, idleSave, pipelineDeps.\n */\n\nimport { readEntry as cronReadEntry } from \"../components/tasks/task-store.js\";\nimport { CronQueue } from \"../components/tasks/task-queue.js\";\nimport { IdleSave } from \"../components/idle-save.js\";\nimport { logWarn, logInfo } from \"../components/logger.js\";\nimport { loadTransport, resolveAgent } from \"../components/transport-config.js\";\nimport { updateCtxStart } from \"./ctx-start.js\";\nimport type { BootCtx, PhaseResult } from \"./context.js\";\nimport type { PipelineDeps } from \"../components/message-pipeline.js\";\nimport type { TaskCompleteCallback } from \"../components/tasks/task-queue.js\";\nimport { getEnv } from \"../components/env-schema.js\";\n\nexport async function phasePipelineDeps(ctx: BootCtx): Promise<PhaseResult> {\n const { config, memoryConfig, transport } = ctx;\n if (!transport) { ctx.phaseHealth.set(phasePipelineDeps.name, { status: \"skipped\", error: \"no transport\" }); logWarn(\"boot\", `${phasePipelineDeps.name}: skipping \u2014 transport not available`); return \"skipped\"; }\n\n ctx.idleSave = new IdleSave(transport, memoryConfig.memoryDir, memoryConfig.memoryEnabled);\n\n // CronQueue first \u2014 pipelineDeps references it\n let shaState: \"idle\" | \"running\" | \"cooldown\" = \"idle\";\n const shaPending: string[] = [];\n const cronQueue = new CronQueue(\n config.transport.agentCliPath,\n config.transport.workingDir,\n (entryId, command, result) => {\n // Three-state SHA guard (#719)\n if (shaState === \"running\") return; // drop entirely \u2014 SHA might be fixing it\n if (ctx.telegramAdapter) {\n ctx.telegramAdapter.sendNotification(String(getEnv().mainChatId), `\u26A0\uFE0F ${entryId} failed`);\n }\n if (!getEnv().selfhealEnabled) return;\n if (shaState === \"cooldown\") {\n shaPending.push(entryId);\n return;\n }\n // SHA idle \u2192 fire\n shaState = \"running\";\n const pending = shaPending.length > 0 ? `\\nAlso failed recently: ${shaPending.join(\", \")}` : \"\";\n shaPending.length = 0;\n if (ctx.telegramAdapter) {\n ctx.telegramAdapter.sendNotification(String(getEnv().mainChatId), `\uD83D\uDD27 Calling SHA, reason: \"${entryId}\" failed`);\n }\n const msg = `[System] You ARE the self-healing agent. A scheduled task failed:\\nTask: \"${entryId}\"\\nCommand: ${command}\\nResult: ${result}${pending}\\n\\nDiagnose the root cause. If you can fix it programmatically (script fix, token refresh, pause task), do it. If the fix requires human action (manual browser login, external service down), state clearly: \"Requires human intervention: <reason>\" \u2014 do NOT create a skill or suggest adding error handling (you ARE the error handling). Be concise.\\n\\nFORBIDDEN: Do NOT modify vital config files unless the bridge is in a crash loop or cannot boot:\\n- transport.json\\n- .env / .env.skills\\n- peers.json\\n- users.json\\nException: fixing JSON structural corruption (invalid syntax, parse errors) is always allowed.\\n\\nA single task failure is NOT grounds for config changes. Investigate root cause, report findings.`;\n void (async () => {\n try {\n const { SubagentRuntime } = await import(\"../components/subagent-runtime.js\");\n const runtime = new SubagentRuntime();\n await runtime.complete(\"coding\", msg, { sessionType: \"S\" });\n await runtime.shutdown();\n } catch (err) {\n logWarn(\"main\", `SHA session failed: ${err}`);\n } finally {\n shaState = \"cooldown\";\n setTimeout(() => { shaState = \"idle\"; }, 60_000);\n }\n })();\n },\n (chatId, title, _reason) => {\n if (!ctx.telegramAdapter) return;\n const msg = `\u26D4 \"${title}\" needs manual fix, further errors suppressed.\\nResume with: /task resume <id>`;\n ctx.telegramAdapter.sendNotification(String(chatId), msg);\n },\n );\n ctx.cronQueue = cronQueue;\n\n // cronCallback closes over ctx \u2014 reads telegramAdapter lazily (set in phase-platforms)\n const cronCallback: TaskCompleteCallback = (_chatId, _message, _result, _dodFiles) => {\n // #857: delivery handled by kanban board poll in heartbeat-tasks.\n // Board was already updated by task-queue (kanbanComplete/kanbanFail).\n // Main agent picks up done cards and delivers on next interaction.\n };\n\n // Wire task_manage --run to the cron queue (singleton: _enqueueCron)\n const { setEnqueueCron } = await import(\"../components/transport/tool-registry.js\");\n const enqueueCron = (id: string, manual?: boolean): string | null => {\n try {\n const entry = cronReadEntry(id);\n if (!entry) return `\u274C Entry ${id} not found`;\n return cronQueue.enqueue(entry, cronCallback, manual);\n } catch (err) {\n return `\u274C ${err instanceof Error ? err.message : String(err)}`;\n }\n };\n setEnqueueCron(enqueueCron);\n\n // Wire secret_get tool to memory DB\n\n // #894: Wire Spin (which IS the session manager now) to runtime\n const { spin } = await import(\"../components/spin.js\");\n spin.setRuntime(ctx.runtime);\n if (ctx.memory) spin.setMemory(ctx.memory as any);\n\n // #936: Register master session in Spin\n const { loadUsers } = await import(\"../components/user-registry.js\");\n const registry = loadUsers();\n const masterUser = registry.users.find(u => u.role === \"master\");\n if (masterUser && transport) {\n const masterChatId = masterUser.platforms.telegram ?? masterUser.platforms.discord;\n if (masterChatId) {\n spin.registerMasterSession({\n userId: masterUser.userId,\n chatId: typeof masterChatId === \"number\" ? masterChatId : parseInt(String(masterChatId), 10),\n platform: masterUser.platforms.telegram ? \"telegram\" : \"discord\",\n transport,\n });\n }\n }\n\n // #998: Set system prompt AFTER memory state is known\n if (transport && \"setSystemPrompt\" in transport && typeof (transport as any).setSystemPrompt === \"function\") {\n const { buildSoulBundle } = await import(\"../components/soul-bundle.js\");\n const bundle = buildSoulBundle(\"A\", ctx.memory ?? null);\n if (bundle) (transport as { setSystemPrompt: (p: string) => void }).setSystemPrompt(bundle);\n }\n\n // #907: Register Nerve notification listeners for Orc\n await import(\"../components/spin-notifications.js\");\n\n // #540: Resume Orc if it was active before crash\n const { readBridgeLockField } = await import(\"../components/transport/bridge-lock-transport.js\");\n const orcCard = readBridgeLockField<number>(\"orc_active\");\n if (orcCard) {\n logInfo(\"boot\", `Orc was active (card #${orcCard}) \u2014 resuming`);\n spin.dispatch({ type: \"O\", goal: \"Resume: reconcile kanban state for your active project\", source: \"agent\", cardId: orcCard });\n }\n\n // Build pipelineDeps. References ctx fields; later phases mutate ctx.sleepHandle /\n // pipelineDeps.loadedCapabilities / pipelineDeps.selfHealerTask in place.\n const pipelineDeps: PipelineDeps = {\n transport,\n memory: ctx.memory,\n memoryConfig,\n nlmConfig: ctx.nlmConfig,\n idleSave: ctx.idleSave,\n conversationBuffer: ctx.conversationBuffer,\n config: {\n workingDir: config.transport.workingDir,\n },\n startedAt: ctx.startedAt,\n sttConfig: ctx.sttConfig,\n ttsConfig: ctx.ttsConfig,\n sessionManager: ctx.sessionManager,\n updateCtxStart,\n cronCurrentJob: () => cronQueue.currentJob,\n enqueueCron,\n requestShutdown: (code?: number) => ctx.requestShutdownWithCode(code ?? 0),\n sleepProgress: () => ctx.sleepHandle?.progress ?? null,\n loadedCapabilities: [],\n selfHealerTask: null,\n hailMary: ctx.hailMary,\n rebuildTransport: async () => {\n const { rebuildTransport } = await import(\"./phase-transport.js\");\n await rebuildTransport(ctx);\n },\n phaseHealth: ctx.phaseHealth,\n registry: ctx.registry,\n bridgeLockPath: ctx.bridgeLockPath,\n get maxContext() {\n try {\n const tc = loadTransport();\n if (tc) {\n const prof = resolveAgent(\"professor\", tc);\n if (prof?.contextWindow) return prof.contextWindow;\n }\n } catch { /* fallback */ }\n return 128000;\n },\n };\n ctx.pipelineDeps = pipelineDeps;\n\n // #944 Step C: Wire full message handler on already-connected platforms\n const { handleInboundMessage } = await import(\"../components/message-pipeline.js\");\n if (ctx.telegramAdapter) {\n ctx.telegramAdapter.setMessageHandler({ pipeline: pipelineDeps, conversationBuffer: ctx.conversationBuffer, transport, memory: ctx.memory, sessionManager: ctx.sessionManager, actionGate: ctx.actionGate });\n logInfo(\"boot\", \"Telegram: full pipeline wired\");\n }\n if (ctx.discordAdapter) {\n ctx.discordAdapter.setMessageHandler({ pipeline: pipelineDeps, transport, memory: ctx.memory, conversationBuffer: ctx.conversationBuffer });\n logInfo(\"boot\", \"Discord: full pipeline wired\");\n }\n for (const [name, adapter] of ctx.platformAdapters) {\n if (name === \"irc\" && \"setMessageHandler\" in adapter) {\n (adapter as any).setMessageHandler((msg: any) => handleInboundMessage(msg, adapter, pipelineDeps));\n logInfo(\"boot\", \"IRC: full pipeline wired\");\n }\n }\n\n // Drain recovery queue \u2014 messages that arrived before pipeline was ready\n const recoveryQueue = (ctx as any)._recoveryQueue as Array<{ msg: any; adapter: any }> | undefined;\n if (recoveryQueue?.length) {\n logInfo(\"boot\", `Draining ${recoveryQueue.length} queued message(s) from recovery handler`);\n for (const { msg, adapter } of recoveryQueue) {\n handleInboundMessage(msg, adapter, pipelineDeps).catch(err => logWarn(\"boot\", `Drain error: ${err}`));\n }\n recoveryQueue.length = 0;\n }\n\n // Wire send_document tool + ActionGate (moved from phase-platforms)\n if (ctx.telegramAdapter) {\n const mainChatId = config.mainChatId;\n if (mainChatId) {\n const { setSendDocument } = await import(\"../components/transport/tool-registry.js\");\n setSendDocument((path, caption) => ctx.telegramAdapter!.sendDocument(String(mainChatId), path, caption));\n if (ctx.actionGate) {\n const api = (ctx.telegramAdapter as any).api;\n const chatId = String(mainChatId);\n ctx.actionGate.setNotify(async (text: string, buttons: Array<{ text: string; data: string }>) => {\n const opts: any = {};\n if (buttons.length > 0) {\n opts.reply_markup = { inline_keyboard: [buttons.map((b: any) => ({ text: b.text, callback_data: b.data }))] };\n }\n await api.sendMessage(chatId, text, opts);\n });\n }\n }\n }\n // Wire IRC send tool\n const ircAdapter = ctx.platformAdapters.get(\"irc\");\n if (ircAdapter) {\n const { setIrcSend } = await import(\"../components/transport/tool-registry.js\");\n setIrcSend((channel, message) => { ircAdapter.sendMessage(channel, message); });\n }\n\n // #1000: \"Back online\" notification moved to bridge-app.ts (fires before greeting)\n\n // #949: Wire channel\u2192remote sync listener\n const { initChannelSync } = await import(\"../components/tasks/kanban-channel.js\");\n initChannelSync();\n\n // Register Tier 3 heartbeat tasks (cron, kanban, self-healer, model-health, etc.)\n const { registerTier3Tasks } = await import(\"./heartbeat-tier3.js\");\n await registerTier3Tasks(ctx);\n\n return \"ran\";\n}\n\n/** Export cronCallback factory for phase-heartbeat's age-check task re-enqueue. */\nexport function createCronCallback(_ctx: BootCtx): TaskCompleteCallback {\n return (_chatId, _message, _result, _dodFiles) => {\n // #857/#1020: delivery handled exclusively by kanban board (phase-heartbeat card:done handler).\n };\n}\n"],
5
- "mappings": "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",
6
- "names": ["recordRun", "readFileSync", "TAG", "TAG", "readFileSync", "join", "abtarsHome", "statSync", "spin", "existsSync", "readFileSync", "writeFileSync", "mkdirSync", "join", "TAG", "join", "writeFileSync", "existsSync", "readFileSync", "mkdirSync", "spin", "recordRun", "producedFiles", "mkdirSync", "join", "memoryDir", "join", "mkdirSync", "spin", "readBridgeLockField"]
7
- }
@@ -1,241 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
3
- import {
4
- init_peer_config,
5
- loadPeerConfig
6
- } from "./chunk-4S554KLW.js";
7
- import {
8
- init_logger,
9
- logDebug,
10
- logInfo,
11
- logTrace,
12
- logWarn
13
- } from "./chunk-GWILHZPT.js";
14
- import {
15
- __esm,
16
- __export
17
- } from "./chunk-7K2YZTLD.js";
18
-
19
- // src/components/peer-transport/gossip.ts
20
- var gossip_exports = {};
21
- __export(gossip_exports, {
22
- findCapablePeer: () => findCapablePeer,
23
- getAlivePeers: () => getAlivePeers,
24
- getLocalCapabilities: () => getLocalCapabilities,
25
- getPeerTable: () => getPeerTable,
26
- gossipBroadcast: () => gossipBroadcast,
27
- setGossipInterval: () => setGossipInterval,
28
- startGossip: () => startGossip,
29
- startGossipListener: () => startGossipListener,
30
- stopGossip: () => stopGossip,
31
- stopGossipListener: () => stopGossipListener
32
- });
33
- import { createSocket } from "node:dgram";
34
- import { execSync } from "node:child_process";
35
- import { existsSync } from "node:fs";
36
- import { cpus, loadavg } from "node:os";
37
- import { createHmac } from "node:crypto";
38
- function discoverCapabilities() {
39
- const caps = ["bash", "node", "memory"];
40
- try {
41
- if (execSync("which docker", { stdio: "pipe" }).toString().trim()) caps.push("docker");
42
- } catch {
43
- }
44
- try {
45
- if (execSync("which xcodebuild", { stdio: "pipe" }).toString().trim()) caps.push("xcode");
46
- } catch {
47
- }
48
- try {
49
- if (execSync("which ollama", { stdio: "pipe" }).toString().trim()) caps.push("ollama");
50
- } catch {
51
- }
52
- if (existsSync("/usr/bin/nvidia-smi") || process.env["CUDA_VISIBLE_DEVICES"]) caps.push("gpu");
53
- if (process.env["BROWSER_ENGINE"]) caps.push("browser");
54
- if (process.env["GROQ_API_KEY"]) caps.push("stt");
55
- return caps;
56
- }
57
- function getLoad() {
58
- const cores = cpus().length || 1;
59
- return Math.min(1, loadavg()[0] / cores);
60
- }
61
- function getGossipKey(config) {
62
- if (config.gossipSecret) return config.gossipSecret;
63
- return null;
64
- }
65
- function buildPacket() {
66
- const config = loadPeerConfig();
67
- const payload = JSON.stringify({
68
- name: config.self.name,
69
- ts: Math.floor(Date.now() / 1e3),
70
- load: Math.round(getLoad() * 100) / 100,
71
- sessions: parseInt(process.env["_ACTIVE_SESSIONS"] ?? "0", 10),
72
- capabilities: _capabilities,
73
- version: process.env["npm_package_version"] ?? "?"
74
- });
75
- const key = getGossipKey(config) ?? Object.values(config.peers)[0]?.token ?? "default";
76
- const sig = createHmac("sha256", key).update(payload).digest("base64url").slice(0, 16);
77
- return Buffer.from(`${payload}|${sig}`);
78
- }
79
- function verifyPacket(data) {
80
- const str = data.toString("utf8");
81
- const sepIdx = str.lastIndexOf("|");
82
- if (sepIdx < 0) return null;
83
- const payload = str.slice(0, sepIdx);
84
- const sig = str.slice(sepIdx + 1);
85
- const config = loadPeerConfig();
86
- const shared = getGossipKey(config);
87
- if (shared) {
88
- const expected = createHmac("sha256", shared).update(payload).digest("base64url").slice(0, 16);
89
- if (sig === expected) {
90
- try {
91
- return JSON.parse(payload);
92
- } catch {
93
- return null;
94
- }
95
- }
96
- return null;
97
- }
98
- for (const peer of Object.values(config.peers)) {
99
- const key = peer.token;
100
- if (!key) continue;
101
- const expected = createHmac("sha256", key).update(payload).digest("base64url").slice(0, 16);
102
- if (sig === expected) {
103
- try {
104
- return JSON.parse(payload);
105
- } catch {
106
- return null;
107
- }
108
- }
109
- }
110
- return null;
111
- }
112
- function broadcast() {
113
- const config = loadPeerConfig();
114
- const packet = buildPacket();
115
- for (const [name, entry] of Object.entries(config.peers)) {
116
- _socket?.send(packet, 0, packet.length, GOSSIP_PORT, entry.host, (err) => {
117
- if (err) logTrace(TAG, `Send to ${name} (${entry.host}:${GOSSIP_PORT}) failed: ${err.message}`);
118
- });
119
- }
120
- logTrace(TAG, `Broadcast to ${Object.keys(config.peers).length} peer(s)`);
121
- const now = Date.now();
122
- for (const [, health] of peerTable) {
123
- const wasAlive = health.alive;
124
- health.alive = now - health.lastSeen < TTL_MS;
125
- if (wasAlive && !health.alive) logDebug(TAG, `PEER_OFFLINE ${health.name} (no heartbeat for ${Math.round((now - health.lastSeen) / 1e3)}s)`);
126
- }
127
- }
128
- function startGossip() {
129
- _capabilities = discoverCapabilities();
130
- logInfo(TAG, `Capabilities: [${_capabilities.join(", ")}]`);
131
- _socket = createSocket("udp4");
132
- _socket.on("message", (msg, rinfo) => {
133
- const parsed = verifyPacket(msg);
134
- if (!parsed || typeof parsed.name !== "string") return;
135
- const name = parsed.name;
136
- const config = loadPeerConfig();
137
- if (parsed.type === "ping") {
138
- const key = getGossipKey(config) ?? Object.values(config.peers)[0]?.token ?? "default";
139
- const pong = "PONG";
140
- const sig = createHmac("sha256", key).update(pong).digest("base64url").slice(0, 16);
141
- const reply = Buffer.from(`${pong}|${sig}`);
142
- _socket?.send(reply, 0, reply.length, rinfo.port, rinfo.address);
143
- return;
144
- }
145
- if (name === config.self.name) return;
146
- const existing = peerTable.get(name);
147
- const health = {
148
- name,
149
- lastSeen: Date.now(),
150
- load: parsed.load ?? 0,
151
- sessions: parsed.sessions ?? 0,
152
- capabilities: parsed.capabilities ?? [],
153
- version: parsed.version ?? "?",
154
- alive: true,
155
- host: rinfo.address,
156
- port: rinfo.port
157
- };
158
- peerTable.set(name, health);
159
- if (!existing) logDebug(TAG, `PEER_ONLINE ${name} [${health.capabilities.join(",")}] v${health.version}`);
160
- else if (!existing.alive) logDebug(TAG, `PEER_ONLINE ${name} returned [${health.capabilities.join(",")}] v${health.version}`);
161
- });
162
- _socket.on("error", (err) => {
163
- logWarn(TAG, `Socket error: ${err.message}`);
164
- });
165
- _socket.bind(GOSSIP_PORT, "0.0.0.0", () => {
166
- logInfo(TAG, `Listening on UDP :${GOSSIP_PORT}`);
167
- });
168
- setTimeout(broadcast, 2e3);
169
- _interval = setInterval(broadcast, BROADCAST_INTERVAL_MS);
170
- }
171
- function stopGossip() {
172
- if (_interval) {
173
- clearInterval(_interval);
174
- _interval = null;
175
- }
176
- if (_socket) {
177
- _socket.close();
178
- _socket = null;
179
- }
180
- }
181
- function getPeerTable(includeAll = false) {
182
- const now = Date.now();
183
- const results = [];
184
- for (const health of peerTable.values()) {
185
- health.alive = now - health.lastSeen < TTL_MS;
186
- if (includeAll || health.alive) results.push(health);
187
- }
188
- return results;
189
- }
190
- function getLocalCapabilities() {
191
- return _capabilities;
192
- }
193
- function findCapablePeer(requires) {
194
- const alive = getPeerTable().filter(
195
- (p) => requires.every((req) => p.capabilities.includes(req))
196
- );
197
- if (alive.length === 0) return null;
198
- alive.sort((a, b) => a.load - b.load);
199
- return alive[0];
200
- }
201
- function setGossipInterval(ms) {
202
- if (_interval) {
203
- clearInterval(_interval);
204
- _interval = setInterval(broadcast, ms);
205
- }
206
- }
207
- var TAG, GOSSIP_PORT, BROADCAST_INTERVAL_MS, TTL_MS, peerTable, _socket, _interval, _capabilities, startGossipListener, getAlivePeers, gossipBroadcast, stopGossipListener;
208
- var init_gossip = __esm({
209
- "src/components/peer-transport/gossip.ts"() {
210
- init_peer_config();
211
- init_logger();
212
- TAG = "gossip";
213
- GOSSIP_PORT = parseInt(process.env["GOSSIP_PORT"] ?? "5355", 10);
214
- BROADCAST_INTERVAL_MS = 6e4;
215
- TTL_MS = 18e4;
216
- peerTable = /* @__PURE__ */ new Map();
217
- _socket = null;
218
- _interval = null;
219
- _capabilities = [];
220
- startGossipListener = startGossip;
221
- getAlivePeers = getPeerTable;
222
- gossipBroadcast = broadcast;
223
- stopGossipListener = stopGossip;
224
- }
225
- });
226
-
227
- export {
228
- startGossip,
229
- stopGossip,
230
- getPeerTable,
231
- getLocalCapabilities,
232
- findCapablePeer,
233
- startGossipListener,
234
- getAlivePeers,
235
- gossipBroadcast,
236
- setGossipInterval,
237
- stopGossipListener,
238
- gossip_exports,
239
- init_gossip
240
- };
241
- //# sourceMappingURL=chunk-HT2BPTZY.js.map