abtars 0.3.4-alpha.7 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. package/bundle/{_registry.generated-WGR4WOPT.js → _registry.generated-AVR7DK2A.js} +17 -14
  2. package/bundle/{_registry.generated-WGR4WOPT.js.map → _registry.generated-AVR7DK2A.js.map} +1 -1
  3. package/bundle/{abmind-lazy-7Z44NODV.js → abmind-lazy-E3YCFKQ5.js} +15 -5
  4. package/bundle/abtars-browser.js +4 -4
  5. package/bundle/abtars-cli.js +23 -13
  6. package/bundle/abtars-cli.js.map +2 -2
  7. package/bundle/abtars-restart.js +3 -3
  8. package/bundle/abtars-task.js +3 -3
  9. package/bundle/abtars-task.js.map +2 -2
  10. package/bundle/abtars.js +610 -455
  11. package/bundle/abtars.js.map +4 -4
  12. package/bundle/{acp-raw-client-E6FM45NC.js → acp-raw-client-UCNK3OTU.js} +2 -2
  13. package/bundle/{action-gate-G2V47NHW.js → action-gate-V4FCBHFB.js} +2 -2
  14. package/bundle/{agent-api-adapter-YAHKQMMZ.js → agent-api-adapter-7HEPYSIN.js} +3 -3
  15. package/bundle/{agent-api-rate-limit-WCFXJMGY.js → agent-api-rate-limit-RZSAM3SW.js} +4 -4
  16. package/bundle/{agent-registry-GI6CLT3Z.js → agent-registry-46A2R5KP.js} +7 -7
  17. package/bundle/{bootstrap-X2QYIZIJ.js → bootstrap-MIHJJSWU.js} +2 -2
  18. package/bundle/{bridge-lock-transport-4ZH7QTJP.js → bridge-lock-transport-7RSN7OLJ.js} +4 -4
  19. package/bundle/{browser-DMARZJIN.js → browser-F6BCWJWW.js} +6 -6
  20. package/bundle/{budget-45QOBDWA.js → budget-WUM3SPKW.js} +3 -3
  21. package/bundle/{capability-JFWX3IQF.js → capability-QVRKGRFC.js} +5 -5
  22. package/bundle/{chunk-YSKCQH6E.js → chunk-2IYJ4I66.js} +2 -2
  23. package/bundle/{chunk-KTYGKPYM.js → chunk-2NLUT5S2.js} +6 -6
  24. package/bundle/chunk-3BG3AIDP.js +191 -0
  25. package/bundle/chunk-3BG3AIDP.js.map +7 -0
  26. package/bundle/{chunk-OKAQICWY.js → chunk-3GQX34S2.js} +3 -3
  27. package/bundle/{chunk-QROWBWLL.js → chunk-3XZ773BS.js} +2 -2
  28. package/bundle/{chunk-DYBW4XXL.js → chunk-467SRLLR.js} +2 -2
  29. package/bundle/{chunk-LGP6TYFI.js → chunk-4AILRHUI.js} +97 -8
  30. package/bundle/chunk-4AILRHUI.js.map +7 -0
  31. package/bundle/{chunk-GPZNXY2U.js → chunk-4S3H4OK7.js} +4 -4
  32. package/bundle/{chunk-NDCRWEEJ.js → chunk-4Y5MJQRE.js} +6 -6
  33. package/bundle/{chunk-FRKW6LWB.js → chunk-55UWKI5C.js} +3 -3
  34. package/bundle/{chunk-4UL3KINB.js → chunk-5PNJFDSW.js} +8 -8
  35. package/bundle/{chunk-LUNA6PM5.js → chunk-5RVOEFGT.js} +4 -2
  36. package/bundle/{chunk-LUNA6PM5.js.map → chunk-5RVOEFGT.js.map} +2 -2
  37. package/bundle/{chunk-OXTSWQCX.js → chunk-5Y3FJ2Y7.js} +2 -2
  38. package/bundle/{chunk-TMUYFERL.js → chunk-6B5ZFUPD.js} +2 -2
  39. package/bundle/{chunk-65VCEC32.js → chunk-6PA5JBUU.js} +2 -2
  40. package/bundle/chunk-BNXV7SZI.js +195 -0
  41. package/bundle/chunk-BNXV7SZI.js.map +7 -0
  42. package/bundle/{chunk-AFREM7FX.js → chunk-CK7YTA2F.js} +2 -2
  43. package/bundle/{chunk-NRUSRJXR.js → chunk-DZJ5QZFD.js} +2 -2
  44. package/bundle/{chunk-YRSMGJFP.js → chunk-E67KESEG.js} +2 -2
  45. package/bundle/{chunk-ZV4IWKDJ.js → chunk-E7XD5UGB.js} +3 -3
  46. package/bundle/{chunk-GXL7HJPT.js → chunk-EAX5ZZUL.js} +63 -39
  47. package/bundle/chunk-EAX5ZZUL.js.map +7 -0
  48. package/bundle/{chunk-PEDX56EL.js → chunk-EFGBM555.js} +2 -2
  49. package/bundle/{chunk-EQSG2CRM.js → chunk-FGYDIX54.js} +22 -15
  50. package/bundle/chunk-FGYDIX54.js.map +7 -0
  51. package/bundle/{chunk-XWRADSXO.js → chunk-GF6NVNA7.js} +15 -5
  52. package/bundle/chunk-GF6NVNA7.js.map +7 -0
  53. package/bundle/{chunk-SIFPBTI4.js → chunk-HGSHCQ5F.js} +113 -73
  54. package/bundle/chunk-HGSHCQ5F.js.map +7 -0
  55. package/bundle/{chunk-YRU2K3O6.js → chunk-IMIGG5EO.js} +39 -39
  56. package/bundle/chunk-IMIGG5EO.js.map +7 -0
  57. package/bundle/{chunk-W4EA4GCA.js → chunk-ITOFPJAV.js} +43 -31
  58. package/bundle/chunk-ITOFPJAV.js.map +7 -0
  59. package/bundle/{chunk-UPRZDU6T.js → chunk-IY6UKLPS.js} +3 -3
  60. package/bundle/{chunk-EUZDKV3C.js → chunk-J4RUFAPK.js} +3 -3
  61. package/bundle/{chunk-HZDLFLRP.js → chunk-J7DRPVMU.js} +35 -5
  62. package/bundle/chunk-J7DRPVMU.js.map +7 -0
  63. package/bundle/{chunk-EGL6UMAO.js → chunk-JG4BKXBN.js} +7 -1
  64. package/bundle/chunk-JG4BKXBN.js.map +7 -0
  65. package/bundle/{chunk-5B5B6EHL.js → chunk-JLWYPGWI.js} +5 -5
  66. package/bundle/{chunk-5QUTMUIK.js → chunk-JXYWDAHD.js} +12 -12
  67. package/bundle/{chunk-GRVWZO4C.js → chunk-KOSFXW2S.js} +24 -3
  68. package/bundle/{chunk-GRVWZO4C.js.map → chunk-KOSFXW2S.js.map} +1 -1
  69. package/bundle/{chunk-ONBF5DDU.js → chunk-L72RIPEC.js} +248 -182
  70. package/bundle/chunk-L72RIPEC.js.map +7 -0
  71. package/bundle/{chunk-TEFZ4JA4.js → chunk-NHPLD3C7.js} +2 -2
  72. package/bundle/{chunk-2KC5G3EA.js → chunk-OWUO5RS3.js} +5 -5
  73. package/bundle/{chunk-4MULJ5SS.js → chunk-OY4Q6AMY.js} +71 -49
  74. package/bundle/chunk-OY4Q6AMY.js.map +7 -0
  75. package/bundle/{chunk-WBTJ2E62.js → chunk-P3NODAHF.js} +2 -5
  76. package/bundle/{chunk-WBTJ2E62.js.map → chunk-P3NODAHF.js.map} +2 -2
  77. package/bundle/{chunk-BROFMHC2.js → chunk-PB5GF4FG.js} +334 -237
  78. package/bundle/chunk-PB5GF4FG.js.map +7 -0
  79. package/bundle/{chunk-WYHGNI56.js → chunk-PMD5BLFS.js} +6 -6
  80. package/bundle/{chunk-URQPDCK5.js → chunk-Q66LQMMZ.js} +3 -3
  81. package/bundle/{chunk-HKRSMUXJ.js → chunk-SC2Y5NR2.js} +71 -132
  82. package/bundle/chunk-SC2Y5NR2.js.map +7 -0
  83. package/bundle/chunk-SFL4EPCZ.js +555 -0
  84. package/bundle/chunk-SFL4EPCZ.js.map +7 -0
  85. package/bundle/{chunk-LDUOOKQY.js → chunk-SJPUNDZ3.js} +5 -5
  86. package/bundle/{chunk-LDUOOKQY.js.map → chunk-SJPUNDZ3.js.map} +1 -1
  87. package/bundle/{chunk-JQDJPUHM.js → chunk-TWB2ZGVH.js} +2 -2
  88. package/bundle/{chunk-IJT4KWXT.js → chunk-U4U47YE7.js} +2 -2
  89. package/bundle/{chunk-2FAZIA37.js → chunk-W546CU3A.js} +3 -3
  90. package/bundle/chunk-WC5O5KOE.js +211 -0
  91. package/bundle/chunk-WC5O5KOE.js.map +7 -0
  92. package/bundle/{chunk-JNIHEDKF.js → chunk-XPWYDNWL.js} +2 -2
  93. package/bundle/{chunk-GWILHZPT.js → chunk-XRTXYN66.js} +10 -7
  94. package/bundle/{chunk-GWILHZPT.js.map → chunk-XRTXYN66.js.map} +2 -2
  95. package/bundle/{chunk-EFJVUJBE.js → chunk-Y5FEFKGM.js} +6 -6
  96. package/bundle/chunk-YJZE4OK3.js +169 -0
  97. package/bundle/chunk-YJZE4OK3.js.map +7 -0
  98. package/bundle/{chunk-GVM5YU5I.js → chunk-Z4FZPB42.js} +2 -2
  99. package/bundle/{chunk-7BSQ5UQO.js → chunk-ZSIDQ66D.js} +3 -3
  100. package/bundle/{chunk-XX6BGTPO.js → chunk-ZZZCJJEO.js} +4 -4
  101. package/bundle/{commands-XYEGVUZF.js → commands-2ZW6CMLC.js} +17 -16
  102. package/bundle/{config-M3P5IOAI.js → config-YMY5YHKN.js} +6 -6
  103. package/bundle/{context-2RJHC2LE.js → context-CL2RSLII.js} +7 -5
  104. package/bundle/context-CL2RSLII.js.map +7 -0
  105. package/bundle/{daemon-TB23FFWY.js → daemon-D7SU63OY.js} +3 -3
  106. package/bundle/{delegation-tools-QKNYQGTQ.js → delegation-tools-WS7Z56KZ.js} +12 -12
  107. package/bundle/{deploy-EPDWNHJU.js → deploy-AMTVKIMU.js} +2 -2
  108. package/bundle/{deps-WVK553KF.js → deps-T63AVJKJ.js} +3 -3
  109. package/bundle/{direct-api-transport-E3LNDBJT.js → direct-api-transport-QNNY2WWP.js} +56 -33
  110. package/bundle/direct-api-transport-QNNY2WWP.js.map +7 -0
  111. package/bundle/{discord-adapter-IT3KP3VB.js → discord-adapter-ABAD56Y2.js} +21 -20
  112. package/bundle/{discord-adapter-IT3KP3VB.js.map → discord-adapter-ABAD56Y2.js.map} +1 -1
  113. package/bundle/{dns-wakeup-IDOJIXBX.js → dns-wakeup-V3LEFXPE.js} +9 -33
  114. package/bundle/dns-wakeup-V3LEFXPE.js.map +7 -0
  115. package/bundle/{doctor-probes-B54JFIW3.js → doctor-probes-O6YI6XSZ.js} +6 -2
  116. package/bundle/{env-schema-4JXQUOH4.js → env-schema-B5RB32DC.js} +3 -3
  117. package/bundle/{gossip-3C3BSNPN.js → gossip-SKRCPOBS.js} +9 -5
  118. package/bundle/{guardrails-DL7ZSWVN.js → guardrails-64GQ5Y5K.js} +4 -4
  119. package/bundle/{heartbeat-system-MVTRS4GP.js → heartbeat-system-X4MUTKJD.js} +6 -6
  120. package/bundle/{heartbeat-tier3-ABWL3P7M.js → heartbeat-tier3-2PTPWEQQ.js} +53 -76
  121. package/bundle/heartbeat-tier3-2PTPWEQQ.js.map +7 -0
  122. package/bundle/{hook-system-M3POLUIB.js → hook-system-YB635OC4.js} +3 -3
  123. package/bundle/{hotskills-FWX4QI7V.js → hotskills-Q75D2DK3.js} +5 -5
  124. package/bundle/{install-OS3CU7NF.js → install-RFKKFSGS.js} +17 -30
  125. package/bundle/install-RFKKFSGS.js.map +7 -0
  126. package/bundle/{install-manifest-5PPWMD2W.js → install-manifest-J7ICPCJN.js} +2 -2
  127. package/bundle/{irc-adapter-PTTZD32W.js → irc-adapter-TVEV4R6H.js} +3 -3
  128. package/bundle/{irc-config-CP7ZMUOX.js → irc-config-M676FOFI.js} +4 -4
  129. package/bundle/{kanban-board-M326B2XJ.js → kanban-board-DLEJUCNN.js} +9 -7
  130. package/bundle/{kanban-channel-IJ52OMNA.js → kanban-channel-XOLUHJZJ.js} +6 -6
  131. package/bundle/kanban-delivery-C4QPBNPX.js +45 -0
  132. package/bundle/kanban-delivery-C4QPBNPX.js.map +7 -0
  133. package/bundle/{lazy-require-KCRVT4SI.js → lazy-require-JKQSALXN.js} +3 -3
  134. package/bundle/{logger-OWCSNYCA.js → logger-3EGHBD4R.js} +2 -2
  135. package/bundle/{main-chat-ZNUZCTNS.js → main-chat-3H63REKK.js} +4 -4
  136. package/bundle/{master-user-HSKM4ZFN.js → master-user-MUBUP3KD.js} +5 -5
  137. package/bundle/{media-utils-3ZYOD7SK.js → media-utils-HUUIALAJ.js} +3 -3
  138. package/bundle/{message-pipeline-P5GAQU4Z.js → message-pipeline-GRDRWONR.js} +17 -16
  139. package/bundle/meta.json +3699 -3138
  140. package/bundle/{metrics-collector-L3VPEHII.js → metrics-collector-YMUGY3PI.js} +31 -2
  141. package/bundle/metrics-collector-YMUGY3PI.js.map +7 -0
  142. package/bundle/{model-health-registry-MLEIZSTV.js → model-health-registry-QADMFQFQ.js} +2 -2
  143. package/bundle/{nerve-IGSXBKZZ.js → nerve-QPAEBRKX.js} +3 -3
  144. package/bundle/{notification-BFSIEECG.js → notification-3JICGXWU.js} +6 -6
  145. package/bundle/{openrouter-credits-NTVZDRYM.js → openrouter-credits-7NEIPYJN.js} +3 -3
  146. package/bundle/{orc-tools-4CHEFWSN.js → orc-tools-UZVPONKY.js} +5 -3
  147. package/bundle/{peer-auth-QC4EF2PM.js → peer-auth-RI43DKJE.js} +24 -15
  148. package/bundle/{peer-client-RGEU5HOK.js → peer-client-UITTMWJ2.js} +34 -29
  149. package/bundle/peer-client-UITTMWJ2.js.map +7 -0
  150. package/bundle/{peer-config-TN55LFDC.js → peer-config-URM7DCW6.js} +9 -4
  151. package/bundle/{peer-transport-I6JPLFZ2.js → peer-transport-SI7I72DB.js} +12 -10
  152. package/bundle/{phase-transport-PGKU2KD4.js → phase-transport-ESWWACZI.js} +17 -17
  153. package/bundle/{reconcile-CTFCLQRN.js → reconcile-GFDQYNBD.js} +3 -3
  154. package/bundle/{reconciler-EBKH3JNU.js → reconciler-IEUJXJN2.js} +12 -12
  155. package/bundle/{restore-IFHPI7I7.js → restore-FARTGLQQ.js} +3 -3
  156. package/bundle/{rollback-ANRI3T5Z.js → rollback-GEWPZABG.js} +2 -2
  157. package/bundle/{sandbox-runtime-QROWHDCS.js → sandbox-runtime-DV6E25J6.js} +2 -2
  158. package/bundle/{self-healer-utils-IFAYOQO2.js → self-healer-utils-P4SKNNEM.js} +3 -3
  159. package/bundle/{sha-tracker-ZWBP6CIJ.js → sha-tracker-77SHLYNY.js} +3 -3
  160. package/bundle/{skill-session-BMSRQSHV.js → skill-session-5HSMXY54.js} +3 -3
  161. package/bundle/{skill-stats-JORH5DGM.js → skill-stats-MI3RSWWL.js} +4 -4
  162. package/bundle/{skill-watcher-E4MGLKLS.js → skill-watcher-5L7JE6TN.js} +4 -4
  163. package/bundle/{sleep-36XS6MHJ.js → sleep-I4JFASCY.js} +11 -8
  164. package/bundle/{soul-bundle-VWAVHCZ6.js → soul-bundle-522C3IRH.js} +9 -8
  165. package/bundle/{spin-TI3TSVVT.js → spin-VHNGNWTD.js} +11 -11
  166. package/bundle/{spin-notifications-SE2HVZI7.js → spin-notifications-7NC5XZEM.js} +5 -5
  167. package/bundle/{spin-types-BLPYAETA.js → spin-types-C5KOQOPD.js} +7 -3
  168. package/bundle/{sse-parser-anthropic-A6R4Z2TB.js → sse-parser-anthropic-MMTVWHLI.js} +3 -3
  169. package/bundle/{sse-parser-responses-HSZY3QGJ.js → sse-parser-responses-3AOFN64C.js} +3 -3
  170. package/bundle/{ssrf-guard-O6SHIK6Q.js → ssrf-guard-U2JA72TC.js} +3 -3
  171. package/bundle/{start-7QZIWO3S.js → start-H5IUFAWF.js} +4 -2
  172. package/bundle/{start-7QZIWO3S.js.map → start-H5IUFAWF.js.map} +2 -2
  173. package/bundle/{stt-LGVPXMVR.js → stt-PSOPPBV4.js} +4 -4
  174. package/bundle/{system-status-JZU5FO7B.js → system-status-4LYGOFNO.js} +38 -24
  175. package/bundle/system-status-4LYGOFNO.js.map +7 -0
  176. package/bundle/{task-store-W5BFIAIH.js → task-store-MNCW42BW.js} +4 -4
  177. package/bundle/{telegram-adapter-H6PMFPMB.js → telegram-adapter-O6KIZDY6.js} +69 -46
  178. package/bundle/telegram-adapter-O6KIZDY6.js.map +7 -0
  179. package/bundle/{tool-registry-IZX2IOBM.js → tool-registry-JJMWCQKZ.js} +26 -24
  180. package/bundle/{tool-sandbox-4UC6GAKA.js → tool-sandbox-CNL6V6IH.js} +4 -4
  181. package/bundle/{transport-config-KBF5W2DP.js → transport-config-6MB2K2XC.js} +7 -7
  182. package/bundle/tribe-GDTFYJTK.js +111 -0
  183. package/bundle/tribe-GDTFYJTK.js.map +7 -0
  184. package/bundle/{update-MESYO4LO.js → update-HGQAOC5L.js} +3 -3
  185. package/bundle/{usage-tracker-NXD364VX.js → usage-tracker-SR4BI6ZT.js} +2 -2
  186. package/bundle/{user-registry-35BW4XKM.js → user-registry-4PACZJIJ.js} +4 -4
  187. package/bundle/wire-platform-KKPWNNNQ.js +88 -0
  188. package/bundle/wire-platform-KKPWNNNQ.js.map +7 -0
  189. package/bundle/ws-peer-client-U3NNPOK7.js +370 -0
  190. package/bundle/ws-peer-client-U3NNPOK7.js.map +7 -0
  191. package/package.json +1 -1
  192. package/scripts/abtars-watchdog.service +2 -1
  193. package/scripts/abtars-watchdog.sh +1 -5
  194. package/scripts/emergency-deploy.sh +2 -2
  195. package/scripts/emergency-update.sh +88 -41
  196. package/bundle/chunk-3AAENI2K.js +0 -210
  197. package/bundle/chunk-3AAENI2K.js.map +0 -7
  198. package/bundle/chunk-4MULJ5SS.js.map +0 -7
  199. package/bundle/chunk-4S554KLW.js +0 -105
  200. package/bundle/chunk-4S554KLW.js.map +0 -7
  201. package/bundle/chunk-5GCLBUBS.js +0 -257
  202. package/bundle/chunk-5GCLBUBS.js.map +0 -7
  203. package/bundle/chunk-BROFMHC2.js.map +0 -7
  204. package/bundle/chunk-EGL6UMAO.js.map +0 -7
  205. package/bundle/chunk-EQSG2CRM.js.map +0 -7
  206. package/bundle/chunk-GXL7HJPT.js.map +0 -7
  207. package/bundle/chunk-HKRSMUXJ.js.map +0 -7
  208. package/bundle/chunk-HT2BPTZY.js +0 -241
  209. package/bundle/chunk-HT2BPTZY.js.map +0 -7
  210. package/bundle/chunk-HZDLFLRP.js.map +0 -7
  211. package/bundle/chunk-IKUZPMVA.js +0 -82
  212. package/bundle/chunk-IKUZPMVA.js.map +0 -7
  213. package/bundle/chunk-LGP6TYFI.js.map +0 -7
  214. package/bundle/chunk-ONBF5DDU.js.map +0 -7
  215. package/bundle/chunk-RWRRGE4U.js +0 -72
  216. package/bundle/chunk-RWRRGE4U.js.map +0 -7
  217. package/bundle/chunk-SIFPBTI4.js.map +0 -7
  218. package/bundle/chunk-VUIX5AGB.js +0 -65
  219. package/bundle/chunk-VUIX5AGB.js.map +0 -7
  220. package/bundle/chunk-W4EA4GCA.js.map +0 -7
  221. package/bundle/chunk-XWRADSXO.js.map +0 -7
  222. package/bundle/chunk-Y76VUJSF.js +0 -75
  223. package/bundle/chunk-Y76VUJSF.js.map +0 -7
  224. package/bundle/chunk-YRU2K3O6.js.map +0 -7
  225. package/bundle/context-2RJHC2LE.js.map +0 -7
  226. package/bundle/direct-api-transport-E3LNDBJT.js.map +0 -7
  227. package/bundle/dns-wakeup-IDOJIXBX.js.map +0 -7
  228. package/bundle/heartbeat-tier3-ABWL3P7M.js.map +0 -7
  229. package/bundle/install-OS3CU7NF.js.map +0 -7
  230. package/bundle/metrics-collector-L3VPEHII.js.map +0 -7
  231. package/bundle/peer-client-RGEU5HOK.js.map +0 -7
  232. package/bundle/peer-jwt-NCCPXJRX.js +0 -18
  233. package/bundle/public/css/dashboard.css +0 -542
  234. package/bundle/public/index.html +0 -180
  235. package/bundle/public/js/app.js +0 -437
  236. package/bundle/public/memory-universe.js +0 -384
  237. package/bundle/stream-single-RFJNUTL6.js +0 -34
  238. package/bundle/stream-single-RFJNUTL6.js.map +0 -7
  239. package/bundle/subagent-runtime-5QUVES3W.js +0 -14
  240. package/bundle/system-status-JZU5FO7B.js.map +0 -7
  241. package/bundle/telegram-adapter-H6PMFPMB.js.map +0 -7
  242. package/bundle/usage-tracker-NXD364VX.js.map +0 -7
  243. package/bundle/user-registry-35BW4XKM.js.map +0 -7
  244. package/bundle/ws-peer-client-AIXCXF7V.js +0 -173
  245. package/bundle/ws-peer-client-AIXCXF7V.js.map +0 -7
  246. /package/bundle/{abmind-lazy-7Z44NODV.js.map → abmind-lazy-E3YCFKQ5.js.map} +0 -0
  247. /package/bundle/{acp-raw-client-E6FM45NC.js.map → acp-raw-client-UCNK3OTU.js.map} +0 -0
  248. /package/bundle/{action-gate-G2V47NHW.js.map → action-gate-V4FCBHFB.js.map} +0 -0
  249. /package/bundle/{agent-api-adapter-YAHKQMMZ.js.map → agent-api-adapter-7HEPYSIN.js.map} +0 -0
  250. /package/bundle/{agent-api-rate-limit-WCFXJMGY.js.map → agent-api-rate-limit-RZSAM3SW.js.map} +0 -0
  251. /package/bundle/{agent-registry-GI6CLT3Z.js.map → agent-registry-46A2R5KP.js.map} +0 -0
  252. /package/bundle/{bootstrap-X2QYIZIJ.js.map → bootstrap-MIHJJSWU.js.map} +0 -0
  253. /package/bundle/{bridge-lock-transport-4ZH7QTJP.js.map → bridge-lock-transport-7RSN7OLJ.js.map} +0 -0
  254. /package/bundle/{browser-DMARZJIN.js.map → browser-F6BCWJWW.js.map} +0 -0
  255. /package/bundle/{budget-45QOBDWA.js.map → budget-WUM3SPKW.js.map} +0 -0
  256. /package/bundle/{capability-JFWX3IQF.js.map → capability-QVRKGRFC.js.map} +0 -0
  257. /package/bundle/{chunk-YSKCQH6E.js.map → chunk-2IYJ4I66.js.map} +0 -0
  258. /package/bundle/{chunk-KTYGKPYM.js.map → chunk-2NLUT5S2.js.map} +0 -0
  259. /package/bundle/{chunk-OKAQICWY.js.map → chunk-3GQX34S2.js.map} +0 -0
  260. /package/bundle/{chunk-QROWBWLL.js.map → chunk-3XZ773BS.js.map} +0 -0
  261. /package/bundle/{chunk-DYBW4XXL.js.map → chunk-467SRLLR.js.map} +0 -0
  262. /package/bundle/{chunk-GPZNXY2U.js.map → chunk-4S3H4OK7.js.map} +0 -0
  263. /package/bundle/{chunk-NDCRWEEJ.js.map → chunk-4Y5MJQRE.js.map} +0 -0
  264. /package/bundle/{chunk-FRKW6LWB.js.map → chunk-55UWKI5C.js.map} +0 -0
  265. /package/bundle/{chunk-4UL3KINB.js.map → chunk-5PNJFDSW.js.map} +0 -0
  266. /package/bundle/{chunk-OXTSWQCX.js.map → chunk-5Y3FJ2Y7.js.map} +0 -0
  267. /package/bundle/{chunk-TMUYFERL.js.map → chunk-6B5ZFUPD.js.map} +0 -0
  268. /package/bundle/{chunk-65VCEC32.js.map → chunk-6PA5JBUU.js.map} +0 -0
  269. /package/bundle/{chunk-AFREM7FX.js.map → chunk-CK7YTA2F.js.map} +0 -0
  270. /package/bundle/{chunk-NRUSRJXR.js.map → chunk-DZJ5QZFD.js.map} +0 -0
  271. /package/bundle/{chunk-YRSMGJFP.js.map → chunk-E67KESEG.js.map} +0 -0
  272. /package/bundle/{chunk-ZV4IWKDJ.js.map → chunk-E7XD5UGB.js.map} +0 -0
  273. /package/bundle/{chunk-PEDX56EL.js.map → chunk-EFGBM555.js.map} +0 -0
  274. /package/bundle/{chunk-UPRZDU6T.js.map → chunk-IY6UKLPS.js.map} +0 -0
  275. /package/bundle/{chunk-EUZDKV3C.js.map → chunk-J4RUFAPK.js.map} +0 -0
  276. /package/bundle/{chunk-5B5B6EHL.js.map → chunk-JLWYPGWI.js.map} +0 -0
  277. /package/bundle/{chunk-5QUTMUIK.js.map → chunk-JXYWDAHD.js.map} +0 -0
  278. /package/bundle/{chunk-TEFZ4JA4.js.map → chunk-NHPLD3C7.js.map} +0 -0
  279. /package/bundle/{chunk-2KC5G3EA.js.map → chunk-OWUO5RS3.js.map} +0 -0
  280. /package/bundle/{chunk-WYHGNI56.js.map → chunk-PMD5BLFS.js.map} +0 -0
  281. /package/bundle/{chunk-URQPDCK5.js.map → chunk-Q66LQMMZ.js.map} +0 -0
  282. /package/bundle/{chunk-JQDJPUHM.js.map → chunk-TWB2ZGVH.js.map} +0 -0
  283. /package/bundle/{chunk-IJT4KWXT.js.map → chunk-U4U47YE7.js.map} +0 -0
  284. /package/bundle/{chunk-2FAZIA37.js.map → chunk-W546CU3A.js.map} +0 -0
  285. /package/bundle/{chunk-JNIHEDKF.js.map → chunk-XPWYDNWL.js.map} +0 -0
  286. /package/bundle/{chunk-EFJVUJBE.js.map → chunk-Y5FEFKGM.js.map} +0 -0
  287. /package/bundle/{chunk-GVM5YU5I.js.map → chunk-Z4FZPB42.js.map} +0 -0
  288. /package/bundle/{chunk-7BSQ5UQO.js.map → chunk-ZSIDQ66D.js.map} +0 -0
  289. /package/bundle/{chunk-XX6BGTPO.js.map → chunk-ZZZCJJEO.js.map} +0 -0
  290. /package/bundle/{commands-XYEGVUZF.js.map → commands-2ZW6CMLC.js.map} +0 -0
  291. /package/bundle/{config-M3P5IOAI.js.map → config-YMY5YHKN.js.map} +0 -0
  292. /package/bundle/{daemon-TB23FFWY.js.map → daemon-D7SU63OY.js.map} +0 -0
  293. /package/bundle/{delegation-tools-QKNYQGTQ.js.map → delegation-tools-WS7Z56KZ.js.map} +0 -0
  294. /package/bundle/{deploy-EPDWNHJU.js.map → deploy-AMTVKIMU.js.map} +0 -0
  295. /package/bundle/{deps-WVK553KF.js.map → deps-T63AVJKJ.js.map} +0 -0
  296. /package/bundle/{doctor-probes-B54JFIW3.js.map → doctor-probes-O6YI6XSZ.js.map} +0 -0
  297. /package/bundle/{env-schema-4JXQUOH4.js.map → env-schema-B5RB32DC.js.map} +0 -0
  298. /package/bundle/{gossip-3C3BSNPN.js.map → gossip-SKRCPOBS.js.map} +0 -0
  299. /package/bundle/{guardrails-DL7ZSWVN.js.map → guardrails-64GQ5Y5K.js.map} +0 -0
  300. /package/bundle/{heartbeat-system-MVTRS4GP.js.map → heartbeat-system-X4MUTKJD.js.map} +0 -0
  301. /package/bundle/{hook-system-M3POLUIB.js.map → hook-system-YB635OC4.js.map} +0 -0
  302. /package/bundle/{hotskills-FWX4QI7V.js.map → hotskills-Q75D2DK3.js.map} +0 -0
  303. /package/bundle/{install-manifest-5PPWMD2W.js.map → install-manifest-J7ICPCJN.js.map} +0 -0
  304. /package/bundle/{irc-adapter-PTTZD32W.js.map → irc-adapter-TVEV4R6H.js.map} +0 -0
  305. /package/bundle/{irc-config-CP7ZMUOX.js.map → irc-config-M676FOFI.js.map} +0 -0
  306. /package/bundle/{kanban-board-M326B2XJ.js.map → kanban-board-DLEJUCNN.js.map} +0 -0
  307. /package/bundle/{kanban-channel-IJ52OMNA.js.map → kanban-channel-XOLUHJZJ.js.map} +0 -0
  308. /package/bundle/{lazy-require-KCRVT4SI.js.map → lazy-require-JKQSALXN.js.map} +0 -0
  309. /package/bundle/{logger-OWCSNYCA.js.map → logger-3EGHBD4R.js.map} +0 -0
  310. /package/bundle/{main-chat-ZNUZCTNS.js.map → main-chat-3H63REKK.js.map} +0 -0
  311. /package/bundle/{master-user-HSKM4ZFN.js.map → master-user-MUBUP3KD.js.map} +0 -0
  312. /package/bundle/{media-utils-3ZYOD7SK.js.map → media-utils-HUUIALAJ.js.map} +0 -0
  313. /package/bundle/{message-pipeline-P5GAQU4Z.js.map → message-pipeline-GRDRWONR.js.map} +0 -0
  314. /package/bundle/{model-health-registry-MLEIZSTV.js.map → model-health-registry-QADMFQFQ.js.map} +0 -0
  315. /package/bundle/{nerve-IGSXBKZZ.js.map → nerve-QPAEBRKX.js.map} +0 -0
  316. /package/bundle/{notification-BFSIEECG.js.map → notification-3JICGXWU.js.map} +0 -0
  317. /package/bundle/{openrouter-credits-NTVZDRYM.js.map → openrouter-credits-7NEIPYJN.js.map} +0 -0
  318. /package/bundle/{orc-tools-4CHEFWSN.js.map → orc-tools-UZVPONKY.js.map} +0 -0
  319. /package/bundle/{peer-auth-QC4EF2PM.js.map → peer-auth-RI43DKJE.js.map} +0 -0
  320. /package/bundle/{peer-config-TN55LFDC.js.map → peer-config-URM7DCW6.js.map} +0 -0
  321. /package/bundle/{peer-jwt-NCCPXJRX.js.map → peer-transport-SI7I72DB.js.map} +0 -0
  322. /package/bundle/{peer-transport-I6JPLFZ2.js.map → phase-transport-ESWWACZI.js.map} +0 -0
  323. /package/bundle/{phase-transport-PGKU2KD4.js.map → reconcile-GFDQYNBD.js.map} +0 -0
  324. /package/bundle/{reconciler-EBKH3JNU.js.map → reconciler-IEUJXJN2.js.map} +0 -0
  325. /package/bundle/{restore-IFHPI7I7.js.map → restore-FARTGLQQ.js.map} +0 -0
  326. /package/bundle/{reconcile-CTFCLQRN.js.map → rollback-GEWPZABG.js.map} +0 -0
  327. /package/bundle/{sandbox-runtime-QROWHDCS.js.map → sandbox-runtime-DV6E25J6.js.map} +0 -0
  328. /package/bundle/{self-healer-utils-IFAYOQO2.js.map → self-healer-utils-P4SKNNEM.js.map} +0 -0
  329. /package/bundle/{rollback-ANRI3T5Z.js.map → sha-tracker-77SHLYNY.js.map} +0 -0
  330. /package/bundle/{skill-session-BMSRQSHV.js.map → skill-session-5HSMXY54.js.map} +0 -0
  331. /package/bundle/{sha-tracker-ZWBP6CIJ.js.map → skill-stats-MI3RSWWL.js.map} +0 -0
  332. /package/bundle/{skill-stats-JORH5DGM.js.map → skill-watcher-5L7JE6TN.js.map} +0 -0
  333. /package/bundle/{skill-watcher-E4MGLKLS.js.map → sleep-I4JFASCY.js.map} +0 -0
  334. /package/bundle/{sleep-36XS6MHJ.js.map → soul-bundle-522C3IRH.js.map} +0 -0
  335. /package/bundle/{soul-bundle-VWAVHCZ6.js.map → spin-VHNGNWTD.js.map} +0 -0
  336. /package/bundle/{spin-notifications-SE2HVZI7.js.map → spin-notifications-7NC5XZEM.js.map} +0 -0
  337. /package/bundle/{spin-TI3TSVVT.js.map → spin-types-C5KOQOPD.js.map} +0 -0
  338. /package/bundle/{sse-parser-anthropic-A6R4Z2TB.js.map → sse-parser-anthropic-MMTVWHLI.js.map} +0 -0
  339. /package/bundle/{sse-parser-responses-HSZY3QGJ.js.map → sse-parser-responses-3AOFN64C.js.map} +0 -0
  340. /package/bundle/{ssrf-guard-O6SHIK6Q.js.map → ssrf-guard-U2JA72TC.js.map} +0 -0
  341. /package/bundle/{spin-types-BLPYAETA.js.map → stt-PSOPPBV4.js.map} +0 -0
  342. /package/bundle/{stt-LGVPXMVR.js.map → task-store-MNCW42BW.js.map} +0 -0
  343. /package/bundle/{subagent-runtime-5QUVES3W.js.map → tool-registry-JJMWCQKZ.js.map} +0 -0
  344. /package/bundle/{task-store-W5BFIAIH.js.map → tool-sandbox-CNL6V6IH.js.map} +0 -0
  345. /package/bundle/{tool-registry-IZX2IOBM.js.map → transport-config-6MB2K2XC.js.map} +0 -0
  346. /package/bundle/{tool-sandbox-4UC6GAKA.js.map → update-HGQAOC5L.js.map} +0 -0
  347. /package/bundle/{transport-config-KBF5W2DP.js.map → usage-tracker-SR4BI6ZT.js.map} +0 -0
  348. /package/bundle/{update-MESYO4LO.js.map → user-registry-4PACZJIJ.js.map} +0 -0
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/components/peer-transport/gossip.ts"],
4
- "sourcesContent": ["/**\n * gossip.ts \u2014 Peer health gossip (#971).\n *\n * Each peer broadcasts liveness + load + capabilities every 60s via UDP.\n * All peers maintain a live peer table (Map with 90s TTL).\n * Orc reads this table for intelligent routing.\n */\n\nimport { createSocket, type Socket } from \"node:dgram\";\nimport { execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { cpus, loadavg } from \"node:os\";\nimport { loadPeerConfig } from \"../peer-config.js\";\nimport { logInfo, logDebug, logWarn, logTrace } from \"../logger.js\";\nimport { createHmac } from \"node:crypto\";\n\nconst TAG = \"gossip\";\nconst GOSSIP_PORT = parseInt(process.env[\"GOSSIP_PORT\"] ?? \"5355\", 10);\nconst BROADCAST_INTERVAL_MS = 60_000;\nconst TTL_MS = 180_000; // 3 missed broadcasts \u2192 dead\n\nexport interface PeerHealth {\n name: string;\n lastSeen: number;\n load: number;\n sessions: number;\n capabilities: string[];\n version: string;\n alive: boolean;\n host: string;\n port: number;\n}\n\nconst peerTable = new Map<string, PeerHealth>();\nlet _socket: Socket | null = null;\nlet _interval: ReturnType<typeof setInterval> | null = null;\nlet _capabilities: string[] = [];\n\n/** Auto-discover this peer's capabilities at boot. */\nfunction discoverCapabilities(): string[] {\n const caps: string[] = [\"bash\", \"node\", \"memory\"];\n try { if (execSync(\"which docker\", { stdio: \"pipe\" }).toString().trim()) caps.push(\"docker\"); } catch {}\n try { if (execSync(\"which xcodebuild\", { stdio: \"pipe\" }).toString().trim()) caps.push(\"xcode\"); } catch {}\n try { if (execSync(\"which ollama\", { stdio: \"pipe\" }).toString().trim()) caps.push(\"ollama\"); } catch {}\n if (existsSync(\"/usr/bin/nvidia-smi\") || process.env[\"CUDA_VISIBLE_DEVICES\"]) caps.push(\"gpu\");\n if (process.env[\"BROWSER_ENGINE\"]) caps.push(\"browser\");\n if (process.env[\"GROQ_API_KEY\"]) caps.push(\"stt\");\n return caps;\n}\n\n/** Get normalized system load (0-1). */\nfunction getLoad(): number {\n const cores = cpus().length || 1;\n return Math.min(1, loadavg()[0]! / cores);\n}\n\n/** Build the gossip packet. */\nfunction getGossipKey(config: ReturnType<typeof loadPeerConfig>): string | null {\n if (config.gossipSecret) return config.gossipSecret as string;\n return null;\n}\n\nfunction buildPacket(): Buffer {\n const config = loadPeerConfig();\n const payload = JSON.stringify({\n name: config.self.name,\n ts: Math.floor(Date.now() / 1000),\n load: Math.round(getLoad() * 100) / 100,\n sessions: parseInt(process.env[\"_ACTIVE_SESSIONS\"] ?? \"0\", 10),\n capabilities: _capabilities,\n version: process.env[\"npm_package_version\"] ?? \"?\",\n });\n const key = getGossipKey(config) ?? Object.values(config.peers)[0]?.token ?? \"default\";\n const sig = createHmac(\"sha256\", key).update(payload).digest(\"base64url\").slice(0, 16);\n return Buffer.from(`${payload}|${sig}`);\n}\n\n/** Verify incoming packet HMAC. */\nfunction verifyPacket(data: Buffer): Record<string, unknown> | null {\n const str = data.toString(\"utf8\");\n const sepIdx = str.lastIndexOf(\"|\");\n if (sepIdx < 0) return null;\n const payload = str.slice(0, sepIdx);\n const sig = str.slice(sepIdx + 1);\n const config = loadPeerConfig();\n // Prefer shared gossipSecret\n const shared = getGossipKey(config);\n if (shared) {\n const expected = createHmac(\"sha256\", shared).update(payload).digest(\"base64url\").slice(0, 16);\n if (sig === expected) { try { return JSON.parse(payload); } catch { return null; } }\n return null;\n }\n // Fallback: try all peer tokens\n for (const peer of Object.values(config.peers)) {\n const key = peer.token;\n if (!key) continue;\n const expected = createHmac(\"sha256\", key).update(payload).digest(\"base64url\").slice(0, 16);\n if (sig === expected) { try { return JSON.parse(payload); } catch { return null; } }\n }\n return null;\n}\n\n/** Broadcast to all known peers. */\nfunction broadcast(): void {\n const config = loadPeerConfig();\n const packet = buildPacket();\n for (const [name, entry] of Object.entries(config.peers)) {\n _socket?.send(packet, 0, packet.length, GOSSIP_PORT, entry.host, (err) => {\n if (err) logTrace(TAG, `Send to ${name} (${entry.host}:${GOSSIP_PORT}) failed: ${err.message}`);\n });\n }\n logTrace(TAG, `Broadcast to ${Object.keys(config.peers).length} peer(s)`);\n // Expire stale entries\n const now = Date.now();\n for (const [, health] of peerTable) {\n const wasAlive = health.alive;\n health.alive = (now - health.lastSeen) < TTL_MS;\n if (wasAlive && !health.alive) logDebug(TAG, `PEER_OFFLINE ${health.name} (no heartbeat for ${Math.round((now - health.lastSeen) / 1000)}s)`);\n }\n}\n\n/** Start gossip system. */\nexport function startGossip(): void {\n _capabilities = discoverCapabilities();\n logInfo(TAG, `Capabilities: [${_capabilities.join(\", \")}]`);\n\n _socket = createSocket(\"udp4\");\n _socket.on(\"message\", (msg, rinfo) => {\n const parsed = verifyPacket(msg);\n if (!parsed || typeof parsed.name !== \"string\") return;\n const name = parsed.name as string;\n const config = loadPeerConfig();\n\n // Ping/pong: reply with signed PONG, skip peer-table update\n if (parsed.type === \"ping\") {\n const key = getGossipKey(config) ?? Object.values(config.peers)[0]?.token ?? \"default\";\n const pong = \"PONG\";\n const sig = createHmac(\"sha256\", key).update(pong).digest(\"base64url\").slice(0, 16);\n const reply = Buffer.from(`${pong}|${sig}`);\n _socket?.send(reply, 0, reply.length, rinfo.port, rinfo.address);\n return;\n }\n\n if (name === config.self.name) return; // ignore own echo\n\n const existing = peerTable.get(name);\n const health: PeerHealth = {\n name,\n lastSeen: Date.now(),\n load: (parsed.load as number) ?? 0,\n sessions: (parsed.sessions as number) ?? 0,\n capabilities: (parsed.capabilities as string[]) ?? [],\n version: (parsed.version as string) ?? \"?\",\n alive: true,\n host: rinfo.address,\n port: rinfo.port,\n };\n peerTable.set(name, health);\n if (!existing) logDebug(TAG, `PEER_ONLINE ${name} [${health.capabilities.join(\",\")}] v${health.version}`);\n else if (!existing.alive) logDebug(TAG, `PEER_ONLINE ${name} returned [${health.capabilities.join(\",\")}] v${health.version}`);\n });\n\n _socket.on(\"error\", (err) => { logWarn(TAG, `Socket error: ${err.message}`); });\n _socket.bind(GOSSIP_PORT, \"0.0.0.0\", () => {\n logInfo(TAG, `Listening on UDP :${GOSSIP_PORT}`);\n });\n\n // Broadcast immediately, then every 60s\n setTimeout(broadcast, 2000);\n _interval = setInterval(broadcast, BROADCAST_INTERVAL_MS);\n}\n\n/** Stop gossip. */\nexport function stopGossip(): void {\n if (_interval) { clearInterval(_interval); _interval = null; }\n if (_socket) { _socket.close(); _socket = null; }\n}\n\n/** Get live peer table (alive peers only unless includeAll). */\nexport function getPeerTable(includeAll = false): PeerHealth[] {\n const now = Date.now();\n const results: PeerHealth[] = [];\n for (const health of peerTable.values()) {\n health.alive = (now - health.lastSeen) < TTL_MS;\n if (includeAll || health.alive) results.push(health);\n }\n return results;\n}\n\n/** Get this peer's capabilities. */\nexport function getLocalCapabilities(): string[] { return _capabilities; }\n\n/** Find best peer matching required capabilities, sorted by load. */\nexport function findCapablePeer(requires: string[]): PeerHealth | null {\n const alive = getPeerTable().filter(p =>\n requires.every(req => p.capabilities.includes(req))\n );\n if (alive.length === 0) return null;\n alive.sort((a, b) => a.load - b.load);\n return alive[0]!;\n}\n\n/** Alias for boot compatibility. */\nexport const startGossipListener = startGossip;\n\n/** Alias for http-transport compatibility. */\nexport const getAlivePeers = getPeerTable;\n\n/** Alias for phase-heartbeat compatibility. */\nexport const gossipBroadcast = broadcast;\n\n/** Alias: update broadcast interval (resets the internal timer). */\nexport function setGossipInterval(ms: number): void {\n if (_interval) { clearInterval(_interval); _interval = setInterval(broadcast, ms); }\n}\n\n/** Alias for stopGossip. */\nexport const stopGossipListener = stopGossip;\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
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
- }
@@ -1,82 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
3
- import {
4
- init_logger,
5
- logDebug,
6
- logError,
7
- logWarn
8
- } from "./chunk-GWILHZPT.js";
9
-
10
- // src/utils/abmind-lazy.ts
11
- init_logger();
12
- import { createRequire } from "node:module";
13
- import { readFileSync } from "node:fs";
14
- var ABMIND_MIN = [0, 3, 0];
15
- var _mod = null;
16
- var _loaded = false;
17
- function resetAbmindCache() {
18
- _mod = null;
19
- _loaded = false;
20
- }
21
- function parseSemver(v) {
22
- const m = /^(\d+)\.(\d+)\.(\d+)/.exec(v);
23
- return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
24
- }
25
- function lt(a, b) {
26
- return a[0] !== b[0] ? a[0] < b[0] : a[1] !== b[1] ? a[1] < b[1] : a[2] < b[2];
27
- }
28
- function isSupportedVersion(version) {
29
- const p = parseSemver(version);
30
- return !!p && !lt(p, ABMIND_MIN);
31
- }
32
- function readResolvedAbmindVersion() {
33
- try {
34
- const req = createRequire(import.meta.url);
35
- const pkgPath = req.resolve("abmind/package.json");
36
- return JSON.parse(readFileSync(pkgPath, "utf-8")).version ?? null;
37
- } catch {
38
- return null;
39
- }
40
- }
41
- async function loadAbmind() {
42
- if (_loaded) return _mod;
43
- _loaded = true;
44
- let mod = null;
45
- try {
46
- const req = createRequire(import.meta.url);
47
- const resolvedPath = req.resolve("abmind");
48
- mod = await import(resolvedPath);
49
- } catch {
50
- mod = null;
51
- }
52
- if (!mod) {
53
- logWarn("boot", "abmind not installed \u2014 running without persistent memory");
54
- _mod = null;
55
- return null;
56
- }
57
- const ver = readResolvedAbmindVersion();
58
- if (!ver || !isSupportedVersion(ver)) {
59
- logError(
60
- "boot",
61
- `abmind@${ver ?? "?"} is below the supported floor ${ABMIND_MIN.join(".")} \u2014 memory disabled to avoid a silent contract break. Upgrade: npm install -g abmind@latest`
62
- );
63
- _mod = null;
64
- return null;
65
- }
66
- logDebug("boot", `memory: enabled via abmind@${ver}`);
67
- _mod = mod;
68
- return _mod;
69
- }
70
- function abmind() {
71
- return _mod;
72
- }
73
-
74
- export {
75
- ABMIND_MIN,
76
- resetAbmindCache,
77
- parseSemver,
78
- isSupportedVersion,
79
- loadAbmind,
80
- abmind
81
- };
82
- //# sourceMappingURL=chunk-IKUZPMVA.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/utils/abmind-lazy.ts"],
4
- "sourcesContent": ["/**\n * Lazy abmind loader \u2014 pre-loaded once at boot, then available synchronously.\n * ALL runtime access to abmind goes through here.\n *\n * If abmind is not installed, or is below the supported contract version\n * (#1243), abmind() returns null and the bridge runs without persistent\n * memory (nullMemory). A below-floor abmind is rejected loudly \u2014 never a\n * silent contract break that would quietly drop memory mid-session.\n */\nimport { createRequire } from \"node:module\";\nimport { readFileSync } from \"node:fs\";\nimport { logDebug, logError, logWarn } from \"../components/logger.js\";\n\ntype AbmindModule = typeof import(\"abmind\");\n\n/**\n * Minimum abmind version that provides the supported contract surface\n * (abmind SUPPORTED-SURFACE.md, #1243). Below this \u2192 memory disabled loudly.\n * Bump only when abtars starts relying on newer surface.\n */\nexport const ABMIND_MIN: readonly [number, number, number] = [0, 3, 0];\n\nlet _mod: AbmindModule | null = null;\nlet _loaded = false;\n\n/** Reset cache \u2014 called on in-process restart. */\nexport function resetAbmindCache(): void {\n _mod = null;\n _loaded = false;\n}\n\n/** Parse the leading major.minor.patch from a semver string (ignores pre-release/build). */\nexport function parseSemver(v: string): [number, number, number] | null {\n const m = /^(\\d+)\\.(\\d+)\\.(\\d+)/.exec(v);\n return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;\n}\n\nfunction lt(a: readonly [number, number, number], b: readonly [number, number, number]): boolean {\n return a[0] !== b[0] ? a[0] < b[0] : a[1] !== b[1] ? a[1] < b[1] : a[2] < b[2];\n}\n\n/** True iff `version` is at least ABMIND_MIN (the supported contract floor). */\nexport function isSupportedVersion(version: string): boolean {\n const p = parseSemver(version);\n return !!p && !lt(p, ABMIND_MIN);\n}\n\n/** Read the version of the resolvable abmind package, or null if not resolvable. */\nfunction readResolvedAbmindVersion(): string | null {\n try {\n const req = createRequire(import.meta.url);\n const pkgPath = req.resolve(\"abmind/package.json\");\n return (JSON.parse(readFileSync(pkgPath, \"utf-8\")).version as string) ?? null;\n } catch {\n return null;\n }\n}\n\n/** Call once at boot (phase-memory). Caches the module. Returns null if unavailable or below-floor. */\nexport async function loadAbmind(): Promise<AbmindModule | null> {\n if (_loaded) return _mod;\n _loaded = true;\n\n let mod: AbmindModule | null = null;\n try {\n const req = createRequire(import.meta.url);\n const resolvedPath = req.resolve(\"abmind\");\n mod = await import(resolvedPath);\n } catch {\n mod = null;\n }\n if (!mod) {\n logWarn(\"boot\", \"abmind not installed \u2014 running without persistent memory\");\n _mod = null;\n return null;\n }\n\n const ver = readResolvedAbmindVersion();\n if (!ver || !isSupportedVersion(ver)) {\n logError(\n \"boot\",\n `abmind@${ver ?? \"?\"} is below the supported floor ${ABMIND_MIN.join(\".\")} \u2014 memory disabled to avoid a silent contract break. Upgrade: npm install -g abmind@latest`,\n );\n _mod = null;\n return null;\n }\n\n logDebug(\"boot\", `memory: enabled via abmind@${ver}`);\n _mod = mod;\n return _mod;\n}\n\n/** Synchronous access after loadAbmind() has been called. Returns null if unavailable. */\nexport function abmind(): AbmindModule | null {\n return _mod;\n}\n"],
5
- "mappings": ";;;;;;;;;;AAWA;AAFA,SAAS,qBAAqB;AAC9B,SAAS,oBAAoB;AAUtB,IAAM,aAAgD,CAAC,GAAG,GAAG,CAAC;AAErE,IAAI,OAA4B;AAChC,IAAI,UAAU;AAGP,SAAS,mBAAyB;AACvC,SAAO;AACP,YAAU;AACZ;AAGO,SAAS,YAAY,GAA4C;AACtE,QAAM,IAAI,uBAAuB,KAAK,CAAC;AACvC,SAAO,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI;AAC1D;AAEA,SAAS,GAAG,GAAsC,GAA+C;AAC/F,SAAO,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAC/E;AAGO,SAAS,mBAAmB,SAA0B;AAC3D,QAAM,IAAI,YAAY,OAAO;AAC7B,SAAO,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,UAAU;AACjC;AAGA,SAAS,4BAA2C;AAClD,MAAI;AACF,UAAM,MAAM,cAAc,YAAY,GAAG;AACzC,UAAM,UAAU,IAAI,QAAQ,qBAAqB;AACjD,WAAQ,KAAK,MAAM,aAAa,SAAS,OAAO,CAAC,EAAE,WAAsB;AAAA,EAC3E,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,aAA2C;AAC/D,MAAI,QAAS,QAAO;AACpB,YAAU;AAEV,MAAI,MAA2B;AAC/B,MAAI;AACF,UAAM,MAAM,cAAc,YAAY,GAAG;AACzC,UAAM,eAAe,IAAI,QAAQ,QAAQ;AACzC,UAAM,MAAM,OAAO;AAAA,EACrB,QAAQ;AACN,UAAM;AAAA,EACR;AACA,MAAI,CAAC,KAAK;AACR,YAAQ,QAAQ,+DAA0D;AAC1E,WAAO;AACP,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,0BAA0B;AACtC,MAAI,CAAC,OAAO,CAAC,mBAAmB,GAAG,GAAG;AACpC;AAAA,MACE;AAAA,MACA,UAAU,OAAO,GAAG,iCAAiC,WAAW,KAAK,GAAG,CAAC;AAAA,IAC3E;AACA,WAAO;AACP,WAAO;AAAA,EACT;AAEA,WAAS,QAAQ,8BAA8B,GAAG,EAAE;AACpD,SAAO;AACP,SAAO;AACT;AAGO,SAAS,SAA8B;AAC5C,SAAO;AACT;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/capabilities/sleep/index.ts"],
4
- "sourcesContent": ["import { logAndSwallow } from \"../../components/log-and-swallow.js\";\nimport { getEnv } from \"../../components/env-schema.js\";\nimport type { CapabilityApi } from \"../capability.js\";\n/**\n * Sleep capability \u2014 spawn nightly sleep cycle via tick system.\n * One path: BED_TIME + quiet ticks \u2192 Dreamy \u2192 quiet ticks \u2192 hardware sleep.\n * Parses PROGRESS:<pct>:<label> from stdout for visibility.\n */\n\nimport { execSync } from \"node:child_process\";\nimport { writeSleepStatus, readAndClearForceSleep } from \"../../components/transport/bridge-lock-transport.js\";\nimport { join } from \"node:path\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport type { Level } from \"abmind\";\nimport { abmind } from \"../../utils/abmind-lazy.js\";\nimport type { SleepRuntime } from \"abmind\";\nimport { logInfo, logWarn, logDebug } from \"../../components/logger.js\";\nimport { readEnv, readEnvWithDefault } from \"../../components/env.js\";\n\nexport interface SleepOpts {\n sleepHour: number;\n sleepAuditDir: string;\n memoryEnabled: boolean;\n memoryDir?: string;\n /** LLM runtime adapter \u2014 bridge wraps its SubagentRuntime.complete(\"dreamy\", ...). */\n runtime: SleepRuntime;\n onComplete: () => void;\n getLastMsgTs?: () => number;\n sendSystemMessage?: (prompt: string) => Promise<void>;\n killWakeInhibit?: () => void;\n}\n\nexport interface SleepProgress {\n percent: number;\n step: string;\n}\n\nexport interface SleepHandle {\n /** True while a sleep cycle is running in-process. */\n readonly isActive: boolean;\n readonly progress: SleepProgress | null;\n readonly awaitingHwSleep: boolean;\n spawn(): void;\n /** Called by tick system to check if hardware sleep should fire. */\n checkHwSleep(): void;\n /** Force-clear isActive if no progress in 30min (#990). */\n checkStale(): void;\n}\n\nconst MAX_RETRIES = 3;\nconst RETRY_MS = 5 * 60 * 1000;\n\nexport function createSleepHandle(opts: SleepOpts): SleepHandle {\n let running = false;\n let attempts = 0;\n let progress: SleepProgress | null = null;\n let _awaitingHwSleep = false;\n // Post-Dreamy hw-sleep quiet-tick tracking (internal to this closure \u2014 decoupled from\n // daily-cycle.quietTickCount which freezes once hasSleepAuditToday returns true).\n // Both reset when _awaitingHwSleep flips to true (see the onComplete handler below).\n let postSleepQuietTicks = 0;\n let lastMsgTsSeenByHwCheck = 0;\n\n function buildDreamReport(): string {\n let dreamReport = \"Dreamy finished nightly maintenance.\";\n try {\n const sleepDir = join(opts.memoryDir ?? \"\", \"sleep\");\n const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, \"\");\n const lockPath = join(sleepDir, `sleep_${dateStr}.lock`);\n if (existsSync(lockPath)) {\n const lockData = JSON.parse(readFileSync(lockPath, \"utf-8\")) as { steps: Record<string, { status: string }>; llmCalls?: number };\n const ok = Object.entries(lockData.steps).filter(([, s]) => s.status === \"ok\").map(([k]) => k);\n const skipped = Object.entries(lockData.steps).filter(([, s]) => s.status === \"skipped\").map(([k]) => k);\n const failed = Object.entries(lockData.steps).filter(([, s]) => s.status === \"failed\" || s.status === \"timeout\").map(([k]) => k);\n dreamReport = `Dreamy finished nightly maintenance (${lockData.llmCalls ?? \"?\"} LLM calls). Completed: ${ok.join(\", \") || \"none\"}.`;\n if (skipped.length > 0) dreamReport += ` Skipped: ${skipped.join(\", \")}.`;\n if (failed.length > 0) dreamReport += ` \u26A0\uFE0F FAILED: ${failed.join(\", \")}. Please review.`;\n }\n } catch (err) { logAndSwallow(\"index\", \"op\", err); }\n return dreamReport;\n }\n\n function spawnSleep(): void {\n const forceSleep = readAndClearForceSleep();\n const forced = forceSleep !== null;\n if (forced) {\n logInfo(\"sleep\", `\u26A1 forceSleep=${forceSleep} \u2014 bypassing time-window + audit-today guards`);\n }\n\n if (!forced) {\n const hour = new Date().getHours();\n const WAKE_HOUR = parseInt(readEnvWithDefault(\"WAKE_TIME\", \"7\", \"wake hour\").split(\":\")[0] ?? \"7\", 10);\n if (opts.sleepHour <= WAKE_HOUR) {\n if (hour < opts.sleepHour || hour >= WAKE_HOUR) {\n logDebug(\"sleep\", `\uD83D\uDE34 Outside sleep window (${opts.sleepHour}:00-${WAKE_HOUR}:00) \u2014 skip`);\n return;\n }\n } else {\n if (hour < opts.sleepHour && hour >= WAKE_HOUR) {\n logDebug(\"sleep\", `\uD83D\uDE34 Outside sleep window (${opts.sleepHour}:00-${WAKE_HOUR}:00) \u2014 skip`);\n return;\n }\n }\n if (abmind()?.hasSleepAuditToday(opts.sleepAuditDir)) {\n logDebug(\"sleep\", \"\uD83D\uDE34 Sleep already done today \u2014 skip\");\n return;\n }\n }\n if (running) return;\n attempts++;\n progress = null;\n running = true;\n writeSleepStatus(\"sleeping\");\n logInfo(\"sleep\", `\uD83D\uDE34 Sleep started in-process (attempt ${attempts}, model=dreamy)`);\n\n const level = (() => {\n if (forced && forceSleep?.includes(\"fresh\")) return \"ultimate\" as Level;\n const raw = getEnv().sleepQuality;\n if (!raw) return abmind()!.DEFAULT_LEVEL;\n try { return abmind()!.parseLevel(raw); }\n catch (err) { logWarn(\"sleep\", `Invalid SLEEP_QUALITY='${raw}', using ${abmind()!.DEFAULT_LEVEL}: ${err instanceof Error ? err.message : String(err)}`); return abmind()!.DEFAULT_LEVEL; }\n })();\n\n abmind()!.runSleepCycle({ runtime: opts.runtime, level, fresh: forced && !!forceSleep?.includes(\"fresh\") })\n .then(async (result: { ok: boolean; failCount: number }) => {\n running = false;\n progress = null;\n logInfo(\"sleep\", `\uD83D\uDE34 Sleep finished (ok=${result.ok}, failCount=${result.failCount}, attempt ${attempts})`);\n writeSleepStatus(\"awake\");\n if (!result.ok) {\n if (attempts < MAX_RETRIES) {\n logWarn(\"sleep\", `\uD83D\uDE34 Sleep had ${result.failCount} failures (attempt ${attempts}/${MAX_RETRIES}) \u2014 retry in 5min`);\n setTimeout(spawnSleep, RETRY_MS);\n } else {\n logWarn(\"sleep\", `\uD83D\uDE34 Sleep failures persist \u2014 exhausted ${MAX_RETRIES} attempts`);\n }\n return;\n }\n\n if (opts.memoryEnabled) opts.onComplete();\n\n // Force-sleep runs are explicit test/verify triggers \u2014 skip hw-sleep even if env enabled.\n const hwEnabled = !forced && readEnv(\"HARDWARE_SLEEP_AFTER_DREAMY\", \"hardware sleep after Dreamy disabled\") === \"true\";\n const quietTicks = Math.ceil(getEnv().bedQuietMin * 60 / parseInt(readEnvWithDefault(\"HEARTBEAT_INTERVAL_SEC\", \"60\", \"hb\"), 10));\n const hbInterval = parseInt(readEnvWithDefault(\"HEARTBEAT_INTERVAL_SEC\", \"60\", \"heartbeat tick interval\"), 10);\n const hwSleepMin = Math.round(quietTicks * hbInterval / 60);\n\n const dreamReport = buildDreamReport();\n const sleepNote = hwEnabled ? ` Hardware sleep in ~${hwSleepMin} minutes if no activity.` : \"\";\n\n // #844: buffer silently \u2014 don't trigger model response\n const { bufferSystemEvent } = await import(\"../../components/system-event-buffer.js\");\n bufferSystemEvent(`${dreamReport}${sleepNote}`);\n\n if (hwEnabled) {\n _awaitingHwSleep = true;\n // Reset hw-check counters \u2014 prevents stale state from a prior cycle (crash, force-sleep\n // re-run) from poisoning this one, and avoids burning the first tick on a spurious\n // reset when the very first checkHwSleep() sees currentMsgTs > 0.\n postSleepQuietTicks = 0;\n lastMsgTsSeenByHwCheck = opts.getLastMsgTs?.() ?? 0;\n logInfo(\"sleep\", `\uD83D\uDCA4 Awaiting hardware sleep \u2014 ${quietTicks} quiet ticks (${hwSleepMin} min) required`);\n }\n })\n .catch((err: unknown) => {\n running = false;\n progress = null;\n writeSleepStatus(\"awake\");\n const msg = err instanceof Error ? err.message : String(err);\n if (attempts < MAX_RETRIES) {\n logWarn(\"sleep\", `\uD83D\uDE34 Sleep threw (attempt ${attempts}/${MAX_RETRIES}): ${msg} \u2014 retry in 5min`);\n setTimeout(spawnSleep, RETRY_MS);\n } else {\n logWarn(\"sleep\", `\uD83D\uDE34 Sleep threw \u2014 exhausted ${MAX_RETRIES} attempts: ${msg}`);\n }\n });\n }\n\n function checkHwSleep(): void {\n if (!_awaitingHwSleep) return;\n\n // Sleep-window cutoff \u2014 give up if we've crossed out of the window. Next night retries.\n // Mirrors spawnSleep()'s window logic for consistency.\n const WAKE_HOUR = parseInt(readEnvWithDefault(\"WAKE_TIME\", \"7\", \"wake hour\").split(\":\")[0] ?? \"7\", 10);\n const BED_HOUR = opts.sleepHour;\n const hour = new Date().getHours();\n const inSleepWindow = (BED_HOUR < WAKE_HOUR)\n ? (hour >= BED_HOUR && hour < WAKE_HOUR) // normal: BED=00:30, WAKE=07:00 \u2192 sleep 00-06\n : (hour >= BED_HOUR || hour < WAKE_HOUR); // overnight: BED=23:00, WAKE=07:00 \u2192 sleep 23-06\n if (!inSleepWindow) {\n logInfo(\"sleep\", `\u23F0 Past sleep window (now ${hour}:00, window ${BED_HOUR}:00-${WAKE_HOUR}:00) \u2014 abandoning hw-sleep attempt`);\n _awaitingHwSleep = false;\n postSleepQuietTicks = 0;\n return;\n }\n\n // User messaged since last check \u2014 postpone and reset\n const currentMsgTs = opts.getLastMsgTs?.() ?? 0;\n if (currentMsgTs > lastMsgTsSeenByHwCheck) {\n lastMsgTsSeenByHwCheck = currentMsgTs;\n postSleepQuietTicks = 0;\n logInfo(\"sleep\", \"\uD83D\uDCA4 Hardware sleep postponed \u2014 user messaged (will retry after quiet period)\");\n return;\n }\n\n // Quiet tick \u2014 increment\n const requiredTicks = Math.ceil(getEnv().bedQuietMin * 60 / parseInt(process.env[\"HEARTBEAT_INTERVAL_SEC\"] ?? \"60\", 10));\n postSleepQuietTicks++;\n if (postSleepQuietTicks < requiredTicks) return;\n\n // Threshold reached \u2014 sleep\n _awaitingHwSleep = false;\n postSleepQuietTicks = 0;\n // Kill any wake inhibitor from /wakeup before sleeping\n opts.killWakeInhibit?.();\n const sleepCmd = process.platform === \"darwin\" ? \"pmset sleepnow\" : \"systemctl suspend\";\n logInfo(\"sleep\", `\uD83D\uDCA4 Putting hardware to sleep (${sleepCmd})...`);\n writeSleepStatus(\"hw_sleep\");\n try { execSync(sleepCmd, { timeout: 5000 }); }\n catch (err) {\n writeSleepStatus(\"awake\"); // recover \u2014 don't leave \"hw_sleep\" if pmset failed\n logWarn(\"sleep\", `\uD83D\uDCA4 Hardware sleep failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n function checkStale(): void {\n if (!running) return;\n const STALE_MS = 30 * 60_000;\n try {\n const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, \"\");\n const lockPath = join(opts.sleepAuditDir, `sleep_${dateStr}.lock`);\n if (!existsSync(lockPath)) { running = false; logWarn(\"sleep\", \"Sleep stuck \u2014 no lock file, force-clearing isActive\"); return; }\n const lock = JSON.parse(readFileSync(lockPath, \"utf-8\")) as { startedAt?: number; steps?: Record<string, { duration?: number }> };\n const stepTimes = Object.values(lock.steps ?? {}).map(s => (s as any).startedAt ?? (s as any).completedAt ?? 0).filter(Boolean);\n const lastActivity = Math.max(lock.startedAt ?? 0, ...stepTimes);\n if (lastActivity > 0 && Date.now() - lastActivity > STALE_MS) {\n running = false;\n logWarn(\"sleep\", `Sleep stuck \u2014 no progress in 30min (last activity ${Math.round((Date.now() - lastActivity) / 60_000)}min ago), force-clearing isActive`);\n }\n } catch { /* lock file unreadable \u2014 leave running as-is, next tick retries */ }\n }\n\n return {\n get isActive() { return running; },\n get progress() { return progress; },\n get awaitingHwSleep() { return _awaitingHwSleep; },\n spawn: spawnSleep,\n checkHwSleep,\n checkStale,\n };\n}\n\n/** Capability registration \u2014 called by discoverCapabilities(). */\nexport function register(_api: CapabilityApi): void {\n // Sleep registration is a no-op here \u2014 the actual SleepHandle is created\n // in phase-sleep.ts because it needs ctx.sendSystemMessage + memory deps\n // that aren't available at capability discovery time.\n // This manifest exists so sleep appears in discoverCapabilities() and\n // can be disabled via DISABLED_CAPABILITIES=sleep.\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/components/spin-sessions.ts", "../src/components/artifact-store.ts", "../src/components/transport/artifact-tools.ts", "../src/components/spin.ts"],
4
- "sourcesContent": ["/**\n * spin-sessions.ts \u2014 Session CRUD on a flat Map<id, ManagedSession> (#953).\n * No PlatformState, no bucketing. Filter/find on the one map.\n */\n\nimport type { ManagedSession, SessionType } from \"./spin-types.js\";\nimport { sessionType, sessionCreatedAt, typeLabel } from \"./spin-types.js\";\n\nconst MAX_LOG = 5;\n\nexport function pushLog(session: ManagedSession, event: string): void {\n session.log.push(`${new Date().toISOString().slice(11, 19)} ${event}`);\n if (session.log.length > MAX_LOG) session.log.shift();\n}\n\nexport function allocateSession(\n sessions: Map<string, ManagedSession>, nextIndex: number,\n type: SessionType, userId: string, platform: string, chatId: number,\n opts?: { active?: boolean; motherId?: string },\n): { session: ManagedSession; nextIndex: number } {\n const idx = nextIndex + 1;\n const ts = Math.floor(Date.now() / 1000);\n const session: ManagedSession = {\n id: `${ts}_${type}_${String(idx).padStart(2, \"0\")}`,\n userId, platform, chatId,\n delivery: \"simple\",\n active: opts?.active ?? false,\n status: \"ready\",\n idleTimeoutMs: 7200000,\n lastActiveAt: Date.now(),\n motherId: opts?.motherId,\n messageCount: 0, tokenCount: 0, toolCallCount: 0,\n log: [],\n shortIndex: idx,\n // Pipeline state defaults (#1040)\n busy: false, queue: [], fullMode: false, pendingStart: false,\n seen: false, compacting: false, ctxWarned: false, compactFailures: 0,\n primingTerms: [], completions: [],\n };\n sessions.set(session.id, session);\n pushLog(session, \"created\");\n return { session, nextIndex: idx };\n}\n\nexport function getActiveSession(sessions: Map<string, ManagedSession>, userId: string, platform: string): ManagedSession | undefined {\n for (const s of sessions.values()) {\n if (s.userId === userId && s.platform === platform && s.active && s.status !== \"ended\") return s;\n }\n return undefined;\n}\n\nexport function createSession(\n sessions: Map<string, ManagedSession>, nextIndex: number,\n userId: string, platform: string, type: SessionType, chatId: number, maxSessions: number,\n): { session: ManagedSession; nextIndex: number } | string {\n const alive = [...sessions.values()].filter(s => s.status !== \"ended\");\n if (alive.length >= maxSessions) return `Max sessions reached (${maxSessions}). End or kill a session first.`;\n\n // Deactivate current active\n const cur = getActiveSession(sessions, userId, platform);\n if (cur) cur.active = false;\n\n const result = allocateSession(sessions, nextIndex, type, userId, platform, chatId, { active: true });\n return result;\n}\n\nexport function createSubSession(\n sessions: Map<string, ManagedSession>, nextIndex: number,\n userId: string, platform: string, type: SessionType, chatId: number, maxSessions: number,\n): { session: ManagedSession; nextIndex: number } | string {\n const alive = [...sessions.values()].filter(s => s.status !== \"ended\");\n if (alive.length >= maxSessions) return `Max sessions reached \u2014 auto-spawn skipped.`;\n\n const active = getActiveSession(sessions, userId, platform);\n return allocateSession(sessions, nextIndex, type, userId, platform, chatId, { active: false, motherId: active?.id });\n}\n\nexport function isHollow(session: ManagedSession): boolean { return !!session.peer; }\n\nexport function createHollowSession(\n sessions: Map<string, ManagedSession>, nextIndex: number,\n userId: string, platform: string, type: SessionType, chatId: number,\n peer: string, remoteSessionId: string, maxSessions: number,\n): { session: ManagedSession; nextIndex: number } | string {\n const alive = [...sessions.values()].filter(s => s.status !== \"ended\");\n if (alive.length >= maxSessions) return `Max sessions reached \u2014 cannot create hollow session.`;\n\n const result = allocateSession(sessions, nextIndex, type, userId, platform, chatId, { active: false });\n result.session.peer = peer;\n result.session.remoteSessionId = remoteSessionId;\n pushLog(result.session, `hollow (${peer})`);\n return result;\n}\n\nexport function switchSession(sessions: Map<string, ManagedSession>, userId: string, platform: string, index: number): ManagedSession | string {\n const target = [...sessions.values()].find(s => s.shortIndex === index && s.status !== \"ended\" && s.userId === userId);\n if (!target) return `Session #${index} not found or not switchable.`;\n const cur = getActiveSession(sessions, userId, platform);\n if (cur) cur.active = false;\n target.active = true;\n return target;\n}\n\nexport function endSession(sessions: Map<string, ManagedSession>, nextIndex: number, userId: string, platform: string, index?: number): { ended: ManagedSession; nextIndex: number } | string {\n const targetIdx = index ?? getActiveSession(sessions, userId, platform)?.shortIndex;\n if (!targetIdx) return `No active session found.`;\n const target = [...sessions.values()].find(s => s.shortIndex === targetIdx && s.status !== \"ended\" && s.userId === userId);\n if (!target) return `Session #${targetIdx} not found.`;\n\n const aliveMains = [...sessions.values()].filter(s => sessionType(s) === \"A\" && s.status !== \"ended\" && s.userId === userId);\n\n target.status = \"ended\";\n target.active = false;\n pushLog(target, \"ended\");\n\n // If ended the last Main, create a replacement\n if (sessionType(target) === \"A\" && aliveMains.length <= 1) {\n const result = allocateSession(sessions, nextIndex, \"A\", userId, platform, target.chatId, { active: true });\n return { ended: target, nextIndex: result.nextIndex };\n }\n\n // If ended the active session, activate first available Main\n if (index === undefined || target.active) {\n const main = [...sessions.values()].find(s => sessionType(s) === \"A\" && s.status !== \"ended\" && s.userId === userId);\n if (main) main.active = true;\n }\n\n return { ended: target, nextIndex };\n}\n\nexport function killSession(sessions: Map<string, ManagedSession>, nextIndex: number, userId: string, platform: string, index: number): { killed: ManagedSession; nextIndex: number } | string {\n const target = [...sessions.values()].find(s => s.shortIndex === index && s.status !== \"ended\" && s.userId === userId);\n if (!target) return `Session #${index} not found.`;\n\n target.status = \"ended\";\n target.active = false;\n pushLog(target, \"killed\");\n\n // If killed a Main and it was the last, create replacement\n const aliveMains = [...sessions.values()].filter(s => sessionType(s) === \"A\" && s.status !== \"ended\" && s.userId === userId);\n if (sessionType(target) === \"A\" && aliveMains.length === 0) {\n const result = allocateSession(sessions, nextIndex, \"A\", userId, platform, target.chatId, { active: true });\n return { killed: target, nextIndex: result.nextIndex };\n }\n\n // If killed the active, activate a Main\n if (!getActiveSession(sessions, userId, platform)) {\n const main = [...sessions.values()].find(s => sessionType(s) === \"A\" && s.status !== \"ended\" && s.userId === userId);\n if (main) main.active = true;\n }\n\n return { killed: target, nextIndex };\n}\n\nexport function pauseSession(sessions: Map<string, ManagedSession>, userId: string, platform: string, index?: number): ManagedSession | string {\n const targetIdx = index ?? getActiveSession(sessions, userId, platform)?.shortIndex;\n if (!targetIdx) return `No active session found.`;\n const target = [...sessions.values()].find(s => s.shortIndex === targetIdx && s.status !== \"ended\" && s.userId === userId);\n if (!target) return `Session #${targetIdx} not found.`;\n if (target.status === \"paused\") return `Session #${targetIdx} is already paused.`;\n target.status = \"paused\";\n pushLog(target, \"paused\");\n return target;\n}\n\nexport function resumeSession(sessions: Map<string, ManagedSession>, userId: string, platform: string, index?: number): ManagedSession | string {\n const targetIdx = index ?? getActiveSession(sessions, userId, platform)?.shortIndex;\n if (!targetIdx) return `No active session found.`;\n const target = [...sessions.values()].find(s => s.shortIndex === targetIdx && s.status !== \"ended\" && s.userId === userId);\n if (!target) return `Session #${targetIdx} not found.`;\n if (target.status !== \"paused\") return `Session #${targetIdx} is not paused.`;\n target.status = \"ready\";\n pushLog(target, \"resumed\");\n return target;\n}\n\nexport function listSessions(sessions: Map<string, ManagedSession>, userId: string, platform: string): ManagedSession[] {\n return [...sessions.values()].filter(s => s.userId === userId && s.platform === platform && s.status !== \"ended\");\n}\n\nexport function listAllSessions(sessions: Map<string, ManagedSession>): ManagedSession[] {\n return [...sessions.values()].filter(s => s.status !== \"ended\");\n}\n\nexport function getSessionById(sessions: Map<string, ManagedSession>, sessionId: string): ManagedSession | undefined {\n return sessions.get(sessionId);\n}\n\nexport function formatList(sessions: Map<string, ManagedSession>, userId: string, platform: string, showAll = false): string {\n const list = showAll ? listAllSessions(sessions) : listSessions(sessions, userId, platform);\n if (list.length === 0) return \"No active sessions.\";\n return list.map(s => {\n const marker = s.active && s.userId === userId ? \" *\" : \"\";\n const owner = showAll && s.userId !== userId ? ` (${s.userId})` : \"\";\n const bg = !s.active && sessionType(s) !== \"A\" ? \" (bg)\" : \"\";\n const paused = s.status === \"paused\" ? \" \u23F8\" : \"\";\n const remote = s.peer ? ` (remote: ${s.peer})` : \"\";\n const model = s.model ? ` ${s.model}` : \"\";\n const nm = s.name ? ` \"${s.name}\"` : \"\";\n const time = new Date(sessionCreatedAt(s)).toLocaleTimeString(\"en-GB\", { hour: \"2-digit\", minute: \"2-digit\" });\n const idle = s.busy ? \"busy\" : `idle ${Math.round((Date.now() - s.lastActiveAt) / 60000)}m`;\n const metrics = s.messageCount ? ` | ${s.messageCount} msgs` : \"\";\n return `#${s.shortIndex} ${typeLabel(sessionType(s))}${owner}${nm}${remote}${bg}${model} \u2014 ${time}${paused}${marker} | ${idle}${metrics}`;\n }).join(\"\\n\");\n}\n", "/**\n * artifact-store.ts \u2014 S3-compatible artifact store with lazy SDK loading (#929).\n */\n\nimport { createReadStream, createWriteStream } from \"node:fs\";\nimport { pipeline } from \"node:stream/promises\";\nimport { execSync } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { Readable } from \"node:stream\";\n\nconst LIB_DIR = join(process.env[\"ABTARS_HOME\"] ?? join(homedir(), \".abtars\"), \"lib\");\nconst localRequire = createRequire(join(LIB_DIR, \"node_modules\", \"_placeholder.js\"));\n\nlet _s3: any;\nlet _presigner: any;\n\nfunction loadSdk(): void {\n if (_s3) return;\n try {\n _s3 = localRequire(\"@aws-sdk/client-s3\");\n _presigner = localRequire(\"@aws-sdk/s3-request-presigner\");\n } catch {\n execSync(`npm install --prefix \"${LIB_DIR}\" @aws-sdk/client-s3 @aws-sdk/s3-request-presigner`, { stdio: \"pipe\" });\n _s3 = localRequire(\"@aws-sdk/client-s3\");\n _presigner = localRequire(\"@aws-sdk/s3-request-presigner\");\n }\n}\n\nfunction getClient(): any {\n const endpoint = process.env[\"ARTIFACT_S3_ENDPOINT\"];\n if (!endpoint) throw new Error(\"Artifact store not configured\");\n loadSdk();\n return new _s3.S3Client({\n endpoint,\n region: process.env[\"ARTIFACT_S3_REGION\"] || \"auto\",\n credentials: { accessKeyId: process.env[\"ARTIFACT_S3_KEY\"] ?? \"\", secretAccessKey: process.env[\"ARTIFACT_S3_SECRET\"] ?? \"\" },\n });\n}\n\nfunction bucket(): string {\n return process.env[\"ARTIFACT_S3_BUCKET\"] || \"abtars-artifacts\";\n}\n\nexport async function upload(localPath: string, remotePath: string): Promise<string> {\n const client = getClient();\n const stream = createReadStream(localPath);\n await client.send(new _s3.PutObjectCommand({ Bucket: bucket(), Key: remotePath, Body: stream }));\n return `${process.env[\"ARTIFACT_S3_ENDPOINT\"]}/${bucket()}/${remotePath}`;\n}\n\nexport async function download(remotePath: string, localPath: string): Promise<void> {\n const client = getClient();\n const resp = await client.send(new _s3.GetObjectCommand({ Bucket: bucket(), Key: remotePath }));\n await pipeline(resp.Body as Readable, createWriteStream(localPath));\n}\n\nexport async function presign(remotePath: string, expiresIn = 3600): Promise<string> {\n const client = getClient();\n const cmd = new _s3.GetObjectCommand({ Bucket: bucket(), Key: remotePath });\n return _presigner.getSignedUrl(client, cmd, { expiresIn });\n}\n\nexport async function exists(remotePath: string): Promise<boolean> {\n const client = getClient();\n try {\n await client.send(new _s3.HeadObjectCommand({ Bucket: bucket(), Key: remotePath }));\n return true;\n } catch { return false; }\n}\n\nexport async function remove(remotePath: string): Promise<void> {\n const client = getClient();\n await client.send(new _s3.DeleteObjectCommand({ Bucket: bucket(), Key: remotePath }));\n}\n", "/**\n * artifact-tools.ts \u2014 Agent tools for S3 artifact store (#929) + inline transfer (#928).\n */\n\nimport type { ToolDefinition } from \"./tool-registry.js\";\nimport { upload, download } from \"../artifact-store.js\";\nimport { readFileSync, statSync } from \"node:fs\";\nimport { basename } from \"node:path\";\n\n// \u2500\u2500 Inline artifact queue (#928) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface InlineArtifact { name: string; content: string }\n\nconst pendingArtifacts = new Map<number, InlineArtifact[]>();\n\nconst MAX_FILE_BYTES = 1_000_000; // 1MB raw\n\nexport function drainArtifacts(cardId: number): InlineArtifact[] | undefined {\n const arts = pendingArtifacts.get(cardId);\n if (arts) pendingArtifacts.delete(cardId);\n return arts;\n}\n\nexport const artifactAttachTool: ToolDefinition = {\n name: \"artifact_attach\",\n description: \"Attach a local file to the task result. The file is base64-encoded and sent back to the delegating peer on task completion. Max 1MB per file.\",\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"Absolute path to the file to attach\" },\n card_id: { type: \"number\", description: \"Current card ID (from environment)\" },\n },\n required: [\"path\", \"card_id\"],\n },\n async execute(args): Promise<string> {\n const filePath = args[\"path\"];\n const cardId = parseInt(args[\"card_id\"] ?? \"0\", 10);\n if (!filePath) return JSON.stringify({ error: \"path is required\" });\n if (!cardId) return JSON.stringify({ error: \"card_id is required\" });\n\n try {\n const stat = statSync(filePath);\n if (stat.size > MAX_FILE_BYTES) {\n return JSON.stringify({ error: `File too large: ${stat.size} bytes (max ${MAX_FILE_BYTES})` });\n }\n const content = readFileSync(filePath).toString(\"base64\");\n const name = basename(filePath);\n const list = pendingArtifacts.get(cardId) ?? [];\n list.push({ name, content });\n pendingArtifacts.set(cardId, list);\n return JSON.stringify({ ok: true, name, size: stat.size, queued: list.length });\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n },\n};\n\nexport const artifactPushTool: ToolDefinition = {\n name: \"artifact_push\",\n description: \"Upload a local file to the shared artifact store (S3). Returns the artifact URL.\",\n parameters: {\n type: \"object\",\n properties: {\n local_path: { type: \"string\", description: \"Absolute path to local file\" },\n remote_path: { type: \"string\", description: \"Remote key/path in the artifact store\" },\n },\n required: [\"local_path\", \"remote_path\"],\n },\n async execute(args): Promise<string> {\n try {\n const url = await upload(args[\"local_path\"] ?? \"\", args[\"remote_path\"] ?? \"\");\n return JSON.stringify({ ok: true, url });\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n },\n};\n\nexport const artifactPullTool: ToolDefinition = {\n name: \"artifact_pull\",\n description: \"Download a file from the shared artifact store (S3) to a local path.\",\n parameters: {\n type: \"object\",\n properties: {\n remote_path: { type: \"string\", description: \"Remote key/path in the artifact store\" },\n local_path: { type: \"string\", description: \"Absolute local path to save the file\" },\n },\n required: [\"remote_path\", \"local_path\"],\n },\n async execute(args): Promise<string> {\n try {\n await download(args[\"remote_path\"] ?? \"\", args[\"local_path\"] ?? \"\");\n return JSON.stringify({ ok: true, path: args[\"local_path\"] });\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n },\n};\n", "/**\n * spin.ts \u2014 Unified session router (#943, #953).\n * Single flat Map<sessionId, ManagedSession>. No bucketing. No PlatformState.\n */\n\nimport { logInfo, logWarn, logDebug } from \"./logger.js\";\nimport { logAndSwallow } from \"./log-and-swallow.js\";\nimport { kanbanEnqueue, kanbanRunning, kanbanComplete, kanbanFail, kanbanRetryOrFail, kanbanList, kanbanGetCard, isUnblocked } from \"./tasks/kanban-board.js\";\nimport type { SubagentRuntime, AgentSession } from \"./subagent-runtime.js\";\nimport type { IKiroTransport } from \"./transport/kiro-transport.js\";\nimport { loadUsers } from \"./user-registry.js\";\nimport { getMasterUserId } from \"./master-user.js\";\nimport type { ManagedSession, SpinRequest, SessionType } from \"./spin-types.js\";\nimport { typeAgent, sessionType } from \"./spin-types.js\";\nimport * as Sessions from \"./spin-sessions.js\";\nimport { pushLog, isHollow } from \"./spin-sessions.js\";\n\nexport type { ManagedSession, SpinRequest, SessionType } from \"./spin-types.js\";\nexport { sessionType, sessionCreatedAt, typeLabel, typeAgent, parseSessionType } from \"./spin-types.js\";\nexport { isHollow };\n\nconst TAG = \"spin\";\nconst USER_SESSION_IDLE_MS = parseInt(process.env[\"USER_SESSION_IDLE_MS\"] ?? \"7200000\", 10);\nconst GUEST_SESSION_IDLE_MS = parseInt(process.env[\"GUEST_SESSION_IDLE_MS\"] ?? \"1800000\", 10);\nconst MAX_TOTAL_SESSIONS = parseInt(process.env[\"MAX_TOTAL_SESSIONS\"] ?? \"12\", 10);\nconst SESSION_CREATE_TIMEOUT_MS = 30_000;\nconst DEFAULT_TIMEOUT_MS = 30 * 60_000;\n\nconst MAX_CONCURRENT: Partial<Record<SessionType, number>> = {\n T: 1, O: 1, B: 1, D: 1, H: 1, W: 3,\n};\n\nexport class Spin {\n private sessions = new Map<string, ManagedSession>();\n private nextIndex = 0;\n private running = new Map<SessionType, Set<number>>();\n private runtime: SubagentRuntime | null = null;\n private memory: { recordMessage(opts: { role: string; content: string; timestamp: number; userId: string; sessionId: string }): void } | null = null;\n private orcSession: AgentSession | null = null;\n private _lastHealerDoneAt = 0;\n private _housekeepCounter = 0;\n\n setRuntime(runtime: SubagentRuntime): void { this.runtime = runtime; }\n setMemory(memory: Spin[\"memory\"]): void { this.memory = memory; }\n\n // \u2500\u2500 Session CRUD \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n getActiveSession(userId: string, platform: string): ManagedSession {\n let s = Sessions.getActiveSession(this.sessions, userId, platform);\n if (!s) {\n // Auto-create initial Main session\n const r = Sessions.allocateSession(this.sessions, this.nextIndex, \"A\", userId, platform, 0, { active: true });\n this.nextIndex = r.nextIndex;\n s = r.session;\n }\n return s;\n }\n\n getActiveSessionId(userId: string, platform: string): string {\n return this.getActiveSession(userId, platform).id;\n }\n\n createSession(userId: string, platform: string, type: SessionType): ManagedSession | string {\n // Ensure a Main session exists before creating additional ones\n this.getActiveSession(userId, platform);\n const r = Sessions.createSession(this.sessions, this.nextIndex, userId, platform, type, 0, MAX_TOTAL_SESSIONS);\n if (typeof r === \"string\") return r;\n this.nextIndex = r.nextIndex;\n return r.session;\n }\n\n createSubSession(userId: string, platform: string, type: SessionType): ManagedSession | string {\n const r = Sessions.createSubSession(this.sessions, this.nextIndex, userId, platform, type, 0, MAX_TOTAL_SESSIONS);\n if (typeof r === \"string\") return r;\n this.nextIndex = r.nextIndex;\n return r.session;\n }\n\n createHollowSession(userId: string, platform: string, type: SessionType, peer: string, remoteSessionId: string): ManagedSession | string {\n const r = Sessions.createHollowSession(this.sessions, this.nextIndex, userId, platform, type, 0, peer, remoteSessionId, MAX_TOTAL_SESSIONS);\n if (typeof r === \"string\") return r;\n this.nextIndex = r.nextIndex;\n return r.session;\n }\n\n switchSession(userId: string, platform: string, index: number): ManagedSession | string {\n return Sessions.switchSession(this.sessions, userId, platform, index);\n }\n\n endSession(userId: string, platform: string, index?: number): ManagedSession | string {\n const r = Sessions.endSession(this.sessions, this.nextIndex, userId, platform, index);\n if (typeof r === \"string\") return r;\n this.nextIndex = r.nextIndex;\n return r.ended;\n }\n\n killSession(userId: string, platform: string, index: number): ManagedSession | string {\n const r = Sessions.killSession(this.sessions, this.nextIndex, userId, platform, index);\n if (typeof r === \"string\") return r;\n this.nextIndex = r.nextIndex;\n return r.killed;\n }\n\n pauseSession(userId: string, platform: string, index?: number): ManagedSession | string {\n return Sessions.pauseSession(this.sessions, userId, platform, index);\n }\n\n resumeSession(userId: string, platform: string, index?: number): ManagedSession | string {\n return Sessions.resumeSession(this.sessions, userId, platform, index);\n }\n\n listSessions(userId: string, platform: string): { sessions: ManagedSession[]; activeIndex: number } {\n const list = Sessions.listSessions(this.sessions, userId, platform);\n const active = list.find(s => s.active);\n return { sessions: list, activeIndex: active?.shortIndex ?? 0 };\n }\n\n listAllSessions(): ManagedSession[] {\n return Sessions.listAllSessions(this.sessions);\n }\n\n getSessionById(sessionId: string): ManagedSession | undefined {\n return this.sessions.get(sessionId);\n }\n\n formatList(userId: string, platform: string, showAll = false): string {\n return Sessions.formatList(this.sessions, userId, platform, showAll);\n }\n\n clearAll(): void { this.sessions.clear(); this.nextIndex = 0; }\n\n // \u2500\u2500 Interactive session lifecycle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n private _greetingSent = false;\n private _greetingAdapter: { injectMessage: (msg: any) => void } | null = null;\n\n registerMasterSession(opts: { userId: string; chatId: number; platform: string; transport: IKiroTransport }): void {\n const session = this.getActiveSession(opts.userId, opts.platform);\n session.transport = opts.transport;\n session.delivery = \"streaming\";\n session.idleTimeoutMs = Infinity;\n session.chatId = opts.chatId;\n session.status = \"ready\";\n session.lastActiveAt = Date.now();\n const t = opts.transport as any;\n session.pid = t?._rawClient?.pid ?? t?.agent?.pid ?? undefined;\n pushLog(session, \"master transport attached\");\n logInfo(TAG, `Master session registered: ${opts.userId} (${opts.platform}:${opts.chatId}${session.pid ? ` pid=${session.pid}` : \"\"})`);\n\n // #980: Fire greeting once adapter is set (deferred via setGreetingAdapter)\n this._masterOpts = { userId: opts.userId, chatId: opts.chatId, platform: opts.platform };\n this.tryFireGreeting();\n }\n\n /** Set the adapter for boot greeting. Called after platforms are up. */\n setGreetingAdapter(adapter: { injectMessage: (msg: any) => void }): void {\n this._greetingAdapter = adapter;\n this.tryFireGreeting();\n }\n\n private _masterOpts: { userId: string; chatId: number; platform: string } | null = null;\n\n private tryFireGreeting(): void {\n if (this._greetingSent || !this._greetingAdapter || !this._masterOpts) return;\n this._greetingSent = true;\n const { userId, chatId, platform } = this._masterOpts;\n const session = this.getActiveSession(userId, platform);\n this.greetSession(session, chatId, userId);\n }\n\n /** Inject a greeting into an interactive session (A/C only). */\n greetSession(session: ManagedSession, chatId: number, userId: string, adapter?: { injectMessage: (msg: any) => void }): void {\n const type = sessionType(session);\n if (type !== \"A\" && type !== \"C\") return;\n if (session.messageCount > 0) return;\n const a = adapter ?? this._greetingAdapter;\n if (!a) return;\n\n let attempt = 0;\n const inject = (): void => {\n attempt++;\n a.injectMessage({\n platform: session.platform,\n channelId: String(chatId),\n userId,\n senderId: String(chatId),\n senderName: userId,\n text: \"[SESSION START] You just came online. Greet the user.\",\n timestamp: Date.now(),\n isGroup: false,\n isVoice: false,\n });\n setTimeout(() => {\n if (session.messageCount > 0) return;\n if (session.busy) return;\n if (attempt >= 3) { logWarn(TAG, \"Greeting failed after 3 attempts\"); return; }\n logWarn(TAG, `Greeting attempt ${attempt}/3 \u2014 no response, retrying`);\n inject();\n }, 60_000);\n };\n\n if (session.transport?.isReady) {\n inject();\n } else if (session.transport) {\n session.transport.onReady = () => inject();\n }\n }\n\n async resolveSession(userId: string, platform: string, chatId: number): Promise<ManagedSession> {\n const session = this.getActiveSession(userId, platform);\n\n if (session.transport) {\n session.lastActiveAt = Date.now();\n return session;\n }\n if (session.status === \"ended\") throw new Error(\"Session ended \u2014 use /session new\");\n\n const total = this.listAllSessions().filter(s => s.transport).length;\n if (total >= MAX_TOTAL_SESSIONS) throw new Error(\"System busy, try again in a few minutes.\");\n\n session.status = \"creating\";\n session.chatId = chatId;\n const registry = loadUsers();\n const user = registry.byUserId.get(userId);\n const role = user?.role ?? \"guest\";\n session.idleTimeoutMs = role === \"master\" ? Infinity : role === \"guest\" ? GUEST_SESSION_IDLE_MS : USER_SESSION_IDLE_MS;\n session.delivery = role === \"master\" ? \"streaming\" : \"simple\";\n\n pushLog(session, `creating transport (${role})`);\n logInfo(TAG, `Creating transport for ${userId} (${role})`);\n\n try {\n const agentSession = await Promise.race([\n this.runtime!.session(\"professor\", userId),\n new Promise<never>((_, rej) => setTimeout(() => rej(new Error(\"Session creation timed out\")), SESSION_CREATE_TIMEOUT_MS)),\n ]);\n session.transport = agentSession.transport!;\n session.status = \"ready\";\n session.lastActiveAt = Date.now();\n const t = session.transport as any;\n session.pid = t?._rawClient?.pid ?? t?.agent?.pid ?? undefined;\n pushLog(session, \"transport ready\");\n logInfo(TAG, `Session ready: ${userId} id=${session.id}${session.pid ? ` pid=${session.pid}` : \"\"}`);\n return session;\n } catch (err) {\n session.status = \"ended\";\n pushLog(session, `error: ${err instanceof Error ? err.message : String(err)}`);\n logWarn(TAG, `Session creation failed for ${userId}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n }\n\n destroySession(userId: string, sessionId?: string): void {\n for (const s of this.sessions.values()) {\n if (s.userId !== userId) continue;\n if (sessionId && s.id !== sessionId) continue;\n if (s.idleTimeoutMs === Infinity) continue;\n if (s.transport) { try { s.transport.destroy(); } catch (err) { logAndSwallow(TAG, \"destroy\", err); } s.transport = undefined; }\n s.status = \"ended\";\n s.active = false;\n pushLog(s, \"destroyed\");\n logInfo(TAG, `Session destroyed: ${userId} id=${s.id}`);\n }\n }\n\n destroyAll(): void {\n for (const s of this.sessions.values()) {\n if (s.transport) { try { s.transport.destroy(); } catch (err) { logAndSwallow(TAG, \"destroy\", err); } }\n }\n if (this.orcSession) { try { this.orcSession.destroy(); } catch (err) { logAndSwallow(TAG, \"destroy\", err); } this.orcSession = null; }\n this.sessions.clear();\n this.nextIndex = 0;\n logInfo(TAG, \"All sessions destroyed (shutdown)\");\n }\n\n // \u2500\u2500 injectGreeting() \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // #1106: replaced inject() (which generated a model response but never\n // delivered to the user). injectGreeting routes a synthetic message\n // through the normal pipeline \u2014 the model responds AND the response is\n // delivered to the user via the standard adapter.sendMessage path.\n\n async injectGreeting(userId: string, prompt: string): Promise<string | null> {\n if (!this._greetingAdapter) { logWarn(TAG, \"injectGreeting: no adapter\"); return null; }\n const registry = loadUsers();\n const user = registry.byUserId.get(userId);\n if (!user) { logWarn(TAG, `inject: unknown user ${userId}`); return null; }\n const chatId = user.platforms.telegram ?? user.platforms.discord;\n if (!chatId) { logWarn(TAG, `inject: no chatId for ${userId}`); return null; }\n const platform = user.platforms.telegram ? \"telegram\" : \"discord\";\n this._greetingAdapter.injectMessage({\n platform,\n channelId: String(chatId),\n userId,\n senderId: String(chatId),\n senderName: userId,\n text: prompt,\n timestamp: Date.now(),\n isGroup: false,\n isVoice: false,\n });\n logInfo(TAG, `injectGreeting: routed to pipeline for ${userId}`);\n return \"routed\";\n }\n\n // \u2500\u2500 Orc \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n getOrcSession(): AgentSession | null { return this.orcSession?.isReady ? this.orcSession : null; }\n\n async sendUserToOrc(message: string): Promise<string | null> {\n const orc = this.getOrcSession();\n if (!orc) return null;\n const response = await orc.sendPrompt(\"orc:user\", `[USER] ${message}`);\n return response;\n }\n\n private async getOrCreateOrc(): Promise<AgentSession> {\n if (this.orcSession?.isReady) return this.orcSession;\n logInfo(TAG, \"Spawning persistent Orc session\");\n this.orcSession = await this.runtime!.session(\"browsie\");\n return this.orcSession;\n }\n\n // \u2500\u2500 Dispatch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** #1010: O-type reuses existing session (one Orc). All others create new. */\n private getOrCreateVisibleSession(userId: string, type: SessionType): ManagedSession | undefined {\n if (type === \"O\") {\n for (const s of this.sessions.values()) {\n if (s.id.includes(\"_O_\") && s.status !== \"ended\") return s;\n }\n }\n const sub = this.createSubSession(userId, \"telegram\", type);\n return typeof sub === \"string\" ? undefined : sub;\n }\n\n dispatch(request: SpinRequest): { cardId: number; sessionId?: string } {\n const cardTitle = request.title ?? request.goal.slice(0, 80);\n const cardId = request.cardId ?? kanbanEnqueue(cardTitle, request.source, undefined, {\n priority: request.priority ?? \"MEDIUM\", type: request.type,\n parent_id: request.parentCardId, deliveryMode: request.deliveryMode,\n notes: request.callbackPeer ? JSON.stringify({ callback_peer: request.callbackPeer }) : undefined,\n chatId: request.chatId, sourcePeer: request.sourcePeer,\n });\n\n if (!this.canDispatch(request.type, cardId)) {\n logInfo(TAG, `${request.type} card:${cardId} queued (concurrency gate)`);\n return { cardId };\n }\n\n this.markRunning(request.type, cardId);\n kanbanRunning(cardId);\n\n const masterUserId = getMasterUserId();\n const session = this.getOrCreateVisibleSession(masterUserId, request.type);\n if (session) { session.name = request.title?.slice(0, 20); pushLog(session, `dispatch card:${cardId}`); }\n\n const timeout = request.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.execute(request, cardId, timeout)\n .then(result => {\n const { drainArtifacts } = require(\"./transport/artifact-tools.js\") as typeof import(\"./transport/artifact-tools.js\");\n const artifacts = drainArtifacts(cardId);\n kanbanComplete(cardId, null, result.slice(0, 500));\n if (request.callbackPeer) {\n const card = kanbanGetCard(cardId);\n fireCallback(request.callbackPeer, cardId, \"done\", result.slice(0, 500), undefined, artifacts, card?.tokens_used ?? 0);\n }\n })\n .catch(err => {\n const msg = (err instanceof Error ? err.message : String(err)).slice(0, 1000);\n logWarn(TAG, `${request.type} card:${cardId} failed: ${msg}`);\n kanbanRetryOrFail(cardId, msg);\n if (request.callbackPeer) fireCallback(request.callbackPeer, cardId, \"failed\", undefined, msg);\n })\n .finally(() => {\n this.markDone(request.type, cardId);\n if (session) { session.status = \"ended\"; session.active = false; pushLog(session, \"completed\"); }\n this.drainQueued();\n });\n\n return { cardId, sessionId: session?.id };\n }\n\n async dispatchAwait(request: SpinRequest): Promise<{ cardId: number; result: string }> {\n // #987: enforce concurrency + cooldown gates (same as dispatch)\n if (!this.canDispatch(request.type, 0)) {\n throw new Error(`${request.type} session busy or in cooldown \u2014 skipping`);\n }\n\n const cardTitle = request.title ?? request.goal.slice(0, 80);\n const cardId = request.cardId ?? kanbanEnqueue(cardTitle, request.source, undefined, {\n priority: request.priority ?? \"MEDIUM\", type: request.type,\n parent_id: request.parentCardId, deliveryMode: request.deliveryMode,\n chatId: request.chatId,\n });\n\n this.markRunning(request.type, cardId);\n kanbanRunning(cardId);\n\n const masterUserId = getMasterUserId();\n const session = this.getOrCreateVisibleSession(masterUserId, request.type);\n if (session) { session.name = request.title?.slice(0, 20); pushLog(session, `dispatchAwait card:${cardId}`); }\n\n const timeout = request.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n try {\n const result = await this.execute(request, cardId, timeout);\n return { cardId, result };\n } finally {\n this.markDone(request.type, cardId);\n // O-type: session stays alive until Orc idle timeout (visible in /session)\n if (session && request.type !== \"O\") { session.status = \"ended\"; session.active = false; pushLog(session, \"completed\"); }\n this.drainQueued();\n }\n }\n\n spawnChild(parentCardId: number, request: Omit<SpinRequest, \"type\"> & { type?: SessionType }): number {\n if (request.type === \"O\") throw new Error(\"Cannot nest orchestrators\");\n return this.dispatch({ ...request, type: \"W\", parentCardId }).cardId;\n }\n\n // \u2500\u2500 Internal \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n private drainQueued(): void {\n const queued = kanbanList(\"queued\");\n const now = new Date().toISOString();\n for (const card of queued) {\n // #897: respect retry backoff\n if ((card as any).next_retry_at && (card as any).next_retry_at > now) continue;\n // #677: respect DAG dependencies\n if (!isUnblocked(card)) continue;\n const type = (card.type as SessionType) ?? \"T\";\n if (this.canDispatch(type, card.id)) {\n this.dispatch({ type, goal: card.title, source: (card.source as SpinRequest[\"source\"]) ?? \"task\", cardId: card.id });\n }\n }\n }\n\n /** Periodic housekeeping \u2014 registered as HB task (#980). */\n async tick(): Promise<void> {\n this.drainQueued();\n this.checkStaleWorkers();\n await this.pollRemoteCards();\n this._housekeepCounter++;\n if (this._housekeepCounter % 72 === 0) {\n this.pruneSkillTrash();\n this.rotateAuditLog();\n this.pruneEndedSessions();\n }\n }\n\n private checkStaleWorkers(): void {\n const STALE_MS = parseInt(process.env[\"WORKER_STALE_MS\"] || \"300000\", 10);\n const now = Date.now();\n for (const [, cardIds] of this.running) {\n for (const cardId of cardIds) {\n const card = kanbanGetCard(cardId);\n if (!card || card.status !== \"running\") continue;\n const lastActivity = new Date(card.updated_at + \"Z\").getTime();\n if (now - lastActivity > STALE_MS) {\n logWarn(TAG, `Stale card ${cardId} (${Math.round((now - lastActivity) / 1000)}s no activity) \u2014 failing`);\n kanbanFail(cardId, \"stale \u2014 no activity\");\n }\n }\n }\n }\n\n /** #613: Prune .trash/ entries older than 7 days (~hourly). */\n private pruneSkillTrash(): void {\n const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;\n const { existsSync, readdirSync, rmSync, statSync } = require(\"node:fs\") as typeof import(\"node:fs\");\n const { join } = require(\"node:path\") as typeof import(\"node:path\");\n const { abtarsHome } = require(\"../paths.js\") as typeof 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 /** #681: Rotate audit.jsonl when > 10MB, prune files older than 30 days (~hourly). */\n private rotateAuditLog(): void {\n const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000;\n const { existsSync, statSync, renameSync, readdirSync, unlinkSync } = require(\"node:fs\") as typeof import(\"node:fs\");\n const { join } = require(\"node:path\") as typeof import(\"node:path\");\n const { abtarsHome } = require(\"../paths.js\") as typeof 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 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 /** #1248: Prune ended sessions older than 1 hour (~hourly). Prevents unbounded Map growth. */\n private pruneEndedSessions(): void {\n const ONE_HOUR_MS = 60 * 60 * 1000;\n const now = Date.now();\n for (const [id, s] of this.sessions) {\n if (s.status === \"ended\" && now - s.lastActiveAt > ONE_HOUR_MS) {\n this.sessions.delete(id);\n logDebug(TAG, `Pruned ended session: ${s.userId} id=${id}`);\n }\n }\n }\n\n private async pollRemoteCards(): Promise<void> {\n const remoteCards = kanbanList(\"running\", \"status\").filter(c => c.type === \"remote\");\n if (remoteCards.length === 0) return;\n const { getPeerTransport } = await import(\"./peer-transport/index.js\");\n const transport = getPeerTransport();\n const REMOTE_MAX_AGE_MS = 15 * 60 * 1000;\n for (const card of remoteCards) {\n try {\n const meta = JSON.parse(card.notes ?? \"{}\") as { peer?: string; remote_task_id?: number };\n if (!meta.peer || !meta.remote_task_id) continue;\n const cardAge = Date.now() - new Date(card.created_at + \"Z\").getTime();\n if (cardAge > REMOTE_MAX_AGE_MS) {\n kanbanFail(card.id, `remote task timeout (${Math.round(cardAge / 60000)}min)`);\n continue;\n }\n const result = await transport.checkTask(meta.peer, meta.remote_task_id);\n if (result.status === \"done\") kanbanComplete(card.id, null, result.result?.slice(0, 500) ?? \"completed\");\n else if (result.status === \"failed\") kanbanFail(card.id, result.error ?? \"remote task failed\");\n } catch (err) { logAndSwallow(TAG, \"pollRemote\", err); }\n }\n }\n\n private canDispatch(type: SessionType, _cardId: number): boolean {\n const max = MAX_CONCURRENT[type] ?? 5;\n if ((this.running.get(type)?.size ?? 0) >= max) return false;\n // #987: 2-min cooldown after H session ends\n if (type === \"H\" && Date.now() - this._lastHealerDoneAt < 120_000) return false;\n return true;\n }\n\n private markRunning(type: SessionType, cardId: number): void {\n if (!this.running.has(type)) this.running.set(type, new Set());\n this.running.get(type)!.add(cardId);\n }\n\n private markDone(type: SessionType, cardId: number): void {\n this.running.get(type)?.delete(cardId);\n if (type === \"H\") this._lastHealerDoneAt = Date.now();\n }\n\n private async execute(request: SpinRequest, cardId: number, timeoutMs: number): Promise<string> {\n if (!this.runtime) throw new Error(\"Spin: runtime not set\");\n if (request.type === \"O\") return this.executeOrc(request, cardId, timeoutMs);\n\n const agentName = request.agent ?? typeAgent(request.type);\n logInfo(TAG, `\u25B6 ${request.type} card:${cardId} agent=${agentName}`);\n\n try {\n const { buildSoulBundle } = await import(\"./soul-bundle.js\");\n const bundle = buildSoulBundle(request.type);\n let fullPrompt = bundle ? `${bundle}\\n\\n---\\n\\n${request.goal}` : request.goal;\n\n // #891: auto-inject channel messages for W/O sessions\n if (request.type === \"W\" || request.type === \"T\") {\n const { channelUnread } = await import(\"./tasks/kanban-channel.js\");\n const workerName = `Worker-${String(cardId).padStart(2, \"0\")}`;\n const parentCard = request.parentCardId ?? cardId;\n const msgs = channelUnread(parentCard, workerName);\n if (msgs.length > 0) {\n const lines = msgs.map(m => `[${m.from_agent}\u2192${m.to_agent}]${m.directive ? \" \u26A1\" : \"\"} ${m.message}`);\n fullPrompt = `[CHANNEL \u2014 ${msgs.length} message(s) for ${workerName}]\\n${lines.join(\"\\n\")}\\n[/CHANNEL]\\n\\n${fullPrompt}`;\n }\n }\n\n const result = (await this.runtime.complete(agentName, fullPrompt, { timeoutMs, session: \"fresh\" })) || \"(no output)\";\n if (this.memory) {\n const sid = `${request.type}_card${cardId}`;\n this.memory.recordMessage({ role: \"user\", content: request.goal, timestamp: Date.now(), userId: \"system\", sessionId: sid });\n this.memory.recordMessage({ role: \"assistant\", content: result, timestamp: Date.now(), userId: \"system\", sessionId: sid });\n }\n return result;\n } finally {}\n }\n\n private async executeOrc(request: SpinRequest, cardId: number, timeoutMs: number): Promise<string> {\n const { updateBridgeLockField } = await import(\"./transport/bridge-lock-transport.js\");\n const { setActiveOrcCard } = await import(\"./transport/orc-tools.js\");\n updateBridgeLockField(\"orc_active\", cardId);\n setActiveOrcCard(cardId);\n const orc = await this.getOrCreateOrc();\n logInfo(TAG, `\u25B6 O card:${cardId} (persistent Orc)`);\n\n // #993: Attach Orc transport to visible session \u2014 user can sneak in\n let orcSessionKey = \"orc:project\"; // fallback\n for (const [, s] of this.sessions) {\n if (s.id.includes(\"_O_\") && s.status !== \"ended\") {\n s.transport = orc.transport as any;\n s.status = \"ready\";\n orcSessionKey = s.id; // use proper ManagedSession ID as ACP session key\n break;\n }\n }\n const timer = setTimeout(() => { logWarn(TAG, `\u23F1\uFE0F O card:${cardId} timed out`); }, timeoutMs);\n try {\n const { buildSoulBundle } = await import(\"./soul-bundle.js\");\n const bundle = buildSoulBundle(\"O\");\n\n // #1005: CONTEXT wrapper (same pattern as Main)\n const { localDateTime } = await import(\"../utils/local-time.js\");\n const context = `[CONTEXT \u2014 do not respond to this section]\\n[PROJECT] card #${cardId}\\n[CURRENT TIME] ${localDateTime()}\\n[/CONTEXT]\\n\\n`;\n\n let fullPrompt = context + (bundle ? `${bundle}\\n\\n---\\n\\n${request.goal}` : request.goal);\n const { drainOrcNotifications } = await import(\"./spin-notifications.js\");\n const notifications = drainOrcNotifications(cardId);\n if (notifications.length) fullPrompt = notifications.join(\"\\n\") + \"\\n\\n\" + fullPrompt;\n\n // #891: Orc sees ALL channel messages on its card\n const { channelUnread } = await import(\"./tasks/kanban-channel.js\");\n const orcMsgs = channelUnread(cardId, \"Orc\");\n if (orcMsgs.length > 0) {\n const lines = orcMsgs.map(m => `[${m.from_agent}\u2192${m.to_agent}]${m.directive ? \" \u26A1\" : \"\"} ${m.message}`);\n fullPrompt = `[CHANNEL \u2014 ${orcMsgs.length} message(s)]\\n${lines.join(\"\\n\")}\\n[/CHANNEL]\\n\\n${fullPrompt}`;\n }\n\n const result = (await orc.sendPrompt(orcSessionKey, fullPrompt)) || \"(no output)\";\n if (this.memory) {\n this.memory.recordMessage({ role: \"user\", content: request.goal, timestamp: Date.now(), userId: \"system\", sessionId: orcSessionKey });\n this.memory.recordMessage({ role: \"assistant\", content: result, timestamp: Date.now(), userId: \"system\", sessionId: orcSessionKey });\n }\n return result;\n } finally { clearTimeout(timer); updateBridgeLockField(\"orc_active\", null); setActiveOrcCard(null); }\n }\n}\n\n/** #675: Fire result callback to the delegating peer. Fire-and-forget. */\nasync function fireCallback(peerName: string, taskId: number, status: \"done\" | \"failed\", result?: string, error?: string, artifacts?: Array<{ name: string; content: string }>, tokensUsed?: number): Promise<void> {\n try {\n const { getPeerTransport } = await import(\"./peer-transport/index.js\");\n const transport = getPeerTransport();\n const payload: Record<string, unknown> = { action: \"callback\", task_id: taskId, status, result_summary: result, error, tokens_used: tokensUsed ?? 0 };\n if (artifacts?.length) payload.artifacts = artifacts;\n await transport.send(peerName, { type: \"task\", payload });\n logInfo(TAG, `Callback fired to ${peerName} for card:${taskId} (${status})`);\n } catch (err) {\n logWarn(TAG, `Callback to ${peerName} failed (card:${taskId}): ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nexport const spin = new Spin();\n"],
5
- "mappings": "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",
6
- "names": ["drainArtifacts", "statSync", "join"]
7
- }
@@ -1,72 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
3
- import {
4
- init_log_and_swallow,
5
- logAndSwallow
6
- } from "./chunk-YSKCQH6E.js";
7
- import {
8
- __esm,
9
- __export
10
- } from "./chunk-7K2YZTLD.js";
11
-
12
- // src/components/peer-jwt.ts
13
- var peer_jwt_exports = {};
14
- __export(peer_jwt_exports, {
15
- signJwt: () => signJwt,
16
- verifyJwt: () => verifyJwt
17
- });
18
- import { createHmac, timingSafeEqual } from "node:crypto";
19
- function base64url(buf) {
20
- return buf.toString("base64url");
21
- }
22
- function base64urlEncode(str) {
23
- return Buffer.from(str, "utf-8").toString("base64url");
24
- }
25
- function base64urlDecode(str) {
26
- return Buffer.from(str, "base64url").toString("utf-8");
27
- }
28
- function signJwt(payload, secret) {
29
- const payloadB64 = base64urlEncode(JSON.stringify(payload));
30
- const sigInput = `${HEADER}.${payloadB64}`;
31
- const sig = base64url(createHmac("sha256", secret).update(sigInput).digest());
32
- return `${sigInput}.${sig}`;
33
- }
34
- function verifyJwt(token, secret, selfName, clockSkewSec = 5) {
35
- const parts = token.split(".");
36
- if (parts.length !== 3) return { ok: false, reason: "malformed" };
37
- const [headerB64, payloadB64, sigB64] = parts;
38
- const sigInput = `${headerB64}.${payloadB64}`;
39
- const expected = createHmac("sha256", secret).update(sigInput).digest();
40
- const actual = Buffer.from(sigB64, "base64url");
41
- if (expected.length !== actual.length || !timingSafeEqual(expected, actual)) {
42
- return { ok: false, reason: "bad_signature" };
43
- }
44
- let payload;
45
- try {
46
- payload = JSON.parse(base64urlDecode(payloadB64));
47
- } catch (err) {
48
- logAndSwallow(TAG, "JSON.parse jwt payload", err);
49
- return { ok: false, reason: "malformed_payload" };
50
- }
51
- const now = Math.floor(Date.now() / 1e3);
52
- if (payload.exp < now) return { ok: false, reason: "expired" };
53
- if (payload.iat > now + clockSkewSec) return { ok: false, reason: "iat_future" };
54
- if (payload.aud !== selfName) return { ok: false, reason: "wrong_aud" };
55
- return { ok: true, payload };
56
- }
57
- var TAG, HEADER;
58
- var init_peer_jwt = __esm({
59
- "src/components/peer-jwt.ts"() {
60
- init_log_and_swallow();
61
- TAG = "peer_jwt";
62
- HEADER = base64urlEncode(JSON.stringify({ alg: "HS256", typ: "JWT" }));
63
- }
64
- });
65
-
66
- export {
67
- signJwt,
68
- verifyJwt,
69
- peer_jwt_exports,
70
- init_peer_jwt
71
- };
72
- //# sourceMappingURL=chunk-RWRRGE4U.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/components/peer-jwt.ts"],
4
- "sourcesContent": ["/**\n * Minimal JWT-HS256 implementation for peer auth (#393).\n * No external deps \u2014 uses Node built-in crypto only.\n */\n\nimport { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { logAndSwallow } from \"./log-and-swallow.js\";\n\nconst TAG = \"peer_jwt\";\n\nexport interface JwtPayload {\n iss: string; // sender name\n aud: string; // receiver name\n iat: number; // issued-at (seconds)\n exp: number; // expiry (seconds)\n}\n\nfunction base64url(buf: Buffer): string {\n return buf.toString(\"base64url\");\n}\n\nfunction base64urlEncode(str: string): string {\n return Buffer.from(str, \"utf-8\").toString(\"base64url\");\n}\n\nfunction base64urlDecode(str: string): string {\n return Buffer.from(str, \"base64url\").toString(\"utf-8\");\n}\n\nconst HEADER = base64urlEncode(JSON.stringify({ alg: \"HS256\", typ: \"JWT\" }));\n\n/**\n * Sign a JWT with HS256.\n */\nexport function signJwt(payload: JwtPayload, secret: string): string {\n const payloadB64 = base64urlEncode(JSON.stringify(payload));\n const sigInput = `${HEADER}.${payloadB64}`;\n const sig = base64url(createHmac(\"sha256\", secret).update(sigInput).digest());\n return `${sigInput}.${sig}`;\n}\n\nexport type VerifyResult =\n | { ok: true; payload: JwtPayload }\n | { ok: false; reason: string };\n\n/**\n * Verify a JWT-HS256 token. Returns the payload if valid.\n *\n * @param token Raw JWT string\n * @param secret Shared secret for this peer\n * @param selfName Our own name (checked against `aud`)\n * @param clockSkewSec Tolerance for clock drift (default 5s)\n */\nexport function verifyJwt(\n token: string,\n secret: string,\n selfName: string,\n clockSkewSec = 5,\n): VerifyResult {\n const parts = token.split(\".\");\n if (parts.length !== 3) return { ok: false, reason: \"malformed\" };\n\n const [headerB64, payloadB64, sigB64] = parts;\n\n // Verify signature (timing-safe)\n const sigInput = `${headerB64}.${payloadB64}`;\n const expected = createHmac(\"sha256\", secret).update(sigInput).digest();\n const actual = Buffer.from(sigB64!, \"base64url\");\n if (expected.length !== actual.length || !timingSafeEqual(expected, actual)) {\n return { ok: false, reason: \"bad_signature\" };\n }\n\n // Decode payload\n let payload: JwtPayload;\n try {\n payload = JSON.parse(base64urlDecode(payloadB64!));\n } catch (err) {\n logAndSwallow(TAG, \"JSON.parse jwt payload\", err);\n return { ok: false, reason: \"malformed_payload\" };\n }\n\n // Check expiry\n const now = Math.floor(Date.now() / 1000);\n if (payload.exp < now) return { ok: false, reason: \"expired\" };\n\n // Check iat not too far in future (clock skew)\n if (payload.iat > now + clockSkewSec) return { ok: false, reason: \"iat_future\" };\n\n // Check audience\n if (payload.aud !== selfName) return { ok: false, reason: \"wrong_aud\" };\n\n return { ok: true, payload };\n}\n"],
5
- "mappings": ";;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,SAAS,YAAY,uBAAuB;AAY5C,SAAS,UAAU,KAAqB;AACtC,SAAO,IAAI,SAAS,WAAW;AACjC;AAEA,SAAS,gBAAgB,KAAqB;AAC5C,SAAO,OAAO,KAAK,KAAK,OAAO,EAAE,SAAS,WAAW;AACvD;AAEA,SAAS,gBAAgB,KAAqB;AAC5C,SAAO,OAAO,KAAK,KAAK,WAAW,EAAE,SAAS,OAAO;AACvD;AAOO,SAAS,QAAQ,SAAqB,QAAwB;AACnE,QAAM,aAAa,gBAAgB,KAAK,UAAU,OAAO,CAAC;AAC1D,QAAM,WAAW,GAAG,MAAM,IAAI,UAAU;AACxC,QAAM,MAAM,UAAU,WAAW,UAAU,MAAM,EAAE,OAAO,QAAQ,EAAE,OAAO,CAAC;AAC5E,SAAO,GAAG,QAAQ,IAAI,GAAG;AAC3B;AAcO,SAAS,UACd,OACA,QACA,UACA,eAAe,GACD;AACd,QAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,MAAI,MAAM,WAAW,EAAG,QAAO,EAAE,IAAI,OAAO,QAAQ,YAAY;AAEhE,QAAM,CAAC,WAAW,YAAY,MAAM,IAAI;AAGxC,QAAM,WAAW,GAAG,SAAS,IAAI,UAAU;AAC3C,QAAM,WAAW,WAAW,UAAU,MAAM,EAAE,OAAO,QAAQ,EAAE,OAAO;AACtE,QAAM,SAAS,OAAO,KAAK,QAAS,WAAW;AAC/C,MAAI,SAAS,WAAW,OAAO,UAAU,CAAC,gBAAgB,UAAU,MAAM,GAAG;AAC3E,WAAO,EAAE,IAAI,OAAO,QAAQ,gBAAgB;AAAA,EAC9C;AAGA,MAAI;AACJ,MAAI;AACF,cAAU,KAAK,MAAM,gBAAgB,UAAW,CAAC;AAAA,EACnD,SAAS,KAAK;AACZ,kBAAc,KAAK,0BAA0B,GAAG;AAChD,WAAO,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,EAClD;AAGA,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,MAAI,QAAQ,MAAM,IAAK,QAAO,EAAE,IAAI,OAAO,QAAQ,UAAU;AAG7D,MAAI,QAAQ,MAAM,MAAM,aAAc,QAAO,EAAE,IAAI,OAAO,QAAQ,aAAa;AAG/E,MAAI,QAAQ,QAAQ,SAAU,QAAO,EAAE,IAAI,OAAO,QAAQ,YAAY;AAEtE,SAAO,EAAE,IAAI,MAAM,QAAQ;AAC7B;AA5FA,IAQM,KAqBA;AA7BN;AAAA;AAMA;AAEA,IAAM,MAAM;AAqBZ,IAAM,SAAS,gBAAgB,KAAK,UAAU,EAAE,KAAK,SAAS,KAAK,MAAM,CAAC,CAAC;AAAA;AAAA;",
6
- "names": []
7
- }