abtars 0.3.3 → 0.3.4-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. package/bundle/{_registry.generated-7DRCE4V6.js → _registry.generated-ZJBAZMXN.js} +16 -15
  2. package/bundle/{_registry.generated-7DRCE4V6.js.map → _registry.generated-ZJBAZMXN.js.map} +1 -1
  3. package/bundle/abtars-browser.js +6 -5
  4. package/bundle/abtars-browser.js.map +1 -1
  5. package/bundle/abtars-cli.js +47 -39
  6. package/bundle/abtars-cli.js.map +2 -2
  7. package/bundle/abtars-restart.js +7 -7
  8. package/bundle/abtars-rss.js +2 -1
  9. package/bundle/abtars-rss.js.map +2 -2
  10. package/bundle/abtars-task.js +6 -5
  11. package/bundle/abtars-task.js.map +1 -1
  12. package/bundle/abtars-todo.js +2 -1
  13. package/bundle/abtars-todo.js.map +1 -1
  14. package/bundle/abtars.js +299 -209
  15. package/bundle/abtars.js.map +4 -4
  16. package/bundle/{acp-raw-client-AZJCEB6S.js → acp-raw-client-YTBGFN4S.js} +4 -3
  17. package/bundle/{acp-raw-client-AZJCEB6S.js.map → acp-raw-client-YTBGFN4S.js.map} +1 -1
  18. package/bundle/{action-gate-QYJL57IX.js → action-gate-YISTP773.js} +4 -3
  19. package/bundle/{action-gate-QYJL57IX.js.map → action-gate-YISTP773.js.map} +1 -1
  20. package/bundle/{agent-api-adapter-PYMNQXHE.js → agent-api-adapter-E4HWVJ32.js} +5 -4
  21. package/bundle/{agent-api-adapter-PYMNQXHE.js.map → agent-api-adapter-E4HWVJ32.js.map} +1 -1
  22. package/bundle/{agent-api-rate-limit-4GEZ4YN5.js → agent-api-rate-limit-VENFGOAD.js} +6 -5
  23. package/bundle/{agent-registry-563P4EUJ.js → agent-registry-DL7UT272.js} +9 -8
  24. package/bundle/bootstrap-V5MROD3X.js +62 -0
  25. package/bundle/bootstrap-V5MROD3X.js.map +7 -0
  26. package/bundle/{bridge-lock-transport-LXCF2IVN.js → bridge-lock-transport-BJAMHMXW.js} +6 -5
  27. package/bundle/{browser-2VZOGOGX.js → browser-PT54UWSW.js} +8 -7
  28. package/bundle/{budget-PPA7WY3D.js → budget-QNK6IIT6.js} +5 -4
  29. package/bundle/{budget-PPA7WY3D.js.map → budget-QNK6IIT6.js.map} +1 -1
  30. package/bundle/{capability-WXEA2WFK.js → capability-EKPGHQIO.js} +7 -6
  31. package/bundle/{chunk-C3EYYJN3.js → chunk-2BXXQG7P.js} +16 -4
  32. package/bundle/chunk-2BXXQG7P.js.map +7 -0
  33. package/bundle/{chunk-4PIVWXUJ.js → chunk-2ZD7VQRW.js} +2 -2
  34. package/bundle/{chunk-OY2HAK33.js → chunk-36ZEYDKZ.js} +1 -1
  35. package/bundle/chunk-36ZEYDKZ.js.map +7 -0
  36. package/bundle/{chunk-3QW2K53E.js → chunk-4IGLXZCC.js} +11 -19
  37. package/bundle/chunk-4IGLXZCC.js.map +7 -0
  38. package/bundle/{chunk-T7TAWGBX.js → chunk-52PQM4EZ.js} +2 -2
  39. package/bundle/{chunk-2RGR3LSV.js → chunk-5P5HF7IJ.js} +2 -2
  40. package/bundle/{chunk-LE23VPN3.js → chunk-63A7ZRIH.js} +4 -4
  41. package/bundle/{chunk-LE23VPN3.js.map → chunk-63A7ZRIH.js.map} +1 -1
  42. package/bundle/chunk-6IB3GVXK.js +77 -0
  43. package/bundle/chunk-6IB3GVXK.js.map +7 -0
  44. package/bundle/{chunk-OOKNHOCB.js → chunk-6S3G6GPO.js} +2 -2
  45. package/bundle/{chunk-E7MV7WFT.js → chunk-6VTHSN4V.js} +6 -6
  46. package/bundle/{chunk-NGZVJ52F.js → chunk-76YN7O3U.js} +7 -7
  47. package/bundle/{chunk-43DKPXTP.js → chunk-7LORCJCQ.js} +4 -4
  48. package/bundle/{chunk-HDOFJVFS.js → chunk-7OI46MH7.js} +3 -3
  49. package/bundle/{chunk-H2K23MOF.js → chunk-7XXISOHU.js} +21 -5
  50. package/bundle/chunk-7XXISOHU.js.map +7 -0
  51. package/bundle/{chunk-CB6S3ZRF.js → chunk-AFFW2LRY.js} +3 -3
  52. package/bundle/{chunk-TCI6FZTP.js → chunk-AHJDG6OM.js} +9 -9
  53. package/bundle/{chunk-NP72ZB7P.js → chunk-AMUJEP6L.js} +45 -45
  54. package/bundle/{chunk-NP72ZB7P.js.map → chunk-AMUJEP6L.js.map} +2 -2
  55. package/bundle/{chunk-BU7LTI2W.js → chunk-AWCO3DQ3.js} +6 -7
  56. package/bundle/chunk-AWCO3DQ3.js.map +7 -0
  57. package/bundle/{chunk-YME7NRGP.js → chunk-B2TIRDZC.js} +2 -2
  58. package/bundle/{chunk-SSCGWDIC.js → chunk-BWJ37KMW.js} +2 -2
  59. package/bundle/{chunk-ULO2PX3T.js → chunk-CCZ43JB7.js} +3 -3
  60. package/bundle/{chunk-FVUL44T4.js → chunk-CNENVY37.js} +2 -2
  61. package/bundle/{chunk-J5NOL4DB.js → chunk-DJOSXXM2.js} +2 -2
  62. package/bundle/{chunk-7RAGSHSH.js → chunk-DMDX35YT.js} +12 -10
  63. package/bundle/chunk-DMDX35YT.js.map +7 -0
  64. package/bundle/{chunk-DNDYD5SL.js → chunk-E7DZYCSF.js} +3 -3
  65. package/bundle/{chunk-M6Q3IQ4H.js → chunk-FF2F7ENH.js} +250 -118
  66. package/bundle/chunk-FF2F7ENH.js.map +7 -0
  67. package/bundle/{chunk-GCFIK6OB.js → chunk-FSGICOCX.js} +21 -21
  68. package/bundle/{chunk-IXKQ4JMX.js → chunk-GFAJSPMD.js} +33 -17
  69. package/bundle/chunk-GFAJSPMD.js.map +7 -0
  70. package/bundle/{chunk-FJF42RZY.js → chunk-GHRLO2UL.js} +3 -3
  71. package/bundle/{chunk-3LQOJVTB.js → chunk-HFOCNYEO.js} +1842 -1220
  72. package/bundle/{chunk-3LQOJVTB.js.map → chunk-HFOCNYEO.js.map} +4 -4
  73. package/bundle/{chunk-7WHXTCVD.js → chunk-HWFN7JGU.js} +2 -2
  74. package/bundle/{chunk-KBPVJGD7.js → chunk-IXGDDDAB.js} +3 -3
  75. package/bundle/chunk-JHLKEUHE.js +37 -0
  76. package/bundle/chunk-JHLKEUHE.js.map +7 -0
  77. package/bundle/{chunk-YEOZN5IE.js → chunk-JRGEEGZF.js} +2 -2
  78. package/bundle/{chunk-56D3Y44D.js → chunk-KLG4SCF7.js} +10 -10
  79. package/bundle/{chunk-ASYX43OU.js → chunk-LB43Q7G6.js} +26 -26
  80. package/bundle/{chunk-TVSPVZTX.js → chunk-LN5MNDSA.js} +3 -3
  81. package/bundle/{chunk-RJX45XIC.js → chunk-LPF2HELD.js} +9 -4
  82. package/bundle/chunk-LPF2HELD.js.map +7 -0
  83. package/bundle/{chunk-72T2Q7IG.js → chunk-MJACYH7A.js} +270 -282
  84. package/bundle/chunk-MJACYH7A.js.map +7 -0
  85. package/bundle/{chunk-SESM4GBM.js → chunk-MPQ2PJQX.js} +52 -25
  86. package/bundle/chunk-MPQ2PJQX.js.map +7 -0
  87. package/bundle/{chunk-FIAVVKGN.js → chunk-MTE32OQH.js} +3 -3
  88. package/bundle/{chunk-MV5KOWOR.js → chunk-N3Q3TASM.js} +7 -7
  89. package/bundle/{chunk-IQKADER4.js → chunk-O4YBJS2K.js} +2 -2
  90. package/bundle/{chunk-VJATH7AN.js → chunk-OOUCUCUW.js} +9 -8
  91. package/bundle/chunk-OOUCUCUW.js.map +7 -0
  92. package/bundle/{chunk-5V4VHKEA.js → chunk-OT6HLPEA.js} +3 -3
  93. package/bundle/{chunk-V6CV3QPH.js → chunk-OWPQIBAO.js} +2 -2
  94. package/bundle/{chunk-EDZGF6BC.js → chunk-QJPDBJDP.js} +11 -4
  95. package/bundle/chunk-QJPDBJDP.js.map +7 -0
  96. package/bundle/{chunk-N5VROZ7A.js → chunk-QMP2KC4W.js} +5 -5
  97. package/bundle/{chunk-4HNCOQSK.js → chunk-QOGZ7BFL.js} +7 -7
  98. package/bundle/{chunk-2LKQV2ND.js → chunk-R23FHZRY.js} +3 -3
  99. package/bundle/{chunk-SXNY6HC4.js → chunk-R4GYWVCR.js} +6 -6
  100. package/bundle/chunk-R4GYWVCR.js.map +7 -0
  101. package/bundle/{chunk-S7ZIGIR5.js → chunk-R76K6L6H.js} +27 -27
  102. package/bundle/{chunk-S7ZIGIR5.js.map → chunk-R76K6L6H.js.map} +1 -1
  103. package/bundle/{chunk-TY26WMQY.js → chunk-RCWQ34QR.js} +2 -2
  104. package/bundle/{chunk-MQJG7OJX.js → chunk-RJ2OUNFU.js} +38 -36
  105. package/bundle/chunk-RJ2OUNFU.js.map +7 -0
  106. package/bundle/{chunk-S6HEHCCG.js → chunk-RO3TAYBR.js} +83 -46
  107. package/bundle/chunk-RO3TAYBR.js.map +7 -0
  108. package/bundle/{chunk-ZOCEBV62.js → chunk-UU3RLJSD.js} +3 -3
  109. package/bundle/{chunk-P5O6QZDC.js → chunk-V7Y2LFO4.js} +10 -6
  110. package/bundle/chunk-V7Y2LFO4.js.map +7 -0
  111. package/bundle/{chunk-WP7FZHMI.js → chunk-W2PSVV2T.js} +2 -2
  112. package/bundle/{chunk-V2QIAXWZ.js → chunk-WEGFRA6G.js} +3 -3
  113. package/bundle/{chunk-ZY6DH2S4.js → chunk-WTIGZO3N.js} +80 -70
  114. package/bundle/chunk-WTIGZO3N.js.map +7 -0
  115. package/bundle/{chunk-O4GKI3Q3.js → chunk-X7DLKIQM.js} +4 -4
  116. package/bundle/{chunk-BNBC4T45.js → chunk-XZ4ZBDM5.js} +3 -3
  117. package/bundle/{chunk-24V4A6RP.js → chunk-YI2KSYB4.js} +4 -4
  118. package/bundle/{chunk-37EX63K4.js → chunk-YWHJJHJ2.js} +6998 -3621
  119. package/bundle/chunk-YWHJJHJ2.js.map +7 -0
  120. package/bundle/{chunk-IK4R3RBZ.js → chunk-YZCOA4DC.js} +3 -3
  121. package/bundle/{chunk-2FZJDMAF.js → chunk-ZGNSCJWH.js} +10 -10
  122. package/bundle/{chunk-W726UGI6.js → chunk-ZKMKAO75.js} +3 -3
  123. package/bundle/{chunk-WGWM4IZM.js → chunk-ZT5ZBGWS.js} +4 -4
  124. package/bundle/{chunk-WGWM4IZM.js.map → chunk-ZT5ZBGWS.js.map} +1 -1
  125. package/bundle/{commands-XXFU2ZF7.js → commands-2JQ5YTJX.js} +20 -20
  126. package/bundle/{config-EWDZ234X.js → config-ZEWIM5Z2.js} +8 -7
  127. package/bundle/{config-show-6J33O4TE.js → config-show-WBJPQPRD.js} +5 -5
  128. package/bundle/{context-OCS7HLJP.js → context-V75QNXB5.js} +5 -2
  129. package/bundle/{context-OCS7HLJP.js.map → context-V75QNXB5.js.map} +1 -1
  130. package/bundle/{daemon-LTDAXNA2.js → daemon-W7VQOSZC.js} +7 -7
  131. package/bundle/{delegation-tools-YDTWQMZD.js → delegation-tools-VGTRFQBF.js} +13 -11
  132. package/bundle/{registry-client-VN2MM2HI.js → deploy-5AGIULM2.js} +10 -6
  133. package/bundle/{deploy-lib-import-RGZJ3CGC.js → deploy-lib-import-ZBDYORN4.js} +5 -3
  134. package/bundle/{deps-PHSLIA77.js → deps-VB3S3RLF.js} +21 -19
  135. package/bundle/deps-VB3S3RLF.js.map +7 -0
  136. package/bundle/{direct-api-transport-OAKYQBJR.js → direct-api-transport-YSROTC35.js} +30 -28
  137. package/bundle/direct-api-transport-YSROTC35.js.map +7 -0
  138. package/bundle/{discord-adapter-WUNYPTDE.js → discord-adapter-LKBSIFLV.js} +26 -26
  139. package/bundle/{dist-7HEHHQI2.js → dist-KMK7TZGN.js} +376 -348
  140. package/bundle/dist-KMK7TZGN.js.map +7 -0
  141. package/bundle/{dns-wakeup-F55ALHXJ.js → dns-wakeup-KIURCCFJ.js} +4 -3
  142. package/bundle/{dns-wakeup-F55ALHXJ.js.map → dns-wakeup-KIURCCFJ.js.map} +1 -1
  143. package/bundle/{doctor-probes-3SLIUGKS.js → doctor-probes-46UKIROK.js} +4 -3
  144. package/bundle/{env-schema-MSDP2YBO.js → env-schema-YGHCKX5B.js} +5 -4
  145. package/bundle/{gossip-CS3G3447.js → gossip-VSEY2HSE.js} +7 -6
  146. package/bundle/{guardrails-24XK2COI.js → guardrails-U7M6H2GE.js} +6 -5
  147. package/bundle/{health-check-FRUNRVNQ.js → health-check-ASRLUJE5.js} +6 -2
  148. package/bundle/health-check-ASRLUJE5.js.map +7 -0
  149. package/bundle/{heartbeat-system-G4IFQXT6.js → heartbeat-system-MUXLT4E6.js} +7 -6
  150. package/bundle/{heartbeat-tier3-3ZO3EVXP.js → heartbeat-tier3-636ZMM4E.js} +45 -44
  151. package/bundle/heartbeat-tier3-636ZMM4E.js.map +7 -0
  152. package/bundle/{hook-system-X6INNJGV.js → hook-system-Z4XD6IM5.js} +5 -4
  153. package/bundle/{hotskills-6FQYTJIO.js → hotskills-AOUWVTQB.js} +7 -6
  154. package/bundle/{install-ZAHTZ5M5.js → install-3GGZUN22.js} +23 -20
  155. package/bundle/install-3GGZUN22.js.map +7 -0
  156. package/bundle/{install-manifest-QX7KVDCA.js → install-manifest-624KOB4S.js} +4 -3
  157. package/bundle/{install-manifest-QX7KVDCA.js.map → install-manifest-624KOB4S.js.map} +1 -1
  158. package/bundle/{irc-adapter-IEJQKKJF.js → irc-adapter-SA7GLJGR.js} +5 -4
  159. package/bundle/{irc-adapter-IEJQKKJF.js.map → irc-adapter-SA7GLJGR.js.map} +1 -1
  160. package/bundle/{irc-config-TTWNYFLH.js → irc-config-PG4X2I4M.js} +6 -5
  161. package/bundle/{irc-config-TTWNYFLH.js.map → irc-config-PG4X2I4M.js.map} +1 -1
  162. package/bundle/{kanban-board-J6RO3ZU7.js → kanban-board-4AI5Z6B5.js} +7 -5
  163. package/bundle/{kanban-channel-5EIXBFSA.js → kanban-channel-JMBYWGWD.js} +8 -6
  164. package/bundle/{lazy-require-V6EFUATC.js → lazy-require-GURNBC3C.js} +11 -6
  165. package/bundle/{logger-Y3VILPRH.js → logger-UQJPZMYV.js} +4 -3
  166. package/bundle/{logs-YS3GDURO.js → logs-2WTDLMB5.js} +5 -5
  167. package/bundle/{main-chat-YLZDNQPO.js → main-chat-EID5Y6H2.js} +6 -5
  168. package/bundle/{master-user-Z4M7KCJE.js → master-user-TKA7M2GL.js} +7 -6
  169. package/bundle/{media-utils-P6RZ2K3U.js → media-utils-X3UN342B.js} +44 -43
  170. package/bundle/{media-utils-P6RZ2K3U.js.map → media-utils-X3UN342B.js.map} +2 -2
  171. package/bundle/{message-pipeline-MHEBDJLH.js → message-pipeline-TAWXNEVS.js} +20 -20
  172. package/bundle/meta.json +9264 -8575
  173. package/bundle/{migrate-layout-RJJQLVGR.js → migrate-layout-KEAIIN26.js} +8 -4
  174. package/bundle/migrate-layout-KEAIIN26.js.map +7 -0
  175. package/bundle/{nerve-VZNMFDGY.js → nerve-TC34H4EL.js} +5 -4
  176. package/bundle/{notification-VV2OR6NW.js → notification-JQNVGICN.js} +8 -7
  177. package/bundle/{openrouter-credits-LXC7P4G6.js → openrouter-credits-5Q3EYWE5.js} +5 -4
  178. package/bundle/{openrouter-credits-LXC7P4G6.js.map → openrouter-credits-5Q3EYWE5.js.map} +1 -1
  179. package/bundle/{orc-KC4USP55.js → orc-74Z62W7B.js} +4 -4
  180. package/bundle/{orc-tools-CHRSXSAS.js → orc-tools-GME3DKIN.js} +5 -4
  181. package/bundle/{paths-EDK6KWHG.js → paths-BAUNPLNJ.js} +6 -2
  182. package/bundle/{paths-RZF6WDMG.js → paths-MZC2KU2C.js} +3 -2
  183. package/bundle/{peer-auth-SRONOLNG.js → peer-auth-VRO3JYL5.js} +9 -8
  184. package/bundle/{peer-client-VOF77T6C.js → peer-client-WLK5GZQS.js} +9 -8
  185. package/bundle/{peer-client-VOF77T6C.js.map → peer-client-WLK5GZQS.js.map} +1 -1
  186. package/bundle/{peer-config-FRWLEYQ5.js → peer-config-24WILLCJ.js} +6 -5
  187. package/bundle/{peer-jwt-XY3XRIA2.js → peer-jwt-ZR6RF3XM.js} +6 -5
  188. package/bundle/{peer-transport-UBBXTDRP.js → peer-transport-BK5VHI2M.js} +8 -7
  189. package/bundle/{phase-transport-4NQHZX75.js → phase-transport-7QJM7J6V.js} +18 -16
  190. package/bundle/{reconcile-2EUXJ6W5.js → reconcile-7N7OE2GU.js} +5 -4
  191. package/bundle/{reconciler-FFQGV4DO.js → reconciler-7LOOUK43.js} +13 -11
  192. package/bundle/{reconciler-FFQGV4DO.js.map → reconciler-7LOOUK43.js.map} +1 -1
  193. package/bundle/{restore-NFDE2RG6.js → restore-MENZ3I3K.js} +13 -9
  194. package/bundle/{restore-NFDE2RG6.js.map → restore-MENZ3I3K.js.map} +3 -3
  195. package/bundle/{rollback-MVZ53XS4.js → rollback-JOHY6KWW.js} +5 -5
  196. package/bundle/{chunk-SKY6656M.js → sandbox-runtime-T7RF4WJD.js} +11 -28
  197. package/bundle/{chunk-SKY6656M.js.map → sandbox-runtime-T7RF4WJD.js.map} +1 -1
  198. package/bundle/{self-healer-utils-KD6LV63S.js → self-healer-utils-OR2N6RLD.js} +5 -4
  199. package/bundle/{self-healer-utils-KD6LV63S.js.map → self-healer-utils-OR2N6RLD.js.map} +1 -1
  200. package/bundle/{sha-tracker-2DB4R2TW.js → sha-tracker-BXOLWZJL.js} +5 -4
  201. package/bundle/{skill-session-BPDVA6ZG.js → skill-session-H6EQ4NGN.js} +5 -4
  202. package/bundle/{skill-session-BPDVA6ZG.js.map → skill-session-H6EQ4NGN.js.map} +1 -1
  203. package/bundle/{skill-stats-TPD2NROA.js → skill-stats-7O777ZSZ.js} +6 -5
  204. package/bundle/{skill-watcher-D7QYYYON.js → skill-watcher-ZGLTDPG5.js} +6 -5
  205. package/bundle/{sleep-GH6DLBJJ.js → sleep-3LFZH727.js} +10 -9
  206. package/bundle/{soul-bundle-GXLMDBCC.js → soul-bundle-RQ2YQMJW.js} +10 -9
  207. package/bundle/{spin-4DBYHS3E.js → spin-76K4R6FK.js} +12 -10
  208. package/bundle/{spin-notifications-IKYJPER5.js → spin-notifications-LD46B4K5.js} +7 -5
  209. package/bundle/{spin-notifications-IKYJPER5.js.map → spin-notifications-LD46B4K5.js.map} +1 -1
  210. package/bundle/{spin-types-PLJH3SIK.js → spin-types-MOKTZXGB.js} +5 -4
  211. package/bundle/{src-SUFZ27S5.js → src-6BTCMOD3.js} +4 -4
  212. package/bundle/{sse-parser-anthropic-U7ILHOY5.js → sse-parser-anthropic-NV2CGBIT.js} +5 -4
  213. package/bundle/{sse-parser-anthropic-U7ILHOY5.js.map → sse-parser-anthropic-NV2CGBIT.js.map} +1 -1
  214. package/bundle/{sse-parser-responses-OI73R3AH.js → sse-parser-responses-FC3PFHQ5.js} +5 -4
  215. package/bundle/{sse-parser-responses-OI73R3AH.js.map → sse-parser-responses-FC3PFHQ5.js.map} +1 -1
  216. package/bundle/{ssrf-guard-6GP4QYVA.js → ssrf-guard-E2YPLW6G.js} +5 -4
  217. package/bundle/{ssrf-guard-6GP4QYVA.js.map → ssrf-guard-E2YPLW6G.js.map} +1 -1
  218. package/bundle/{start-JT2BPMSW.js → start-HPO5LYJP.js} +5 -5
  219. package/bundle/start-HPO5LYJP.js.map +7 -0
  220. package/bundle/{stt-KD3AABKG.js → stt-UE7EOYD7.js} +6 -5
  221. package/bundle/{subagent-runtime-LVECAUPV.js → subagent-runtime-4X3UHF4H.js} +6 -5
  222. package/bundle/system-status-PLPWV4RF.js +346 -0
  223. package/bundle/system-status-PLPWV4RF.js.map +7 -0
  224. package/bundle/{task-store-2XRDM3AW.js → task-store-RAFMDQ7N.js} +6 -5
  225. package/bundle/{telegram-adapter-UJ3RYYV6.js → telegram-adapter-PPXKTGOP.js} +35 -35
  226. package/bundle/{tool-registry-YU6WBXPA.js → tool-registry-NKIPNJZ5.js} +25 -23
  227. package/bundle/{tool-sandbox-RNNPDR5M.js → tool-sandbox-DQCP3UTU.js} +6 -5
  228. package/bundle/{transport-config-OK3MZPJK.js → transport-config-SF6GBV47.js} +9 -8
  229. package/bundle/{update-ENNPRW7Y.js → update-QOOGMFSJ.js} +6 -6
  230. package/bundle/{update-check-SJB6GV3A.js → update-check-LPZG3K5P.js} +3 -2
  231. package/bundle/{update-check-SJB6GV3A.js.map → update-check-LPZG3K5P.js.map} +1 -1
  232. package/bundle/{usage-tracker-HRSGC7QC.js → usage-tracker-TBDM4KE6.js} +2 -2
  233. package/bundle/{user-registry-6PUJJ5J2.js → user-registry-OYJVAHDD.js} +6 -5
  234. package/bundle/{wrapper-WLHLG4MI.js → wrapper-W66YICNZ.js} +3 -3
  235. package/bundle/{ws-peer-client-WHW3RJTD.js → ws-peer-client-G5QHOF6K.js} +15 -14
  236. package/bundle/{ws-peer-client-WHW3RJTD.js.map → ws-peer-client-G5QHOF6K.js.map} +2 -2
  237. package/package.json +3 -7
  238. package/scripts/emergency-deploy.sh +11 -8
  239. package/scripts/emergency-update.sh +156 -23
  240. package/templates/config/.env +1 -1
  241. package/templates/config/models.json +13 -0
  242. package/bundle/chunk-37EX63K4.js.map +0 -7
  243. package/bundle/chunk-3QW2K53E.js.map +0 -7
  244. package/bundle/chunk-72T2Q7IG.js.map +0 -7
  245. package/bundle/chunk-7RAGSHSH.js.map +0 -7
  246. package/bundle/chunk-BU7LTI2W.js.map +0 -7
  247. package/bundle/chunk-C3EYYJN3.js.map +0 -7
  248. package/bundle/chunk-CAOIIVFP.js +0 -110
  249. package/bundle/chunk-CAOIIVFP.js.map +0 -7
  250. package/bundle/chunk-EDZGF6BC.js.map +0 -7
  251. package/bundle/chunk-H2K23MOF.js.map +0 -7
  252. package/bundle/chunk-HAZHNBBY.js +0 -156
  253. package/bundle/chunk-HAZHNBBY.js.map +0 -7
  254. package/bundle/chunk-IXKQ4JMX.js.map +0 -7
  255. package/bundle/chunk-JAJ3DUQ2.js +0 -30
  256. package/bundle/chunk-JAJ3DUQ2.js.map +0 -7
  257. package/bundle/chunk-KMFR5AVY.js +0 -45
  258. package/bundle/chunk-KMFR5AVY.js.map +0 -7
  259. package/bundle/chunk-M6Q3IQ4H.js.map +0 -7
  260. package/bundle/chunk-MQJG7OJX.js.map +0 -7
  261. package/bundle/chunk-OY2HAK33.js.map +0 -7
  262. package/bundle/chunk-P5O6QZDC.js.map +0 -7
  263. package/bundle/chunk-RJX45XIC.js.map +0 -7
  264. package/bundle/chunk-S6HEHCCG.js.map +0 -7
  265. package/bundle/chunk-SESM4GBM.js.map +0 -7
  266. package/bundle/chunk-SXNY6HC4.js.map +0 -7
  267. package/bundle/chunk-VJATH7AN.js.map +0 -7
  268. package/bundle/chunk-ZY6DH2S4.js.map +0 -7
  269. package/bundle/deps-PHSLIA77.js.map +0 -7
  270. package/bundle/direct-api-transport-OAKYQBJR.js.map +0 -7
  271. package/bundle/dist-7HEHHQI2.js.map +0 -7
  272. package/bundle/health-check-FRUNRVNQ.js.map +0 -7
  273. package/bundle/heartbeat-tier3-3ZO3EVXP.js.map +0 -7
  274. package/bundle/install-ZAHTZ5M5.js.map +0 -7
  275. package/bundle/migrate-layout-RJJQLVGR.js.map +0 -7
  276. package/bundle/phase-config-V4XETN5F.js +0 -18
  277. package/bundle/sandbox-runtime-WHACQLLN.js +0 -22
  278. package/bundle/start-JT2BPMSW.js.map +0 -7
  279. package/bundle/system-status-XXJWTVJN.js +0 -243
  280. package/bundle/system-status-XXJWTVJN.js.map +0 -7
  281. package/bundle/user-registry-6PUJJ5J2.js.map +0 -7
  282. package/bundle/wrapper-WLHLG4MI.js.map +0 -7
  283. /package/bundle/{agent-api-rate-limit-4GEZ4YN5.js.map → agent-api-rate-limit-VENFGOAD.js.map} +0 -0
  284. /package/bundle/{agent-registry-563P4EUJ.js.map → agent-registry-DL7UT272.js.map} +0 -0
  285. /package/bundle/{bridge-lock-transport-LXCF2IVN.js.map → bridge-lock-transport-BJAMHMXW.js.map} +0 -0
  286. /package/bundle/{browser-2VZOGOGX.js.map → browser-PT54UWSW.js.map} +0 -0
  287. /package/bundle/{capability-WXEA2WFK.js.map → capability-EKPGHQIO.js.map} +0 -0
  288. /package/bundle/{chunk-4PIVWXUJ.js.map → chunk-2ZD7VQRW.js.map} +0 -0
  289. /package/bundle/{chunk-T7TAWGBX.js.map → chunk-52PQM4EZ.js.map} +0 -0
  290. /package/bundle/{chunk-2RGR3LSV.js.map → chunk-5P5HF7IJ.js.map} +0 -0
  291. /package/bundle/{chunk-OOKNHOCB.js.map → chunk-6S3G6GPO.js.map} +0 -0
  292. /package/bundle/{chunk-E7MV7WFT.js.map → chunk-6VTHSN4V.js.map} +0 -0
  293. /package/bundle/{chunk-NGZVJ52F.js.map → chunk-76YN7O3U.js.map} +0 -0
  294. /package/bundle/{chunk-43DKPXTP.js.map → chunk-7LORCJCQ.js.map} +0 -0
  295. /package/bundle/{chunk-HDOFJVFS.js.map → chunk-7OI46MH7.js.map} +0 -0
  296. /package/bundle/{chunk-CB6S3ZRF.js.map → chunk-AFFW2LRY.js.map} +0 -0
  297. /package/bundle/{chunk-TCI6FZTP.js.map → chunk-AHJDG6OM.js.map} +0 -0
  298. /package/bundle/{chunk-YME7NRGP.js.map → chunk-B2TIRDZC.js.map} +0 -0
  299. /package/bundle/{chunk-SSCGWDIC.js.map → chunk-BWJ37KMW.js.map} +0 -0
  300. /package/bundle/{chunk-ULO2PX3T.js.map → chunk-CCZ43JB7.js.map} +0 -0
  301. /package/bundle/{chunk-FVUL44T4.js.map → chunk-CNENVY37.js.map} +0 -0
  302. /package/bundle/{chunk-J5NOL4DB.js.map → chunk-DJOSXXM2.js.map} +0 -0
  303. /package/bundle/{chunk-DNDYD5SL.js.map → chunk-E7DZYCSF.js.map} +0 -0
  304. /package/bundle/{chunk-GCFIK6OB.js.map → chunk-FSGICOCX.js.map} +0 -0
  305. /package/bundle/{chunk-FJF42RZY.js.map → chunk-GHRLO2UL.js.map} +0 -0
  306. /package/bundle/{chunk-7WHXTCVD.js.map → chunk-HWFN7JGU.js.map} +0 -0
  307. /package/bundle/{chunk-KBPVJGD7.js.map → chunk-IXGDDDAB.js.map} +0 -0
  308. /package/bundle/{chunk-YEOZN5IE.js.map → chunk-JRGEEGZF.js.map} +0 -0
  309. /package/bundle/{chunk-56D3Y44D.js.map → chunk-KLG4SCF7.js.map} +0 -0
  310. /package/bundle/{chunk-ASYX43OU.js.map → chunk-LB43Q7G6.js.map} +0 -0
  311. /package/bundle/{chunk-TVSPVZTX.js.map → chunk-LN5MNDSA.js.map} +0 -0
  312. /package/bundle/{chunk-FIAVVKGN.js.map → chunk-MTE32OQH.js.map} +0 -0
  313. /package/bundle/{chunk-MV5KOWOR.js.map → chunk-N3Q3TASM.js.map} +0 -0
  314. /package/bundle/{chunk-IQKADER4.js.map → chunk-O4YBJS2K.js.map} +0 -0
  315. /package/bundle/{chunk-5V4VHKEA.js.map → chunk-OT6HLPEA.js.map} +0 -0
  316. /package/bundle/{chunk-V6CV3QPH.js.map → chunk-OWPQIBAO.js.map} +0 -0
  317. /package/bundle/{chunk-N5VROZ7A.js.map → chunk-QMP2KC4W.js.map} +0 -0
  318. /package/bundle/{chunk-4HNCOQSK.js.map → chunk-QOGZ7BFL.js.map} +0 -0
  319. /package/bundle/{chunk-2LKQV2ND.js.map → chunk-R23FHZRY.js.map} +0 -0
  320. /package/bundle/{chunk-TY26WMQY.js.map → chunk-RCWQ34QR.js.map} +0 -0
  321. /package/bundle/{chunk-ZOCEBV62.js.map → chunk-UU3RLJSD.js.map} +0 -0
  322. /package/bundle/{chunk-WP7FZHMI.js.map → chunk-W2PSVV2T.js.map} +0 -0
  323. /package/bundle/{chunk-V2QIAXWZ.js.map → chunk-WEGFRA6G.js.map} +0 -0
  324. /package/bundle/{chunk-O4GKI3Q3.js.map → chunk-X7DLKIQM.js.map} +0 -0
  325. /package/bundle/{chunk-BNBC4T45.js.map → chunk-XZ4ZBDM5.js.map} +0 -0
  326. /package/bundle/{chunk-24V4A6RP.js.map → chunk-YI2KSYB4.js.map} +0 -0
  327. /package/bundle/{chunk-IK4R3RBZ.js.map → chunk-YZCOA4DC.js.map} +0 -0
  328. /package/bundle/{chunk-2FZJDMAF.js.map → chunk-ZGNSCJWH.js.map} +0 -0
  329. /package/bundle/{chunk-W726UGI6.js.map → chunk-ZKMKAO75.js.map} +0 -0
  330. /package/bundle/{commands-XXFU2ZF7.js.map → commands-2JQ5YTJX.js.map} +0 -0
  331. /package/bundle/{config-EWDZ234X.js.map → config-ZEWIM5Z2.js.map} +0 -0
  332. /package/bundle/{config-show-6J33O4TE.js.map → config-show-WBJPQPRD.js.map} +0 -0
  333. /package/bundle/{daemon-LTDAXNA2.js.map → daemon-W7VQOSZC.js.map} +0 -0
  334. /package/bundle/{delegation-tools-YDTWQMZD.js.map → delegation-tools-VGTRFQBF.js.map} +0 -0
  335. /package/bundle/{deploy-lib-import-RGZJ3CGC.js.map → deploy-5AGIULM2.js.map} +0 -0
  336. /package/bundle/{doctor-probes-3SLIUGKS.js.map → deploy-lib-import-ZBDYORN4.js.map} +0 -0
  337. /package/bundle/{discord-adapter-WUNYPTDE.js.map → discord-adapter-LKBSIFLV.js.map} +0 -0
  338. /package/bundle/{env-schema-MSDP2YBO.js.map → doctor-probes-46UKIROK.js.map} +0 -0
  339. /package/bundle/{gossip-CS3G3447.js.map → env-schema-YGHCKX5B.js.map} +0 -0
  340. /package/bundle/{guardrails-24XK2COI.js.map → gossip-VSEY2HSE.js.map} +0 -0
  341. /package/bundle/{heartbeat-system-G4IFQXT6.js.map → guardrails-U7M6H2GE.js.map} +0 -0
  342. /package/bundle/{hook-system-X6INNJGV.js.map → heartbeat-system-MUXLT4E6.js.map} +0 -0
  343. /package/bundle/{hotskills-6FQYTJIO.js.map → hook-system-Z4XD6IM5.js.map} +0 -0
  344. /package/bundle/{kanban-board-J6RO3ZU7.js.map → hotskills-AOUWVTQB.js.map} +0 -0
  345. /package/bundle/{kanban-channel-5EIXBFSA.js.map → kanban-board-4AI5Z6B5.js.map} +0 -0
  346. /package/bundle/{lazy-require-V6EFUATC.js.map → kanban-channel-JMBYWGWD.js.map} +0 -0
  347. /package/bundle/{logger-Y3VILPRH.js.map → lazy-require-GURNBC3C.js.map} +0 -0
  348. /package/bundle/{main-chat-YLZDNQPO.js.map → logger-UQJPZMYV.js.map} +0 -0
  349. /package/bundle/{logs-YS3GDURO.js.map → logs-2WTDLMB5.js.map} +0 -0
  350. /package/bundle/{master-user-Z4M7KCJE.js.map → main-chat-EID5Y6H2.js.map} +0 -0
  351. /package/bundle/{message-pipeline-MHEBDJLH.js.map → master-user-TKA7M2GL.js.map} +0 -0
  352. /package/bundle/{nerve-VZNMFDGY.js.map → message-pipeline-TAWXNEVS.js.map} +0 -0
  353. /package/bundle/{notification-VV2OR6NW.js.map → nerve-TC34H4EL.js.map} +0 -0
  354. /package/bundle/{orc-tools-CHRSXSAS.js.map → notification-JQNVGICN.js.map} +0 -0
  355. /package/bundle/{orc-KC4USP55.js.map → orc-74Z62W7B.js.map} +0 -0
  356. /package/bundle/{paths-EDK6KWHG.js.map → orc-tools-GME3DKIN.js.map} +0 -0
  357. /package/bundle/{paths-RZF6WDMG.js.map → paths-BAUNPLNJ.js.map} +0 -0
  358. /package/bundle/{peer-auth-SRONOLNG.js.map → paths-MZC2KU2C.js.map} +0 -0
  359. /package/bundle/{peer-config-FRWLEYQ5.js.map → peer-auth-VRO3JYL5.js.map} +0 -0
  360. /package/bundle/{peer-jwt-XY3XRIA2.js.map → peer-config-24WILLCJ.js.map} +0 -0
  361. /package/bundle/{peer-transport-UBBXTDRP.js.map → peer-jwt-ZR6RF3XM.js.map} +0 -0
  362. /package/bundle/{phase-config-V4XETN5F.js.map → peer-transport-BK5VHI2M.js.map} +0 -0
  363. /package/bundle/{phase-transport-4NQHZX75.js.map → phase-transport-7QJM7J6V.js.map} +0 -0
  364. /package/bundle/{reconcile-2EUXJ6W5.js.map → reconcile-7N7OE2GU.js.map} +0 -0
  365. /package/bundle/{registry-client-VN2MM2HI.js.map → rollback-JOHY6KWW.js.map} +0 -0
  366. /package/bundle/{rollback-MVZ53XS4.js.map → sha-tracker-BXOLWZJL.js.map} +0 -0
  367. /package/bundle/{sandbox-runtime-WHACQLLN.js.map → skill-stats-7O777ZSZ.js.map} +0 -0
  368. /package/bundle/{sha-tracker-2DB4R2TW.js.map → skill-watcher-ZGLTDPG5.js.map} +0 -0
  369. /package/bundle/{skill-stats-TPD2NROA.js.map → sleep-3LFZH727.js.map} +0 -0
  370. /package/bundle/{skill-watcher-D7QYYYON.js.map → soul-bundle-RQ2YQMJW.js.map} +0 -0
  371. /package/bundle/{sleep-GH6DLBJJ.js.map → spin-76K4R6FK.js.map} +0 -0
  372. /package/bundle/{soul-bundle-GXLMDBCC.js.map → spin-types-MOKTZXGB.js.map} +0 -0
  373. /package/bundle/{spin-4DBYHS3E.js.map → src-6BTCMOD3.js.map} +0 -0
  374. /package/bundle/{spin-types-PLJH3SIK.js.map → stt-UE7EOYD7.js.map} +0 -0
  375. /package/bundle/{src-SUFZ27S5.js.map → subagent-runtime-4X3UHF4H.js.map} +0 -0
  376. /package/bundle/{stt-KD3AABKG.js.map → task-store-RAFMDQ7N.js.map} +0 -0
  377. /package/bundle/{telegram-adapter-UJ3RYYV6.js.map → telegram-adapter-PPXKTGOP.js.map} +0 -0
  378. /package/bundle/{subagent-runtime-LVECAUPV.js.map → tool-registry-NKIPNJZ5.js.map} +0 -0
  379. /package/bundle/{task-store-2XRDM3AW.js.map → tool-sandbox-DQCP3UTU.js.map} +0 -0
  380. /package/bundle/{tool-registry-YU6WBXPA.js.map → transport-config-SF6GBV47.js.map} +0 -0
  381. /package/bundle/{tool-sandbox-RNNPDR5M.js.map → update-QOOGMFSJ.js.map} +0 -0
  382. /package/bundle/{transport-config-OK3MZPJK.js.map → usage-tracker-TBDM4KE6.js.map} +0 -0
  383. /package/bundle/{update-ENNPRW7Y.js.map → user-registry-OYJVAHDD.js.map} +0 -0
  384. /package/bundle/{usage-tracker-HRSGC7QC.js.map → wrapper-W66YICNZ.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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\n/** #613: Prune .trash/ entries older than 7 days. */\nexport function createSkillTrashPruneTask(): HeartbeatTask {\n const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;\n let counter = 0;\n return {\n name: \"skill-trash-prune\",\n execute: async () => {\n counter++;\n if (counter % 72 !== 0) return; // ~hourly (72 ticks \u00D7 50s)\n const { existsSync, readdirSync, rmSync, statSync } = await import(\"node:fs\");\n const { join } = await import(\"node:path\");\n const { abtarsHome } = await import(\"../paths.js\");\n const trashPath = join(abtarsHome(), \"skills\", \".trash\");\n if (!existsSync(trashPath)) return;\n const now = Date.now();\n for (const entry of readdirSync(trashPath)) {\n try {\n const full = join(trashPath, entry);\n const stat = statSync(full);\n if (now - stat.mtimeMs > SEVEN_DAYS_MS) {\n rmSync(full, { recursive: true });\n logInfo(\"skill-trash-prune\", `Pruned: ${entry}`);\n }\n } catch (err) { logAndSwallow(TAG, \"prune entry\", err); }\n }\n },\n };\n}\n\n/** #681: Rotate audit.jsonl when > 10MB, prune files older than 30 days. */\nexport function createAuditRotationTask(): HeartbeatTask {\n const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000;\n let counter = 0;\n return {\n name: \"audit-rotation\",\n execute: async () => {\n counter++;\n if (counter % 72 !== 0) return; // ~hourly\n const { existsSync, statSync, renameSync, readdirSync, unlinkSync } = await import(\"node:fs\");\n const { join } = await import(\"node:path\");\n const { abtarsHome } = await import(\"../paths.js\");\n const logsDir = join(abtarsHome(), \"logs\");\n const auditPath = join(logsDir, \"audit.jsonl\");\n if (!existsSync(auditPath)) return;\n try {\n const stat = statSync(auditPath);\n if (stat.size > 10 * 1024 * 1024) {\n const date = new Date().toISOString().slice(0, 10);\n renameSync(auditPath, join(logsDir, `audit-${date}.jsonl`));\n logInfo(\"audit-rotation\", `Rotated audit.jsonl (${(stat.size / 1024 / 1024).toFixed(1)}MB)`);\n }\n } catch (err) { logAndSwallow(TAG, \"audit rotate\", err); }\n // Prune old audit files\n const now = Date.now();\n try {\n for (const f of readdirSync(logsDir)) {\n if (!f.startsWith(\"audit-\") || !f.endsWith(\".jsonl\")) continue;\n const full = join(logsDir, f);\n const stat = statSync(full);\n if (now - stat.mtimeMs > THIRTY_DAYS_MS) {\n unlinkSync(full);\n logInfo(\"audit-rotation\", `Pruned: ${f}`);\n }\n }\n } catch (err) { logAndSwallow(TAG, \"audit prune\", err); }\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, 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 } 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) 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 mkdirSync(dir, { recursive: true });\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 { sanitizeOutbound } from \"../components/sanitize-outbound.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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",
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\n/** #613: Prune .trash/ entries older than 7 days. */\nexport function createSkillTrashPruneTask(): HeartbeatTask {\n const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;\n let counter = 0;\n return {\n name: \"skill-trash-prune\",\n execute: async () => {\n counter++;\n if (counter % 72 !== 0) return; // ~hourly (72 ticks \u00D7 50s)\n const { existsSync, readdirSync, rmSync, statSync } = await import(\"node:fs\");\n const { join } = await import(\"node:path\");\n const { abtarsHome } = await import(\"../paths.js\");\n const trashPath = join(abtarsHome(), \"skills\", \".trash\");\n if (!existsSync(trashPath)) return;\n const now = Date.now();\n for (const entry of readdirSync(trashPath)) {\n try {\n const full = join(trashPath, entry);\n const stat = statSync(full);\n if (now - stat.mtimeMs > SEVEN_DAYS_MS) {\n rmSync(full, { recursive: true });\n logInfo(\"skill-trash-prune\", `Pruned: ${entry}`);\n }\n } catch (err) { logAndSwallow(TAG, \"prune entry\", err); }\n }\n },\n };\n}\n\n/** #681: Rotate audit.jsonl when > 10MB, prune files older than 30 days. */\nexport function createAuditRotationTask(): HeartbeatTask {\n const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000;\n let counter = 0;\n return {\n name: \"audit-rotation\",\n execute: async () => {\n counter++;\n if (counter % 72 !== 0) return; // ~hourly\n const { existsSync, statSync, renameSync, readdirSync, unlinkSync } = await import(\"node:fs\");\n const { join } = await import(\"node:path\");\n const { abtarsHome } = await import(\"../paths.js\");\n const logsDir = join(abtarsHome(), \"logs\");\n const auditPath = join(logsDir, \"audit.jsonl\");\n if (!existsSync(auditPath)) return;\n try {\n const stat = statSync(auditPath);\n if (stat.size > 10 * 1024 * 1024) {\n const date = new Date().toISOString().slice(0, 10);\n renameSync(auditPath, join(logsDir, `audit-${date}.jsonl`));\n logInfo(\"audit-rotation\", `Rotated audit.jsonl (${(stat.size / 1024 / 1024).toFixed(1)}MB)`);\n }\n } catch (err) { logAndSwallow(TAG, \"audit rotate\", err); }\n // Prune old audit files\n const now = Date.now();\n try {\n for (const f of readdirSync(logsDir)) {\n if (!f.startsWith(\"audit-\") || !f.endsWith(\".jsonl\")) continue;\n const full = join(logsDir, f);\n const stat = statSync(full);\n if (now - stat.mtimeMs > THIRTY_DAYS_MS) {\n unlinkSync(full);\n logInfo(\"audit-rotation\", `Pruned: ${f}`);\n }\n }\n } catch (err) { logAndSwallow(TAG, \"audit prune\", err); }\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 } 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) 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 mkdirSync(dir, { recursive: true });\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
6
  "names": ["recordRun", "readFileSync", "TAG", "TAG", "readFileSync", "join", "abtarsHome", "statSync", "TAG", "spin", "existsSync", "readFileSync", "writeFileSync", "mkdirSync", "join", "TAG", "join", "writeFileSync", "existsSync", "readFileSync", "mkdirSync", "spin", "recordRun", "producedFiles", "mkdirSync", "join", "memoryDir", "join", "mkdirSync", "spin", "readBridgeLockField"]
7
7
  }
@@ -2,22 +2,21 @@
2
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
3
  import {
4
4
  printBanner
5
- } from "./chunk-TVSPVZTX.js";
5
+ } from "./chunk-LN5MNDSA.js";
6
6
  import {
7
7
  acquireLock
8
- } from "./chunk-EDZGF6BC.js";
8
+ } from "./chunk-QJPDBJDP.js";
9
9
  import {
10
10
  packagePaths
11
- } from "./chunk-C3EYYJN3.js";
11
+ } from "./chunk-2BXXQG7P.js";
12
12
 
13
13
  // src/cli/commands/rollback.ts
14
14
  import { existsSync, readFileSync, writeFileSync, unlinkSync, symlinkSync } from "node:fs";
15
- import { join, resolve } from "node:path";
16
- import { homedir } from "node:os";
15
+ import { join } from "node:path";
17
16
  async function rollback(opts) {
18
17
  await printBanner("rollback");
19
18
  const paths = packagePaths("abtars");
20
- const releasesDir = resolve(homedir(), ".abtars-releases");
19
+ const releasesDir = paths.releasesDir;
21
20
  const historyFile = join(releasesDir, "history.json");
22
21
  const currentLink = join(releasesDir, "current");
23
22
  const slot = opts?.to ?? 1;
@@ -83,4 +82,4 @@ async function rollback(opts) {
83
82
  export {
84
83
  rollback
85
84
  };
86
- //# sourceMappingURL=chunk-BU7LTI2W.js.map
85
+ //# sourceMappingURL=chunk-AWCO3DQ3.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/cli/commands/rollback.ts"],
4
+ "sourcesContent": ["import { printBanner } from './banner.js';\n/**\n * `abtars rollback` \u2014 repoint current symlink to a previous release from history.json.\n * --to N (1-3, default 1) selects which prior to restore.\n */\n\nimport { existsSync, readFileSync, writeFileSync, unlinkSync, symlinkSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { acquireLock, packagePaths } from '../deploy-lib-import.js';\n\nexport async function rollback(opts?: { to?: number }): Promise<number> {\n await printBanner(\"rollback\");\n const paths = packagePaths('abtars');\n const releasesDir = paths.releasesDir;\n const historyFile = join(releasesDir, 'history.json');\n const currentLink = join(releasesDir, 'current');\n const slot = opts?.to ?? 1;\n\n if (slot < 1 || slot > 3) {\n process.stderr.write(`Invalid --to value: ${slot}. Must be 1-3.\\n`);\n return 2;\n }\n\n let history: string[] = [];\n try { history = JSON.parse(readFileSync(historyFile, \"utf-8\")); } catch {}\n\n if (history.length <= slot) {\n process.stderr.write(`Nothing at slot ${slot} (history has ${history.length} entries).\\n`);\n return 2;\n }\n\n const target = history[slot]!;\n const targetDir = join(releasesDir, target);\n if (!existsSync(targetDir)) {\n process.stderr.write(`Release dir ${target} not found on disk.\\n`);\n return 2;\n }\n\n const release = await acquireLock(paths.lock, 'rollback');\n try {\n // Repoint current symlink\n try { unlinkSync(currentLink); } catch {}\n symlinkSync(targetDir, currentLink);\n\n // Also repoint legacy app/ symlink\n try { unlinkSync(paths.app); } catch {}\n try { symlinkSync(targetDir, paths.app); } catch {}\n\n process.stdout.write(`\u2713 rolled back to ${target} (slot ${slot})\\n`);\n\n // Reset circuit breaker counter\n try {\n const state = JSON.parse(readFileSync(join(paths.home, 'deploy.state'), 'utf-8'));\n state.restartCount = 0;\n writeFileSync(join(paths.home, 'deploy.state'), JSON.stringify(state) + '\\n');\n } catch {}\n\n // Write start reason + restart\n writeFileSync(join(paths.home, '.start-reason'), `rollback:${target}`);\n\n // Kill bridge so WD respawns from rolled-back code\n try {\n const bridgePid = JSON.parse(readFileSync(join(paths.home, 'bridge.lock'), 'utf-8')).pid;\n if (bridgePid > 0) process.kill(bridgePid, 'SIGTERM');\n } catch {}\n\n process.stdout.write(`\u267B\uFE0F Bridge killed \u2014 WD will respawn from ${target}\\n`);\n return 0;\n } finally {\n await release();\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;AAMA,SAAS,YAAY,cAAc,eAAe,YAAY,mBAAmB;AACjF,SAAS,YAAY;AAGrB,eAAsB,SAAS,MAAyC;AACtE,QAAM,YAAY,UAAU;AAC5B,QAAM,QAAQ,aAAa,QAAQ;AACnC,QAAM,cAAc,MAAM;AAC1B,QAAM,cAAc,KAAK,aAAa,cAAc;AACpD,QAAM,cAAc,KAAK,aAAa,SAAS;AAC/C,QAAM,OAAO,MAAM,MAAM;AAEzB,MAAI,OAAO,KAAK,OAAO,GAAG;AACxB,YAAQ,OAAO,MAAM,uBAAuB,IAAI;AAAA,CAAkB;AAClE,WAAO;AAAA,EACT;AAEA,MAAI,UAAoB,CAAC;AACzB,MAAI;AAAE,cAAU,KAAK,MAAM,aAAa,aAAa,OAAO,CAAC;AAAA,EAAG,QAAQ;AAAA,EAAC;AAEzE,MAAI,QAAQ,UAAU,MAAM;AAC1B,YAAQ,OAAO,MAAM,mBAAmB,IAAI,iBAAiB,QAAQ,MAAM;AAAA,CAAc;AACzF,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,QAAQ,IAAI;AAC3B,QAAM,YAAY,KAAK,aAAa,MAAM;AAC1C,MAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,YAAQ,OAAO,MAAM,eAAe,MAAM;AAAA,CAAuB;AACjE,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,MAAM,YAAY,MAAM,MAAM,UAAU;AACxD,MAAI;AAEF,QAAI;AAAE,iBAAW,WAAW;AAAA,IAAG,QAAQ;AAAA,IAAC;AACxC,gBAAY,WAAW,WAAW;AAGlC,QAAI;AAAE,iBAAW,MAAM,GAAG;AAAA,IAAG,QAAQ;AAAA,IAAC;AACtC,QAAI;AAAE,kBAAY,WAAW,MAAM,GAAG;AAAA,IAAG,QAAQ;AAAA,IAAC;AAElD,YAAQ,OAAO,MAAM,yBAAoB,MAAM,UAAU,IAAI;AAAA,CAAK;AAGlE,QAAI;AACF,YAAM,QAAQ,KAAK,MAAM,aAAa,KAAK,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC;AAChF,YAAM,eAAe;AACrB,oBAAc,KAAK,MAAM,MAAM,cAAc,GAAG,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9E,QAAQ;AAAA,IAAC;AAGT,kBAAc,KAAK,MAAM,MAAM,eAAe,GAAG,YAAY,MAAM,EAAE;AAGrE,QAAI;AACF,YAAM,YAAY,KAAK,MAAM,aAAa,KAAK,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,EAAE;AACrF,UAAI,YAAY,EAAG,SAAQ,KAAK,WAAW,SAAS;AAAA,IACtD,QAAQ;AAAA,IAAC;AAET,YAAQ,OAAO,MAAM,0DAA2C,MAAM;AAAA,CAAI;AAC1E,WAAO;AAAA,EACT,UAAE;AACA,UAAM,QAAQ;AAAA,EAChB;AACF;",
6
+ "names": []
7
+ }
@@ -3,7 +3,7 @@
3
3
  import {
4
4
  init_logger,
5
5
  logDebug
6
- } from "./chunk-OOKNHOCB.js";
6
+ } from "./chunk-6S3G6GPO.js";
7
7
  import {
8
8
  __esm
9
9
  } from "./chunk-7K2YZTLD.js";
@@ -29,4 +29,4 @@ export {
29
29
  nerve,
30
30
  init_nerve
31
31
  };
32
- //# sourceMappingURL=chunk-YME7NRGP.js.map
32
+ //# sourceMappingURL=chunk-B2TIRDZC.js.map
@@ -4,7 +4,7 @@ import {
4
4
  init_logger,
5
5
  logInfo,
6
6
  logWarn
7
- } from "./chunk-OOKNHOCB.js";
7
+ } from "./chunk-6S3G6GPO.js";
8
8
  import {
9
9
  __esm
10
10
  } from "./chunk-7K2YZTLD.js";
@@ -306,4 +306,4 @@ export {
306
306
  _resetEnv,
307
307
  init_env_schema
308
308
  };
309
- //# sourceMappingURL=chunk-SSCGWDIC.js.map
309
+ //# sourceMappingURL=chunk-BWJ37KMW.js.map
@@ -3,11 +3,11 @@
3
3
  import {
4
4
  init_log_and_swallow,
5
5
  logAndSwallow
6
- } from "./chunk-WP7FZHMI.js";
6
+ } from "./chunk-W2PSVV2T.js";
7
7
  import {
8
8
  abtarsHome,
9
9
  init_paths
10
- } from "./chunk-H2K23MOF.js";
10
+ } from "./chunk-7XXISOHU.js";
11
11
 
