abtars 0.3.4-alpha.8 → 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 (335) hide show
  1. package/bundle/{_registry.generated-YP5GLSG7.js → _registry.generated-AVR7DK2A.js} +15 -15
  2. package/bundle/{abmind-lazy-7Z44NODV.js → abmind-lazy-E3YCFKQ5.js} +15 -5
  3. package/bundle/abtars-browser.js +4 -4
  4. package/bundle/abtars-cli.js +23 -13
  5. package/bundle/abtars-cli.js.map +2 -2
  6. package/bundle/abtars-restart.js +3 -3
  7. package/bundle/abtars-task.js +3 -3
  8. package/bundle/abtars.js +385 -466
  9. package/bundle/abtars.js.map +4 -4
  10. package/bundle/{acp-raw-client-E6FM45NC.js → acp-raw-client-UCNK3OTU.js} +2 -2
  11. package/bundle/{action-gate-G2V47NHW.js → action-gate-V4FCBHFB.js} +2 -2
  12. package/bundle/{agent-api-adapter-WRGEQ6DV.js → agent-api-adapter-7HEPYSIN.js} +3 -3
  13. package/bundle/{agent-api-rate-limit-WCFXJMGY.js → agent-api-rate-limit-RZSAM3SW.js} +4 -4
  14. package/bundle/{agent-registry-GHNG2PH3.js → agent-registry-46A2R5KP.js} +7 -7
  15. package/bundle/{bootstrap-PZIDBPEJ.js → bootstrap-MIHJJSWU.js} +2 -2
  16. package/bundle/{bridge-lock-transport-4ZH7QTJP.js → bridge-lock-transport-7RSN7OLJ.js} +4 -4
  17. package/bundle/{browser-D3LZV7ZK.js → browser-F6BCWJWW.js} +6 -6
  18. package/bundle/{budget-45QOBDWA.js → budget-WUM3SPKW.js} +3 -3
  19. package/bundle/{capability-JFWX3IQF.js → capability-QVRKGRFC.js} +5 -5
  20. package/bundle/{chunk-YSKCQH6E.js → chunk-2IYJ4I66.js} +2 -2
  21. package/bundle/{chunk-W2R2HFOQ.js → chunk-2NLUT5S2.js} +6 -6
  22. package/bundle/chunk-3BG3AIDP.js +191 -0
  23. package/bundle/chunk-3BG3AIDP.js.map +7 -0
  24. package/bundle/{chunk-OKAQICWY.js → chunk-3GQX34S2.js} +3 -3
  25. package/bundle/{chunk-QROWBWLL.js → chunk-3XZ773BS.js} +2 -2
  26. package/bundle/{chunk-DYBW4XXL.js → chunk-467SRLLR.js} +2 -2
  27. package/bundle/{chunk-374NCXFZ.js → chunk-4AILRHUI.js} +10 -8
  28. package/bundle/chunk-4AILRHUI.js.map +7 -0
  29. package/bundle/{chunk-GPZNXY2U.js → chunk-4S3H4OK7.js} +4 -4
  30. package/bundle/{chunk-NDCRWEEJ.js → chunk-4Y5MJQRE.js} +6 -6
  31. package/bundle/{chunk-FRKW6LWB.js → chunk-55UWKI5C.js} +3 -3
  32. package/bundle/{chunk-7JN2MMU7.js → chunk-5PNJFDSW.js} +8 -8
  33. package/bundle/{chunk-LUNA6PM5.js → chunk-5RVOEFGT.js} +4 -2
  34. package/bundle/{chunk-LUNA6PM5.js.map → chunk-5RVOEFGT.js.map} +2 -2
  35. package/bundle/{chunk-OXTSWQCX.js → chunk-5Y3FJ2Y7.js} +2 -2
  36. package/bundle/{chunk-TMUYFERL.js → chunk-6B5ZFUPD.js} +2 -2
  37. package/bundle/{chunk-65VCEC32.js → chunk-6PA5JBUU.js} +2 -2
  38. package/bundle/{chunk-C7K6VZNY.js → chunk-BNXV7SZI.js} +21 -12
  39. package/bundle/chunk-BNXV7SZI.js.map +7 -0
  40. package/bundle/{chunk-AFREM7FX.js → chunk-CK7YTA2F.js} +2 -2
  41. package/bundle/{chunk-NRUSRJXR.js → chunk-DZJ5QZFD.js} +2 -2
  42. package/bundle/{chunk-YRSMGJFP.js → chunk-E67KESEG.js} +2 -2
  43. package/bundle/{chunk-ZV4IWKDJ.js → chunk-E7XD5UGB.js} +3 -3
  44. package/bundle/{chunk-CXXU3HAU.js → chunk-EAX5ZZUL.js} +63 -39
  45. package/bundle/chunk-EAX5ZZUL.js.map +7 -0
  46. package/bundle/{chunk-PEDX56EL.js → chunk-EFGBM555.js} +2 -2
  47. package/bundle/{chunk-EQSG2CRM.js → chunk-FGYDIX54.js} +22 -15
  48. package/bundle/chunk-FGYDIX54.js.map +7 -0
  49. package/bundle/{chunk-YPAQEQSC.js → chunk-GF6NVNA7.js} +15 -5
  50. package/bundle/chunk-GF6NVNA7.js.map +7 -0
  51. package/bundle/{chunk-UNM3OXHB.js → chunk-HGSHCQ5F.js} +110 -72
  52. package/bundle/{chunk-UNM3OXHB.js.map → chunk-HGSHCQ5F.js.map} +2 -2
  53. package/bundle/{chunk-VXCETPZU.js → chunk-IMIGG5EO.js} +39 -39
  54. package/bundle/chunk-IMIGG5EO.js.map +7 -0
  55. package/bundle/{chunk-P2K2K6XL.js → chunk-ITOFPJAV.js} +44 -32
  56. package/bundle/chunk-ITOFPJAV.js.map +7 -0
  57. package/bundle/{chunk-75ATTOW4.js → chunk-IY6UKLPS.js} +3 -3
  58. package/bundle/{chunk-EUZDKV3C.js → chunk-J4RUFAPK.js} +3 -3
  59. package/bundle/{chunk-HZDLFLRP.js → chunk-J7DRPVMU.js} +35 -5
  60. package/bundle/chunk-J7DRPVMU.js.map +7 -0
  61. package/bundle/{chunk-EGL6UMAO.js → chunk-JG4BKXBN.js} +7 -1
  62. package/bundle/chunk-JG4BKXBN.js.map +7 -0
  63. package/bundle/{chunk-N4EB6LA7.js → chunk-JLWYPGWI.js} +5 -5
  64. package/bundle/{chunk-5QUTMUIK.js → chunk-JXYWDAHD.js} +12 -12
  65. package/bundle/{chunk-GRVWZO4C.js → chunk-KOSFXW2S.js} +24 -3
  66. package/bundle/{chunk-GRVWZO4C.js.map → chunk-KOSFXW2S.js.map} +1 -1
  67. package/bundle/{chunk-M3JEX6L4.js → chunk-L72RIPEC.js} +9 -9
  68. package/bundle/{chunk-TEFZ4JA4.js → chunk-NHPLD3C7.js} +2 -2
  69. package/bundle/{chunk-2KC5G3EA.js → chunk-OWUO5RS3.js} +5 -5
  70. package/bundle/{chunk-4MULJ5SS.js → chunk-OY4Q6AMY.js} +71 -49
  71. package/bundle/chunk-OY4Q6AMY.js.map +7 -0
  72. package/bundle/{chunk-WBTJ2E62.js → chunk-P3NODAHF.js} +2 -5
  73. package/bundle/{chunk-WBTJ2E62.js.map → chunk-P3NODAHF.js.map} +2 -2
  74. package/bundle/{chunk-SMPHE3ZM.js → chunk-PB5GF4FG.js} +215 -163
  75. package/bundle/chunk-PB5GF4FG.js.map +7 -0
  76. package/bundle/{chunk-WYHGNI56.js → chunk-PMD5BLFS.js} +6 -6
  77. package/bundle/{chunk-URQPDCK5.js → chunk-Q66LQMMZ.js} +3 -3
  78. package/bundle/{chunk-IHYKTDIP.js → chunk-SC2Y5NR2.js} +36 -119
  79. package/bundle/chunk-SC2Y5NR2.js.map +7 -0
  80. package/bundle/chunk-SFL4EPCZ.js +555 -0
  81. package/bundle/chunk-SFL4EPCZ.js.map +7 -0
  82. package/bundle/{chunk-LDUOOKQY.js → chunk-SJPUNDZ3.js} +5 -5
  83. package/bundle/{chunk-LDUOOKQY.js.map → chunk-SJPUNDZ3.js.map} +1 -1
  84. package/bundle/{chunk-JQDJPUHM.js → chunk-TWB2ZGVH.js} +2 -2
  85. package/bundle/{chunk-IJT4KWXT.js → chunk-U4U47YE7.js} +2 -2
  86. package/bundle/{chunk-2FAZIA37.js → chunk-W546CU3A.js} +3 -3
  87. package/bundle/chunk-WC5O5KOE.js +211 -0
  88. package/bundle/chunk-WC5O5KOE.js.map +7 -0
  89. package/bundle/{chunk-JNIHEDKF.js → chunk-XPWYDNWL.js} +2 -2
  90. package/bundle/{chunk-GWILHZPT.js → chunk-XRTXYN66.js} +10 -7
  91. package/bundle/{chunk-GWILHZPT.js.map → chunk-XRTXYN66.js.map} +2 -2
  92. package/bundle/{chunk-EFJVUJBE.js → chunk-Y5FEFKGM.js} +6 -6
  93. package/bundle/chunk-YJZE4OK3.js +169 -0
  94. package/bundle/chunk-YJZE4OK3.js.map +7 -0
  95. package/bundle/{chunk-GVM5YU5I.js → chunk-Z4FZPB42.js} +2 -2
  96. package/bundle/{chunk-7BSQ5UQO.js → chunk-ZSIDQ66D.js} +3 -3
  97. package/bundle/{chunk-XX6BGTPO.js → chunk-ZZZCJJEO.js} +4 -4
  98. package/bundle/{commands-OIISYHTD.js → commands-2ZW6CMLC.js} +17 -16
  99. package/bundle/{config-M3P5IOAI.js → config-YMY5YHKN.js} +6 -6
  100. package/bundle/{context-2RJHC2LE.js → context-CL2RSLII.js} +7 -5
  101. package/bundle/context-CL2RSLII.js.map +7 -0
  102. package/bundle/{daemon-TB23FFWY.js → daemon-D7SU63OY.js} +3 -3
  103. package/bundle/{delegation-tools-YATZFKYO.js → delegation-tools-WS7Z56KZ.js} +12 -12
  104. package/bundle/{deploy-T6R45OZJ.js → deploy-AMTVKIMU.js} +2 -2
  105. package/bundle/{deps-WVK553KF.js → deps-T63AVJKJ.js} +3 -3
  106. package/bundle/{direct-api-transport-S2RDH2I7.js → direct-api-transport-QNNY2WWP.js} +51 -32
  107. package/bundle/direct-api-transport-QNNY2WWP.js.map +7 -0
  108. package/bundle/{discord-adapter-UTXUWX3A.js → discord-adapter-ABAD56Y2.js} +21 -20
  109. package/bundle/{discord-adapter-UTXUWX3A.js.map → discord-adapter-ABAD56Y2.js.map} +1 -1
  110. package/bundle/{dns-wakeup-IDOJIXBX.js → dns-wakeup-V3LEFXPE.js} +9 -33
  111. package/bundle/dns-wakeup-V3LEFXPE.js.map +7 -0
  112. package/bundle/{doctor-probes-B54JFIW3.js → doctor-probes-O6YI6XSZ.js} +6 -2
  113. package/bundle/{env-schema-4JXQUOH4.js → env-schema-B5RB32DC.js} +3 -3
  114. package/bundle/{gossip-3C3BSNPN.js → gossip-SKRCPOBS.js} +9 -5
  115. package/bundle/{guardrails-DL7ZSWVN.js → guardrails-64GQ5Y5K.js} +4 -4
  116. package/bundle/{heartbeat-system-MVTRS4GP.js → heartbeat-system-X4MUTKJD.js} +6 -6
  117. package/bundle/{heartbeat-tier3-6KH45CL6.js → heartbeat-tier3-2PTPWEQQ.js} +53 -76
  118. package/bundle/heartbeat-tier3-2PTPWEQQ.js.map +7 -0
  119. package/bundle/{hook-system-M3POLUIB.js → hook-system-YB635OC4.js} +3 -3
  120. package/bundle/{hotskills-FWX4QI7V.js → hotskills-Q75D2DK3.js} +5 -5
  121. package/bundle/{install-OS3CU7NF.js → install-RFKKFSGS.js} +17 -30
  122. package/bundle/install-RFKKFSGS.js.map +7 -0
  123. package/bundle/{install-manifest-5PPWMD2W.js → install-manifest-J7ICPCJN.js} +2 -2
  124. package/bundle/{irc-adapter-PTTZD32W.js → irc-adapter-TVEV4R6H.js} +3 -3
  125. package/bundle/{irc-config-CP7ZMUOX.js → irc-config-M676FOFI.js} +4 -4
  126. package/bundle/{kanban-board-M326B2XJ.js → kanban-board-DLEJUCNN.js} +9 -7
  127. package/bundle/{kanban-channel-IJ52OMNA.js → kanban-channel-XOLUHJZJ.js} +6 -6
  128. package/bundle/kanban-delivery-C4QPBNPX.js +45 -0
  129. package/bundle/kanban-delivery-C4QPBNPX.js.map +7 -0
  130. package/bundle/{lazy-require-KCRVT4SI.js → lazy-require-JKQSALXN.js} +3 -3
  131. package/bundle/{logger-OWCSNYCA.js → logger-3EGHBD4R.js} +2 -2
  132. package/bundle/{main-chat-ZNUZCTNS.js → main-chat-3H63REKK.js} +4 -4
  133. package/bundle/{master-user-HSKM4ZFN.js → master-user-MUBUP3KD.js} +5 -5
  134. package/bundle/{media-utils-3ZYOD7SK.js → media-utils-HUUIALAJ.js} +3 -3
  135. package/bundle/{message-pipeline-AUIUNM5R.js → message-pipeline-GRDRWONR.js} +17 -16
  136. package/bundle/meta.json +2773 -2241
  137. package/bundle/{metrics-collector-L3VPEHII.js → metrics-collector-YMUGY3PI.js} +31 -2
  138. package/bundle/metrics-collector-YMUGY3PI.js.map +7 -0
  139. package/bundle/{model-health-registry-MLEIZSTV.js → model-health-registry-QADMFQFQ.js} +2 -2
  140. package/bundle/{nerve-IGSXBKZZ.js → nerve-QPAEBRKX.js} +3 -3
  141. package/bundle/{notification-BFSIEECG.js → notification-3JICGXWU.js} +6 -6
  142. package/bundle/{openrouter-credits-NTVZDRYM.js → openrouter-credits-7NEIPYJN.js} +3 -3
  143. package/bundle/{orc-tools-TOD4WHTM.js → orc-tools-UZVPONKY.js} +5 -3
  144. package/bundle/{peer-auth-QC4EF2PM.js → peer-auth-RI43DKJE.js} +24 -15
  145. package/bundle/{peer-client-RGEU5HOK.js → peer-client-UITTMWJ2.js} +34 -29
  146. package/bundle/peer-client-UITTMWJ2.js.map +7 -0
  147. package/bundle/{peer-config-TN55LFDC.js → peer-config-URM7DCW6.js} +9 -4
  148. package/bundle/{peer-transport-5VKK2I7P.js → peer-transport-SI7I72DB.js} +12 -10
  149. package/bundle/{phase-transport-FS6NL4A5.js → phase-transport-ESWWACZI.js} +17 -17
  150. package/bundle/{reconcile-CTFCLQRN.js → reconcile-GFDQYNBD.js} +3 -3
  151. package/bundle/{reconciler-NZ4O4BCP.js → reconciler-IEUJXJN2.js} +12 -12
  152. package/bundle/{restore-IFHPI7I7.js → restore-FARTGLQQ.js} +3 -3
  153. package/bundle/{rollback-ANRI3T5Z.js → rollback-GEWPZABG.js} +2 -2
  154. package/bundle/{sandbox-runtime-QROWHDCS.js → sandbox-runtime-DV6E25J6.js} +2 -2
  155. package/bundle/{self-healer-utils-IFAYOQO2.js → self-healer-utils-P4SKNNEM.js} +3 -3
  156. package/bundle/{sha-tracker-ZWBP6CIJ.js → sha-tracker-77SHLYNY.js} +3 -3
  157. package/bundle/{skill-session-VJXTKOKL.js → skill-session-5HSMXY54.js} +3 -3
  158. package/bundle/{skill-stats-JORH5DGM.js → skill-stats-MI3RSWWL.js} +4 -4
  159. package/bundle/{skill-watcher-E4MGLKLS.js → skill-watcher-5L7JE6TN.js} +4 -4
  160. package/bundle/{sleep-BEWAUFCL.js → sleep-I4JFASCY.js} +11 -11
  161. package/bundle/{soul-bundle-VWAVHCZ6.js → soul-bundle-522C3IRH.js} +9 -8
  162. package/bundle/{spin-E3ZDEDKT.js → spin-VHNGNWTD.js} +11 -11
  163. package/bundle/{spin-notifications-SE2HVZI7.js → spin-notifications-7NC5XZEM.js} +5 -5
  164. package/bundle/{spin-types-OIE67MJK.js → spin-types-C5KOQOPD.js} +7 -3
  165. package/bundle/{sse-parser-anthropic-A6R4Z2TB.js → sse-parser-anthropic-MMTVWHLI.js} +3 -3
  166. package/bundle/{sse-parser-responses-HSZY3QGJ.js → sse-parser-responses-3AOFN64C.js} +3 -3
  167. package/bundle/{ssrf-guard-O6SHIK6Q.js → ssrf-guard-U2JA72TC.js} +3 -3
  168. package/bundle/{start-7QZIWO3S.js → start-H5IUFAWF.js} +4 -2
  169. package/bundle/{start-7QZIWO3S.js.map → start-H5IUFAWF.js.map} +2 -2
  170. package/bundle/{stt-LGVPXMVR.js → stt-PSOPPBV4.js} +4 -4
  171. package/bundle/{system-status-FAVNIUFJ.js → system-status-4LYGOFNO.js} +38 -24
  172. package/bundle/system-status-4LYGOFNO.js.map +7 -0
  173. package/bundle/{task-store-W5BFIAIH.js → task-store-MNCW42BW.js} +4 -4
  174. package/bundle/{telegram-adapter-4TX7QWKC.js → telegram-adapter-O6KIZDY6.js} +62 -45
  175. package/bundle/telegram-adapter-O6KIZDY6.js.map +7 -0
  176. package/bundle/{tool-registry-7FK3OQGL.js → tool-registry-JJMWCQKZ.js} +26 -24
  177. package/bundle/{tool-sandbox-4UC6GAKA.js → tool-sandbox-CNL6V6IH.js} +4 -4
  178. package/bundle/{transport-config-KBF5W2DP.js → transport-config-6MB2K2XC.js} +7 -7
  179. package/bundle/tribe-GDTFYJTK.js +111 -0
  180. package/bundle/tribe-GDTFYJTK.js.map +7 -0
  181. package/bundle/{update-CKFP6LBE.js → update-HGQAOC5L.js} +3 -3
  182. package/bundle/{usage-tracker-NXD364VX.js → usage-tracker-SR4BI6ZT.js} +2 -2
  183. package/bundle/{user-registry-35BW4XKM.js → user-registry-4PACZJIJ.js} +4 -4
  184. package/bundle/wire-platform-KKPWNNNQ.js +88 -0
  185. package/bundle/wire-platform-KKPWNNNQ.js.map +7 -0
  186. package/bundle/ws-peer-client-U3NNPOK7.js +370 -0
  187. package/bundle/ws-peer-client-U3NNPOK7.js.map +7 -0
  188. package/package.json +1 -1
  189. package/scripts/abtars-watchdog.sh +1 -5
  190. package/scripts/emergency-deploy.sh +2 -2
  191. package/scripts/emergency-update.sh +36 -37
  192. package/bundle/chunk-374NCXFZ.js.map +0 -7
  193. package/bundle/chunk-4MULJ5SS.js.map +0 -7
  194. package/bundle/chunk-4S554KLW.js +0 -105
  195. package/bundle/chunk-4S554KLW.js.map +0 -7
  196. package/bundle/chunk-C7K6VZNY.js.map +0 -7
  197. package/bundle/chunk-CXXU3HAU.js.map +0 -7
  198. package/bundle/chunk-EGL6UMAO.js.map +0 -7
  199. package/bundle/chunk-EQSG2CRM.js.map +0 -7
  200. package/bundle/chunk-HT2BPTZY.js +0 -241
  201. package/bundle/chunk-HT2BPTZY.js.map +0 -7
  202. package/bundle/chunk-HZDLFLRP.js.map +0 -7
  203. package/bundle/chunk-IHYKTDIP.js.map +0 -7
  204. package/bundle/chunk-IKUZPMVA.js +0 -82
  205. package/bundle/chunk-IKUZPMVA.js.map +0 -7
  206. package/bundle/chunk-P2K2K6XL.js.map +0 -7
  207. package/bundle/chunk-PU5HSKWH.js +0 -257
  208. package/bundle/chunk-PU5HSKWH.js.map +0 -7
  209. package/bundle/chunk-RWRRGE4U.js +0 -72
  210. package/bundle/chunk-RWRRGE4U.js.map +0 -7
  211. package/bundle/chunk-SMPHE3ZM.js.map +0 -7
  212. package/bundle/chunk-VUIX5AGB.js +0 -65
  213. package/bundle/chunk-VUIX5AGB.js.map +0 -7
  214. package/bundle/chunk-VXCETPZU.js.map +0 -7
  215. package/bundle/chunk-YPAQEQSC.js.map +0 -7
  216. package/bundle/context-2RJHC2LE.js.map +0 -7
  217. package/bundle/direct-api-transport-S2RDH2I7.js.map +0 -7
  218. package/bundle/dns-wakeup-IDOJIXBX.js.map +0 -7
  219. package/bundle/heartbeat-tier3-6KH45CL6.js.map +0 -7
  220. package/bundle/install-OS3CU7NF.js.map +0 -7
  221. package/bundle/metrics-collector-L3VPEHII.js.map +0 -7
  222. package/bundle/peer-client-RGEU5HOK.js.map +0 -7
  223. package/bundle/peer-jwt-NCCPXJRX.js +0 -18
  224. package/bundle/stream-single-RFJNUTL6.js +0 -34
  225. package/bundle/stream-single-RFJNUTL6.js.map +0 -7
  226. package/bundle/system-status-FAVNIUFJ.js.map +0 -7
  227. package/bundle/telegram-adapter-4TX7QWKC.js.map +0 -7
  228. package/bundle/user-registry-35BW4XKM.js.map +0 -7
  229. package/bundle/ws-peer-client-AIXCXF7V.js +0 -173
  230. package/bundle/ws-peer-client-AIXCXF7V.js.map +0 -7
  231. /package/bundle/{_registry.generated-YP5GLSG7.js.map → _registry.generated-AVR7DK2A.js.map} +0 -0
  232. /package/bundle/{abmind-lazy-7Z44NODV.js.map → abmind-lazy-E3YCFKQ5.js.map} +0 -0
  233. /package/bundle/{acp-raw-client-E6FM45NC.js.map → acp-raw-client-UCNK3OTU.js.map} +0 -0
  234. /package/bundle/{action-gate-G2V47NHW.js.map → action-gate-V4FCBHFB.js.map} +0 -0
  235. /package/bundle/{agent-api-adapter-WRGEQ6DV.js.map → agent-api-adapter-7HEPYSIN.js.map} +0 -0
  236. /package/bundle/{agent-api-rate-limit-WCFXJMGY.js.map → agent-api-rate-limit-RZSAM3SW.js.map} +0 -0
  237. /package/bundle/{agent-registry-GHNG2PH3.js.map → agent-registry-46A2R5KP.js.map} +0 -0
  238. /package/bundle/{bootstrap-PZIDBPEJ.js.map → bootstrap-MIHJJSWU.js.map} +0 -0
  239. /package/bundle/{bridge-lock-transport-4ZH7QTJP.js.map → bridge-lock-transport-7RSN7OLJ.js.map} +0 -0
  240. /package/bundle/{browser-D3LZV7ZK.js.map → browser-F6BCWJWW.js.map} +0 -0
  241. /package/bundle/{budget-45QOBDWA.js.map → budget-WUM3SPKW.js.map} +0 -0
  242. /package/bundle/{capability-JFWX3IQF.js.map → capability-QVRKGRFC.js.map} +0 -0
  243. /package/bundle/{chunk-YSKCQH6E.js.map → chunk-2IYJ4I66.js.map} +0 -0
  244. /package/bundle/{chunk-W2R2HFOQ.js.map → chunk-2NLUT5S2.js.map} +0 -0
  245. /package/bundle/{chunk-OKAQICWY.js.map → chunk-3GQX34S2.js.map} +0 -0
  246. /package/bundle/{chunk-QROWBWLL.js.map → chunk-3XZ773BS.js.map} +0 -0
  247. /package/bundle/{chunk-DYBW4XXL.js.map → chunk-467SRLLR.js.map} +0 -0
  248. /package/bundle/{chunk-GPZNXY2U.js.map → chunk-4S3H4OK7.js.map} +0 -0
  249. /package/bundle/{chunk-NDCRWEEJ.js.map → chunk-4Y5MJQRE.js.map} +0 -0
  250. /package/bundle/{chunk-FRKW6LWB.js.map → chunk-55UWKI5C.js.map} +0 -0
  251. /package/bundle/{chunk-7JN2MMU7.js.map → chunk-5PNJFDSW.js.map} +0 -0
  252. /package/bundle/{chunk-OXTSWQCX.js.map → chunk-5Y3FJ2Y7.js.map} +0 -0
  253. /package/bundle/{chunk-TMUYFERL.js.map → chunk-6B5ZFUPD.js.map} +0 -0
  254. /package/bundle/{chunk-65VCEC32.js.map → chunk-6PA5JBUU.js.map} +0 -0
  255. /package/bundle/{chunk-AFREM7FX.js.map → chunk-CK7YTA2F.js.map} +0 -0
  256. /package/bundle/{chunk-NRUSRJXR.js.map → chunk-DZJ5QZFD.js.map} +0 -0
  257. /package/bundle/{chunk-YRSMGJFP.js.map → chunk-E67KESEG.js.map} +0 -0
  258. /package/bundle/{chunk-ZV4IWKDJ.js.map → chunk-E7XD5UGB.js.map} +0 -0
  259. /package/bundle/{chunk-PEDX56EL.js.map → chunk-EFGBM555.js.map} +0 -0
  260. /package/bundle/{chunk-75ATTOW4.js.map → chunk-IY6UKLPS.js.map} +0 -0
  261. /package/bundle/{chunk-EUZDKV3C.js.map → chunk-J4RUFAPK.js.map} +0 -0
  262. /package/bundle/{chunk-N4EB6LA7.js.map → chunk-JLWYPGWI.js.map} +0 -0
  263. /package/bundle/{chunk-5QUTMUIK.js.map → chunk-JXYWDAHD.js.map} +0 -0
  264. /package/bundle/{chunk-M3JEX6L4.js.map → chunk-L72RIPEC.js.map} +0 -0
  265. /package/bundle/{chunk-TEFZ4JA4.js.map → chunk-NHPLD3C7.js.map} +0 -0
  266. /package/bundle/{chunk-2KC5G3EA.js.map → chunk-OWUO5RS3.js.map} +0 -0
  267. /package/bundle/{chunk-WYHGNI56.js.map → chunk-PMD5BLFS.js.map} +0 -0
  268. /package/bundle/{chunk-URQPDCK5.js.map → chunk-Q66LQMMZ.js.map} +0 -0
  269. /package/bundle/{chunk-JQDJPUHM.js.map → chunk-TWB2ZGVH.js.map} +0 -0
  270. /package/bundle/{chunk-IJT4KWXT.js.map → chunk-U4U47YE7.js.map} +0 -0
  271. /package/bundle/{chunk-2FAZIA37.js.map → chunk-W546CU3A.js.map} +0 -0
  272. /package/bundle/{chunk-JNIHEDKF.js.map → chunk-XPWYDNWL.js.map} +0 -0
  273. /package/bundle/{chunk-EFJVUJBE.js.map → chunk-Y5FEFKGM.js.map} +0 -0
  274. /package/bundle/{chunk-GVM5YU5I.js.map → chunk-Z4FZPB42.js.map} +0 -0
  275. /package/bundle/{chunk-7BSQ5UQO.js.map → chunk-ZSIDQ66D.js.map} +0 -0
  276. /package/bundle/{chunk-XX6BGTPO.js.map → chunk-ZZZCJJEO.js.map} +0 -0
  277. /package/bundle/{commands-OIISYHTD.js.map → commands-2ZW6CMLC.js.map} +0 -0
  278. /package/bundle/{config-M3P5IOAI.js.map → config-YMY5YHKN.js.map} +0 -0
  279. /package/bundle/{daemon-TB23FFWY.js.map → daemon-D7SU63OY.js.map} +0 -0
  280. /package/bundle/{delegation-tools-YATZFKYO.js.map → delegation-tools-WS7Z56KZ.js.map} +0 -0
  281. /package/bundle/{deploy-T6R45OZJ.js.map → deploy-AMTVKIMU.js.map} +0 -0
  282. /package/bundle/{deps-WVK553KF.js.map → deps-T63AVJKJ.js.map} +0 -0
  283. /package/bundle/{doctor-probes-B54JFIW3.js.map → doctor-probes-O6YI6XSZ.js.map} +0 -0
  284. /package/bundle/{env-schema-4JXQUOH4.js.map → env-schema-B5RB32DC.js.map} +0 -0
  285. /package/bundle/{gossip-3C3BSNPN.js.map → gossip-SKRCPOBS.js.map} +0 -0
  286. /package/bundle/{guardrails-DL7ZSWVN.js.map → guardrails-64GQ5Y5K.js.map} +0 -0
  287. /package/bundle/{heartbeat-system-MVTRS4GP.js.map → heartbeat-system-X4MUTKJD.js.map} +0 -0
  288. /package/bundle/{hook-system-M3POLUIB.js.map → hook-system-YB635OC4.js.map} +0 -0
  289. /package/bundle/{hotskills-FWX4QI7V.js.map → hotskills-Q75D2DK3.js.map} +0 -0
  290. /package/bundle/{install-manifest-5PPWMD2W.js.map → install-manifest-J7ICPCJN.js.map} +0 -0
  291. /package/bundle/{irc-adapter-PTTZD32W.js.map → irc-adapter-TVEV4R6H.js.map} +0 -0
  292. /package/bundle/{irc-config-CP7ZMUOX.js.map → irc-config-M676FOFI.js.map} +0 -0
  293. /package/bundle/{kanban-board-M326B2XJ.js.map → kanban-board-DLEJUCNN.js.map} +0 -0
  294. /package/bundle/{kanban-channel-IJ52OMNA.js.map → kanban-channel-XOLUHJZJ.js.map} +0 -0
  295. /package/bundle/{lazy-require-KCRVT4SI.js.map → lazy-require-JKQSALXN.js.map} +0 -0
  296. /package/bundle/{logger-OWCSNYCA.js.map → logger-3EGHBD4R.js.map} +0 -0
  297. /package/bundle/{main-chat-ZNUZCTNS.js.map → main-chat-3H63REKK.js.map} +0 -0
  298. /package/bundle/{master-user-HSKM4ZFN.js.map → master-user-MUBUP3KD.js.map} +0 -0
  299. /package/bundle/{media-utils-3ZYOD7SK.js.map → media-utils-HUUIALAJ.js.map} +0 -0
  300. /package/bundle/{message-pipeline-AUIUNM5R.js.map → message-pipeline-GRDRWONR.js.map} +0 -0
  301. /package/bundle/{model-health-registry-MLEIZSTV.js.map → model-health-registry-QADMFQFQ.js.map} +0 -0
  302. /package/bundle/{nerve-IGSXBKZZ.js.map → nerve-QPAEBRKX.js.map} +0 -0
  303. /package/bundle/{notification-BFSIEECG.js.map → notification-3JICGXWU.js.map} +0 -0
  304. /package/bundle/{openrouter-credits-NTVZDRYM.js.map → openrouter-credits-7NEIPYJN.js.map} +0 -0
  305. /package/bundle/{orc-tools-TOD4WHTM.js.map → orc-tools-UZVPONKY.js.map} +0 -0
  306. /package/bundle/{peer-auth-QC4EF2PM.js.map → peer-auth-RI43DKJE.js.map} +0 -0
  307. /package/bundle/{peer-config-TN55LFDC.js.map → peer-config-URM7DCW6.js.map} +0 -0
  308. /package/bundle/{peer-jwt-NCCPXJRX.js.map → peer-transport-SI7I72DB.js.map} +0 -0
  309. /package/bundle/{peer-transport-5VKK2I7P.js.map → phase-transport-ESWWACZI.js.map} +0 -0
  310. /package/bundle/{phase-transport-FS6NL4A5.js.map → reconcile-GFDQYNBD.js.map} +0 -0
  311. /package/bundle/{reconciler-NZ4O4BCP.js.map → reconciler-IEUJXJN2.js.map} +0 -0
  312. /package/bundle/{restore-IFHPI7I7.js.map → restore-FARTGLQQ.js.map} +0 -0
  313. /package/bundle/{reconcile-CTFCLQRN.js.map → rollback-GEWPZABG.js.map} +0 -0
  314. /package/bundle/{sandbox-runtime-QROWHDCS.js.map → sandbox-runtime-DV6E25J6.js.map} +0 -0
  315. /package/bundle/{self-healer-utils-IFAYOQO2.js.map → self-healer-utils-P4SKNNEM.js.map} +0 -0
  316. /package/bundle/{rollback-ANRI3T5Z.js.map → sha-tracker-77SHLYNY.js.map} +0 -0
  317. /package/bundle/{skill-session-VJXTKOKL.js.map → skill-session-5HSMXY54.js.map} +0 -0
  318. /package/bundle/{sha-tracker-ZWBP6CIJ.js.map → skill-stats-MI3RSWWL.js.map} +0 -0
  319. /package/bundle/{skill-stats-JORH5DGM.js.map → skill-watcher-5L7JE6TN.js.map} +0 -0
  320. /package/bundle/{skill-watcher-E4MGLKLS.js.map → sleep-I4JFASCY.js.map} +0 -0
  321. /package/bundle/{sleep-BEWAUFCL.js.map → soul-bundle-522C3IRH.js.map} +0 -0
  322. /package/bundle/{soul-bundle-VWAVHCZ6.js.map → spin-VHNGNWTD.js.map} +0 -0
  323. /package/bundle/{spin-notifications-SE2HVZI7.js.map → spin-notifications-7NC5XZEM.js.map} +0 -0
  324. /package/bundle/{spin-E3ZDEDKT.js.map → spin-types-C5KOQOPD.js.map} +0 -0
  325. /package/bundle/{sse-parser-anthropic-A6R4Z2TB.js.map → sse-parser-anthropic-MMTVWHLI.js.map} +0 -0
  326. /package/bundle/{sse-parser-responses-HSZY3QGJ.js.map → sse-parser-responses-3AOFN64C.js.map} +0 -0
  327. /package/bundle/{ssrf-guard-O6SHIK6Q.js.map → ssrf-guard-U2JA72TC.js.map} +0 -0
  328. /package/bundle/{spin-types-OIE67MJK.js.map → stt-PSOPPBV4.js.map} +0 -0
  329. /package/bundle/{stt-LGVPXMVR.js.map → task-store-MNCW42BW.js.map} +0 -0
  330. /package/bundle/{task-store-W5BFIAIH.js.map → tool-registry-JJMWCQKZ.js.map} +0 -0
  331. /package/bundle/{tool-registry-7FK3OQGL.js.map → tool-sandbox-CNL6V6IH.js.map} +0 -0
  332. /package/bundle/{tool-sandbox-4UC6GAKA.js.map → transport-config-6MB2K2XC.js.map} +0 -0
  333. /package/bundle/{transport-config-KBF5W2DP.js.map → update-HGQAOC5L.js.map} +0 -0
  334. /package/bundle/{update-CKFP6LBE.js.map → usage-tracker-SR4BI6ZT.js.map} +0 -0
  335. /package/bundle/{usage-tracker-NXD364VX.js.map → user-registry-4PACZJIJ.js.map} +0 -0
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/components/agent-registry.ts"],
4
- "sourcesContent": ["import { getEnv } from \"./env-schema.js\";\n/**\n * agent-registry.ts \u2014 Centralized agent role configuration.\n * Single factory for all agent transports. Transport-agnostic.\n */\n\nimport { AcpTransport } from \"./transport/acp-transport.js\";\nimport { logInfo, logWarn } from \"./logger.js\";\nimport type { IKiroTransport } from \"./transport/kiro-transport.js\";\n\nexport type AgentRole = \"professor\" | \"dreamy\" | \"browsie\" | \"coding\" | \"task\";\n\nexport interface AgentRoleConfig {\n agent: string | null;\n model: string | null;\n autoReinit: boolean;\n tag: string;\n trust: number;\n}\n\nconst AGENT_ROLES: Record<AgentRole, AgentRoleConfig> = {\n professor: { agent: \"professor\", model: null, autoReinit: true, tag: \"acp-main\", trust: 3 },\n dreamy: { agent: \"dreamy\", model: null, autoReinit: false, tag: \"acp-sleep\", trust: 2 },\n coding: { agent: \"coding-agent\", model: null, autoReinit: true, tag: \"acp-coding\", trust: 2 },\n browsie: { agent: \"browsie\", model: null, autoReinit: false, tag: \"acp-browsie\", trust: 1 },\n task: { agent: \"professor\", model: null, autoReinit: false, tag: \"acp-task\", trust: 2 },\n};\n\nfunction resolveModel(role: AgentRole): string | undefined {\n switch (role) {\n case \"dreamy\": return getEnv().sleepModel;\n case \"browsie\": return getEnv().browsingAgent;\n case \"coding\": return getEnv().codingModel;\n default: return undefined;\n }\n}\n\nexport interface TransportConfig {\n cliPath: string;\n workingDir: string;\n agentCli?: string;\n model?: string;\n}\n\nexport function createAgentTransport(\n role: AgentRole,\n tc: TransportConfig,\n overrides?: Partial<AgentRoleConfig>,\n): AcpTransport {\n const cfg = { ...AGENT_ROLES[role], ...overrides };\n const cliArgs = tc.agentCli === \"gemini\" ? [\"--acp\", \"-y\"] : undefined;\n const model = tc.model ?? resolveModel(role);\n\n return new AcpTransport(tc.cliPath, tc.workingDir, {\n agent: cfg.agent ?? undefined,\n model,\n autoReinit: cfg.autoReinit,\n tag: cfg.tag,\n cliArgs,\n });\n}\n\nexport type SubagentRole = \"sleep\" | \"browse\" | \"coding\" | \"task\";\n\nconst SUBAGENT_TO_AGENT: Record<SubagentRole, string> = {\n sleep: \"dreamy\",\n browse: \"browsie\",\n coding: \"coding\",\n task: \"professor\",\n};\n\nconst SUBAGENT_ACP_ROLE: Record<SubagentRole, AgentRole> = {\n sleep: \"dreamy\",\n browse: \"browsie\",\n coding: \"coding\",\n task: \"task\",\n};\n\n/** Unified transport factory for all subagents. Reads from transport.json + models.json. */\n/** @internal Used only by SubagentRuntime. Do not call directly. */\nexport async function createSubagentTransport(role: SubagentRole, registry?: import(\"./transport/model-health-registry.js\").ModelHealthRegistry, currentModel?: string): Promise<{ transport: IKiroTransport; model: string }> {\n const { resolveAgent, getEnvFallback, loadTransport } = await import(\"./transport-config.js\");\n const tc = loadTransport();\n const agentName = SUBAGENT_TO_AGENT[role];\n const resolved = tc ? resolveAgent(agentName, tc) : null;\n\n // Fallback: use professor's config. If that also fails, use .env defaults.\n const profResolved = resolved ?? (tc ? resolveAgent(\"professor\", tc) : null);\n const agent = profResolved ?? (() => {\n const fb = getEnvFallback();\n return { model: fb.model, provider: fb.provider, providerName: fb.providerName, contextWindow: fb.contextWindow, maxOutput: fb.maxOutput, fallbacks: [] };\n })();\n\n if (agent.provider.transport === \"api\") {\n const { DirectApiTransport } = await import(\"./transport/direct-api-transport.js\");\n const { FallbackPolicy } = await import(\"./transport/fallback-policy.js\");\n const apiKey = getEnv().getApiKey(agent.provider.apiKeyEnv ?? \"API_KEY\");\n\n // Use main transport's active model if available, else static config\n const startModel = currentModel ?? agent.model;\n\n // Build per-agent candidate list\n const candidates: Array<{ model: string; endpoint: string; apiKey?: string; maxContext: number }> = [\n { endpoint: agent.provider.endpoint ?? \"http://localhost:11434/v1\", apiKey, model: startModel, maxContext: agent.contextWindow },\n ];\n\n // Add static config model if different from startModel\n if (agent.model !== startModel && !candidates.some(c => c.model === agent.model)) {\n candidates.push({ endpoint: agent.provider.endpoint ?? \"http://localhost:11434/v1\", apiKey, model: agent.model, maxContext: agent.contextWindow });\n }\n\n // Add professor's model as fallback if different and transport-compatible\n const profAgent = tc ? resolveAgent(\"professor\", tc) : null;\n const agentTransport = agent.provider.transport ?? \"api\";\n if (profAgent && profAgent.model !== startModel && !candidates.some(c => c.model === profAgent.model)) {\n const profTransport = profAgent.provider.transport ?? \"api\";\n if (profTransport === agentTransport && profAgent.provider.endpoint) {\n candidates.push({\n endpoint: profAgent.provider.endpoint,\n apiKey: profAgent.provider.apiKeyEnv ? getEnv().getApiKey(profAgent.provider.apiKeyEnv) : apiKey,\n model: profAgent.model,\n maxContext: profAgent.contextWindow,\n });\n }\n }\n\n // Inherit professor's full fallback chain (fb1\u2192fb2\u2192fb3)\n if (profAgent) {\n for (const fb of profAgent.fallbacks ?? []) {\n if (candidates.some(c => c.model === fb.model)) continue;\n const fbProvider = tc?.providers[fb.provider];\n const fbEndpoint = fbProvider?.endpoint ?? profAgent.provider.endpoint;\n if (!fbEndpoint) { logWarn(\"subagent\", `Skipping fallback ${fb.model} \u2014 no endpoint configured`); continue; }\n const fbApiKey = fbProvider?.apiKeyEnv ? getEnv().getApiKey(fbProvider.apiKeyEnv) : apiKey;\n candidates.push({ endpoint: fbEndpoint, apiKey: fbApiKey, model: fb.model, maxContext: profAgent.contextWindow });\n }\n for (const chainModel of profAgent.provider.fallbackChain ?? []) {\n if (candidates.some(c => c.model === chainModel)) continue;\n if (!profAgent.provider.endpoint) { logWarn(\"subagent\", `Skipping chain model ${chainModel} \u2014 no endpoint configured`); continue; }\n candidates.push({ endpoint: profAgent.provider.endpoint, apiKey, model: chainModel, maxContext: profAgent.contextWindow });\n }\n }\n\n // Append agent-level cross-provider fallbacks\n for (const fb of agent.fallbacks) {\n if (candidates.some(c => c.model === fb.model)) continue;\n const fbProvider = tc?.providers[fb.provider];\n const fbEndpoint = fbProvider?.endpoint ?? agent.provider.endpoint;\n if (!fbEndpoint) { logWarn(\"subagent\", `Skipping fallback ${fb.model} \u2014 no endpoint configured`); continue; }\n const fbApiKey = fbProvider?.apiKeyEnv ? getEnv().getApiKey(fbProvider.apiKeyEnv) : apiKey;\n candidates.push({ endpoint: fbEndpoint, apiKey: fbApiKey, model: fb.model, maxContext: agent.contextWindow });\n }\n\n // Append fallbackChain entries as last-resort candidates\n const chain = agent.provider.fallbackChain ?? [];\n for (const chainModel of chain) {\n if (!candidates.some(c => c.model === chainModel)) {\n if (!agent.provider.endpoint) { logWarn(\"subagent\", `Skipping chain model ${chainModel} \u2014 no endpoint configured`); continue; }\n candidates.push({\n endpoint: agent.provider.endpoint,\n apiKey, model: chainModel, maxContext: agent.contextWindow,\n });\n }\n }\n\n // Use shared registry if provided, otherwise create isolated one\n const { ModelHealthRegistry } = await import(\"./transport/model-health-registry.js\");\n const policy = new FallbackPolicy(candidates, registry ?? new ModelHealthRegistry());\n\n const transport = new DirectApiTransport({\n endpoint: agent.provider.endpoint ?? \"http://localhost:11434/v1\",\n apiKey, model: startModel,\n maxContext: agent.contextWindow, maxOutput: agent.maxOutput,\n maxTurns: tc?.maxTurns ?? 50,\n maxToolRounds: tc?.maxToolRounds ?? 25,\n }, policy);\n await transport.initialize();\n logInfo(\"subagent\", `${role} transport: DirectAPI ${agent.providerName} (model=${startModel}, ${candidates.length} candidates, shared registry: ${!!registry})`);\n return { transport, model: agent.model };\n }\n\n // ACP path \u2014 try configured model, then fallbackChain on failure\n const { loadAndValidateConfig } = await import(\"./config.js\");\n const config = await loadAndValidateConfig();\n const chain = agent.provider.fallbackChain ?? [];\n const modelsToTry = [agent.model, ...chain.filter(m => m !== agent.model)];\n\n for (let i = 0; i < modelsToTry.length; i++) {\n const model = modelsToTry[i]!;\n const transport = createAgentTransport(SUBAGENT_ACP_ROLE[role], {\n cliPath: agent.provider.cli ?? config.transport.agentCliPath,\n workingDir: config.transport.workingDir,\n agentCli: agent.provider.cli ?? \"kiro-cli\",\n model,\n });\n try {\n await transport.initialize();\n if (i > 0) logWarn(\"subagent\", `${role}: configured model failed, fell back to ${model}`);\n logInfo(\"subagent\", `${role} transport: ACP ${agent.providerName} (model=${model}${i > 0 ? \", fallback\" : \"\"})`);\n return { transport, model };\n } catch (err) {\n if (i < modelsToTry.length - 1) {\n logWarn(\"subagent\", `${role}: model ${model} init failed (${err instanceof Error ? err.message : String(err)}), trying ${modelsToTry[i + 1]}`);\n continue;\n }\n throw err;\n }\n }\n throw new Error(`${role}: all models exhausted (tried ${modelsToTry.join(\", \")})`);\n}\n"],
5
- "mappings": "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",
6
- "names": ["chain"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/components/transport/model-health-registry.ts"],
4
- "sourcesContent": ["/**\n * ModelHealthRegistry \u2014 shared per-model error tracking.\n * Leaky-bucket algorithm: fills on errors, drains over time. Full = skip.\n * One instance per bridge process, shared across all FallbackPolicy instances.\n *\n * All tuning constants configurable via transport.json `healthPolicy` key.\n * Missing fields fall back to hardcoded defaults.\n */\n\nexport type ErrorKind = \"rate_limit\" | \"credits\" | \"auth\" | \"transient\" | \"weak\" | \"empty\" | \"truncated\";\nexport type ModelStatus = \"healthy\" | \"degraded\" | \"exhausted\" | \"auth_failed\";\n\nexport interface HealthPolicyConfig {\n /** Bucket level (0-1) above which model is skipped. Default: 0.7 */\n skipThreshold?: number;\n /** Drain rate per minute (0-1). Default: 0.03 */\n leakPerMinute?: number;\n /** Auth error: fill amount (0-1). Default: 1.0 (instant full) */\n authFill?: number;\n /** Auth errors are sticky (never auto-drain). Default: true */\n authSticky?: boolean;\n /** Rate-limit fill per hit. Default: 0.5 */\n rateLimitFill?: number;\n /** Weak-model fill per hit. Default: 0.05 */\n weakFill?: number;\n /** Empty response (0 tokens) fill per hit. Default: 0.25 */\n emptyFill?: number;\n /** Truncated response (finish_reason=length) fill per hit. Default: 0 (disabled) */\n truncatedFill?: number;\n /** Transient progressive fill array. Default: [0.1, 0.2, 0.4, 0.8] */\n transientProgressive?: number[];\n /** Consecutive errors before cooldown kicks in. Default: 3 */\n transientCooldownAfter?: number;\n /** Max cooldown seconds for transient errors. Default: 300 */\n transientMaxCooldownSec?: number;\n}\n\ninterface Bucket {\n level: number;\n lastUpdate: number;\n consecutiveErrors: number;\n cooldownUntil?: number;\n authFailed?: boolean;\n demoted?: boolean;\n}\n\n// Defaults (unchanged from pre-config behavior)\nconst D_SKIP_THRESHOLD = 0.7;\nconst D_LEAK_PER_MIN = 0.03;\nconst D_AUTH_STICKY = true;\nconst D_RATE_LIMIT_FILL = 0.5;\nconst D_WEAK_FILL = 0.35;\nconst D_EMPTY_FILL = 0.25;\nconst D_TRUNCATED_FILL = 0;\nconst D_TRANSIENT_PROGRESSIVE = [0.1, 0.2, 0.4, 0.8];\nconst D_TRANSIENT_COOLDOWN_AFTER = 3;\nconst D_TRANSIENT_MAX_COOLDOWN_SEC = 300;\n\nexport class ModelHealthRegistry {\n private readonly buckets = new Map<string, Bucket>();\n private readonly skipThreshold: number;\n private readonly leakPerMs: number;\n private readonly authSticky: boolean;\n private readonly rateLimitFill: number;\n private readonly weakFill: number;\n private readonly emptyFill: number;\n private readonly truncatedFill: number;\n private readonly transientProgressive: number[];\n private readonly transientCooldownAfter: number;\n private readonly transientMaxCooldownMs: number;\n\n /** Fired when a model crosses the demotion threshold. Wired at boot. */\n onDemote?: (model: string, endpoint: string, reason: \"auth\" | \"timeout\") => void;\n\n constructor(config?: HealthPolicyConfig) {\n this.skipThreshold = config?.skipThreshold ?? D_SKIP_THRESHOLD;\n this.leakPerMs = (config?.leakPerMinute ?? D_LEAK_PER_MIN) / 60000;\n this.authSticky = config?.authSticky ?? D_AUTH_STICKY;\n this.rateLimitFill = config?.rateLimitFill ?? D_RATE_LIMIT_FILL;\n this.weakFill = config?.weakFill ?? D_WEAK_FILL;\n this.emptyFill = config?.emptyFill ?? D_EMPTY_FILL;\n this.truncatedFill = config?.truncatedFill ?? D_TRUNCATED_FILL;\n this.transientProgressive = config?.transientProgressive ?? D_TRANSIENT_PROGRESSIVE;\n this.transientCooldownAfter = config?.transientCooldownAfter ?? D_TRANSIENT_COOLDOWN_AFTER;\n this.transientMaxCooldownMs = (config?.transientMaxCooldownSec ?? D_TRANSIENT_MAX_COOLDOWN_SEC) * 1000;\n }\n\n private drain(b: Bucket, now: number): void {\n if (this.authSticky && b.authFailed) return;\n const elapsed = now - b.lastUpdate;\n b.level = Math.max(0, b.level - elapsed * this.leakPerMs);\n b.lastUpdate = now;\n }\n\n shouldSkip(model: string, endpoint: string): boolean {\n const b = this.buckets.get(`${endpoint}|${model}`);\n if (!b) return false;\n const now = Date.now();\n if (b.cooldownUntil && now < b.cooldownUntil) return true;\n if (b.cooldownUntil && now >= b.cooldownUntil) b.cooldownUntil = undefined;\n this.drain(b, now);\n return b.level > this.skipThreshold;\n }\n\n recordSuccess(model: string, endpoint: string): void {\n const b = this.buckets.get(`${endpoint}|${model}`);\n if (!b) return;\n b.consecutiveErrors = 0;\n b.cooldownUntil = undefined;\n b.authFailed = false;\n }\n\n recordError(model: string, endpoint: string, kind: ErrorKind, retryAfterMs?: number): void {\n const key = `${endpoint}|${model}`;\n const now = Date.now();\n const b = this.buckets.get(key) ?? { level: 0, lastUpdate: now, consecutiveErrors: 0 };\n this.drain(b, now);\n\n switch (kind) {\n case \"auth\":\n b.level = 1.0;\n b.authFailed = true;\n if (this.onDemote && !b.demoted) {\n b.demoted = true;\n this.onDemote(model, endpoint, \"auth\");\n }\n break;\n case \"transient\": {\n const idx = Math.min(b.consecutiveErrors, this.transientProgressive.length - 1);\n b.level = Math.min(1.0, b.level + this.transientProgressive[idx]!);\n if (b.consecutiveErrors >= this.transientCooldownAfter) {\n b.cooldownUntil = now + Math.min((b.consecutiveErrors + 1) * 60_000, this.transientMaxCooldownMs);\n }\n break;\n }\n case \"rate_limit\":\n case \"credits\":\n b.level = Math.min(1.0, b.level + this.rateLimitFill);\n if (retryAfterMs && retryAfterMs > 0) b.cooldownUntil = now + retryAfterMs;\n break;\n case \"weak\":\n b.level = Math.min(1.0, b.level + this.weakFill);\n break;\n case \"empty\":\n b.level = Math.min(1.0, b.level + this.emptyFill);\n break;\n case \"truncated\":\n if (this.truncatedFill > 0) b.level = Math.min(1.0, b.level + this.truncatedFill);\n break;\n }\n\n b.consecutiveErrors++;\n b.lastUpdate = now;\n this.buckets.set(key, b);\n }\n\n getHealth(): Map<string, { level: number; consecutiveErrors: number; cooldownUntil?: number; status: ModelStatus }> {\n const now = Date.now();\n const result = new Map<string, { level: number; consecutiveErrors: number; cooldownUntil?: number; status: ModelStatus }>();\n for (const [key, b] of this.buckets) {\n this.drain(b, now);\n let status: ModelStatus = \"healthy\";\n if (b.authFailed) status = \"auth_failed\";\n else if (b.level > this.skipThreshold) status = \"exhausted\";\n else if (b.level > 0.3) status = \"degraded\";\n result.set(key, { level: Math.round(b.level * 100), consecutiveErrors: b.consecutiveErrors, cooldownUntil: b.cooldownUntil, status });\n }\n return result;\n }\n\n /** Get bucket level for a specific model (0-100%). */\n getBucketLevel(model: string, endpoint: string): number {\n const b = this.buckets.get(`${endpoint}|${model}`);\n if (!b) return 0;\n this.drain(b, Date.now());\n return Math.round(b.level * 100);\n }\n\n resetAll(): void {\n this.buckets.clear();\n }\n}\n\n/** Classify HTTP status to error kind. */\nexport function classifyError(status: number, message?: string): ErrorKind {\n if (status === 402 && message?.includes(\"credits\")) return \"credits\";\n if (status === 429 || status === 402) return \"rate_limit\";\n if (status === 404 && message && /image input|No endpoints found/i.test(message)) return \"transient\";\n if (status === 401 || status === 403 || status === 404) return \"auth\";\n return \"transient\";\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/components/tasks/kanban-board.ts"],
4
- "sourcesContent": ["/**\n * kanban-board.ts \u2014 Local Kanban board backed by SQLite.\n *\n * Workers write completion; main agent polls and delivers.\n * DB lives at ~/.abtars/kanban/kanban.db\n */\n\nimport { join } from \"node:path\";\nimport { mkdirSync } from \"node:fs\";\nimport { abtarsHome } from \"../../paths.js\";\nimport { resolveNativeDep } from \"../../utils/lazy-require.js\";\nimport { logWarn } from \"../logger.js\";\n\n// better-sqlite3 is external (native module, resolved from ~/.local/lib/node_modules/)\ntype SqliteDb = { prepare(sql: string): any; exec(sql: string): void; pragma(s: string): void };\n\nexport interface KanbanCard {\n id: number;\n title: string;\n source: string;\n source_id: string | null;\n assignee: string;\n priority: string;\n status: string;\n type: string | null;\n notes: string | null;\n result_summary: string | null;\n result_path: string | null;\n error: string | null;\n delivery_attempts: number;\n approval: string | null;\n due_at: string | null;\n labels: string | null;\n parent_id: number | null;\n blocked_by: string | null;\n created_at: string;\n updated_at: string;\n completed_at: string | null;\n delivered_at: string | null;\n max_tokens: number | null;\n tokens_used: number | null;\n delivery_mode: string;\n chat_id: string | null;\n source_peer: string | null;\n}\n\nlet _db: SqliteDb | null = null;\nlet _dbAttempted = false;\n\nfunction db(): SqliteDb | null {\n if (_dbAttempted) return _db;\n _dbAttempted = true;\n const dir = join(abtarsHome(), \"kanban\");\n mkdirSync(dir, { recursive: true });\n try {\n const Database = resolveNativeDep(\"better-sqlite3\");\n _db = new Database(join(dir, \"kanban.db\")) as SqliteDb;\n _db.pragma(\"journal_mode = WAL\");\n _db.exec(`CREATE TABLE IF NOT EXISTS kanban_board (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n title TEXT NOT NULL,\n source TEXT NOT NULL,\n source_id TEXT,\n assignee TEXT DEFAULT 'local',\n priority TEXT NOT NULL DEFAULT 'MEDIUM' CHECK(priority IN ('CRITICAL','HIGH','MEDIUM','LOW')),\n status TEXT NOT NULL DEFAULT 'queued' CHECK(status IN ('queued','running','done','failed','delivering','delivered')),\n type TEXT,\n notes TEXT,\n result_summary TEXT,\n result_path TEXT,\n error TEXT,\n delivery_attempts INTEGER DEFAULT 0,\n approval TEXT CHECK(approval IS NULL OR approval IN ('pending','approved','rejected')),\n due_at TEXT,\n labels TEXT,\n parent_id INTEGER REFERENCES kanban_board(id),\n blocked_by TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n completed_at TEXT,\n delivered_at TEXT\n )`);\n // Migrations \u2014 safe to re-run (silently skip if column exists)\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN max_tokens INTEGER`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN tokens_used INTEGER DEFAULT 0`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN progress TEXT`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN delivery_mode TEXT DEFAULT 'deliver'`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN retry_count INTEGER DEFAULT 0`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN next_retry_at TEXT`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN chat_id TEXT`); } catch {}\n try { _db.exec(`ALTER TABLE kanban_board ADD COLUMN source_peer TEXT`); } catch {}\n } catch {\n logWarn(\"kanban\", \"better-sqlite3 not available \u2014 kanban features disabled (run: abtars deps install)\");\n _db = null;\n }\n return _db;\n}\n\nimport { nerve } from \"../nerve.js\";\n\n/** Return db or null (with warning logged once). */\nfunction dbOrNull(): SqliteDb | null {\n return db();\n}\n\nexport function kanbanEnqueue(title: string, source: string, sourceId?: string, opts?: { priority?: string; type?: string; labels?: string; due_at?: string; parent_id?: number; notes?: string; deliveryMode?: \"silent\" | \"deliver\" | \"announce\"; blocked_by?: string; chatId?: string; sourcePeer?: string }): number {\n const d = dbOrNull();\n if (!d) return 0;\n const deliveryMode = opts?.deliveryMode ?? \"deliver\";\n const stmt = d.prepare(\n `INSERT INTO kanban_board (title, source, source_id, priority, type, labels, due_at, parent_id, notes, delivery_mode, blocked_by, chat_id, source_peer)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n );\n const result = stmt.run(title, source, sourceId ?? null, opts?.priority ?? \"MEDIUM\", opts?.type ?? null, opts?.labels ?? null, opts?.due_at ?? null, opts?.parent_id ?? null, opts?.notes ?? null, deliveryMode, opts?.blocked_by ?? null, opts?.chatId ?? null, opts?.sourcePeer ?? null);\n const id = Number(result.lastInsertRowid);\n nerve.fire(\"card:queued\", id);\n return id;\n}\n\nexport function kanbanRunning(id: number): void {\n const d = dbOrNull();\n if (!d) return;\n d.prepare(`UPDATE kanban_board SET status = 'running', updated_at = datetime('now') WHERE id = ?`).run(id);\n nerve.fire(\"card:running\", id);\n}\n\nexport function kanbanComplete(id: number, resultPath: string | null, summary: string): void {\n const d = dbOrNull();\n if (!d) return;\n d.prepare(\n `UPDATE kanban_board SET status = 'done', result_path = ?, result_summary = ?, completed_at = datetime('now'), updated_at = datetime('now') WHERE id = ?`\n ).run(resultPath, summary.slice(0, 4000), id);\n nerve.fire(\"card:done\", id);\n}\n\nexport function kanbanFail(id: number, error: string): void {\n const d = dbOrNull();\n if (!d) return;\n d.prepare(\n `UPDATE kanban_board SET status = 'failed', error = ?, completed_at = datetime('now'), updated_at = datetime('now') WHERE id = ?`\n ).run(error.slice(0, 1000), id);\n nerve.fire(\"card:failed\", id);\n}\n\nconst MAX_RETRIES = 3;\n\n/** Fail with retry logic \u2014 exponential backoff (10s\u219220s\u219240s, cap 5min). After MAX_RETRIES \u2192 permanent fail. */\nexport function kanbanRetryOrFail(id: number, error: string): \"retrying\" | \"failed\" {\n const d = dbOrNull();\n if (!d) return \"failed\";\n const card = d.prepare(\"SELECT retry_count FROM kanban_board WHERE id = ?\").get(id) as { retry_count: number } | undefined;\n const retryCount = (card?.retry_count ?? 0) + 1;\n if (retryCount > MAX_RETRIES) {\n kanbanFail(id, `${error} (after ${MAX_RETRIES} retries)`);\n return \"failed\";\n }\n const backoffMs = Math.min(10_000 * Math.pow(2, retryCount - 1), 300_000);\n const nextRetryAt = new Date(Date.now() + backoffMs).toISOString();\n d.prepare(\n `UPDATE kanban_board SET status = 'queued', retry_count = ?, next_retry_at = ?, error = ?, updated_at = datetime('now') WHERE id = ?`\n ).run(retryCount, nextRetryAt, error.slice(0, 1000), id);\n nerve.fire(\"card:queued\", id);\n return \"retrying\";\n}\n\nexport function kanbanPending(): KanbanCard[] {\n const d = dbOrNull();\n if (!d) return [];\n return d.prepare(\n `SELECT * FROM kanban_board WHERE status = 'done' AND delivery_attempts < 3 ORDER BY priority = 'CRITICAL' DESC, priority = 'HIGH' DESC, created_at ASC`\n ).all() as KanbanCard[];\n}\n\nexport function kanbanSetDelivering(id: number): void {\n const d = dbOrNull();\n if (!d) return;\n d.prepare(`UPDATE kanban_board SET status = 'delivering', updated_at = datetime('now') WHERE id = ?`).run(id);\n}\n\nexport function kanbanMarkDelivered(id: number): void {\n const d = dbOrNull();\n if (!d) return;\n d.prepare(\n `UPDATE kanban_board SET status = 'delivered', delivered_at = datetime('now'), updated_at = datetime('now') WHERE id = ?`\n ).run(id);\n nerve.fire(\"card:delivered\", id);\n}\n\nexport function kanbanDeliveryFailed(id: number): void {\n const d = dbOrNull();\n if (!d) return;\n const card = d.prepare(`SELECT delivery_attempts FROM kanban_board WHERE id = ?`).get(id) as { delivery_attempts: number } | undefined;\n const attempts = (card?.delivery_attempts ?? 0) + 1;\n if (attempts >= 3) {\n d.prepare(`UPDATE kanban_board SET status = 'failed', error = 'delivery failed after 3 attempts', delivery_attempts = ?, updated_at = datetime('now') WHERE id = ?`).run(attempts, id);\n } else {\n d.prepare(`UPDATE kanban_board SET status = 'done', delivery_attempts = ?, updated_at = datetime('now') WHERE id = ?`).run(attempts, id);\n }\n}\n\nexport function kanbanList(filter?: string, filterKey?: string): KanbanCard[] {\n const d = dbOrNull();\n if (!d) return [];\n if (filter === \"*\") {\n return d.prepare(`SELECT * FROM kanban_board ORDER BY created_at DESC LIMIT 50`).all() as KanbanCard[];\n }\n if (filter && filterKey) {\n if (filterKey === \"labels\") {\n return d.prepare(`SELECT * FROM kanban_board WHERE labels LIKE ? ORDER BY created_at DESC LIMIT 50`).all(`%${filter}%`) as KanbanCard[];\n }\n const allowed = new Set([\"status\", \"source\", \"priority\", \"type\"]);\n if (allowed.has(filterKey)) {\n return d.prepare(`SELECT * FROM kanban_board WHERE ${filterKey} = ? ORDER BY created_at DESC LIMIT 50`).all(filter) as KanbanCard[];\n }\n }\n if (filter) {\n return d.prepare(`SELECT * FROM kanban_board WHERE status = ? ORDER BY created_at DESC LIMIT 50`).all(filter) as KanbanCard[];\n }\n return d.prepare(`SELECT * FROM kanban_board WHERE status NOT IN ('delivered') ORDER BY status = 'running' DESC, priority = 'CRITICAL' DESC, created_at DESC LIMIT 50`).all() as KanbanCard[];\n}\n\nexport function kanbanUpdate(id: number, fields: Partial<Pick<KanbanCard, \"title\" | \"status\" | \"priority\" | \"type\" | \"labels\" | \"due_at\" | \"notes\" | \"parent_id\" | \"approval\">>): void {\n const d = dbOrNull();\n if (!d) return;\n const sets: string[] = [\"updated_at = datetime('now')\"];\n const vals: unknown[] = [];\n for (const [k, v] of Object.entries(fields)) {\n if (v !== undefined) { sets.push(`${k} = ?`); vals.push(v); }\n }\n vals.push(id);\n d.prepare(`UPDATE kanban_board SET ${sets.join(\", \")} WHERE id = ?`).run(...vals);\n}\n\nexport function kanbanCleanup(olderThanDays = 7): number {\n const d = dbOrNull();\n if (!d) return 0;\n const result = d.prepare(\n `DELETE FROM kanban_board WHERE status = 'delivered' AND delivered_at < datetime('now', '-' || ? || ' days')`\n ).run(olderThanDays);\n return result.changes;\n}\n\nexport function kanbanGetCard(id: number): KanbanCard | undefined {\n const d = dbOrNull();\n if (!d) return undefined;\n return d.prepare(`SELECT * FROM kanban_board WHERE id = ?`).get(id) as KanbanCard | undefined;\n}\n\nexport function kanbanGetChildren(parentId: number): KanbanCard[] {\n const d = dbOrNull();\n if (!d) return [];\n return d.prepare(`SELECT * FROM kanban_board WHERE parent_id = ? ORDER BY id`).all(parentId) as KanbanCard[];\n}\n\nexport function kanbanAddTokens(id: number, tokens: number): void {\n const d = dbOrNull();\n if (!d) return;\n d.prepare(`UPDATE kanban_board SET tokens_used = COALESCE(tokens_used, 0) + ?, updated_at = datetime('now') WHERE id = ?`).run(tokens, id);\n const card = kanbanGetCard(id);\n if (card?.parent_id) {\n d.prepare(`UPDATE kanban_board SET tokens_used = COALESCE(tokens_used, 0) + ?, updated_at = datetime('now') WHERE id = ?`).run(tokens, card.parent_id);\n }\n}\n\n// #907: Worker progress \u2014 30s debounce per card\nconst _progressTimers = new Map<number, ReturnType<typeof setTimeout>>();\nconst _progressPending = new Map<number, Record<string, unknown>>();\n\nexport function kanbanProgress(id: number, data: { toolUseCount?: number; tokenCount?: number; lastTool?: string; summary?: string }): void {\n _progressPending.set(id, data);\n if (_progressTimers.has(id)) return;\n _progressTimers.set(id, setTimeout(() => {\n _progressTimers.delete(id);\n const pending = _progressPending.get(id);\n if (pending) {\n const d = dbOrNull();\n if (d) d.prepare(`UPDATE kanban_board SET progress = ?, updated_at = datetime('now') WHERE id = ?`).run(JSON.stringify(pending), id);\n _progressPending.delete(id);\n }\n }, 30_000));\n}\n\n// \u2500\u2500 DAG orchestration (#677) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Check if all dependencies of a card are satisfied. */\nexport function isUnblocked(card: KanbanCard): boolean {\n if (!card.blocked_by) return true;\n if (card.blocked_by === \"children\") {\n const kids = kanbanGetChildren(card.id);\n return kids.length > 0 && kids.every(k => k.status === \"done\" || k.status === \"delivered\");\n }\n const depIds = card.blocked_by.split(\",\").map(Number).filter(n => !isNaN(n));\n if (depIds.length === 0) return true;\n return depIds.every(id => {\n const dep = kanbanGetCard(id);\n return dep?.status === \"done\" || dep?.status === \"delivered\";\n });\n}\n\n/** Cascade-fail all cards depending (transitively) on a failed card. */\nexport function cascadeFail(failedId: number, projectCards: KanbanCard[]): void {\n for (const card of projectCards) {\n if (card.status !== \"queued\") continue;\n if (!card.blocked_by) continue;\n const deps = card.blocked_by.split(\",\").map(Number).filter(n => !isNaN(n));\n if (deps.includes(failedId)) {\n kanbanFail(card.id, `upstream #${failedId} failed`);\n cascadeFail(card.id, projectCards);\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,241 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
3
- import {
4
- init_peer_config,
5
- loadPeerConfig
6
- } from "./chunk-4S554KLW.js";
7
- import {
8
- init_logger,
9
- logDebug,
10
- logInfo,
11
- logTrace,
12
- logWarn
13
- } from "./chunk-GWILHZPT.js";
14
- import {
15
- __esm,
16
- __export
17
- } from "./chunk-7K2YZTLD.js";
18
-
19
- // src/components/peer-transport/gossip.ts
20
- var gossip_exports = {};
21
- __export(gossip_exports, {
22
- findCapablePeer: () => findCapablePeer,
23
- getAlivePeers: () => getAlivePeers,
24
- getLocalCapabilities: () => getLocalCapabilities,
25
- getPeerTable: () => getPeerTable,
26
- gossipBroadcast: () => gossipBroadcast,
27
- setGossipInterval: () => setGossipInterval,
28
- startGossip: () => startGossip,
29
- startGossipListener: () => startGossipListener,
30
- stopGossip: () => stopGossip,
31
- stopGossipListener: () => stopGossipListener
32
- });
33
- import { createSocket } from "node:dgram";
34
- import { execSync } from "node:child_process";
35
- import { existsSync } from "node:fs";
36
- import { cpus, loadavg } from "node:os";
37
- import { createHmac } from "node:crypto";
38
- function discoverCapabilities() {
39
- const caps = ["bash", "node", "memory"];
40
- try {
41
- if (execSync("which docker", { stdio: "pipe" }).toString().trim()) caps.push("docker");
42
- } catch {
43
- }
44
- try {
45
- if (execSync("which xcodebuild", { stdio: "pipe" }).toString().trim()) caps.push("xcode");
46
- } catch {
47
- }
48
- try {
49
- if (execSync("which ollama", { stdio: "pipe" }).toString().trim()) caps.push("ollama");
50
- } catch {
51
- }
52
- if (existsSync("/usr/bin/nvidia-smi") || process.env["CUDA_VISIBLE_DEVICES"]) caps.push("gpu");
53
- if (process.env["BROWSER_ENGINE"]) caps.push("browser");
54
- if (process.env["GROQ_API_KEY"]) caps.push("stt");
55
- return caps;
56
- }
57
- function getLoad() {
58
- const cores = cpus().length || 1;
59
- return Math.min(1, loadavg()[0] / cores);
60
- }
61
- function getGossipKey(config) {
62
- if (config.gossipSecret) return config.gossipSecret;
63
- return null;
64
- }
65
- function buildPacket() {
66
- const config = loadPeerConfig();
67
- const payload = JSON.stringify({
68
- name: config.self.name,
69
- ts: Math.floor(Date.now() / 1e3),
70
- load: Math.round(getLoad() * 100) / 100,
71
- sessions: parseInt(process.env["_ACTIVE_SESSIONS"] ?? "0", 10),
72
- capabilities: _capabilities,
73
- version: process.env["npm_package_version"] ?? "?"
74
- });
75
- const key = getGossipKey(config) ?? Object.values(config.peers)[0]?.token ?? "default";
76
- const sig = createHmac("sha256", key).update(payload).digest("base64url").slice(0, 16);
77
- return Buffer.from(`${payload}|${sig}`);
78
- }
79
- function verifyPacket(data) {
80
- const str = data.toString("utf8");
81
- const sepIdx = str.lastIndexOf("|");
82
- if (sepIdx < 0) return null;
83
- const payload = str.slice(0, sepIdx);
84
- const sig = str.slice(sepIdx + 1);
85
- const config = loadPeerConfig();
86
- const shared = getGossipKey(config);
87
- if (shared) {
88
- const expected = createHmac("sha256", shared).update(payload).digest("base64url").slice(0, 16);
89
- if (sig === expected) {
90
- try {
91
- return JSON.parse(payload);
92
- } catch {
93
- return null;
94
- }
95
- }
96
- return null;
97
- }
98
- for (const peer of Object.values(config.peers)) {
99
- const key = peer.token;
100
- if (!key) continue;
101
- const expected = createHmac("sha256", key).update(payload).digest("base64url").slice(0, 16);
102
- if (sig === expected) {
103
- try {
104
- return JSON.parse(payload);
105
- } catch {
106
- return null;
107
- }
108
- }
109
- }
110
- return null;
111
- }
112
- function broadcast() {
113
- const config = loadPeerConfig();
114
- const packet = buildPacket();
115
- for (const [name, entry] of Object.entries(config.peers)) {
116
- _socket?.send(packet, 0, packet.length, GOSSIP_PORT, entry.host, (err) => {
117
- if (err) logTrace(TAG, `Send to ${name} (${entry.host}:${GOSSIP_PORT}) failed: ${err.message}`);
118
- });
119
- }
120
- logTrace(TAG, `Broadcast to ${Object.keys(config.peers).length} peer(s)`);
121
- const now = Date.now();
122
- for (const [, health] of peerTable) {
123
- const wasAlive = health.alive;
124
- health.alive = now - health.lastSeen < TTL_MS;
125
- if (wasAlive && !health.alive) logDebug(TAG, `PEER_OFFLINE ${health.name} (no heartbeat for ${Math.round((now - health.lastSeen) / 1e3)}s)`);
126
- }
127
- }
128
- function startGossip() {
129
- _capabilities = discoverCapabilities();
130
- logInfo(TAG, `Capabilities: [${_capabilities.join(", ")}]`);
131
- _socket = createSocket("udp4");
132
- _socket.on("message", (msg, rinfo) => {
133
- const parsed = verifyPacket(msg);
134
- if (!parsed || typeof parsed.name !== "string") return;
135
- const name = parsed.name;
136
- const config = loadPeerConfig();
137
- if (parsed.type === "ping") {
138
- const key = getGossipKey(config) ?? Object.values(config.peers)[0]?.token ?? "default";
139
- const pong = "PONG";
140
- const sig = createHmac("sha256", key).update(pong).digest("base64url").slice(0, 16);
141
- const reply = Buffer.from(`${pong}|${sig}`);
142
- _socket?.send(reply, 0, reply.length, rinfo.port, rinfo.address);
143
- return;
144
- }
145
- if (name === config.self.name) return;
146
- const existing = peerTable.get(name);
147
- const health = {
148
- name,
149
- lastSeen: Date.now(),
150
- load: parsed.load ?? 0,
151
- sessions: parsed.sessions ?? 0,
152
- capabilities: parsed.capabilities ?? [],
153
- version: parsed.version ?? "?",
154
- alive: true,
155
- host: rinfo.address,
156
- port: rinfo.port
157
- };
158
- peerTable.set(name, health);
159
- if (!existing) logDebug(TAG, `PEER_ONLINE ${name} [${health.capabilities.join(",")}] v${health.version}`);
160
- else if (!existing.alive) logDebug(TAG, `PEER_ONLINE ${name} returned [${health.capabilities.join(",")}] v${health.version}`);
161
- });
162
- _socket.on("error", (err) => {
163
- logWarn(TAG, `Socket error: ${err.message}`);
164
- });
165
- _socket.bind(GOSSIP_PORT, "0.0.0.0", () => {
166
- logInfo(TAG, `Listening on UDP :${GOSSIP_PORT}`);
167
- });
168
- setTimeout(broadcast, 2e3);
169
- _interval = setInterval(broadcast, BROADCAST_INTERVAL_MS);
170
- }
171
- function stopGossip() {
172
- if (_interval) {
173
- clearInterval(_interval);
174
- _interval = null;
175
- }
176
- if (_socket) {
177
- _socket.close();
178
- _socket = null;
179
- }
180
- }
181
- function getPeerTable(includeAll = false) {
182
- const now = Date.now();
183
- const results = [];
184
- for (const health of peerTable.values()) {
185
- health.alive = now - health.lastSeen < TTL_MS;
186
- if (includeAll || health.alive) results.push(health);
187
- }
188
- return results;
189
- }
190
- function getLocalCapabilities() {
191
- return _capabilities;
192
- }
193
- function findCapablePeer(requires) {
194
- const alive = getPeerTable().filter(
195
- (p) => requires.every((req) => p.capabilities.includes(req))
196
- );
197
- if (alive.length === 0) return null;
198
- alive.sort((a, b) => a.load - b.load);
199
- return alive[0];
200
- }
201
- function setGossipInterval(ms) {
202
- if (_interval) {
203
- clearInterval(_interval);
204
- _interval = setInterval(broadcast, ms);
205
- }
206
- }
207
- var TAG, GOSSIP_PORT, BROADCAST_INTERVAL_MS, TTL_MS, peerTable, _socket, _interval, _capabilities, startGossipListener, getAlivePeers, gossipBroadcast, stopGossipListener;
208
- var init_gossip = __esm({
209
- "src/components/peer-transport/gossip.ts"() {
210
- init_peer_config();
211
- init_logger();
212
- TAG = "gossip";
213
- GOSSIP_PORT = parseInt(process.env["GOSSIP_PORT"] ?? "5355", 10);
214
- BROADCAST_INTERVAL_MS = 6e4;
215
- TTL_MS = 18e4;
216
- peerTable = /* @__PURE__ */ new Map();
217
- _socket = null;
218
- _interval = null;
219
- _capabilities = [];
220
- startGossipListener = startGossip;
221
- getAlivePeers = getPeerTable;
222
- gossipBroadcast = broadcast;
223
- stopGossipListener = stopGossip;
224
- }
225
- });
226
-
227
- export {
228
- startGossip,
229
- stopGossip,
230
- getPeerTable,
231
- getLocalCapabilities,
232
- findCapablePeer,
233
- startGossipListener,
234
- getAlivePeers,
235
- gossipBroadcast,
236
- setGossipInterval,
237
- stopGossipListener,
238
- gossip_exports,
239
- init_gossip
240
- };
241
- //# sourceMappingURL=chunk-HT2BPTZY.js.map
@@ -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
- }