12
12
  // src/components/skill-stats.ts
13
13
  init_paths();
@@ -81,4 +81,4 @@ export {
81
81
  _getStats,
82
82
  _reset
83
83
  };
84
- //# sourceMappingURL=chunk-ULO2PX3T.js.map
84
+ //# sourceMappingURL=chunk-CCZ43JB7.js.map
@@ -4,7 +4,7 @@ import {
4
4
  init_logger,
5
5
  logDebug,
6
6
  logWarn
7
- } from "./chunk-OOKNHOCB.js";
7
+ } from "./chunk-6S3G6GPO.js";
8
8
 
9
9
  // src/components/sha-tracker.ts
10
10
  init_logger();
@@ -170,4 +170,4 @@ export {
170
170
  isPolicyCorrupt,
171
171
  reload
172
172
  };
173
- //# sourceMappingURL=chunk-FVUL44T4.js.map
173
+ //# sourceMappingURL=chunk-CNENVY37.js.map
@@ -3,7 +3,7 @@
3
3
  import {
4
4
  init_log_and_swallow,
5
5
  logAndSwallow
6
- } from "./chunk-WP7FZHMI.js";
6
+ } from "./chunk-W2PSVV2T.js";
7
7
 
8
8
  // src/boot/ctx-start.ts
9
9
  init_log_and_swallow();
@@ -38,4 +38,4 @@ export {
38
38
  updateCtxStart,
39
39
  resetAllCtxStarts
40
40
  };
41
- //# sourceMappingURL=chunk-J5NOL4DB.js.map
41
+ //# sourceMappingURL=chunk-DJOSXXM2.js.map