abtars 0.3.3 → 0.3.4-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. package/bundle/{_registry.generated-7DRCE4V6.js → _registry.generated-ZJBAZMXN.js} +16 -15
  2. package/bundle/{_registry.generated-7DRCE4V6.js.map → _registry.generated-ZJBAZMXN.js.map} +1 -1
  3. package/bundle/abtars-browser.js +6 -5
  4. package/bundle/abtars-browser.js.map +1 -1
  5. package/bundle/abtars-cli.js +47 -39
  6. package/bundle/abtars-cli.js.map +2 -2
  7. package/bundle/abtars-restart.js +7 -7
  8. package/bundle/abtars-rss.js +2 -1
  9. package/bundle/abtars-rss.js.map +2 -2
  10. package/bundle/abtars-task.js +6 -5
  11. package/bundle/abtars-task.js.map +1 -1
  12. package/bundle/abtars-todo.js +2 -1
  13. package/bundle/abtars-todo.js.map +1 -1
  14. package/bundle/abtars.js +299 -209
  15. package/bundle/abtars.js.map +4 -4
  16. package/bundle/{acp-raw-client-AZJCEB6S.js → acp-raw-client-YTBGFN4S.js} +4 -3
  17. package/bundle/{acp-raw-client-AZJCEB6S.js.map → acp-raw-client-YTBGFN4S.js.map} +1 -1
  18. package/bundle/{action-gate-QYJL57IX.js → action-gate-YISTP773.js} +4 -3
  19. package/bundle/{action-gate-QYJL57IX.js.map → action-gate-YISTP773.js.map} +1 -1
  20. package/bundle/{agent-api-adapter-PYMNQXHE.js → agent-api-adapter-E4HWVJ32.js} +5 -4
  21. package/bundle/{agent-api-adapter-PYMNQXHE.js.map → agent-api-adapter-E4HWVJ32.js.map} +1 -1
  22. package/bundle/{agent-api-rate-limit-4GEZ4YN5.js → agent-api-rate-limit-VENFGOAD.js} +6 -5
  23. package/bundle/{agent-registry-563P4EUJ.js → agent-registry-DL7UT272.js} +9 -8
  24. package/bundle/bootstrap-V5MROD3X.js +62 -0
  25. package/bundle/bootstrap-V5MROD3X.js.map +7 -0
  26. package/bundle/{bridge-lock-transport-LXCF2IVN.js → bridge-lock-transport-BJAMHMXW.js} +6 -5
  27. package/bundle/{browser-2VZOGOGX.js → browser-PT54UWSW.js} +8 -7
  28. package/bundle/{budget-PPA7WY3D.js → budget-QNK6IIT6.js} +5 -4
  29. package/bundle/{budget-PPA7WY3D.js.map → budget-QNK6IIT6.js.map} +1 -1
  30. package/bundle/{capability-WXEA2WFK.js → capability-EKPGHQIO.js} +7 -6
  31. package/bundle/{chunk-C3EYYJN3.js → chunk-2BXXQG7P.js} +16 -4
  32. package/bundle/chunk-2BXXQG7P.js.map +7 -0
  33. package/bundle/{chunk-4PIVWXUJ.js → chunk-2ZD7VQRW.js} +2 -2
  34. package/bundle/{chunk-OY2HAK33.js → chunk-36ZEYDKZ.js} +1 -1
  35. package/bundle/chunk-36ZEYDKZ.js.map +7 -0
  36. package/bundle/{chunk-3QW2K53E.js → chunk-4IGLXZCC.js} +11 -19
  37. package/bundle/chunk-4IGLXZCC.js.map +7 -0
  38. package/bundle/{chunk-T7TAWGBX.js → chunk-52PQM4EZ.js} +2 -2
  39. package/bundle/{chunk-2RGR3LSV.js → chunk-5P5HF7IJ.js} +2 -2
  40. package/bundle/{chunk-LE23VPN3.js → chunk-63A7ZRIH.js} +4 -4
  41. package/bundle/{chunk-LE23VPN3.js.map → chunk-63A7ZRIH.js.map} +1 -1
  42. package/bundle/chunk-6IB3GVXK.js +77 -0
  43. package/bundle/chunk-6IB3GVXK.js.map +7 -0
  44. package/bundle/{chunk-OOKNHOCB.js → chunk-6S3G6GPO.js} +2 -2
  45. package/bundle/{chunk-E7MV7WFT.js → chunk-6VTHSN4V.js} +6 -6
  46. package/bundle/{chunk-NGZVJ52F.js → chunk-76YN7O3U.js} +7 -7
  47. package/bundle/{chunk-43DKPXTP.js → chunk-7LORCJCQ.js} +4 -4
  48. package/bundle/{chunk-HDOFJVFS.js → chunk-7OI46MH7.js} +3 -3
  49. package/bundle/{chunk-H2K23MOF.js → chunk-7XXISOHU.js} +21 -5
  50. package/bundle/chunk-7XXISOHU.js.map +7 -0
  51. package/bundle/{chunk-CB6S3ZRF.js → chunk-AFFW2LRY.js} +3 -3
  52. package/bundle/{chunk-TCI6FZTP.js → chunk-AHJDG6OM.js} +9 -9
  53. package/bundle/{chunk-NP72ZB7P.js → chunk-AMUJEP6L.js} +45 -45
  54. package/bundle/{chunk-NP72ZB7P.js.map → chunk-AMUJEP6L.js.map} +2 -2
  55. package/bundle/{chunk-BU7LTI2W.js → chunk-AWCO3DQ3.js} +6 -7
  56. package/bundle/chunk-AWCO3DQ3.js.map +7 -0
  57. package/bundle/{chunk-YME7NRGP.js → chunk-B2TIRDZC.js} +2 -2
  58. package/bundle/{chunk-SSCGWDIC.js → chunk-BWJ37KMW.js} +2 -2
  59. package/bundle/{chunk-ULO2PX3T.js → chunk-CCZ43JB7.js} +3 -3
  60. package/bundle/{chunk-FVUL44T4.js → chunk-CNENVY37.js} +2 -2
  61. package/bundle/{chunk-J5NOL4DB.js → chunk-DJOSXXM2.js} +2 -2
  62. package/bundle/{chunk-7RAGSHSH.js → chunk-DMDX35YT.js} +12 -10
  63. package/bundle/chunk-DMDX35YT.js.map +7 -0
  64. package/bundle/{chunk-DNDYD5SL.js → chunk-E7DZYCSF.js} +3 -3
  65. package/bundle/{chunk-M6Q3IQ4H.js → chunk-FF2F7ENH.js} +250 -118
  66. package/bundle/chunk-FF2F7ENH.js.map +7 -0
  67. package/bundle/{chunk-GCFIK6OB.js → chunk-FSGICOCX.js} +21 -21
  68. package/bundle/{chunk-IXKQ4JMX.js → chunk-GFAJSPMD.js} +33 -17
  69. package/bundle/chunk-GFAJSPMD.js.map +7 -0
  70. package/bundle/{chunk-FJF42RZY.js → chunk-GHRLO2UL.js} +3 -3
  71. package/bundle/{chunk-3LQOJVTB.js → chunk-HFOCNYEO.js} +1842 -1220
  72. package/bundle/{chunk-3LQOJVTB.js.map → chunk-HFOCNYEO.js.map} +4 -4
  73. package/bundle/{chunk-7WHXTCVD.js → chunk-HWFN7JGU.js} +2 -2
  74. package/bundle/{chunk-KBPVJGD7.js → chunk-IXGDDDAB.js} +3 -3
  75. package/bundle/chunk-JHLKEUHE.js +37 -0
  76. package/bundle/chunk-JHLKEUHE.js.map +7 -0
  77. package/bundle/{chunk-YEOZN5IE.js → chunk-JRGEEGZF.js} +2 -2
  78. package/bundle/{chunk-56D3Y44D.js → chunk-KLG4SCF7.js} +10 -10
  79. package/bundle/{chunk-ASYX43OU.js → chunk-LB43Q7G6.js} +26 -26
  80. package/bundle/{chunk-TVSPVZTX.js → chunk-LN5MNDSA.js} +3 -3
  81. package/bundle/{chunk-RJX45XIC.js → chunk-LPF2HELD.js} +9 -4
  82. package/bundle/chunk-LPF2HELD.js.map +7 -0
  83. package/bundle/{chunk-72T2Q7IG.js → chunk-MJACYH7A.js} +270 -282
  84. package/bundle/chunk-MJACYH7A.js.map +7 -0
  85. package/bundle/{chunk-SESM4GBM.js → chunk-MPQ2PJQX.js} +52 -25
  86. package/bundle/chunk-MPQ2PJQX.js.map +7 -0
  87. package/bundle/{chunk-FIAVVKGN.js → chunk-MTE32OQH.js} +3 -3
  88. package/bundle/{chunk-MV5KOWOR.js → chunk-N3Q3TASM.js} +7 -7
  89. package/bundle/{chunk-IQKADER4.js → chunk-O4YBJS2K.js} +2 -2
  90. package/bundle/{chunk-VJATH7AN.js → chunk-OOUCUCUW.js} +9 -8
  91. package/bundle/chunk-OOUCUCUW.js.map +7 -0
  92. package/bundle/{chunk-5V4VHKEA.js → chunk-OT6HLPEA.js} +3 -3
  93. package/bundle/{chunk-V6CV3QPH.js → chunk-OWPQIBAO.js} +2 -2
  94. package/bundle/{chunk-EDZGF6BC.js → chunk-QJPDBJDP.js} +11 -4
  95. package/bundle/chunk-QJPDBJDP.js.map +7 -0
  96. package/bundle/{chunk-N5VROZ7A.js → chunk-QMP2KC4W.js} +5 -5
  97. package/bundle/{chunk-4HNCOQSK.js → chunk-QOGZ7BFL.js} +7 -7
  98. package/bundle/{chunk-2LKQV2ND.js → chunk-R23FHZRY.js} +3 -3
  99. package/bundle/{chunk-SXNY6HC4.js → chunk-R4GYWVCR.js} +6 -6
  100. package/bundle/chunk-R4GYWVCR.js.map +7 -0
  101. package/bundle/{chunk-S7ZIGIR5.js → chunk-R76K6L6H.js} +27 -27
  102. package/bundle/{chunk-S7ZIGIR5.js.map → chunk-R76K6L6H.js.map} +1 -1
  103. package/bundle/{chunk-TY26WMQY.js → chunk-RCWQ34QR.js} +2 -2
  104. package/bundle/{chunk-MQJG7OJX.js → chunk-RJ2OUNFU.js} +38 -36
  105. package/bundle/chunk-RJ2OUNFU.js.map +7 -0
  106. package/bundle/{chunk-S6HEHCCG.js → chunk-RO3TAYBR.js} +83 -46
  107. package/bundle/chunk-RO3TAYBR.js.map +7 -0
  108. package/bundle/{chunk-ZOCEBV62.js → chunk-UU3RLJSD.js} +3 -3
  109. package/bundle/{chunk-P5O6QZDC.js → chunk-V7Y2LFO4.js} +10 -6
  110. package/bundle/chunk-V7Y2LFO4.js.map +7 -0
  111. package/bundle/{chunk-WP7FZHMI.js → chunk-W2PSVV2T.js} +2 -2
  112. package/bundle/{chunk-V2QIAXWZ.js → chunk-WEGFRA6G.js} +3 -3
  113. package/bundle/{chunk-ZY6DH2S4.js → chunk-WTIGZO3N.js} +80 -70
  114. package/bundle/chunk-WTIGZO3N.js.map +7 -0
  115. package/bundle/{chunk-O4GKI3Q3.js → chunk-X7DLKIQM.js} +4 -4
  116. package/bundle/{chunk-BNBC4T45.js → chunk-XZ4ZBDM5.js} +3 -3
  117. package/bundle/{chunk-24V4A6RP.js → chunk-YI2KSYB4.js} +4 -4
  118. package/bundle/{chunk-37EX63K4.js → chunk-YWHJJHJ2.js} +6998 -3621
  119. package/bundle/chunk-YWHJJHJ2.js.map +7 -0
  120. package/bundle/{chunk-IK4R3RBZ.js → chunk-YZCOA4DC.js} +3 -3
  121. package/bundle/{chunk-2FZJDMAF.js → chunk-ZGNSCJWH.js} +10 -10
  122. package/bundle/{chunk-W726UGI6.js → chunk-ZKMKAO75.js} +3 -3
  123. package/bundle/{chunk-WGWM4IZM.js → chunk-ZT5ZBGWS.js} +4 -4
  124. package/bundle/{chunk-WGWM4IZM.js.map → chunk-ZT5ZBGWS.js.map} +1 -1
  125. package/bundle/{commands-XXFU2ZF7.js → commands-2JQ5YTJX.js} +20 -20
  126. package/bundle/{config-EWDZ234X.js → config-ZEWIM5Z2.js} +8 -7
  127. package/bundle/{config-show-6J33O4TE.js → config-show-WBJPQPRD.js} +5 -5
  128. package/bundle/{context-OCS7HLJP.js → context-V75QNXB5.js} +5 -2
  129. package/bundle/{context-OCS7HLJP.js.map → context-V75QNXB5.js.map} +1 -1
  130. package/bundle/{daemon-LTDAXNA2.js → daemon-W7VQOSZC.js} +7 -7
  131. package/bundle/{delegation-tools-YDTWQMZD.js → delegation-tools-VGTRFQBF.js} +13 -11
  132. package/bundle/{registry-client-VN2MM2HI.js → deploy-5AGIULM2.js} +10 -6
  133. package/bundle/{deploy-lib-import-RGZJ3CGC.js → deploy-lib-import-ZBDYORN4.js} +5 -3
  134. package/bundle/{deps-PHSLIA77.js → deps-VB3S3RLF.js} +21 -19
  135. package/bundle/deps-VB3S3RLF.js.map +7 -0
  136. package/bundle/{direct-api-transport-OAKYQBJR.js → direct-api-transport-YSROTC35.js} +30 -28
  137. package/bundle/direct-api-transport-YSROTC35.js.map +7 -0
  138. package/bundle/{discord-adapter-WUNYPTDE.js → discord-adapter-LKBSIFLV.js} +26 -26
  139. package/bundle/{dist-7HEHHQI2.js → dist-KMK7TZGN.js} +376 -348
  140. package/bundle/dist-KMK7TZGN.js.map +7 -0
  141. package/bundle/{dns-wakeup-F55ALHXJ.js → dns-wakeup-KIURCCFJ.js} +4 -3
  142. package/bundle/{dns-wakeup-F55ALHXJ.js.map → dns-wakeup-KIURCCFJ.js.map} +1 -1
  143. package/bundle/{doctor-probes-3SLIUGKS.js → doctor-probes-46UKIROK.js} +4 -3
  144. package/bundle/{env-schema-MSDP2YBO.js → env-schema-YGHCKX5B.js} +5 -4
  145. package/bundle/{gossip-CS3G3447.js → gossip-VSEY2HSE.js} +7 -6
  146. package/bundle/{guardrails-24XK2COI.js → guardrails-U7M6H2GE.js} +6 -5
  147. package/bundle/{health-check-FRUNRVNQ.js → health-check-ASRLUJE5.js} +6 -2
  148. package/bundle/health-check-ASRLUJE5.js.map +7 -0
  149. package/bundle/{heartbeat-system-G4IFQXT6.js → heartbeat-system-MUXLT4E6.js} +7 -6
  150. package/bundle/{heartbeat-tier3-3ZO3EVXP.js → heartbeat-tier3-636ZMM4E.js} +45 -44
  151. package/bundle/heartbeat-tier3-636ZMM4E.js.map +7 -0
  152. package/bundle/{hook-system-X6INNJGV.js → hook-system-Z4XD6IM5.js} +5 -4
  153. package/bundle/{hotskills-6FQYTJIO.js → hotskills-AOUWVTQB.js} +7 -6
  154. package/bundle/{install-ZAHTZ5M5.js → install-3GGZUN22.js} +23 -20
  155. package/bundle/install-3GGZUN22.js.map +7 -0
  156. package/bundle/{install-manifest-QX7KVDCA.js → install-manifest-624KOB4S.js} +4 -3
  157. package/bundle/{install-manifest-QX7KVDCA.js.map → install-manifest-624KOB4S.js.map} +1 -1
  158. package/bundle/{irc-adapter-IEJQKKJF.js → irc-adapter-SA7GLJGR.js} +5 -4
  159. package/bundle/{irc-adapter-IEJQKKJF.js.map → irc-adapter-SA7GLJGR.js.map} +1 -1
  160. package/bundle/{irc-config-TTWNYFLH.js → irc-config-PG4X2I4M.js} +6 -5
  161. package/bundle/{irc-config-TTWNYFLH.js.map → irc-config-PG4X2I4M.js.map} +1 -1
  162. package/bundle/{kanban-board-J6RO3ZU7.js → kanban-board-4AI5Z6B5.js} +7 -5
  163. package/bundle/{kanban-channel-5EIXBFSA.js → kanban-channel-JMBYWGWD.js} +8 -6
  164. package/bundle/{lazy-require-V6EFUATC.js → lazy-require-GURNBC3C.js} +11 -6
  165. package/bundle/{logger-Y3VILPRH.js → logger-UQJPZMYV.js} +4 -3
  166. package/bundle/{logs-YS3GDURO.js → logs-2WTDLMB5.js} +5 -5
  167. package/bundle/{main-chat-YLZDNQPO.js → main-chat-EID5Y6H2.js} +6 -5
  168. package/bundle/{master-user-Z4M7KCJE.js → master-user-TKA7M2GL.js} +7 -6
  169. package/bundle/{media-utils-P6RZ2K3U.js → media-utils-X3UN342B.js} +44 -43
  170. package/bundle/{media-utils-P6RZ2K3U.js.map → media-utils-X3UN342B.js.map} +2 -2
  171. package/bundle/{message-pipeline-MHEBDJLH.js → message-pipeline-TAWXNEVS.js} +20 -20
  172. package/bundle/meta.json +9264 -8575
  173. package/bundle/{migrate-layout-RJJQLVGR.js → migrate-layout-KEAIIN26.js} +8 -4
  174. package/bundle/migrate-layout-KEAIIN26.js.map +7 -0
  175. package/bundle/{nerve-VZNMFDGY.js → nerve-TC34H4EL.js} +5 -4
  176. package/bundle/{notification-VV2OR6NW.js → notification-JQNVGICN.js} +8 -7
  177. package/bundle/{openrouter-credits-LXC7P4G6.js → openrouter-credits-5Q3EYWE5.js} +5 -4
  178. package/bundle/{openrouter-credits-LXC7P4G6.js.map → openrouter-credits-5Q3EYWE5.js.map} +1 -1
  179. package/bundle/{orc-KC4USP55.js → orc-74Z62W7B.js} +4 -4
  180. package/bundle/{orc-tools-CHRSXSAS.js → orc-tools-GME3DKIN.js} +5 -4
  181. package/bundle/{paths-EDK6KWHG.js → paths-BAUNPLNJ.js} +6 -2
  182. package/bundle/{paths-RZF6WDMG.js → paths-MZC2KU2C.js} +3 -2
  183. package/bundle/{peer-auth-SRONOLNG.js → peer-auth-VRO3JYL5.js} +9 -8
  184. package/bundle/{peer-client-VOF77T6C.js → peer-client-WLK5GZQS.js} +9 -8
  185. package/bundle/{peer-client-VOF77T6C.js.map → peer-client-WLK5GZQS.js.map} +1 -1
  186. package/bundle/{peer-config-FRWLEYQ5.js → peer-config-24WILLCJ.js} +6 -5
  187. package/bundle/{peer-jwt-XY3XRIA2.js → peer-jwt-ZR6RF3XM.js} +6 -5
  188. package/bundle/{peer-transport-UBBXTDRP.js → peer-transport-BK5VHI2M.js} +8 -7
  189. package/bundle/{phase-transport-4NQHZX75.js → phase-transport-7QJM7J6V.js} +18 -16
  190. package/bundle/{reconcile-2EUXJ6W5.js → reconcile-7N7OE2GU.js} +5 -4
  191. package/bundle/{reconciler-FFQGV4DO.js → reconciler-7LOOUK43.js} +13 -11
  192. package/bundle/{reconciler-FFQGV4DO.js.map → reconciler-7LOOUK43.js.map} +1 -1
  193. package/bundle/{restore-NFDE2RG6.js → restore-MENZ3I3K.js} +13 -9
  194. package/bundle/{restore-NFDE2RG6.js.map → restore-MENZ3I3K.js.map} +3 -3
  195. package/bundle/{rollback-MVZ53XS4.js → rollback-JOHY6KWW.js} +5 -5
  196. package/bundle/{chunk-SKY6656M.js → sandbox-runtime-T7RF4WJD.js} +11 -28
  197. package/bundle/{chunk-SKY6656M.js.map → sandbox-runtime-T7RF4WJD.js.map} +1 -1
  198. package/bundle/{self-healer-utils-KD6LV63S.js → self-healer-utils-OR2N6RLD.js} +5 -4
  199. package/bundle/{self-healer-utils-KD6LV63S.js.map → self-healer-utils-OR2N6RLD.js.map} +1 -1
  200. package/bundle/{sha-tracker-2DB4R2TW.js → sha-tracker-BXOLWZJL.js} +5 -4
  201. package/bundle/{skill-session-BPDVA6ZG.js → skill-session-H6EQ4NGN.js} +5 -4
  202. package/bundle/{skill-session-BPDVA6ZG.js.map → skill-session-H6EQ4NGN.js.map} +1 -1
  203. package/bundle/{skill-stats-TPD2NROA.js → skill-stats-7O777ZSZ.js} +6 -5
  204. package/bundle/{skill-watcher-D7QYYYON.js → skill-watcher-ZGLTDPG5.js} +6 -5
  205. package/bundle/{sleep-GH6DLBJJ.js → sleep-3LFZH727.js} +10 -9
  206. package/bundle/{soul-bundle-GXLMDBCC.js → soul-bundle-RQ2YQMJW.js} +10 -9
  207. package/bundle/{spin-4DBYHS3E.js → spin-76K4R6FK.js} +12 -10
  208. package/bundle/{spin-notifications-IKYJPER5.js → spin-notifications-LD46B4K5.js} +7 -5
  209. package/bundle/{spin-notifications-IKYJPER5.js.map → spin-notifications-LD46B4K5.js.map} +1 -1
  210. package/bundle/{spin-types-PLJH3SIK.js → spin-types-MOKTZXGB.js} +5 -4
  211. package/bundle/{src-SUFZ27S5.js → src-6BTCMOD3.js} +4 -4
  212. package/bundle/{sse-parser-anthropic-U7ILHOY5.js → sse-parser-anthropic-NV2CGBIT.js} +5 -4
  213. package/bundle/{sse-parser-anthropic-U7ILHOY5.js.map → sse-parser-anthropic-NV2CGBIT.js.map} +1 -1
  214. package/bundle/{sse-parser-responses-OI73R3AH.js → sse-parser-responses-FC3PFHQ5.js} +5 -4
  215. package/bundle/{sse-parser-responses-OI73R3AH.js.map → sse-parser-responses-FC3PFHQ5.js.map} +1 -1
  216. package/bundle/{ssrf-guard-6GP4QYVA.js → ssrf-guard-E2YPLW6G.js} +5 -4
  217. package/bundle/{ssrf-guard-6GP4QYVA.js.map → ssrf-guard-E2YPLW6G.js.map} +1 -1
  218. package/bundle/{start-JT2BPMSW.js → start-HPO5LYJP.js} +5 -5
  219. package/bundle/start-HPO5LYJP.js.map +7 -0
  220. package/bundle/{stt-KD3AABKG.js → stt-UE7EOYD7.js} +6 -5
  221. package/bundle/{subagent-runtime-LVECAUPV.js → subagent-runtime-4X3UHF4H.js} +6 -5
  222. package/bundle/system-status-PLPWV4RF.js +346 -0
  223. package/bundle/system-status-PLPWV4RF.js.map +7 -0
  224. package/bundle/{task-store-2XRDM3AW.js → task-store-RAFMDQ7N.js} +6 -5
  225. package/bundle/{telegram-adapter-UJ3RYYV6.js → telegram-adapter-PPXKTGOP.js} +35 -35
  226. package/bundle/{tool-registry-YU6WBXPA.js → tool-registry-NKIPNJZ5.js} +25 -23
  227. package/bundle/{tool-sandbox-RNNPDR5M.js → tool-sandbox-DQCP3UTU.js} +6 -5
  228. package/bundle/{transport-config-OK3MZPJK.js → transport-config-SF6GBV47.js} +9 -8
  229. package/bundle/{update-ENNPRW7Y.js → update-QOOGMFSJ.js} +6 -6
  230. package/bundle/{update-check-SJB6GV3A.js → update-check-LPZG3K5P.js} +3 -2
  231. package/bundle/{update-check-SJB6GV3A.js.map → update-check-LPZG3K5P.js.map} +1 -1
  232. package/bundle/{usage-tracker-HRSGC7QC.js → usage-tracker-TBDM4KE6.js} +2 -2
  233. package/bundle/{user-registry-6PUJJ5J2.js → user-registry-OYJVAHDD.js} +6 -5
  234. package/bundle/{wrapper-WLHLG4MI.js → wrapper-W66YICNZ.js} +3 -3
  235. package/bundle/{ws-peer-client-WHW3RJTD.js → ws-peer-client-G5QHOF6K.js} +15 -14
  236. package/bundle/{ws-peer-client-WHW3RJTD.js.map → ws-peer-client-G5QHOF6K.js.map} +2 -2
  237. package/package.json +3 -7
  238. package/scripts/emergency-deploy.sh +11 -8
  239. package/scripts/emergency-update.sh +156 -23
  240. package/templates/config/.env +1 -1
  241. package/templates/config/models.json +13 -0
  242. package/bundle/chunk-37EX63K4.js.map +0 -7
  243. package/bundle/chunk-3QW2K53E.js.map +0 -7
  244. package/bundle/chunk-72T2Q7IG.js.map +0 -7
  245. package/bundle/chunk-7RAGSHSH.js.map +0 -7
  246. package/bundle/chunk-BU7LTI2W.js.map +0 -7
  247. package/bundle/chunk-C3EYYJN3.js.map +0 -7
  248. package/bundle/chunk-CAOIIVFP.js +0 -110
  249. package/bundle/chunk-CAOIIVFP.js.map +0 -7
  250. package/bundle/chunk-EDZGF6BC.js.map +0 -7
  251. package/bundle/chunk-H2K23MOF.js.map +0 -7
  252. package/bundle/chunk-HAZHNBBY.js +0 -156
  253. package/bundle/chunk-HAZHNBBY.js.map +0 -7
  254. package/bundle/chunk-IXKQ4JMX.js.map +0 -7
  255. package/bundle/chunk-JAJ3DUQ2.js +0 -30
  256. package/bundle/chunk-JAJ3DUQ2.js.map +0 -7
  257. package/bundle/chunk-KMFR5AVY.js +0 -45
  258. package/bundle/chunk-KMFR5AVY.js.map +0 -7
  259. package/bundle/chunk-M6Q3IQ4H.js.map +0 -7
  260. package/bundle/chunk-MQJG7OJX.js.map +0 -7
  261. package/bundle/chunk-OY2HAK33.js.map +0 -7
  262. package/bundle/chunk-P5O6QZDC.js.map +0 -7
  263. package/bundle/chunk-RJX45XIC.js.map +0 -7
  264. package/bundle/chunk-S6HEHCCG.js.map +0 -7
  265. package/bundle/chunk-SESM4GBM.js.map +0 -7
  266. package/bundle/chunk-SXNY6HC4.js.map +0 -7
  267. package/bundle/chunk-VJATH7AN.js.map +0 -7
  268. package/bundle/chunk-ZY6DH2S4.js.map +0 -7
  269. package/bundle/deps-PHSLIA77.js.map +0 -7
  270. package/bundle/direct-api-transport-OAKYQBJR.js.map +0 -7
  271. package/bundle/dist-7HEHHQI2.js.map +0 -7
  272. package/bundle/health-check-FRUNRVNQ.js.map +0 -7
  273. package/bundle/heartbeat-tier3-3ZO3EVXP.js.map +0 -7
  274. package/bundle/install-ZAHTZ5M5.js.map +0 -7
  275. package/bundle/migrate-layout-RJJQLVGR.js.map +0 -7
  276. package/bundle/phase-config-V4XETN5F.js +0 -18
  277. package/bundle/sandbox-runtime-WHACQLLN.js +0 -22
  278. package/bundle/start-JT2BPMSW.js.map +0 -7
  279. package/bundle/system-status-XXJWTVJN.js +0 -243
  280. package/bundle/system-status-XXJWTVJN.js.map +0 -7
  281. package/bundle/user-registry-6PUJJ5J2.js.map +0 -7
  282. package/bundle/wrapper-WLHLG4MI.js.map +0 -7
  283. /package/bundle/{agent-api-rate-limit-4GEZ4YN5.js.map → agent-api-rate-limit-VENFGOAD.js.map} +0 -0
  284. /package/bundle/{agent-registry-563P4EUJ.js.map → agent-registry-DL7UT272.js.map} +0 -0
  285. /package/bundle/{bridge-lock-transport-LXCF2IVN.js.map → bridge-lock-transport-BJAMHMXW.js.map} +0 -0
  286. /package/bundle/{browser-2VZOGOGX.js.map → browser-PT54UWSW.js.map} +0 -0
  287. /package/bundle/{capability-WXEA2WFK.js.map → capability-EKPGHQIO.js.map} +0 -0
  288. /package/bundle/{chunk-4PIVWXUJ.js.map → chunk-2ZD7VQRW.js.map} +0 -0
  289. /package/bundle/{chunk-T7TAWGBX.js.map → chunk-52PQM4EZ.js.map} +0 -0
  290. /package/bundle/{chunk-2RGR3LSV.js.map → chunk-5P5HF7IJ.js.map} +0 -0
  291. /package/bundle/{chunk-OOKNHOCB.js.map → chunk-6S3G6GPO.js.map} +0 -0
  292. /package/bundle/{chunk-E7MV7WFT.js.map → chunk-6VTHSN4V.js.map} +0 -0
  293. /package/bundle/{chunk-NGZVJ52F.js.map → chunk-76YN7O3U.js.map} +0 -0
  294. /package/bundle/{chunk-43DKPXTP.js.map → chunk-7LORCJCQ.js.map} +0 -0
  295. /package/bundle/{chunk-HDOFJVFS.js.map → chunk-7OI46MH7.js.map} +0 -0
  296. /package/bundle/{chunk-CB6S3ZRF.js.map → chunk-AFFW2LRY.js.map} +0 -0
  297. /package/bundle/{chunk-TCI6FZTP.js.map → chunk-AHJDG6OM.js.map} +0 -0
  298. /package/bundle/{chunk-YME7NRGP.js.map → chunk-B2TIRDZC.js.map} +0 -0
  299. /package/bundle/{chunk-SSCGWDIC.js.map → chunk-BWJ37KMW.js.map} +0 -0
  300. /package/bundle/{chunk-ULO2PX3T.js.map → chunk-CCZ43JB7.js.map} +0 -0
  301. /package/bundle/{chunk-FVUL44T4.js.map → chunk-CNENVY37.js.map} +0 -0
  302. /package/bundle/{chunk-J5NOL4DB.js.map → chunk-DJOSXXM2.js.map} +0 -0
  303. /package/bundle/{chunk-DNDYD5SL.js.map → chunk-E7DZYCSF.js.map} +0 -0
  304. /package/bundle/{chunk-GCFIK6OB.js.map → chunk-FSGICOCX.js.map} +0 -0
  305. /package/bundle/{chunk-FJF42RZY.js.map → chunk-GHRLO2UL.js.map} +0 -0
  306. /package/bundle/{chunk-7WHXTCVD.js.map → chunk-HWFN7JGU.js.map} +0 -0
  307. /package/bundle/{chunk-KBPVJGD7.js.map → chunk-IXGDDDAB.js.map} +0 -0
  308. /package/bundle/{chunk-YEOZN5IE.js.map → chunk-JRGEEGZF.js.map} +0 -0
  309. /package/bundle/{chunk-56D3Y44D.js.map → chunk-KLG4SCF7.js.map} +0 -0
  310. /package/bundle/{chunk-ASYX43OU.js.map → chunk-LB43Q7G6.js.map} +0 -0
  311. /package/bundle/{chunk-TVSPVZTX.js.map → chunk-LN5MNDSA.js.map} +0 -0
  312. /package/bundle/{chunk-FIAVVKGN.js.map → chunk-MTE32OQH.js.map} +0 -0
  313. /package/bundle/{chunk-MV5KOWOR.js.map → chunk-N3Q3TASM.js.map} +0 -0
  314. /package/bundle/{chunk-IQKADER4.js.map → chunk-O4YBJS2K.js.map} +0 -0
  315. /package/bundle/{chunk-5V4VHKEA.js.map → chunk-OT6HLPEA.js.map} +0 -0
  316. /package/bundle/{chunk-V6CV3QPH.js.map → chunk-OWPQIBAO.js.map} +0 -0
  317. /package/bundle/{chunk-N5VROZ7A.js.map → chunk-QMP2KC4W.js.map} +0 -0
  318. /package/bundle/{chunk-4HNCOQSK.js.map → chunk-QOGZ7BFL.js.map} +0 -0
  319. /package/bundle/{chunk-2LKQV2ND.js.map → chunk-R23FHZRY.js.map} +0 -0
  320. /package/bundle/{chunk-TY26WMQY.js.map → chunk-RCWQ34QR.js.map} +0 -0
  321. /package/bundle/{chunk-ZOCEBV62.js.map → chunk-UU3RLJSD.js.map} +0 -0
  322. /package/bundle/{chunk-WP7FZHMI.js.map → chunk-W2PSVV2T.js.map} +0 -0
  323. /package/bundle/{chunk-V2QIAXWZ.js.map → chunk-WEGFRA6G.js.map} +0 -0
  324. /package/bundle/{chunk-O4GKI3Q3.js.map → chunk-X7DLKIQM.js.map} +0 -0
  325. /package/bundle/{chunk-BNBC4T45.js.map → chunk-XZ4ZBDM5.js.map} +0 -0
  326. /package/bundle/{chunk-24V4A6RP.js.map → chunk-YI2KSYB4.js.map} +0 -0
  327. /package/bundle/{chunk-IK4R3RBZ.js.map → chunk-YZCOA4DC.js.map} +0 -0
  328. /package/bundle/{chunk-2FZJDMAF.js.map → chunk-ZGNSCJWH.js.map} +0 -0
  329. /package/bundle/{chunk-W726UGI6.js.map → chunk-ZKMKAO75.js.map} +0 -0
  330. /package/bundle/{commands-XXFU2ZF7.js.map → commands-2JQ5YTJX.js.map} +0 -0
  331. /package/bundle/{config-EWDZ234X.js.map → config-ZEWIM5Z2.js.map} +0 -0
  332. /package/bundle/{config-show-6J33O4TE.js.map → config-show-WBJPQPRD.js.map} +0 -0
  333. /package/bundle/{daemon-LTDAXNA2.js.map → daemon-W7VQOSZC.js.map} +0 -0
  334. /package/bundle/{delegation-tools-YDTWQMZD.js.map → delegation-tools-VGTRFQBF.js.map} +0 -0
  335. /package/bundle/{deploy-lib-import-RGZJ3CGC.js.map → deploy-5AGIULM2.js.map} +0 -0
  336. /package/bundle/{doctor-probes-3SLIUGKS.js.map → deploy-lib-import-ZBDYORN4.js.map} +0 -0
  337. /package/bundle/{discord-adapter-WUNYPTDE.js.map → discord-adapter-LKBSIFLV.js.map} +0 -0
  338. /package/bundle/{env-schema-MSDP2YBO.js.map → doctor-probes-46UKIROK.js.map} +0 -0
  339. /package/bundle/{gossip-CS3G3447.js.map → env-schema-YGHCKX5B.js.map} +0 -0
  340. /package/bundle/{guardrails-24XK2COI.js.map → gossip-VSEY2HSE.js.map} +0 -0
  341. /package/bundle/{heartbeat-system-G4IFQXT6.js.map → guardrails-U7M6H2GE.js.map} +0 -0
  342. /package/bundle/{hook-system-X6INNJGV.js.map → heartbeat-system-MUXLT4E6.js.map} +0 -0
  343. /package/bundle/{hotskills-6FQYTJIO.js.map → hook-system-Z4XD6IM5.js.map} +0 -0
  344. /package/bundle/{kanban-board-J6RO3ZU7.js.map → hotskills-AOUWVTQB.js.map} +0 -0
  345. /package/bundle/{kanban-channel-5EIXBFSA.js.map → kanban-board-4AI5Z6B5.js.map} +0 -0
  346. /package/bundle/{lazy-require-V6EFUATC.js.map → kanban-channel-JMBYWGWD.js.map} +0 -0
  347. /package/bundle/{logger-Y3VILPRH.js.map → lazy-require-GURNBC3C.js.map} +0 -0
  348. /package/bundle/{main-chat-YLZDNQPO.js.map → logger-UQJPZMYV.js.map} +0 -0
  349. /package/bundle/{logs-YS3GDURO.js.map → logs-2WTDLMB5.js.map} +0 -0
  350. /package/bundle/{master-user-Z4M7KCJE.js.map → main-chat-EID5Y6H2.js.map} +0 -0
  351. /package/bundle/{message-pipeline-MHEBDJLH.js.map → master-user-TKA7M2GL.js.map} +0 -0
  352. /package/bundle/{nerve-VZNMFDGY.js.map → message-pipeline-TAWXNEVS.js.map} +0 -0
  353. /package/bundle/{notification-VV2OR6NW.js.map → nerve-TC34H4EL.js.map} +0 -0
  354. /package/bundle/{orc-tools-CHRSXSAS.js.map → notification-JQNVGICN.js.map} +0 -0
  355. /package/bundle/{orc-KC4USP55.js.map → orc-74Z62W7B.js.map} +0 -0
  356. /package/bundle/{paths-EDK6KWHG.js.map → orc-tools-GME3DKIN.js.map} +0 -0
  357. /package/bundle/{paths-RZF6WDMG.js.map → paths-BAUNPLNJ.js.map} +0 -0
  358. /package/bundle/{peer-auth-SRONOLNG.js.map → paths-MZC2KU2C.js.map} +0 -0
  359. /package/bundle/{peer-config-FRWLEYQ5.js.map → peer-auth-VRO3JYL5.js.map} +0 -0
  360. /package/bundle/{peer-jwt-XY3XRIA2.js.map → peer-config-24WILLCJ.js.map} +0 -0
  361. /package/bundle/{peer-transport-UBBXTDRP.js.map → peer-jwt-ZR6RF3XM.js.map} +0 -0
  362. /package/bundle/{phase-config-V4XETN5F.js.map → peer-transport-BK5VHI2M.js.map} +0 -0
  363. /package/bundle/{phase-transport-4NQHZX75.js.map → phase-transport-7QJM7J6V.js.map} +0 -0
  364. /package/bundle/{reconcile-2EUXJ6W5.js.map → reconcile-7N7OE2GU.js.map} +0 -0
  365. /package/bundle/{registry-client-VN2MM2HI.js.map → rollback-JOHY6KWW.js.map} +0 -0
  366. /package/bundle/{rollback-MVZ53XS4.js.map → sha-tracker-BXOLWZJL.js.map} +0 -0
  367. /package/bundle/{sandbox-runtime-WHACQLLN.js.map → skill-stats-7O777ZSZ.js.map} +0 -0
  368. /package/bundle/{sha-tracker-2DB4R2TW.js.map → skill-watcher-ZGLTDPG5.js.map} +0 -0
  369. /package/bundle/{skill-stats-TPD2NROA.js.map → sleep-3LFZH727.js.map} +0 -0
  370. /package/bundle/{skill-watcher-D7QYYYON.js.map → soul-bundle-RQ2YQMJW.js.map} +0 -0
  371. /package/bundle/{sleep-GH6DLBJJ.js.map → spin-76K4R6FK.js.map} +0 -0
  372. /package/bundle/{soul-bundle-GXLMDBCC.js.map → spin-types-MOKTZXGB.js.map} +0 -0
  373. /package/bundle/{spin-4DBYHS3E.js.map → src-6BTCMOD3.js.map} +0 -0
  374. /package/bundle/{spin-types-PLJH3SIK.js.map → stt-UE7EOYD7.js.map} +0 -0
  375. /package/bundle/{src-SUFZ27S5.js.map → subagent-runtime-4X3UHF4H.js.map} +0 -0
  376. /package/bundle/{stt-KD3AABKG.js.map → task-store-RAFMDQ7N.js.map} +0 -0
  377. /package/bundle/{telegram-adapter-UJ3RYYV6.js.map → telegram-adapter-PPXKTGOP.js.map} +0 -0
  378. /package/bundle/{subagent-runtime-LVECAUPV.js.map → tool-registry-NKIPNJZ5.js.map} +0 -0
  379. /package/bundle/{task-store-2XRDM3AW.js.map → tool-sandbox-DQCP3UTU.js.map} +0 -0
  380. /package/bundle/{tool-registry-YU6WBXPA.js.map → transport-config-SF6GBV47.js.map} +0 -0
  381. /package/bundle/{tool-sandbox-RNNPDR5M.js.map → update-QOOGMFSJ.js.map} +0 -0
  382. /package/bundle/{transport-config-OK3MZPJK.js.map → usage-tracker-TBDM4KE6.js.map} +0 -0
  383. /package/bundle/{update-ENNPRW7Y.js.map → user-registry-OYJVAHDD.js.map} +0 -0
  384. /package/bundle/{usage-tracker-HRSGC7QC.js.map → wrapper-W66YICNZ.js.map} +0 -0
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/components/transport/tool-registry.ts", "../src/components/transport/skill-authoring.ts", "../src/components/transport/mcp-tool.ts", "../src/components/transport/peer-delegation-tools.ts", "../src/components/transport/kanban-tool.ts", "../src/components/transport/channel-tool.ts"],
4
- "sourcesContent": ["/**\n * Tool registry for DirectApiTransport.\n * Phase 2: native tool schemas. Phase 3: in-process memory when available.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { appendFileSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { MemoryBackend } from \"abmind\";\nimport type { InstantStoreParams } from \"../../types/index.js\";\nimport { logWarn, redactSecrets } from \"../logger.js\";\nimport { logAndSwallow } from \"../log-and-swallow.js\";\nimport { checkTool, checkPath, auditDeny, type SandboxPolicy } from \"../tool-sandbox.js\";\nimport { getMasterUserId } from \"../master-user.js\";\n\nfunction getMasterUserId(): string {\n return getMasterUserId();\n}\n\nconst TAG = \"tool_registry\";\n\n// #449: append-only audit log\nconst AUDIT_DIR = join(process.env[\"ABTARS_HOME\"] ?? join(homedir(), \".abtars\"), \"logs\");\nconst AUDIT_PATH = join(AUDIT_DIR, \"audit.jsonl\");\ntry { mkdirSync(AUDIT_DIR, { recursive: true }); } catch (err) { logAndSwallow(TAG, \"mkdirSync audit dir\", err); }\nfunction audit(entry: Record<string, unknown>): void {\n try { appendFileSync(AUDIT_PATH, JSON.stringify(entry) + \"\\n\"); } catch (err) { logAndSwallow(TAG, \"audit write\", err); }\n}\n\nexport type ToolDefinition = {\n readonly name: string;\n readonly description: string;\n readonly parameters: Record<string, unknown>;\n execute(args: Record<string, string>, context?: { userId: string; signal?: AbortSignal }): Promise<string>;\n};\n\nconst BASH_TIMEOUT_MS = 300_000;\nconst CLI_TIMEOUT_MS = 60_000;\n\n/**\n * Patterns that would spawn or restart a bridge/watchdog process.\n * Blocked to prevent the LLM (especially fallback models) from accidentally\n * starting a second bridge instance, which would cause port conflicts,\n * Telegram 409 errors, and bridge.lock PID confusion.\n *\n * See post-mortem of 2026-04-22 outage: cron agent ran execute_bash that\n * spawned a rogue bridge alongside the watchdog-supervised one.\n */\nconst BLOCKED_PATTERNS: readonly RegExp[] = [\n /\\bmain\\.js\\b/, // node .../current/dist/main.js ...\n /\\babtars\\.sh\\b/, // the launcher\n /\\bwatchdog\\.sh\\b/, // the watchdog\n /\\blaunchctl\\s+(load|bootstrap|kickstart|start)\\b/, // launchd bridge start\n];\n\nexport function isBridgeSpawnCommand(cmd: string): boolean {\n return BLOCKED_PATTERNS.some(p => p.test(cmd));\n}\n\n/** Block kill/pkill/killall targeting the bridge's own PID or process patterns (#414). */\nfunction isBridgeKillCommand(cmd: string): boolean {\n const pid = process.pid;\n const ppid = process.ppid;\n // Direct kill of own PID or parent\n if (new RegExp(`\\\\bkill\\\\s+(-\\\\d+\\\\s+)?${pid}\\\\b`).test(cmd)) return true;\n if (new RegExp(`\\\\bkill\\\\s+(-\\\\d+\\\\s+)?${ppid}\\\\b`).test(cmd)) return true;\n // pkill/killall targeting bridge patterns\n if (/\\b(pkill|killall)\\b.*\\b(abtars|main\\.js|watchdog)\\b/.test(cmd)) return true;\n if (/\\bkill\\b.*\\$\\(.*pgrep.*abtars/.test(cmd)) return true;\n return false;\n}\n\nfunction runBash(cmd: string, timeout = BASH_TIMEOUT_MS, signal?: AbortSignal): Promise<string> {\n // Guardrails: command check\n const { checkCommand, classifyCommand } = require(\"../guardrails.js\") as typeof import(\"../guardrails.js\");\n const cmdBlock = checkCommand(cmd);\n if (cmdBlock) {\n logWarn(\"tool-registry\", `Guardrails blocked: ${cmd.slice(0, 200)}`);\n return Promise.resolve(JSON.stringify({ stderr: cmdBlock, exit_code: 126 }));\n }\n\n // Action gate: auth-required commands\n const tier = classifyCommand(cmd);\n if (tier === \"auth-required\" && _actionGate) {\n return _actionGate.requestAuth(\"bash-auth\", cmd).then((granted) => {\n if (!granted) {\n logWarn(\"tool-registry\", `Auth denied for: ${cmd.slice(0, 200)}`);\n return JSON.stringify({ stderr: \"Command requires authorization. Master denied or timed out.\", exit_code: 126 });\n }\n return executeBash(cmd, timeout, signal);\n });\n }\n\n if (isBridgeSpawnCommand(cmd)) {\n logWarn(\"tool-registry\", `Blocked bridge-spawn command: ${cmd.slice(0, 200)}`);\n return Promise.resolve(JSON.stringify({\n stderr: \"Command blocked: this would spawn/restart a bridge or watchdog process. The bridge is already running under launchd+watchdog supervision; use launchctl inspection commands (launchctl list, launchctl print) or signal the existing process instead.\",\n exit_code: 126,\n }));\n }\n if (isBridgeKillCommand(cmd)) {\n logWarn(\"tool-registry\", `Blocked bridge-kill command: ${cmd.slice(0, 200)}`);\n return Promise.resolve(JSON.stringify({\n stderr: \"Command blocked: this would kill the bridge process (yourself). Ask the user to send /restart for a session reset or restart the bridge manually.\",\n exit_code: 126,\n }));\n }\n return executeBash(cmd, timeout, signal);\n}\n\nlet _seatbeltActive = false;\nlet _seatbeltPolicy: import(\"../seatbelt/policy.js\").SeatbeltPolicy | null = null;\n\n/** Wire seatbelt for OS-level command sandboxing (#906). */\nexport function setSeatbelt(active: boolean, policy?: import(\"../seatbelt/policy.js\").SeatbeltPolicy): void {\n _seatbeltActive = active;\n _seatbeltPolicy = policy ?? null;\n}\n\nfunction executeBash(cmd: string, timeout: number, signal?: AbortSignal): Promise<string> {\n return new Promise((resolve) => {\n let bin = \"bash\";\n let args = [\"-c\", cmd];\n\n // #906: Wrap in OS sandbox if seatbelt active and command needs sandboxing\n if (_seatbeltActive && _seatbeltPolicy) {\n const { shouldSandbox, wrapCommand } = require(\"../seatbelt/index.js\") as typeof import(\"../seatbelt/index.js\");\n if (shouldSandbox(cmd)) {\n const wrapped = wrapCommand(cmd, _seatbeltPolicy);\n bin = wrapped.bin;\n args = wrapped.args;\n }\n }\n\n const child = execFile(bin, args, { timeout, maxBuffer: 1024 * 1024 }, (err, stdout, stderr) => {\n const result: Record<string, unknown> = {};\n if (stdout) result[\"stdout\"] = stdout.slice(0, 50_000);\n if (stderr) result[\"stderr\"] = stderr.slice(0, 10_000);\n if (err) result[\"exit_code\"] = (err as NodeJS.ErrnoException & { code?: number }).code ?? 1;\n else result[\"exit_code\"] = 0;\n resolve(JSON.stringify(result));\n });\n if (signal) {\n if (signal.aborted) { child.kill(\"SIGTERM\"); return; }\n const onAbort = (): void => {\n child.kill(\"SIGTERM\");\n // #1003: escalate to SIGKILL if child doesn't exit within 3s\n setTimeout(() => { try { child.kill(\"SIGKILL\"); } catch {} }, 3000);\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n child.on(\"exit\", () => signal.removeEventListener(\"abort\", onAbort));\n }\n });\n}\n\nlet memoryBackend: MemoryBackend | null = null;\n\n/** Wire in-process memory backend. Call once after memory init. */\nexport function setMemoryBackend(backend: MemoryBackend | null): void {\n memoryBackend = backend;\n}\n\nlet _actionGate: import(\"../action-gate.js\").ActionGate | null = null;\n\n/** Wire action gate for auth-required commands. */\nexport function setActionGate(gate: import(\"../action-gate.js\").ActionGate | null): void {\n _actionGate = gate;\n}\n\nlet _peerActivityCb: ((msg: string) => void) | null = null;\n\n/** Wire peer activity notification callback. */\nexport function setPeerActivityCallback(cb: ((msg: string) => void) | null): void {\n _peerActivityCb = cb;\n}\n\n// --- Tool definitions ---\n\nconst bashTool: ToolDefinition = {\n name: \"execute_bash\",\n description: \"Execute a bash command. Use for file operations, git, running scripts, and any shell command. Commands that would spawn or restart a bridge/watchdog process (node main.js, abtars.sh, abtars-watchdog.sh, launchctl load/bootstrap/kickstart/start) are blocked \u2014 the bridge is already supervised.\",\n parameters: {\n type: \"object\",\n properties: { command: { type: \"string\", description: \"The bash command to execute\" } },\n required: [\"command\"],\n },\n execute: (args, context) => runBash(args[\"command\"] ?? \"\", BASH_TIMEOUT_MS, context?.signal),\n};\n\nlet _storeCount = 0;\nconst STORE_CAP = 20;\n\n/** Reset store counter (called on new subagent session). */\nexport function resetStoreCounter(): void { _storeCount = 0; }\n\nconst memoryStoreTool: ToolDefinition = {\n name: \"memory_store\",\n description: \"Store a memory. Use after learning something about the user, their preferences, decisions, or facts worth remembering.\",\n parameters: {\n type: \"object\",\n properties: {\n translated: { type: \"string\", description: \"Memory content in English\" },\n original: { type: \"string\", description: \"Memory content in original language (if not English)\" },\n type: { type: \"string\", enum: [\"fact\", \"preference\", \"decision\", \"experience\", \"skill\", \"relationship\", \"goal\"], description: \"Memory type\" },\n emotion: { type: \"integer\", description: \"Emotion score -5 to +5 (0=neutral)\" },\n confidence: { type: \"integer\", description: \"Confidence 1-5 (3=default)\" },\n classification: { type: \"integer\", description: \"0=public (general knowledge), 1=internal (default), 2=confidential (personal preferences, habits, opinions about specific users), 3=secret (credentials, API keys, tokens, passwords \u2014 store IMMEDIATELY with exact string, never paraphrase, never wait for Dreamy)\" },\n },\n required: [\"translated\", \"type\"],\n },\n async execute(args, context): Promise<string> {\n if (++_storeCount > STORE_CAP) {\n return JSON.stringify({ stored: false, error: \"Store limit reached for this session. Move to next task.\" });\n }\n if (memoryBackend) {\n try {\n const params: InstantStoreParams = {\n userId: context?.userId ?? getMasterUserId(),\n contentEn: args[\"translated\"] ?? \"\",\n contentOriginal: args[\"original\"] ?? args[\"translated\"] ?? \"\",\n memoryType: (args[\"type\"] ?? \"fact\") as InstantStoreParams[\"memoryType\"],\n emotionScore: parseInt(args[\"emotion\"] ?? \"0\", 10),\n confidence: parseInt(args[\"confidence\"] ?? \"3\", 10),\n classification: parseInt(args[\"classification\"] ?? \"1\", 10),\n };\n const result = await memoryBackend.instantStore({ ...params, createdBy: \"tool:memory_store\" });\n return JSON.stringify(result);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n // #706: FTS5 corruption self-heal \u2014 rebuild indexes and retry once\n if (msg.includes(\"fts5\") || msg.includes(\"corruption\")) {\n try {\n memoryBackend.rebuildFtsIndexes();\n logWarn(\"tool-registry\", \"FTS corruption detected \u2014 rebuilt indexes, retrying store\");\n const params: InstantStoreParams = {\n userId: context?.userId ?? getMasterUserId(),\n contentEn: args[\"translated\"] ?? \"\",\n contentOriginal: args[\"original\"] ?? args[\"translated\"] ?? \"\",\n memoryType: (args[\"type\"] ?? \"fact\") as InstantStoreParams[\"memoryType\"],\n emotionScore: parseInt(args[\"emotion\"] ?? \"0\", 10),\n confidence: parseInt(args[\"confidence\"] ?? \"3\", 10),\n classification: parseInt(args[\"classification\"] ?? \"1\", 10),\n };\n const result = await memoryBackend.instantStore({ ...params, createdBy: \"tool:memory_store\" });\n return JSON.stringify(result);\n } catch (retryErr) { /* fall through */ }\n }\n return JSON.stringify({ error: msg });\n }\n }\n let cmd = `abmind store --translated ${JSON.stringify(args[\"translated\"] ?? \"\")} --type ${args[\"type\"] ?? \"fact\"}`;\n if (args[\"original\"]) cmd += ` --original ${JSON.stringify(args[\"original\"])}`;\n if (args[\"emotion\"]) cmd += ` --emotion-score ${args[\"emotion\"]}`;\n if (args[\"confidence\"]) cmd += ` --confidence ${args[\"confidence\"]}`;\n if (args[\"classification\"]) cmd += ` --classification ${args[\"classification\"]}`;\n return runBash(cmd, CLI_TIMEOUT_MS);\n },\n};\n\nconst memoryRecallTool: ToolDefinition = {\n name: \"memory_recall\",\n description: \"Search memories by keyword or semantic query. Returns relevant stored memories.\",\n parameters: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Search query\" },\n limit: { type: \"integer\", description: \"Max results (default 10)\" },\n },\n required: [\"query\"],\n },\n async execute(args, context): Promise<string> {\n if (memoryBackend) {\n try {\n const t0 = Date.now();\n const userId = context?.userId ?? getMasterUserId();\n const { loadUsers } = await import(\"../user-registry.js\");\n const userEntry = loadUsers().byUserId.get(userId);\n const result = await memoryBackend.recall({\n translated: [args[\"query\"] ?? \"\"],\n original: args[\"query\"] ?? \"\",\n userId,\n limit: parseInt(args[\"limit\"] ?? \"10\", 10),\n maxClassification: userEntry?.maxClass ?? 1,\n });\n import(\"../metrics-collector.js\").then(({ recordLatency }) => recordLatency(\"recall\", Date.now() - t0)).catch(() => {});\n return JSON.stringify(result);\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n }\n let cmd = `abmind recall ${JSON.stringify(args[\"query\"] ?? \"\")}`;\n if (args[\"limit\"]) cmd += ` --limit ${args[\"limit\"]}`;\n return runBash(cmd, CLI_TIMEOUT_MS);\n },\n};\n\nconst memoryEditTool: ToolDefinition = {\n name: \"memory_edit\",\n description: \"Edit an existing memory by ID. Change content, type, emotion, confidence, or classification.\",\n parameters: {\n type: \"object\",\n properties: {\n memory_id: { type: \"integer\", description: \"Memory ID to edit\" },\n translated: { type: \"string\", description: \"New English content\" },\n original: { type: \"string\", description: \"New original language content\" },\n type: { type: \"string\", description: \"New memory type\" },\n emotion: { type: \"integer\", description: \"New emotion score\" },\n confidence: { type: \"integer\", description: \"New confidence\" },\n classification: { type: \"integer\", description: \"New classification\" },\n caller: { type: \"string\", enum: [\"kp\", \"dreamy\"], description: \"Who is making the edit\" },\n },\n required: [\"memory_id\"],\n },\n async execute(args): Promise<string> {\n if (memoryBackend) {\n try {\n const result = await memoryBackend.editMemory({\n memoryId: parseInt(args[\"memory_id\"] ?? \"0\", 10),\n contentEn: args[\"translated\"],\n contentOriginal: args[\"original\"],\n memoryType: args[\"type\"] as \"fact\" | \"decision\" | \"preference\" | \"event\" | undefined,\n emotionScore: args[\"emotion\"] ? parseInt(args[\"emotion\"], 10) : undefined,\n confidence: args[\"confidence\"] ? parseInt(args[\"confidence\"], 10) : undefined,\n classification: args[\"classification\"] ? parseInt(args[\"classification\"], 10) : undefined,\n caller: (args[\"caller\"] ?? \"kp\") as \"kp\" | \"dreamy\",\n });\n return JSON.stringify(result);\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n }\n let cmd = `abmind edit --memory-id ${args[\"memory_id\"] ?? \"0\"}`;\n if (args[\"translated\"]) cmd += ` --translated ${JSON.stringify(args[\"translated\"])}`;\n if (args[\"original\"]) cmd += ` --original ${JSON.stringify(args[\"original\"])}`;\n if (args[\"type\"]) cmd += ` --type ${args[\"type\"]}`;\n if (args[\"emotion\"]) cmd += ` --emotion-score ${args[\"emotion\"]}`;\n if (args[\"confidence\"]) cmd += ` --confidence ${args[\"confidence\"]}`;\n if (args[\"classification\"]) cmd += ` --classification ${args[\"classification\"]}`;\n if (args[\"caller\"]) cmd += ` --caller ${args[\"caller\"]}`;\n return runBash(cmd, CLI_TIMEOUT_MS);\n },\n};\n\nconst webBrowseTool: ToolDefinition = {\n name: \"web_browse\",\n description: \"Browse a URL or perform a complex multi-step web task. For quick lookups use execute_bash with curl.\",\n parameters: {\n type: \"object\",\n properties: {\n task: { type: \"string\", description: \"What to do on the web\" },\n chat_id: { type: \"string\", description: \"Chat ID for result delivery\" },\n engine: { type: \"string\", enum: [\"cloakbrowser\"], description: \"Browser engine (default: cloakbrowser)\" },\n },\n required: [\"task\", \"chat_id\"],\n },\n execute: (args) => {\n let cmd = `abtars-browse --task ${JSON.stringify(args[\"task\"] ?? \"\")} --chat-id ${args[\"chat_id\"] ?? \"0\"}`;\n if (args[\"engine\"]) cmd += ` --engine ${args[\"engine\"]}`;\n return runBash(cmd, CLI_TIMEOUT_MS);\n },\n};\n\nconst todoTool: ToolDefinition = {\n name: \"todo_manage\",\n description: \"Manage TODO items. Add, complete, or list tasks.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", enum: [\"add\", \"done\", \"list\", \"remove\"], description: \"Action to perform\" },\n text: { type: \"string\", description: \"TODO text (for add)\" },\n id: { type: \"string\", description: \"TODO ID (for done/remove)\" },\n },\n required: [\"action\"],\n },\n execute: (args) => {\n const action = args[\"action\"] ?? \"list\";\n if (action === \"add\") return runBash(`abtars-todo add ${JSON.stringify(args[\"text\"] ?? \"\")}`, CLI_TIMEOUT_MS);\n if (action === \"done\") return runBash(`abtars-todo done ${args[\"id\"] ?? \"\"}`, CLI_TIMEOUT_MS);\n if (action === \"remove\") return runBash(`abtars-todo remove ${args[\"id\"] ?? \"\"}`, CLI_TIMEOUT_MS);\n return runBash(\"abtars-todo list\", CLI_TIMEOUT_MS);\n },\n};\n\nlet _enqueueCron: ((id: string, manual?: boolean) => string | null) | null = null;\n\n/** Inject enqueueCron from bridge for task_manage --run. */\nexport function setEnqueueCron(fn: (id: string, manual?: boolean) => string | null): void { _enqueueCron = fn; }\n\nlet _ircSend: ((channel: string, message: string) => void) | null = null;\n\n/** Inject IRC send from bridge for irc_send tool. */\nexport function setIrcSend(fn: (channel: string, message: string) => void): void { _ircSend = fn; }\n\n/** @deprecated \u2014 secret_get now reads from file, not DB. Kept for backward compat (callers may still call this). */\n\nlet _sendDocument: ((path: string, caption?: string) => Promise<number>) | null = null;\n\n/**\n * Inject sendDocument from bridge for the send_document tool.\n * Caller binds main chat id + telegram adapter; tool is a thin wrapper around that.\n */\nexport function setSendDocument(fn: ((path: string, caption?: string) => Promise<number>) | null): void { _sendDocument = fn; }\n\nconst sendDocumentTool: ToolDefinition = {\n name: \"send_document\",\n description: \"Send a file from disk to the user's Telegram chat. Use for delivering reports, daily summaries, logs, or any .md file the user asks for. Do not summarize \u2014 the raw file is sent as an attachment.\",\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"Absolute path to the file\" },\n caption: { type: \"string\", description: \"Optional short caption (\u22641024 chars)\" },\n },\n required: [\"path\"],\n },\n execute: async (args) => {\n const path = args[\"path\"];\n if (!path) return JSON.stringify({ error: \"path is required\" });\n if (!_sendDocument) return JSON.stringify({ error: \"Telegram not configured (sendDocument unavailable)\" });\n try {\n const messageId = await _sendDocument(path, args[\"caption\"]);\n return JSON.stringify({ ok: true, message_id: messageId });\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n },\n};\n\nconst taskTool: ToolDefinition = {\n name: \"task_manage\",\n description: \"Manage scheduled/recurring tasks (cron). Add, list, remove, pause, resume, or run tasks. Use action=run to execute a task immediately via the cron queue (isolated subagent).\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", enum: [\"add\", \"list\", \"remove\", \"pause\", \"resume\", \"run\"], description: \"Action\" },\n message: { type: \"string\", description: \"Task message/command (for add)\" },\n schedule: { type: \"string\", description: \"Cron schedule expression (for add)\" },\n type: { type: \"string\", enum: [\"reminder\", \"script\", \"agent\"], description: \"Task type (for add)\" },\n chat_id: { type: \"string\", description: \"Chat ID (for add)\" },\n id: { type: \"string\", description: \"Task ID (for remove/pause/resume/run)\" },\n },\n required: [\"action\"],\n },\n execute: (args) => {\n const action = args[\"action\"] ?? \"list\";\n if (action === \"list\") return runBash(\"abtars-task list\", CLI_TIMEOUT_MS);\n if (action === \"remove\") return runBash(`abtars-task remove ${args[\"id\"] ?? \"\"}`, CLI_TIMEOUT_MS);\n if (action === \"pause\") return runBash(`abtars-task pause ${args[\"id\"] ?? \"\"}`, CLI_TIMEOUT_MS);\n if (action === \"resume\") return runBash(`abtars-task resume ${args[\"id\"] ?? \"\"}`, CLI_TIMEOUT_MS);\n if (action === \"run\") {\n if (!_enqueueCron) return Promise.resolve(JSON.stringify({ error: \"enqueueCron not available\" }));\n const err = _enqueueCron(args[\"id\"] ?? \"\", true);\n return Promise.resolve(JSON.stringify(err ? { error: err } : { ok: true, message: `Task ${args[\"id\"]} enqueued for immediate execution` }));\n }\n let cmd = `abtars-task add --message ${JSON.stringify(args[\"message\"] ?? \"\")}`;\n if (args[\"schedule\"]) cmd += ` --schedule ${JSON.stringify(args[\"schedule\"])}`;\n if (args[\"type\"]) cmd += ` --type ${args[\"type\"]}`;\n if (args[\"chat_id\"]) cmd += ` --chat-id ${args[\"chat_id\"]}`;\n return runBash(cmd, CLI_TIMEOUT_MS);\n },\n};\n\nconst peerSessionTool: ToolDefinition = {\n name: \"peer_session\",\n description: \"Open or continue a peer-to-peer session with another agent. Messages persist across turns. Use only when the user explicitly asks to contact another agent.\",\n parameters: {\n type: \"object\",\n properties: {\n peer_name: { type: \"string\", description: \"Name of the peer (as in peers.json)\" },\n message: { type: \"string\", description: \"Your message to the peer\" },\n session_id: { type: \"string\", description: \"Session ID from previous call (omit for new conversation)\" },\n },\n required: [\"peer_name\", \"message\"],\n },\n async execute(args) {\n const { callPeer } = await import(\"../peer-client.js\");\n const { loadPeerConfig } = await import(\"../peer-config.js\");\n const { getOrCreateSession, addTurn, isEnded, destroySession } = await import(\"../peer-sessions.js\");\n\n const peerName = args.peer_name?.trim();\n const message = args.message?.trim();\n if (!peerName || !message) return JSON.stringify({ error: \"peer_name and message required\" });\n\n const config = loadPeerConfig();\n if (peerName === config.self.name) return JSON.stringify({ error: \"Cannot chat with yourself\" });\n if (!config.peers[peerName]) return JSON.stringify({ error: `Unknown peer: ${peerName}` });\n\n const session = getOrCreateSession(args.session_id?.trim() || undefined, peerName);\n\n // Check turn cap before sending\n if (session.messages.length >= 20) {\n destroySession(session.id);\n return JSON.stringify({ session_id: session.id, response: \"[SESSION_END] Turn limit reached.\", ended: true, reason: \"max-turns\" });\n }\n\n addTurn(session, \"user\", message);\n\n // Build full conversation for peer (OpenAI messages format)\n const prompt = session.messages.map(m => `${m.role === \"user\" ? \"You\" : \"Peer\"}: ${m.content}`).join(\"\\n\") + \"\\n\\nRespond to the latest message.\";\n\n try {\n const response = await callPeer(peerName, prompt, config.maxHops);\n addTurn(session, \"assistant\", response);\n _peerActivityCb?.(`\uD83E\uDD16 Agents: ${config.self.name} \u2194 ${peerName} session. [turn ${session.messages.length}]`);\n\n const { ended, reason } = isEnded(session, response);\n if (ended) destroySession(session.id);\n\n return JSON.stringify({ session_id: session.id, response, ended, reason });\n } catch (err) {\n destroySession(session.id);\n return JSON.stringify({ error: `peer_session failed: ${err instanceof Error ? err.message : String(err)}`, session_id: session.id, ended: true });\n }\n },\n};\n\nconst peerWakeupTool: ToolDefinition = {\n name: \"peer_wakeup\",\n description: \"Send a wake-up signal to a peer that cannot reach us directly (firewall). The peer's bridge will call us back via A2A within seconds.\",\n parameters: {\n type: \"object\",\n properties: {\n peer_name: { type: \"string\", description: \"Name of the peer to wake up (as in peers.json)\" },\n },\n required: [\"peer_name\"],\n },\n async execute(args) {\n const { sendWakeup } = await import(\"../dns-wakeup.js\");\n const { loadPeerConfig } = await import(\"../peer-config.js\");\n const peerName = args.peer_name?.trim();\n if (!peerName) return JSON.stringify({ error: \"peer_name required\" });\n const config = loadPeerConfig();\n const peer = config.peers[peerName];\n if (!peer) return JSON.stringify({ error: `Unknown peer: ${peerName}` });\n const udpPort = peer.udpPort ?? 5353;\n sendWakeup(config.self.name, peer.host, udpPort, peer.token);\n return JSON.stringify({ ok: true, message: `Wake-up sent to ${peerName}. Expect callback within seconds.` });\n },\n};\n\nconst ircSendTool: ToolDefinition = {\n name: \"irc_send\",\n description: \"Send a message to an IRC channel (e.g. #bridges)\",\n parameters: {\n channel: { type: \"string\", description: \"IRC channel (e.g. #bridges)\" },\n message: { type: \"string\", description: \"Message text to send\" },\n },\n execute: async (args) => {\n if (!_ircSend) return JSON.stringify({ error: \"IRC adapter not connected\" });\n const channel = args[\"channel\"] ?? \"\";\n const message = args[\"message\"] ?? \"\";\n if (!channel || !message) return JSON.stringify({ error: \"channel and message are required\" });\n _ircSend(channel, message);\n return JSON.stringify({ ok: true, channel, sent: message.length + \" chars\" });\n },\n};\n\nconst secretGetTool: ToolDefinition = {\n name: \"secret_get\",\n description: \"Retrieve a secret from ~/.abtars/secret/. For env-var secrets (no extension), returns the value. For files (with extension like .json), returns the full decrypted content. NEVER echo the value to the user.\",\n parameters: {\n properties: {\n name: { type: \"string\", description: \"Exact filename in secret/ dir (e.g. 'OPENROUTER_API_KEY', 'x-cookies.json')\" },\n },\n required: [\"name\"],\n },\n execute: async (args) => {\n const name = args.name?.trim();\n if (!name) return JSON.stringify({ error: \"name is required\" });\n try {\n const { join } = await import(\"node:path\");\n const { homedir } = await import(\"node:os\");\n const { readFileSync, existsSync } = await import(\"node:fs\");\n const { createDecipheriv, hkdfSync } = await import(\"node:crypto\");\n const { loadKey } = await import(\"abmind\");\n\n const secretPath = join(homedir(), \".abtars\", \"secret\", name);\n if (!existsSync(secretPath)) return JSON.stringify({ error: `secret '${name}' not found` });\n\n const raw = readFileSync(secretPath, \"utf-8\").trim();\n if (!raw) return JSON.stringify({ error: `secret '${name}' is empty` });\n\n let value: string;\n if (raw.startsWith(\"ENC:\")) {\n const master = loadKey();\n const key = Buffer.from(hkdfSync(\"sha256\", master, \"\", \"abtars-secrets-files-v1\", 32));\n const buf = Buffer.from(raw.slice(4), \"base64\");\n const d = createDecipheriv(\"aes-256-gcm\", key, buf.subarray(1, 13));\n d.setAuthTag(buf.subarray(buf.length - 16));\n value = d.update(buf.subarray(13, buf.length - 16), undefined, \"utf-8\") + d.final(\"utf-8\");\n } else {\n value = raw;\n }\n\n // For env-var type (no extension): also inject into process.env\n if (!name.includes(\".\")) {\n process.env[name] = value;\n return JSON.stringify({ ok: true, env_var: `$${name}`, hint: `Use $${name} in commands. NEVER print or echo the value.` });\n }\n return JSON.stringify({ ok: true, content: value });\n } catch (err) {\n return JSON.stringify({ error: `secret_get failed: ${err instanceof Error ? err.message : String(err)}` });\n }\n },\n};\n\nimport { skillCreateTool, skillUpdateTool, skillPatchTool, skillRemoveTool } from \"./skill-authoring.js\";\nimport { mcpTool } from \"./mcp-tool.js\";\nimport { getDelegationTools } from \"./delegation-tools.js\";\nimport { getPeerDelegationTools } from \"./peer-delegation-tools.js\";\nimport { getOrcTools } from \"./orc-tools.js\";\nimport { kanbanTool } from \"./kanban-tool.js\";\nimport { channelPostTool, channelReadTool } from \"./channel-tool.js\";\nimport { artifactPushTool, artifactPullTool, artifactAttachTool } from \"./artifact-tools.js\";\n\nconst ALL_TOOLS: ToolDefinition[] = [bashTool, memoryStoreTool, memoryRecallTool, memoryEditTool, webBrowseTool, todoTool, taskTool, sendDocumentTool, peerSessionTool, peerWakeupTool, ircSendTool, secretGetTool, skillCreateTool, skillUpdateTool, skillPatchTool, skillRemoveTool, mcpTool, kanbanTool, channelPostTool, channelReadTool, artifactAttachTool, ...getDelegationTools(), ...getPeerDelegationTools(), ...getOrcTools()];\n\n// Conditional: artifact store tools (#929)\nif (process.env[\"ARTIFACT_S3_ENDPOINT\"]) {\n ALL_TOOLS.push(artifactPushTool, artifactPullTool);\n}\n\nexport function getToolDefinitions(): ToolDefinition[] { return ALL_TOOLS; }\n\nexport function getToolSchemas(policy?: SandboxPolicy): Array<{ type: \"function\"; function: { name: string; description: string; parameters: Record<string, unknown> } }> {\n const tools = policy ? ALL_TOOLS.filter(t => checkTool(t.name, policy).allowed) : ALL_TOOLS;\n return tools.map(t => ({\n type: \"function\" as const,\n function: { name: t.name, description: t.description, parameters: t.parameters },\n }));\n}\n\nimport { bumpRead } from \"../skill-stats.js\";\n\n/** Check if a bash command result indicates a skill file was read. */\nfunction checkSkillRead(toolName: string, args: Record<string, string>): void {\n if (toolName !== \"execute_bash\") return;\n const cmd = args[\"command\"] ?? \"\";\n if (cmd.includes(\"/.abtars/skills/\") && cmd.includes(\"/SKILL.md\")) {\n const match = cmd.match(/\\/.abtars\\/skills\\/[^/]+\\/([^/]+)\\/SKILL\\.md/);\n if (match) bumpRead(match[1]!);\n }\n}\n\nexport async function executeToolCall(name: string, args: Record<string, string>, context?: { userId: string; signal?: AbortSignal; sandboxPolicy?: SandboxPolicy }): Promise<string> {\n // Sandbox enforcement\n if (context?.sandboxPolicy) {\n const toolCheck = checkTool(name, context.sandboxPolicy);\n if (!toolCheck.allowed) {\n const available = ALL_TOOLS.filter(t => checkTool(t.name, context.sandboxPolicy!).allowed).map(t => t.name);\n auditDeny(name, undefined, \"session\", toolCheck.reason!);\n return JSON.stringify({ error: `Tool '${name}' not available in this session`, available_tools: available, reason: \"peer_sandbox\" });\n }\n const filePath = args[\"path\"] ?? args[\"file_path\"];\n if (filePath) {\n const mode = name.includes(\"read\") || name === \"memory_recall\" ? \"read\" as const : \"write\" as const;\n const pathCheck = checkPath(filePath, mode, context.sandboxPolicy);\n if (!pathCheck.allowed) {\n auditDeny(name, filePath, \"session\", pathCheck.reason!);\n return JSON.stringify({ error: pathCheck.reason, reason: \"peer_sandbox\" });\n }\n }\n }\n\n const tool = ALL_TOOLS.find(t => t.name === name);\n if (!tool) return JSON.stringify({ error: `Unknown tool: ${name}` });\n const ts = Date.now();\n\n // #621: redact abmind_store args based on classification\n const storeClass = (name === \"abmind_store\" || name === \"memory_store\") ? parseInt(args.classification ?? args.class ?? \"1\", 10) : 0;\n const auditArgs = storeClass >= 2\n ? `{\"class\":${storeClass},\"[REDACTED]\":true}`\n : redactSecrets(JSON.stringify(args));\n audit({ ts, tool: name, args: auditArgs, userId: context?.userId });\n\n try {\n const result = await tool.execute(args, context);\n audit({ ts, tool: name, status: \"ok\", chars: result.length });\n checkSkillRead(name, args);\n return result;\n } catch (err) {\n audit({ ts, tool: name, status: \"error\", error: err instanceof Error ? err.message : String(err) });\n throw err;\n }\n}\n", "/**\n * skill-authoring.ts \u2014 skill lifecycle tools (#381, #613, #614).\n * Agent persists procedural knowledge as skills under ~/.abtars/skills/self/.\n */\n\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, renameSync, appendFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { abmind } from \"../../utils/abmind-lazy.js\";\nimport { abtarsHome } from \"../../paths.js\";\nimport { logInfo } from \"../logger.js\";\nimport { logAndSwallow } from \"../log-and-swallow.js\";\nimport { setProvenance } from \"../skill-stats.js\";\nimport type { ToolDefinition } from \"./tool-registry.js\";\n\nconst TAG = \"skill-authoring\";\nconst NAME_RE = /^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/;\nconst MIN_BYTES = 100;\nconst MAX_BYTES = 50_000;\nconst MAX_TAGS = 5;\n\nfunction skillsDir(): string { return join(abtarsHome(), \"skills\"); }\nfunction selfDir(): string { return join(skillsDir(), \"self\"); }\nfunction trashDir(): string { return join(skillsDir(), \".trash\"); }\nfunction auditLogPath(): string { return join(abtarsHome(), \"logs\", \"skill-authoring.log\"); }\n\nfunction audit(entry: string): void {\n const line = `[${new Date().toISOString()}] ${entry}\\n`;\n try {\n const dir = join(abtarsHome(), \"logs\");\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n appendFileSync(auditLogPath(), line);\n } catch (err) { logAndSwallow(TAG, \"audit write\", err); }\n}\n\nfunction validate(name: string, description: string, content: string): string | null {\n if (!NAME_RE.test(name)) return `Invalid name \"${name}\". Must be 3-64 chars, lowercase alphanumeric + hyphens, no leading/trailing hyphens.`;\n const desc = description.trim();\n if (desc.length < 1 || desc.length > 120) return `Description must be 1-120 chars (got ${desc.length}).`;\n const bytes = Buffer.byteLength(content, \"utf-8\");\n if (bytes < MIN_BYTES) return `Content too short (${bytes} bytes, minimum ${MIN_BYTES}). Write a useful skill, not a one-liner.`;\n if (bytes > MAX_BYTES) return `Content too large (${bytes} bytes, maximum ${MAX_BYTES}). Split into a skill + references/ files.`;\n const path = join(selfDir(), name, \"SKILL.md\");\n if (existsSync(path)) return `Skill \"${name}\" already exists. Use skill_update to modify it.`;\n const scan = abmind()?.scanForInjection(content);\n if (scan && !scan.safe) return `Content blocked by injection scanner: ${scan.flags[0]?.category ?? \"unknown\"} (score=${scan.score}). Rephrase the content.`;\n return null;\n}\n\n/** Parse YAML-like frontmatter from SKILL.md content. */\nfunction parseFrontmatter(raw: string): { meta: Record<string, unknown>; body: string } {\n const match = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n\\n?([\\s\\S]*)$/);\n if (!match) return { meta: {}, body: raw };\n const meta: Record<string, unknown> = {};\n for (const line of match[1]!.split(\"\\n\")) {\n const idx = line.indexOf(\":\");\n if (idx < 0) continue;\n const key = line.slice(0, idx).trim();\n let val: unknown = line.slice(idx + 1).trim();\n // Parse array: [a, b, c]\n if (typeof val === \"string\" && val.startsWith(\"[\") && val.endsWith(\"]\")) {\n val = val.slice(1, -1).split(\",\").map(s => s.trim()).filter(Boolean);\n }\n meta[key] = val;\n }\n return { meta, body: match[2]! };\n}\n\n/** Serialize frontmatter fields back to YAML-like string. */\nfunction serializeFrontmatter(meta: Record<string, unknown>): string {\n const lines: string[] = [\"---\"];\n for (const [k, v] of Object.entries(meta)) {\n if (v === undefined || v === null) continue;\n if (Array.isArray(v) && v.length > 0) {\n lines.push(`${k}: [${v.join(\", \")}]`);\n } else if (!Array.isArray(v)) {\n lines.push(`${k}: ${v}`);\n }\n }\n lines.push(\"---\\n\\n\");\n return lines.join(\"\\n\");\n}\n\n/** Guard: skill must exist in self/ dir. Returns error string or null. */\nfunction guardSelfSkill(name: string): string | null {\n if (!NAME_RE.test(name)) return `Invalid name \"${name}\".`;\n const path = join(selfDir(), name, \"SKILL.md\");\n if (!existsSync(path)) return `Skill \"${name}\" not found in self/.`;\n return null;\n}\n\nexport const skillCreateTool: ToolDefinition = {\n name: \"skill_create\",\n description: \"Persist a new procedural skill to disk. Use when you've solved a novel task, discovered a workflow, or received a correction worth remembering as a repeatable recipe. Skills become available in future sessions via the skills_catalog.\",\n parameters: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Skill identifier, kebab-case, e.g. 'fix-pnpm-workspace-drift'. 3-64 chars, [a-z0-9-]+.\" },\n description: { type: \"string\", description: \"One-line description, max 120 chars. Shown in skills_catalog.\" },\n content: { type: \"string\", description: \"Skill body in Markdown. Starts with # <Title>. No frontmatter \u2014 the tool writes it.\" },\n tags: { type: \"array\", items: { type: \"string\" }, description: \"Optional tags for categorization (max 5). E.g. ['tools', 'browser', 'debugging'].\" },\n related: { type: \"array\", items: { type: \"string\" }, description: \"Optional related skill names.\" },\n },\n required: [\"name\", \"description\", \"content\"],\n },\n async execute(args) {\n const { name, description, content, tags, related } = args as unknown as { name: string; description: string; content: string; tags?: string[]; related?: string[] };\n const error = validate(name, description, content);\n if (error) {\n audit(`skill_create name=${name} bytes=${content.length} ok=false error=\"${error}\"`);\n return JSON.stringify({ error });\n }\n\n const tagList = (tags ?? []).slice(0, MAX_TAGS).map(t => t.toLowerCase().trim()).filter(Boolean);\n const relList = (related ?? []).filter(Boolean);\n const tagsLine = tagList.length > 0 ? `tags: [${tagList.join(\", \")}]\\n` : \"\";\n const relatedLine = relList.length > 0 ? `related: [${relList.join(\", \")}]\\n` : \"\";\n const frontmatter = `---\\nname: ${name}\\ndescription: ${description.trim()}\\n${tagsLine}${relatedLine}---\\n\\n`;\n const fullContent = frontmatter + content;\n const dir = join(selfDir(), name);\n const filePath = join(dir, \"SKILL.md\");\n const tmpPath = filePath + \".tmp\";\n\n try {\n mkdirSync(dir, { recursive: true });\n writeFileSync(tmpPath, fullContent, \"utf-8\");\n renameSync(tmpPath, filePath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n audit(`skill_create name=${name} bytes=${content.length} ok=false error=\"write failed: ${msg}\"`);\n return JSON.stringify({ error: `Write failed: ${msg}` });\n }\n\n setProvenance(name, \"agent\");\n audit(`skill_create name=${name} tags=[${tagList.join(\",\")}] bytes=${content.length} ok=true`);\n logInfo(TAG, `Created skill: self/${name} (${content.length} bytes)`);\n return JSON.stringify({ ok: true, path: filePath, message: `Skill \"${name}\" created in self/. Available in skills_catalog after /skill reload.` });\n },\n};\n\nexport const skillUpdateTool: ToolDefinition = {\n name: \"skill_update\",\n description: \"Full rewrite of an existing skill's SKILL.md in self/. Preserves frontmatter fields (tags, related, description) when omitted by caller.\",\n parameters: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Skill name (must exist in self/).\" },\n description: { type: \"string\", description: \"New description (optional \u2014 keeps existing if omitted).\" },\n content: { type: \"string\", description: \"New skill body in Markdown (no frontmatter).\" },\n tags: { type: \"array\", items: { type: \"string\" }, description: \"New tags (optional \u2014 keeps existing if omitted).\" },\n related: { type: \"array\", items: { type: \"string\" }, description: \"New related skills (optional \u2014 keeps existing if omitted).\" },\n },\n required: [\"name\", \"content\"],\n },\n async execute(args) {\n const { name, content, description, tags, related } = args as unknown as { name: string; content: string; description?: string; tags?: string[]; related?: string[] };\n const guard = guardSelfSkill(name);\n if (guard) { audit(`skill_update name=${name} ok=false error=\"${guard}\"`); return JSON.stringify({ error: guard }); }\n\n const bytes = Buffer.byteLength(content, \"utf-8\");\n if (bytes < MIN_BYTES) return JSON.stringify({ error: `Content too short (${bytes} bytes, minimum ${MIN_BYTES}).` });\n if (bytes > MAX_BYTES) return JSON.stringify({ error: `Content too large (${bytes} bytes, maximum ${MAX_BYTES}).` });\n\n const scan = abmind()?.scanForInjection(content);\n if (scan && !scan.safe) return JSON.stringify({ error: `Content blocked by injection scanner: ${scan.flags[0]?.category ?? \"unknown\"}.` });\n\n const filePath = join(selfDir(), name, \"SKILL.md\");\n const existing = readFileSync(filePath, \"utf-8\");\n const { meta } = parseFrontmatter(existing);\n\n // Merge: caller fields override, omitted fields preserved\n const merged: Record<string, unknown> = { ...meta, name };\n if (description !== undefined) merged[\"description\"] = description.trim();\n if (tags !== undefined) merged[\"tags\"] = tags.slice(0, MAX_TAGS).map(t => t.toLowerCase().trim()).filter(Boolean);\n if (related !== undefined) merged[\"related\"] = related.filter(Boolean);\n\n const fullContent = serializeFrontmatter(merged) + content;\n const tmpPath = filePath + \".tmp\";\n try {\n writeFileSync(tmpPath, fullContent, \"utf-8\");\n renameSync(tmpPath, filePath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n audit(`skill_update name=${name} ok=false error=\"write failed: ${msg}\"`);\n return JSON.stringify({ error: `Write failed: ${msg}` });\n }\n\n audit(`skill_update name=${name} bytes=${bytes} ok=true`);\n logInfo(TAG, `Updated skill: self/${name} (${bytes} bytes)`);\n return JSON.stringify({ ok: true, path: filePath, message: `Skill \"${name}\" updated.` });\n },\n};\n\nexport const skillPatchTool: ToolDefinition = {\n name: \"skill_patch\",\n description: \"Targeted find-and-replace within a skill's SKILL.md in self/. old_string must match exactly once.\",\n parameters: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Skill name (must exist in self/).\" },\n old_string: { type: \"string\", description: \"Exact string to find (must match once).\" },\n new_string: { type: \"string\", description: \"Replacement string.\" },\n },\n required: [\"name\", \"old_string\", \"new_string\"],\n },\n async execute(args) {\n const { name, old_string, new_string } = args as unknown as { name: string; old_string: string; new_string: string };\n const guard = guardSelfSkill(name);\n if (guard) { audit(`skill_patch name=${name} ok=false error=\"${guard}\"`); return JSON.stringify({ error: guard }); }\n\n const filePath = join(selfDir(), name, \"SKILL.md\");\n const existing = readFileSync(filePath, \"utf-8\");\n\n const count = existing.split(old_string).length - 1;\n if (count === 0) return JSON.stringify({ error: `old_string not found in skill \"${name}\".` });\n if (count > 1) return JSON.stringify({ error: `old_string matches ${count} times \u2014 must match exactly once.` });\n\n const patched = existing.replace(old_string, new_string);\n const scan = abmind()?.scanForInjection(patched);\n if (scan && !scan.safe) return JSON.stringify({ error: `Patched content blocked by injection scanner: ${scan.flags[0]?.category ?? \"unknown\"}.` });\n\n const tmpPath = filePath + \".tmp\";\n try {\n writeFileSync(tmpPath, patched, \"utf-8\");\n renameSync(tmpPath, filePath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n audit(`skill_patch name=${name} ok=false error=\"write failed: ${msg}\"`);\n return JSON.stringify({ error: `Write failed: ${msg}` });\n }\n\n audit(`skill_patch name=${name} ok=true`);\n logInfo(TAG, `Patched skill: self/${name}`);\n return JSON.stringify({ ok: true, path: filePath, message: `Skill \"${name}\" patched.` });\n },\n};\n\nexport const skillRemoveTool: ToolDefinition = {\n name: \"skill_remove\",\n description: \"Soft-delete a skill from self/ by moving it to .trash/ (recoverable for 7 days).\",\n parameters: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Skill name (must exist in self/).\" },\n },\n required: [\"name\"],\n },\n async execute(args) {\n const { name } = args as unknown as { name: string };\n const guard = guardSelfSkill(name);\n if (guard) { audit(`skill_remove name=${name} ok=false error=\"${guard}\"`); return JSON.stringify({ error: guard }); }\n\n const srcDir = join(selfDir(), name);\n const ts = Date.now();\n const destDir = join(trashDir(), `${name}-${ts}`);\n try {\n mkdirSync(trashDir(), { recursive: true });\n renameSync(srcDir, destDir);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n audit(`skill_remove name=${name} ok=false error=\"move failed: ${msg}\"`);\n return JSON.stringify({ error: `Move failed: ${msg}` });\n }\n\n audit(`skill_remove name=${name} dest=${destDir} ok=true`);\n logInfo(TAG, `Removed skill: self/${name} \u2192 .trash/`);\n return JSON.stringify({ ok: true, message: `Skill \"${name}\" moved to .trash/. Will be pruned after 7 days.` });\n },\n};\n", "/**\n * mcp-tool.ts \u2014 Generic MCP tool (#471 v2).\n * Single tool that routes to any mcporter server/tool. Daemon starts on-demand.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { logInfo, logWarn } from \"../logger.js\";\nimport { logAndSwallow } from \"../log-and-swallow.js\";\nimport type { ToolDefinition } from \"./tool-registry.js\";\n\nconst execFileAsync = promisify(execFile);\nconst TAG = \"mcp\";\nlet daemonStarted = false;\n\nasync function ensureDaemon(): Promise<void> {\n if (daemonStarted) return;\n try {\n await execFileAsync(\"mcporter\", [\"daemon\", \"start\"], { timeout: 10_000 });\n daemonStarted = true;\n logInfo(TAG, \"mcporter daemon started (on-demand)\");\n } catch {\n logWarn(TAG, \"mcporter daemon start failed \u2014 calls may still work if already running\");\n daemonStarted = true; // don't retry every call \u2014 assume already running\n }\n}\n\nexport const mcpTool: ToolDefinition = {\n name: \"mcp\",\n description: \"Call an MCP server tool via mcporter. Available servers shown by /mcp command. Use when you need JIRA, presentations, or other MCP-connected services.\",\n parameters: {\n type: \"object\",\n properties: {\n server: { type: \"string\", description: \"Server name (e.g. 'pptx', 'atlassian')\" },\n tool: { type: \"string\", description: \"Tool name (e.g. 'jira_search', 'create_presentation')\" },\n args: { type: \"string\", description: \"Tool arguments as JSON string (e.g. '{\\\"query\\\": \\\"assignee = me\\\"}')\" },\n },\n required: [\"server\", \"tool\"],\n },\n async execute(params) {\n await ensureDaemon();\n const { server, tool, args } = params as { server: string; tool: string; args?: string };\n const cliArgs = [\"call\", `${server}.${tool}`];\n if (args) {\n try {\n const parsed = JSON.parse(args) as Record<string, string>;\n for (const [k, v] of Object.entries(parsed)) cliArgs.push(`${k}=${v}`);\n } catch (err) {\n logAndSwallow(TAG, \"JSON.parse mcp args\", err);\n cliArgs.push(args);\n }\n }\n try {\n const { stdout } = await execFileAsync(\"mcporter\", cliArgs, { timeout: 30_000, encoding: \"utf-8\" });\n return stdout;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return JSON.stringify({ error: `mcp call failed: ${msg}` });\n }\n },\n};\n", "/**\n * peer-delegation-tools.ts \u2014 peer_delegate, peer_check, peer_terminate (#675).\n *\n * Remote delegation tools for the Orc. Uses PeerTransport to call\n * remote peers' /v1/tasks endpoints. Results tracked in local kanban\n * with type=\"remote\" and meta JSON for peer + remote_task_id.\n */\n\nimport type { ToolDefinition } from \"./tool-registry.js\";\nimport { getPeerTransport } from \"../peer-transport/index.js\";\nimport { kanbanEnqueue } from \"../tasks/kanban-board.js\";\nimport { logInfo, logWarn, logDebug, logTrace } from \"../logger.js\";\n\nconst TAG = \"peer-delegate\";\n\nexport const peerDelegateTool: ToolDefinition = {\n name: \"peer_delegate\",\n description: \"Delegate a task to a remote peer. If peer is omitted, auto-selects the best capable peer by load. Use 'requires' to specify needed capabilities (gpu, docker, ollama, browser, xcode).\",\n parameters: {\n type: \"object\",\n properties: {\n peer: { type: \"string\", description: \"Peer name (optional \u2014 auto-selects if omitted)\" },\n goal: { type: \"string\", description: \"Task goal/instructions for the remote peer\" },\n priority: { type: \"string\", enum: [\"CRITICAL\", \"HIGH\", \"MEDIUM\", \"LOW\"], description: \"Task priority (default: MEDIUM)\" },\n context: { type: \"string\", description: \"Optional context to include\" },\n requires: { type: \"array\", items: { type: \"string\" }, description: \"Required capabilities (e.g. ['gpu', 'docker'])\" },\n artifacts: { type: \"string\", description: \"JSON array of {name, content} objects (base64-encoded files to send)\" },\n },\n required: [\"goal\"],\n },\n async execute(args: Record<string, string>): Promise<string> {\n const { goal, priority, context } = args;\n let peer = args.peer;\n const requires: string[] = args.requires ? (typeof args.requires === \"string\" ? JSON.parse(args.requires) : args.requires) : [];\n const artifacts: Array<{ name: string; content: string }> | undefined = args.artifacts ? JSON.parse(args.artifacts) : undefined;\n\n if (!goal) return JSON.stringify({ error: \"goal is required\" });\n\n // Auto-select peer if not specified\n if (!peer && requires.length > 0) {\n const { findCapablePeer } = await import(\"../peer-transport/gossip.js\");\n const match = findCapablePeer(requires);\n if (!match) return JSON.stringify({ error: `No alive peer with capabilities: [${requires.join(\", \")}]` });\n peer = match.name;\n logDebug(TAG, `Auto-selected peer ${peer} for requires=[${requires.join(\",\")}] (load=${match.load})`);\n } else if (!peer) {\n // No peer, no requires \u2014 pick least loaded\n const { getPeerTable } = await import(\"../peer-transport/gossip.js\");\n const alive = getPeerTable().sort((a, b) => a.load - b.load);\n if (alive.length === 0) return JSON.stringify({ error: \"No alive peers available\" });\n peer = alive[0]!.name;\n logDebug(TAG, `Auto-selected least-loaded peer ${peer} (load=${alive[0]!.load})`);\n }\n\n // Validate capabilities if requires specified + explicit peer\n if (requires.length > 0 && args.peer) {\n const { getPeerTable } = await import(\"../peer-transport/gossip.js\");\n const entry = getPeerTable(true).find(p => p.name.toLowerCase() === peer!.toLowerCase());\n if (entry && !requires.every(r => entry.capabilities.includes(r))) {\n const missing = requires.filter(r => !entry.capabilities.includes(r));\n return JSON.stringify({ error: `Peer ${peer} lacks capabilities: [${missing.join(\", \")}]` });\n }\n }\n\n logDebug(TAG, `peer_delegate: peer=${peer} priority=${priority ?? \"MEDIUM\"} goal=${goal.length}ch requires=[${requires.join(\",\")}]`);\n logTrace(TAG, `peer_delegate goal: ${goal.slice(0, 500)}`);\n\n try {\n const transport = getPeerTransport();\n const { taskId: remoteTaskId, remoteSessionId } = await transport.delegateTask(peer, goal, { priority, context, artifacts });\n\n const localCardId = kanbanEnqueue(`[remote:${peer}] ${goal.slice(0, 80)}`, \"peer\", undefined, {\n type: \"remote\",\n priority: priority ?? \"MEDIUM\",\n notes: JSON.stringify({ peer, remote_task_id: remoteTaskId, remote_session_id: remoteSessionId, goal, requires }),\n });\n\n // #949: Create hollow session to track remote worker locally\n if (remoteSessionId) {\n const { spin } = await import(\"../spin.js\");\n const { getMasterUserId } = await import(\"../../boot/phase-config.js\");\n spin.createHollowSession(getMasterUserId(), \"telegram\", \"W\", peer, remoteSessionId);\n }\n\n logInfo(TAG, `Delegated to ${peer}: remote#${remoteTaskId} \u2192 local#${localCardId}`);\n return JSON.stringify({ ok: true, local_card_id: localCardId, remote_task_id: remoteTaskId, remote_session_id: remoteSessionId, peer, status: \"queued\" });\n } catch (err) {\n logWarn(TAG, `peer_delegate failed: ${err instanceof Error ? err.message : String(err)}`);\n return JSON.stringify({ error: `peer_delegate failed: ${err instanceof Error ? err.message : String(err)}` });\n }\n },\n};\n\nexport const peerCheckTool: ToolDefinition = {\n name: \"peer_check\",\n description: \"Check the status of a task delegated to a remote peer. Returns status and result if complete.\",\n parameters: {\n type: \"object\",\n properties: {\n peer: { type: \"string\", description: \"Peer name\" },\n task_id: { type: \"number\", description: \"Remote task ID (from peer_delegate result)\" },\n },\n required: [\"peer\", \"task_id\"],\n },\n async execute(args: Record<string, string>): Promise<string> {\n const peer = args.peer;\n const taskId = parseInt(args.task_id ?? \"\", 10);\n if (!peer || isNaN(taskId)) return JSON.stringify({ error: \"peer and task_id are required\" });\n\n try {\n const transport = getPeerTransport();\n const result = await transport.checkTask(peer, taskId);\n return JSON.stringify({ ok: true, ...result });\n } catch (err) {\n logWarn(TAG, `peer_check failed: ${err instanceof Error ? err.message : String(err)}`);\n return JSON.stringify({ error: `peer_check failed: ${err instanceof Error ? err.message : String(err)}` });\n }\n },\n};\n\nexport const peerTerminateTool: ToolDefinition = {\n name: \"peer_terminate\",\n description: \"Cancel/terminate a task running on a remote peer.\",\n parameters: {\n type: \"object\",\n properties: {\n peer: { type: \"string\", description: \"Peer name\" },\n task_id: { type: \"number\", description: \"Remote task ID to terminate\" },\n },\n required: [\"peer\", \"task_id\"],\n },\n async execute(args: Record<string, string>): Promise<string> {\n const peer = args.peer;\n const taskId = parseInt(args.task_id ?? \"\", 10);\n if (!peer || isNaN(taskId)) return JSON.stringify({ error: \"peer and task_id are required\" });\n\n try {\n const transport = getPeerTransport();\n await transport.terminateTask(peer, taskId);\n logInfo(TAG, `Terminated remote task ${taskId} on ${peer}`);\n return JSON.stringify({ ok: true, terminated: true, peer, task_id: taskId });\n } catch (err) {\n logWarn(TAG, `peer_terminate failed: ${err instanceof Error ? err.message : String(err)}`);\n return JSON.stringify({ error: `peer_terminate failed: ${err instanceof Error ? err.message : String(err)}` });\n }\n },\n};\n\nexport function getPeerDelegationTools(): ToolDefinition[] {\n return [peerDelegateTool, peerCheckTool, peerTerminateTool];\n}\n", "/**\n * kanban-tool.ts \u2014 Agent-facing tool for managing the kanban board.\n */\n\nimport type { ToolDefinition } from \"./tool-registry.js\";\nimport { kanbanEnqueue, kanbanUpdate, kanbanList, type KanbanCard } from \"../tasks/kanban-board.js\";\n\nfunction formatCard(c: KanbanCard): string {\n const icon = c.status === \"delivered\" ? \"*\" : c.status === \"done\" ? \"*\" : c.status === \"running\" ? \"~\" : c.status === \"failed\" ? \"x\" : \"+\";\n const due = c.due_at ? ` due:${c.due_at}` : \"\";\n const lbl = c.labels ? ` [${c.labels}]` : \"\";\n const deps = c.blocked_by ? ` <- #${c.blocked_by}` : \"\";\n const tokens = c.tokens_used ? ` ${c.tokens_used} tok` : \"\";\n const source = c.type === \"remote\" ? (() => { try { return ` [${JSON.parse(c.notes ?? \"{}\").peer}]`; } catch { return \" [remote]\"; } })() : \"\";\n return `${icon} #${c.id} ${c.title} (${c.priority}/${c.status})${tokens}${source}${due}${lbl}${deps}`;\n}\n\nasync function execute(args: Record<string, string>): Promise<string> {\n const action = args.action;\n\n if (action === \"create\") {\n if (!args.title) return \"[err] title required\";\n const id = kanbanEnqueue(args.title, args.source || \"agent\", undefined, {\n priority: args.priority,\n type: args.type,\n labels: args.labels,\n due_at: args.due_at,\n parent_id: args.parent_id ? parseInt(args.parent_id, 10) : undefined,\n notes: args.notes,\n blocked_by: args.blocked_by || undefined,\n });\n return `+ Card #${id} created: \"${args.title}\"${args.blocked_by ? ` (blocked_by: ${args.blocked_by})` : \"\"}`;\n }\n\n if (action === \"update\") {\n if (!args.id) return \"[err] id required\";\n const fields: Record<string, unknown> = {};\n for (const k of [\"title\", \"status\", \"priority\", \"type\", \"labels\", \"due_at\", \"notes\", \"approval\"] as const) {\n if (args[k]) fields[k] = args[k];\n }\n if (args.parent_id) fields.parent_id = parseInt(args.parent_id, 10);\n kanbanUpdate(parseInt(args.id, 10), fields as any);\n return `* Card #${args.id} updated`;\n }\n\n if (action === \"list\") {\n const cards = kanbanList(args.status || undefined);\n if (cards.length === 0) return \"Board is empty\";\n return `Kanban Board (${cards.length}):\\n` + cards.map(formatCard).join(\"\\n\");\n }\n\n return `[err] Unknown action: ${action}. Use create | update | list`;\n}\n\nexport const kanbanTool: ToolDefinition = {\n name: \"kanban_manage\",\n description: \"Create, update, or list cards on the kanban board. Use for tracking work items, user requests, and task decomposition.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"create | update | list\", enum: [\"create\", \"update\", \"list\"] },\n title: { type: \"string\", description: \"Card title (required for create)\" },\n id: { type: \"string\", description: \"Card ID (required for update)\" },\n source: { type: \"string\", description: \"Who created: user | agent | cron | peer\" },\n status: { type: \"string\", description: \"New status (for update): queued | running | done | failed\" },\n priority: { type: \"string\", description: \"CRITICAL | HIGH | MEDIUM | LOW\" },\n type: { type: \"string\", description: \"Card type (task, bug, feature, research, report, etc.)\" },\n labels: { type: \"string\", description: \"Comma-separated tags\" },\n due_at: { type: \"string\", description: \"ISO deadline (e.g. 2026-06-08T12:00:00)\" },\n parent_id: { type: \"string\", description: \"Parent card ID for subtasks\" },\n notes: { type: \"string\", description: \"Additional context\" },\n blocked_by: { type: \"string\", description: \"Comma-separated card IDs this card depends on, or 'children' to wait for all child cards\" },\n approval: { type: \"string\", description: \"pending | approved | rejected\" },\n },\n required: [\"action\"],\n },\n execute,\n};\n", "/**\n * channel-tool.ts \u2014 Agent-facing tools for the communication channel (#891).\n */\n\nimport type { ToolDefinition } from \"./tool-registry.js\";\nimport { channelPost, channelRead, type ChannelMessage } from \"../tasks/kanban-channel.js\";\n\nfunction formatMsg(m: ChannelMessage): string {\n const dir = m.directive ? \" \u26A1\" : \"\";\n return `[${m.from_agent}\u2192${m.to_agent}]${dir} ${m.message} (${m.created_at})`;\n}\n\nasync function executePost(args: Record<string, string>, ctx?: { userId?: string }): Promise<string> {\n const cardId = parseInt(args.card_id ?? \"\", 10);\n if (!cardId) return \"\u274C card_id required\";\n if (!args.message) return \"\u274C message required\";\n const from = args.from || ctx?.userId || \"agent\";\n const to = args.to || \"ALL\";\n const directive = args.directive === \"true\" || args.directive === \"1\";\n const msgType = args.type || \"progress\";\n const id = channelPost(cardId, from, to, args.message, directive, msgType);\n return `\u2713 Posted #${id} to card:${cardId} [${from}\u2192${to}]`;\n}\n\nasync function executeRead(args: Record<string, string>): Promise<string> {\n const cardId = parseInt(args.card_id ?? \"\", 10);\n if (!cardId) return \"\u274C card_id required\";\n const msgs = channelRead(cardId, { since: args.since, from: args.from });\n if (msgs.length === 0) return \"No messages.\";\n return msgs.map(formatMsg).join(\"\\n\");\n}\n\nexport const channelPostTool: ToolDefinition = {\n name: \"channel_post\",\n description: \"Post a message to the project discussion channel. Keep messages short (<1000 chars). For long plans, write a file and reference the path.\",\n parameters: {\n type: \"object\",\n properties: {\n card_id: { type: \"string\", description: \"Kanban card ID this message belongs to\" },\n to: { type: \"string\", description: \"Recipient: ALL (default), Worker-01, ORC, MASTER, or peer:name\" },\n message: { type: \"string\", description: \"Short message (max 1000 chars)\" },\n directive: { type: \"string\", description: \"Set to 'true' for priority directive (Orc/master only)\" },\n type: { type: \"string\", enum: [\"progress\", \"question\", \"result\", \"error\"], description: \"Message type (default: progress)\" },\n },\n required: [\"card_id\", \"message\"],\n },\n execute: executePost,\n};\n\nexport const channelReadTool: ToolDefinition = {\n name: \"channel_read\",\n description: \"Read messages from the project discussion channel.\",\n parameters: {\n type: \"object\",\n properties: {\n card_id: { type: \"string\", description: \"Kanban card ID to read messages from\" },\n since: { type: \"string\", description: \"ISO timestamp \u2014 only messages after this time\" },\n from: { type: \"string\", description: \"Filter by sender name\" },\n },\n required: [\"card_id\"],\n },\n execute: executeRead,\n};\n"],
5
- "mappings": "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",
6
- "names": ["execFile", "appendFileSync", "mkdirSync", "join", "TAG", "TAG", "getMasterUserId", "TAG", "join", "mkdirSync", "audit", "appendFileSync", "execFile", "homedir", "readFileSync", "existsSync"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/utils/crypto.ts"],
4
- "sourcesContent": ["/**\n * crypto.ts \u2014 AES-256-GCM encryption for abtars secrets.\n * Shared utility (same logic in abmind). See shared-utilities.md.\n *\n * Key: ~/.abtars/secret/abtars.key (32-byte hex, passphrase-derived via scrypt).\n * Purpose derivation: HKDF(master, \"abtars-secrets-v1\") for file encryption.\n */\n\nimport { createDecipheriv, createCipheriv, randomBytes, hkdfSync, scryptSync, createHash } from \"node:crypto\";\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\n\nconst ALGO = \"aes-256-gcm\";\nconst IV_LEN = 12;\nconst TAG_LEN = 16;\nconst PURPOSE = \"abtars-secrets-v1\";\n\nlet _cachedKey: Buffer | null = null;\n\n/** Load master key from file. Returns null if file doesn't exist. */\nexport function loadKey(keyPath: string): Buffer | null {\n try {\n if (!existsSync(keyPath)) return null;\n const hex = readFileSync(keyPath, \"utf-8\").trim();\n if (hex.length !== 64) return null;\n return Buffer.from(hex, \"hex\");\n } catch { return null; }\n}\n\n/** Derive purpose-specific key from master via HKDF. */\nexport function deriveKey(master: Buffer, purpose: string = PURPOSE): Buffer {\n return Buffer.from(hkdfSync(\"sha256\", master, \"\", purpose, 32));\n}\n\n/** Derive master key from passphrase + username (same algorithm as abmind). */\nexport function deriveFromPassphrase(passphrase: string, username: string): Buffer {\n const salt = createHash(\"sha256\").update(\"abtars:\" + username).digest().subarray(0, 16);\n return scryptSync(passphrase, salt, 32, { N: 16384, r: 8, p: 1 });\n}\n\n/** Encrypt plaintext. Returns \"ENC:\" + base64(version + iv + ciphertext + tag). */\nexport function encrypt(plaintext: string, key: Buffer): string {\n const iv = randomBytes(IV_LEN);\n const c = createCipheriv(ALGO, key, iv);\n const enc = Buffer.concat([c.update(plaintext, \"utf-8\"), c.final()]);\n return \"ENC:\" + Buffer.concat([Buffer.from([0x01]), iv, enc, c.getAuthTag()]).toString(\"base64\");\n}\n\n/** Decrypt \"ENC:...\" string. Returns plaintext or null on failure. */\nexport function decrypt(raw: string, key: Buffer): string | null {\n try {\n const buf = Buffer.from(raw.slice(4), \"base64\");\n const iv = buf.subarray(1, 1 + IV_LEN);\n const tag = buf.subarray(buf.length - TAG_LEN);\n const ct = buf.subarray(1 + IV_LEN, buf.length - TAG_LEN);\n const d = createDecipheriv(ALGO, key, iv);\n d.setAuthTag(tag);\n return d.update(ct, undefined, \"utf-8\") + d.final(\"utf-8\");\n } catch { return null; }\n}\n\n/** Write key to file (hex, mode 600). Creates parent dir if needed. */\nexport function writeKeyFile(keyPath: string, master: Buffer): void {\n mkdirSync(dirname(keyPath), { recursive: true });\n writeFileSync(keyPath, master.toString(\"hex\"), { mode: 0o600 });\n}\n\nconst VERIFY_PLAINTEXT = \"abtars-verify\";\n\n/** Create key.verify file next to the key (encrypt known plaintext). */\nexport function writeKeyVerify(keyPath: string, key: Buffer): void {\n const iv = randomBytes(IV_LEN);\n const cipher = createCipheriv(ALGO, key, iv);\n const enc = Buffer.concat([cipher.update(VERIFY_PLAINTEXT, \"utf-8\"), cipher.final()]);\n const blob = Buffer.concat([iv, enc, cipher.getAuthTag()]).toString(\"base64\");\n writeFileSync(join(dirname(keyPath), \"key.verify\"), blob, { mode: 0o600 });\n}\n\n/** Validate a key against key.verify. Returns true if key is correct or no verify file exists. */\nexport function validateKey(keyPath: string, key: Buffer): boolean {\n const verifyPath = join(dirname(keyPath), \"key.verify\");\n if (!existsSync(verifyPath)) return true; // no verify file = skip validation\n try {\n const blob = readFileSync(verifyPath, \"utf-8\").trim();\n const buf = Buffer.from(blob, \"base64\");\n const iv = buf.subarray(0, IV_LEN);\n const tag = buf.subarray(buf.length - TAG_LEN);\n const ct = buf.subarray(IV_LEN, buf.length - TAG_LEN);\n const d = createDecipheriv(ALGO, key, iv);\n d.setAuthTag(tag);\n const result = d.update(ct, undefined, \"utf-8\") + d.final(\"utf-8\");\n return result === VERIFY_PLAINTEXT;\n } catch { return false; }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/cli/deploy-lib/reconcile.ts"],
4
- "sourcesContent": ["/**\n * reconcile.ts \u2014 Guarantee correct runtime tree after deploy/restore.\n * OVERWRITE: source-controlled dirs (always replaced from templates).\n * SEED: user-owned files (created if missing, never overwritten).\n */\n\nimport { existsSync, mkdirSync, rmSync, cpSync, copyFileSync, readdirSync, statSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join, dirname, relative } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { logInfo } from \"../../components/logger.js\";\n\nconst TAG = \"reconcile\";\n\n/** Dirs under templates/ that are always overwritten (source-controlled). */\nconst OVERWRITE: string[][] = [\n [\"skills\"], // templates/skills/ \u2192 ~/.abtars/skills/core/\n [\"prompts\"], // templates/prompts/ \u2192 ~/.abtars/prompts/\n];\n\n/** Dirs under templates/ that are seeded file-by-file (skip existing). */\nconst SEED = [\"config\", \"tasks\"];\n\n/** Legacy paths to remove (one-time cleanup, idempotent). */\nconst LEGACY_CLEANUP = [\"core/prompts\", \"core\"];\n\n/**\n * Reconcile runtime tree from templates source.\n * @param templatesSrc - Path to templates/ (from deployed release or source checkout)\n * @param home - Path to ~/.abtars/\n */\nexport function reconcile(templatesSrc: string, home: string): void {\n if (!existsSync(templatesSrc)) {\n // Fallback: try source checkout\n const fallback = join(homedir(), \".abtars-releases\", \"src\", \"abtars\", \"templates\");\n if (existsSync(fallback)) {\n return reconcile(fallback, home);\n }\n logInfo(TAG, `Templates not found at ${templatesSrc} \u2014 skipping`);\n return;\n }\n\n // --- OVERWRITE: source-controlled dirs ---\n for (const parts of OVERWRITE) {\n const src = join(templatesSrc, ...parts);\n // skills \u2192 ~/.abtars/skills/core/ (preserve custom/, self/)\n // prompts \u2192 ~/.abtars/prompts/\n const dst = parts[0] === \"skills\"\n ? join(home, \"skills\", \"core\")\n : join(home, ...parts);\n if (!existsSync(src)) continue;\n rmSync(dst, { recursive: true, force: true });\n mkdirSync(dirname(dst), { recursive: true });\n cpSync(src, dst, { recursive: true });\n }\n logInfo(TAG, \"Overwrite: skills/core, prompts\");\n\n // --- SEED: user-owned files (create if missing) ---\n let seeded = 0;\n for (const dir of SEED) {\n const src = join(templatesSrc, dir);\n if (!existsSync(src)) continue;\n for (const f of walkFiles(src)) {\n const rel = relative(src, f);\n const dst = join(home, dir, rel);\n if (existsSync(dst)) continue;\n mkdirSync(dirname(dst), { recursive: true });\n copyFileSync(f, dst);\n seeded++;\n }\n }\n if (seeded > 0) logInfo(TAG, `Seeded ${seeded} missing config/task file(s)`);\n\n // --- Legacy cleanup (remove old paths, idempotent) ---\n for (const rel of LEGACY_CLEANUP) {\n const p = join(home, rel);\n if (!existsSync(p)) continue;\n rmSync(p, { recursive: true, force: true });\n logInfo(TAG, `Removed legacy: ${rel}`);\n }\n}\n\n/** Recursively list all files under a directory. */\nfunction walkFiles(dir: string): string[] {\n const results: string[] = [];\n for (const entry of readdirSync(dir)) {\n const full = join(dir, entry);\n if (statSync(full).isDirectory()) results.push(...walkFiles(full));\n else results.push(full);\n }\n return results;\n}\n\n/** Config format migrations (idempotent). */\nexport function migrate(home: string): void {\n // #1185: move ~/.abtars/lib/ \u2192 ~/.abtars-releases/deps/\n const oldLib = join(home, \"lib\");\n if (existsSync(join(oldLib, \"node_modules\"))) {\n const { homedir } = require(\"node:os\");\n const newDeps = join(homedir(), \".abtars-releases\", \"deps\");\n if (!existsSync(newDeps)) {\n const { renameSync } = require(\"node:fs\");\n renameSync(oldLib, newDeps);\n logInfo(TAG, \"Migrated: ~/.abtars/lib/ \u2192 ~/.abtars-releases/deps/\");\n } else {\n rmSync(oldLib, { recursive: true, force: true });\n logInfo(TAG, \"Removed: ~/.abtars/lib/ (deps already at new location)\");\n }\n }\n\n // irc-secure-to-signed: rename \"secure\" \u2192 \"signed\" in irc.json\n const ircPath = join(home, \"config\", \"irc.json\");\n if (existsSync(ircPath)) {\n const content = readFileSync(ircPath, \"utf-8\");\n if (content.includes('\"secure\"')) {\n writeFileSync(ircPath, content.replace(/\"secure\"/g, '\"signed\"'));\n logInfo(TAG, \"Migrated: irc-secure-to-signed\");\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["homedir"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/cli/commands/doctor-probes.ts"],
4
- "sourcesContent": ["/**\n * doctor-probes.ts \u2014 structured health probes grouped by subsystem layer.\n * Replaces scripts/doctor.sh entirely.\n */\n\nimport { existsSync, readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { abtarsHome } from \"../../paths.js\";\n\n// \u2500\u2500 Types \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\u2500\u2500\u2500\u2500\n\nexport interface ProbeResult {\n name: string;\n status: \"ok\" | \"failed\" | \"skipped\";\n detail?: string;\n ms?: number;\n}\n\nexport interface FixResult {\n probe: string;\n action: string;\n success: boolean;\n}\n\nexport type LayerName = \"body\" | \"heart\" | \"brain\" | \"soul\" | \"tribe\";\n\nexport interface DoctorOutput {\n version: \"1.0\";\n totalMs: number;\n layers: Record<LayerName, ProbeResult[]>;\n fixes?: FixResult[];\n}\n\n// \u2500\u2500 Helpers \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\u2500\u2500\n\nconst home = abtarsHome();\nconst configDir = join(home, \"config\");\n\nfunction readJson(path: string): any | null {\n try { return JSON.parse(readFileSync(path, \"utf-8\")); } catch { return null; }\n}\n\nfunction readEnv(): Map<string, string> {\n const envPath = join(configDir, \".env\");\n const map = new Map<string, string>();\n if (!existsSync(envPath)) return map;\n for (const line of readFileSync(envPath, \"utf-8\").split(\"\\n\")) {\n const m = line.match(/^([A-Z_]+)=(.*)$/);\n if (m) map.set(m[1]!, m[2]!.replace(/^[\"']|[\"']$/g, \"\"));\n }\n return map;\n}\n\nfunction pidAlive(pid: number): boolean {\n try { process.kill(pid, 0); return true; } catch { return false; }\n}\n\nfunction ago(ms: number): string {\n const s = Math.round(ms / 1000);\n if (s < 60) return `${s}s ago`;\n return `${Math.round(s / 60)}m ago`;\n}\n\nasync function timedProbe(fn: () => Promise<ProbeResult>): Promise<ProbeResult> {\n const start = Date.now();\n try {\n const r = await fn();\n r.ms = r.ms ?? (Date.now() - start);\n return r;\n } catch (err) {\n return { name: \"unknown\", status: \"failed\", detail: String(err), ms: Date.now() - start };\n }\n}\n\n// \u2500\u2500 Body Probes \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\nasync function probePlatforms(): Promise<ProbeResult> {\n const env = readEnv();\n const parts: string[] = [];\n if (env.get(\"TELEGRAM_BOT_TOKEN\") || env.get(\"TELEGRAM_TOKEN\")) parts.push(\"telegram\");\n if (env.get(\"DISCORD_TOKEN\") || env.get(\"DISCORD_BOT_TOKEN\")) parts.push(\"discord\");\n if (env.get(\"IRC_SERVER\")) parts.push(\"irc\");\n\n if (parts.length === 0) return { name: \"platforms\", status: \"failed\", detail: \"no platform configured\" };\n\n // Check bridge.lock for running status\n const lock = readJson(join(home, \"bridge.lock\"));\n if (lock?.pid && pidAlive(lock.pid)) {\n return { name: \"platforms\", status: \"ok\", detail: parts.map(p => `${p} \u2713`).join(\", \") };\n }\n return { name: \"platforms\", status: \"ok\", detail: `configured: ${parts.join(\", \")} (bridge not running)` };\n}\n\nasync function probeDashboard(): Promise<ProbeResult> {\n const env = readEnv();\n if (env.get(\"ENABLE_DASHBOARD\") !== \"true\") return { name: \"dashboard\", status: \"skipped\", detail: \"not enabled\" };\n const port = env.get(\"DASHBOARD_PORT\") || env.get(\"WEB_PORT\") || \"3000\";\n try {\n const res = await fetch(`http://127.0.0.1:${port}/`, { signal: AbortSignal.timeout(3000) });\n return { name: \"dashboard\", status: res.ok ? \"ok\" : \"failed\", detail: `:${port}` };\n } catch {\n return { name: \"dashboard\", status: \"failed\", detail: `:${port} unreachable` };\n }\n}\n\nasync function probeSecurity(): Promise<ProbeResult> {\n const env = readEnv();\n const mode = env.get(\"SECURITY_MODE\") || \"off\";\n const validModes = [\"off\", \"guardrails\", \"seatbelt\", \"docker\"];\n if (!validModes.includes(mode)) return { name: \"security\", status: \"failed\", detail: `invalid mode: ${mode}` };\n\n // Check secret file perms\n const secretDir = join(home, \"secret\");\n let permIssues = 0;\n if (existsSync(secretDir)) {\n for (const f of readdirSync(secretDir)) {\n const st = statSync(join(secretDir, f));\n if (st.isFile() && (st.mode & 0o777) !== 0o600) permIssues++;\n }\n }\n\n const parts = [mode];\n if (existsSync(join(home, \"auth\", \"rules.json\"))) parts.push(\"ActionGate\");\n if (permIssues > 0) return { name: \"security\", status: \"failed\", detail: `${mode}, ${permIssues} file(s) not 600` };\n return { name: \"security\", status: \"ok\", detail: parts.join(\", \") };\n}\n\nasync function probeWatchdog(): Promise<ProbeResult> {\n const lock = readJson(join(home, \"bridge.lock\"));\n if (!lock) return { name: \"watchdog\", status: \"failed\", detail: \"bridge.lock missing\" };\n\n const bridgePid = lock.pid ?? 0;\n const wdPid = lock.watchdogPid ?? 0;\n const bridgeAlive = bridgePid > 0 && pidAlive(bridgePid);\n const wdAlive = wdPid > 0 && pidAlive(wdPid);\n\n if (bridgeAlive && wdAlive) return { name: \"watchdog\", status: \"ok\", detail: `bridge:${bridgePid}, wd:${wdPid}` };\n if (!bridgeAlive && !wdAlive) return { name: \"watchdog\", status: \"failed\", detail: `bridge:${bridgePid} dead, wd:${wdPid} dead` };\n if (!wdAlive) return { name: \"watchdog\", status: \"failed\", detail: `bridge:${bridgePid} alive, wd:${wdPid} dead (unprotected)` };\n return { name: \"watchdog\", status: \"failed\", detail: `bridge:${bridgePid} dead, wd:${wdPid} alive (will restart)` };\n}\n\n// \u2500\u2500 Heart Probes \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\nasync function probeHeartbeat(): Promise<ProbeResult> {\n const lock = readJson(join(home, \"bridge.lock\"));\n if (!lock?.lastHeartbeat) return { name: \"heartbeat\", status: \"skipped\", detail: \"no bridge.lock\" };\n const ageMs = Date.now() - lock.lastHeartbeat;\n if (ageMs > 120_000) return { name: \"heartbeat\", status: \"failed\", detail: `stale (${ago(ageMs)})` };\n return { name: \"heartbeat\", status: \"ok\", detail: ago(ageMs) };\n}\n\n// \u2500\u2500 Brain Probes \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\nasync function probeTransport(): Promise<ProbeResult> {\n const tPath = join(configDir, \"transport.json\");\n const t = readJson(tPath);\n if (!t) return { name: \"transport\", status: \"failed\", detail: \"transport.json missing or invalid\" };\n const agents = Object.keys(t.agents ?? {});\n if (agents.length === 0) return { name: \"transport\", status: \"failed\", detail: \"no agents configured\" };\n return { name: \"transport\", status: \"ok\", detail: `${agents.length} agent(s): ${agents.join(\", \")}` };\n}\n\nasync function probeSpin(): Promise<ProbeResult> {\n const lock = readJson(join(home, \"bridge.lock\"));\n if (!lock?.pid || !pidAlive(lock.pid)) return { name: \"spin\", status: \"failed\", detail: \"bridge not running\" };\n return { name: \"spin\", status: \"ok\", detail: \"bridge alive\" };\n}\n\nasync function probeKanban(): Promise<ProbeResult> {\n const dbPath = join(home, \"kanban\", \"kanban.db\");\n if (!existsSync(dbPath)) return { name: \"kanban\", status: \"skipped\", detail: \"kanban.db not found\" };\n try {\n const Db = require(\"better-sqlite3\");\n const db = new Db(dbPath, { readonly: true });\n const row = db.prepare(\"SELECT COUNT(*) as cnt FROM cards\").get() as { cnt: number };\n const stuck = db.prepare(\"SELECT COUNT(*) as cnt FROM cards WHERE status='running' AND updated_at < datetime('now', '-10 minutes')\").get() as { cnt: number };\n db.close();\n const detail = stuck.cnt > 0 ? `${row.cnt} cards, ${stuck.cnt} stuck` : `${row.cnt} cards`;\n return { name: \"kanban\", status: stuck.cnt > 0 ? \"failed\" : \"ok\", detail };\n } catch {\n return { name: \"kanban\", status: \"skipped\", detail: \"better-sqlite3 not available\" };\n }\n}\n\nasync function probeSkills(): Promise<ProbeResult> {\n const catalog = join(home, \"skills\", \"skills_catalog.md\");\n if (!existsSync(catalog)) return { name: \"skills\", status: \"failed\", detail: \"skills_catalog.md missing\" };\n const content = readFileSync(catalog, \"utf-8\");\n const count = (content.match(/^## /gm) || []).length;\n if (count === 0) return { name: \"skills\", status: \"failed\", detail: \"catalog empty\" };\n return { name: \"skills\", status: \"ok\", detail: `${count} loaded` };\n}\n\nasync function probeSha(): Promise<ProbeResult> {\n // Check if healer skill exists in catalog\n const catalog = join(home, \"skills\", \"skills_catalog.md\");\n if (!existsSync(catalog)) return { name: \"sha\", status: \"skipped\", detail: \"no catalog\" };\n const content = readFileSync(catalog, \"utf-8\");\n if (/self.heal|healer|auto.fix/i.test(content)) return { name: \"sha\", status: \"ok\", detail: \"rules loaded\" };\n // Check sha-policy.json\n if (existsSync(join(configDir, \"sha-policy.json\"))) return { name: \"sha\", status: \"ok\", detail: \"rules loaded\" };\n return { name: \"sha\", status: \"skipped\", detail: \"no healer rules configured\" };\n}\n\n// \u2500\u2500 Tribe Probes \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\nasync function probeAgentApi(): Promise<ProbeResult> {\n const env = readEnv();\n if (env.get(\"ENABLE_AGENT_API\") !== \"true\") return { name: \"agent-api\", status: \"skipped\", detail: \"not enabled\" };\n const port = parseInt(env.get(\"AGENT_API_PORT\") || \"7100\", 10);\n try {\n const { createConnection } = await import(\"node:net\");\n await new Promise<void>((resolve, reject) => {\n const sock = createConnection({ port, host: \"127.0.0.1\" }, () => { sock.destroy(); resolve(); });\n sock.on(\"error\", reject);\n sock.setTimeout(2000, () => { sock.destroy(); reject(new Error(\"timeout\")); });\n });\n return { name: \"agent-api\", status: \"ok\", detail: `:${port}` };\n } catch {\n return { name: \"agent-api\", status: \"failed\", detail: `:${port} not listening` };\n }\n}\n\nasync function probePeers(): Promise<ProbeResult> {\n const peersPath = join(configDir, \"peers.json\");\n const peers = readJson(peersPath);\n if (!peers) return { name: \"peers\", status: \"skipped\", detail: \"peers.json missing\" };\n const peerCount = Object.keys(peers.peers ?? {}).length;\n if (peerCount === 0) return { name: \"peers\", status: \"ok\", detail: \"no peers configured\" };\n\n const lock = readJson(join(home, \"bridge.lock\"));\n const gossipAge = lock?.lastGossipBroadcast ? ago(Date.now() - lock.lastGossipBroadcast) : \"unknown\";\n return { name: \"peers\", status: \"ok\", detail: `${peerCount} configured, gossip: ${gossipAge}` };\n}\n\nasync function probeTls(): Promise<ProbeResult> {\n const env = readEnv();\n if (env.get(\"ENABLE_AGENT_API\") !== \"true\") return { name: \"tls\", status: \"skipped\", detail: \"agent-api disabled\" };\n const certExists = existsSync(join(configDir, \"identity.crt\"));\n const keyExists = existsSync(join(configDir, \"identity.tls.key\"));\n if (certExists && keyExists) return { name: \"tls\", status: \"ok\", detail: \"certs present\" };\n const missing = [!certExists && \"identity.crt\", !keyExists && \"identity.tls.key\"].filter(Boolean);\n return { name: \"tls\", status: \"failed\", detail: `missing: ${missing.join(\", \")}` };\n}\n\nasync function probeA2a(): Promise<ProbeResult> {\n const peersPath = join(configDir, \"peers.json\");\n const peers = readJson(peersPath);\n if (!peers?.self?.udpPort) return { name: \"a2a\", status: \"skipped\", detail: \"no gossip port configured\" };\n\n const port = peers.self.udpPort;\n try {\n const dgram = await import(\"node:dgram\");\n const { createHmac } = await import(\"node:crypto\");\n const key = peers.gossipSecret ?? Object.values(peers.peers ?? {})[0]?.token ?? \"default\";\n const payload = JSON.stringify({ type: \"ping\", name: \"__doctor__\" });\n const sig = createHmac(\"sha256\", key).update(payload).digest(\"base64url\").slice(0, 16);\n const ping = Buffer.from(`${payload}|${sig}`);\n\n const alive = await new Promise<boolean>((resolve) => {\n const sock = dgram.createSocket(\"udp4\");\n const timer = setTimeout(() => { sock.close(); resolve(false); }, 500);\n sock.on(\"message\", () => { clearTimeout(timer); sock.close(); resolve(true); });\n sock.on(\"error\", () => { clearTimeout(timer); sock.close(); resolve(false); });\n sock.send(ping, port, \"127.0.0.1\");\n });\n return { name: \"a2a\", status: alive ? \"ok\" : \"failed\", detail: alive ? `UDP :${port} alive` : `UDP :${port} no response` };\n } catch {\n return { name: \"a2a\", status: \"failed\", detail: \"UDP probe error\" };\n }\n}\n\n// \u2500\u2500 Soul Probes \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\nasync function probeMind(): Promise<ProbeResult> {\n try {\n const { spawnSync } = await import(\"node:child_process\");\n const r = spawnSync(\"abmind\", [\"doctor\", \"--json\"], { encoding: \"utf-8\", timeout: 10_000 });\n if (r.status === null || r.error) return { name: \"mind\", status: \"skipped\", detail: \"abmind not on PATH\" };\n const data = JSON.parse(r.stdout);\n const checks: Array<{ name: string; status: string }> = data.checks ?? [];\n const total = checks.length;\n const ok = checks.filter(c => c.status === \"ok\").length;\n const warnings = checks.filter(c => c.status === \"warn\" || c.status === \"error\");\n if (warnings.length === 0) return { name: \"mind\", status: \"ok\", detail: `abmind: ${ok}/${total} ok` };\n const names = warnings.slice(0, 3).map(w => w.name).join(\", \");\n return { name: \"mind\", status: \"failed\", detail: `abmind: ${ok}/${total} (${warnings.length} issues: ${names})` };\n } catch {\n return { name: \"mind\", status: \"skipped\", detail: \"abmind doctor failed\" };\n }\n}\n\n// \u2500\u2500 Runner \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\u2500\u2500\u2500\n\nexport async function runAllProbes(): Promise<DoctorOutput> {\n const start = Date.now();\n\n const [body, heart, brain, soul, tribe] = await Promise.all([\n Promise.all([probePlatforms(), probeDashboard(), probeSecurity(), probeWatchdog()].map(p => timedProbe(() => p))),\n Promise.all([probeHeartbeat()].map(p => timedProbe(() => p))),\n Promise.all([probeTransport(), probeSpin(), probeKanban(), probeSkills(), probeSha()].map(p => timedProbe(() => p))),\n Promise.all([probeMind()].map(p => timedProbe(() => p))),\n Promise.all([probeAgentApi(), probePeers(), probeTls(), probeA2a()].map(p => timedProbe(() => p))),\n ]);\n\n return { version: \"1.0\", totalMs: Date.now() - start, layers: { body, heart, brain, soul, tribe } };\n}\n\n// \u2500\u2500 Fix Logic \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\nexport async function runFixes(): Promise<FixResult[]> {\n const { chmodSync, unlinkSync, mkdirSync, existsSync: ex, readdirSync: rd, statSync: st, readFileSync: rf, writeFileSync: wf } = await import(\"node:fs\");\n const { execSync, spawnSync } = await import(\"node:child_process\");\n const fixes: FixResult[] = [];\n\n function fix(probe: string, action: string, fn: () => void): void {\n try { fn(); fixes.push({ probe, action, success: true }); }\n catch { fixes.push({ probe, action, success: false }); }\n }\n\n // 1. chmod 700 sensitive dirs\n for (const dir of [\"config\", \"secret\", \"auth\", \"hooks\"]) {\n const p = join(home, dir);\n if (ex(p) && (st(p).mode & 0o777) !== 0o700) {\n fix(\"security\", `${dir}/ \u2192 700`, () => chmodSync(p, 0o700));\n }\n }\n\n // 2. chmod 600 secret files\n const secretDir = join(home, \"secret\");\n if (ex(secretDir)) {\n for (const f of rd(secretDir)) {\n const fp = join(secretDir, f);\n if (st(fp).isFile() && (st(fp).mode & 0o777) !== 0o600) {\n fix(\"security\", `${f} \u2192 600`, () => chmodSync(fp, 0o600));\n }\n }\n }\n\n // 3. chmod 600 config files\n if (ex(configDir)) {\n for (const f of rd(configDir)) {\n const fp = join(configDir, f);\n if (st(fp).isFile() && (st(fp).mode & 0o777) !== 0o600) {\n fix(\"security\", `config/${f} \u2192 600`, () => chmodSync(fp, 0o600));\n }\n }\n }\n\n // 4. Stale deploy.lock\n const deployLock = join(home, \"deploy.lock\");\n if (ex(deployLock)) {\n const lock = readJson(deployLock);\n const lockAge = lock?.startedAt ? (Date.now() - new Date(lock.startedAt).getTime()) / 1000 : 9999;\n const lockPid = lock?.pid ?? 0;\n if (lockAge > 300 && (lockPid === 0 || !pidAlive(lockPid))) {\n fix(\"watchdog\", \"removed stale deploy.lock\", () => unlinkSync(deployLock));\n }\n }\n\n // 5. Stale .start-reason\n const startReason = join(home, \".start-reason\");\n if (ex(startReason)) {\n const age = (Date.now() - st(startReason).mtimeMs) / 1000;\n if (age > 300) fix(\"watchdog\", \"removed stale .start-reason\", () => unlinkSync(startReason));\n }\n\n // 6. Create missing dirs\n for (const dir of [\"logs\", \"workspace\", \"overflow\", \"received\"]) {\n const p = join(home, dir);\n if (!ex(p)) fix(\"watchdog\", `created ${dir}/`, () => mkdirSync(p, { recursive: true }));\n }\n\n // 7. Kill orphan CLI processes\n try {\n const lock = readJson(join(home, \"bridge.lock\"));\n const bridgePid = lock?.pid ?? 0;\n const wdPid = lock?.watchdogPid ?? 0;\n\n // Orphan kiro-cli\n const kiro = spawnSync(\"pgrep\", [\"-f\", \"kiro-cli.*acp\"], { encoding: \"utf-8\" });\n if (kiro.stdout) {\n for (const pid of kiro.stdout.trim().split(\"\\n\").filter(Boolean).map(Number)) {\n if (pid > 0 && pid !== bridgePid && pid !== wdPid && pid !== process.pid) {\n fix(\"brain\", `killed orphan kiro-cli ${pid}`, () => process.kill(pid, \"SIGTERM\"));\n }\n }\n }\n\n // Orphan abtars-sleep\n const sleep = spawnSync(\"pgrep\", [\"-f\", \"abtars-sleep\"], { encoding: \"utf-8\" });\n if (sleep.stdout) {\n for (const pid of sleep.stdout.trim().split(\"\\n\").filter(Boolean).map(Number)) {\n if (pid > 0 && pid !== bridgePid) {\n fix(\"brain\", `killed orphan abtars-sleep ${pid}`, () => process.kill(pid, \"SIGTERM\"));\n }\n }\n }\n } catch { /* pgrep not available or no orphans */ }\n\n // 8. Stale locks/sockets\n for (const f of [\"sleep.lock\", \"memory.sock\"]) {\n const p = join(home, f);\n if (ex(p)) {\n const age = (Date.now() - st(p).mtimeMs) / 1000;\n const lock = readJson(join(home, \"bridge.lock\"));\n if (age > 600 && (!lock?.pid || !pidAlive(lock.pid))) {\n fix(\"watchdog\", `removed stale ${f}`, () => unlinkSync(p));\n }\n }\n }\n\n // 9. Retention: delete old logs/overflow/media\n const LOGS_KEEP_DAYS = 7;\n const DATA_KEEP_DAYS = 30;\n try {\n const cutoffLogs = Date.now() - LOGS_KEEP_DAYS * 86400_000;\n const cutoffData = Date.now() - DATA_KEEP_DAYS * 86400_000;\n\n for (const [dir, cutoff] of [[join(home, \"logs\"), cutoffLogs], [join(home, \"overflow\"), cutoffData], [join(home, \"received\", \"media\"), cutoffLogs]] as const) {\n if (!ex(dir)) continue;\n let deleted = 0;\n for (const f of rd(dir)) {\n const fp = join(dir, f);\n if (st(fp).isFile() && st(fp).mtimeMs < cutoff) { unlinkSync(fp); deleted++; }\n }\n if (deleted > 0) fixes.push({ probe: \"retention\", action: `deleted ${deleted} stale file(s) from ${dir.split(\"/\").pop()}`, success: true });\n }\n\n // Truncate audit.jsonl if >10MB\n const auditPath = join(home, \"auth\", \"audit.jsonl\");\n if (ex(auditPath) && st(auditPath).size > 10_000_000) {\n const lines = rf(auditPath, \"utf-8\").split(\"\\n\");\n wf(auditPath, lines.slice(-1000).join(\"\\n\"));\n fixes.push({ probe: \"retention\", action: \"truncated audit.jsonl\", success: true });\n }\n } catch { /* retention errors non-fatal */ }\n\n // 10. Kill duplicate bridges\n try {\n const lock = readJson(join(home, \"bridge.lock\"));\n const expectedPid = lock?.pid ?? 0;\n const pgrep = spawnSync(\"pgrep\", [\"-f\", \"abtars.*main\"], { encoding: \"utf-8\" });\n if (pgrep.stdout) {\n for (const pid of pgrep.stdout.trim().split(\"\\n\").filter(Boolean).map(Number)) {\n if (pid > 0 && pid !== expectedPid && pid !== process.pid) {\n fix(\"watchdog\", `killed duplicate bridge ${pid}`, () => process.kill(pid, \"SIGTERM\"));\n }\n }\n }\n } catch { /* non-fatal */ }\n\n // 11. Hooks dir perms\n const hooksDir = join(home, \"hooks\");\n if (ex(hooksDir) && (st(hooksDir).mode & 0o777) !== 0o700) {\n fix(\"security\", \"hooks/ \u2192 700\", () => chmodSync(hooksDir, 0o700));\n }\n\n // 12. Install watchdog service if missing\n try {\n const manifest = readJson(join(home, \"manifest.json\"));\n if (manifest?.installMode === \"daemon\") {\n const { platform } = await import(\"node:os\");\n if (platform() === \"darwin\") {\n const plist = `${home}/com.abtars.watchdog.plist`;\n const dst = `${process.env[\"HOME\"]}/Library/LaunchAgents/com.abtars.watchdog.plist`;\n if (ex(plist) && !ex(dst)) {\n fix(\"watchdog\", \"installed LaunchAgent\", () => {\n const { copyFileSync } = require(\"node:fs\");\n copyFileSync(plist, dst);\n spawnSync(\"launchctl\", [\"load\", dst]);\n });\n }\n } else {\n const svc = `${home}/abtars-watchdog.service`;\n const dst = `${process.env[\"HOME\"]}/.config/systemd/user/abtars-watchdog.service`;\n if (ex(svc) && !ex(dst)) {\n fix(\"watchdog\", \"installed systemd unit\", () => {\n mkdirSync(join(process.env[\"HOME\"]!, \".config\", \"systemd\", \"user\"), { recursive: true });\n const { copyFileSync } = require(\"node:fs\");\n copyFileSync(svc, dst);\n spawnSync(\"systemctl\", [\"--user\", \"enable\", \"--now\", \"abtars-watchdog.service\"]);\n });\n }\n }\n }\n } catch { /* non-fatal */ }\n\n return fixes;\n}\n\n// \u2500\u2500 Renderer \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\u2500\n\nconst ICON = { ok: \"\u2713\", failed: \"\u2717\", skipped: \"~\" } as const;\n\nexport function renderHuman(output: DoctorOutput): string {\n const lines: string[] = [];\n for (const [layer, probes] of Object.entries(output.layers) as [string, ProbeResult[]][]) {\n lines.push(`${layer.charAt(0).toUpperCase() + layer.slice(1)}:`);\n for (const p of probes) {\n const ms = p.ms && p.ms > 500 ? ` (${p.ms}ms)` : \"\";\n const detail = p.detail ? ` \u2014 ${p.detail}` : \"\";\n lines.push(` ${ICON[p.status]} ${p.name}${ms}${detail}`);\n }\n }\n const total = Object.values(output.layers).flat();\n const okCount = total.filter(r => r.status === \"ok\").length;\n lines.push(`\\n${okCount}/${total.length} ok (${(output.totalMs / 1000).toFixed(1)}s)`);\n return lines.join(\"\\n\");\n}\n\nexport function renderJson(output: DoctorOutput): string {\n return JSON.stringify(output, null, 2);\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\";\n\n// better-sqlite3 is external (native module, available at runtime via abmind)\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;\n\nfunction db(): SqliteDb {\n if (!_db) {\n const dir = join(abtarsHome(), \"kanban\");\n mkdirSync(dir, { recursive: true });\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n let Database: any;\n try {\n Database = require(\"better-sqlite3\");\n } catch {\n // Self-heal: attempt native rebuild (#1185)\n try {\n const { execSync } = require(\"node:child_process\");\n const modPath = require.resolve(\"better-sqlite3/package.json\").replace(\"/package.json\", \"\");\n execSync(\"npx --yes node-gyp rebuild\", { cwd: modPath, timeout: 60_000, stdio: \"pipe\" });\n Database = require(\"better-sqlite3\");\n } catch (e) {\n throw new Error(`better-sqlite3 not available and rebuild failed: ${e instanceof Error ? e.message : e}`);\n }\n }\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 }\n return _db;\n}\n\nimport { nerve } from \"../nerve.js\";\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 deliveryMode = opts?.deliveryMode ?? \"deliver\";\n const stmt = db().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 db().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 db().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 db().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 card = db().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 db().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 return db().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 db().prepare(`UPDATE kanban_board SET status = 'delivering', updated_at = datetime('now') WHERE id = ?`).run(id);\n}\n\nexport function kanbanMarkDelivered(id: number): void {\n db().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 card = db().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 db().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 db().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 if (filter === \"*\") {\n return db().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 // LIKE match for comma-separated labels\n return db().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 db().prepare(`SELECT * FROM kanban_board WHERE ${filterKey} = ? ORDER BY created_at DESC LIMIT 50`).all(filter) as KanbanCard[];\n }\n }\n if (filter) {\n // Bare word = status filter\n return db().prepare(`SELECT * FROM kanban_board WHERE status = ? ORDER BY created_at DESC LIMIT 50`).all(filter) as KanbanCard[];\n }\n return db().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 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 db().prepare(`UPDATE kanban_board SET ${sets.join(\", \")} WHERE id = ?`).run(...vals);\n}\n\nexport function kanbanCleanup(olderThanDays = 7): number {\n const result = db().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 return db().prepare(`SELECT * FROM kanban_board WHERE id = ?`).get(id) as KanbanCard | undefined;\n}\n\nexport function kanbanGetChildren(parentId: number): KanbanCard[] {\n return db().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 db().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 db().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 db().prepare(`UPDATE kanban_board SET progress = ?, updated_at = datetime('now') WHERE id = ?`).run(JSON.stringify(pending), id);\n _progressPending.delete(id);\n }\n }, 30_000));\n}\n\n// \u2500\u2500 DAG orchestration (#677) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Check if all dependencies of a card are satisfied. */\nexport function isUnblocked(card: KanbanCard): boolean {\n if (!card.blocked_by) return true;\n if (card.blocked_by === \"children\") {\n const kids = kanbanGetChildren(card.id);\n return kids.length > 0 && kids.every(k => k.status === \"done\" || k.status === \"delivered\");\n }\n const depIds = card.blocked_by.split(\",\").map(Number).filter(n => !isNaN(n));\n if (depIds.length === 0) return true;\n return depIds.every(id => {\n const dep = kanbanGetCard(id);\n return dep?.status === \"done\" || dep?.status === \"delivered\";\n });\n}\n\n/** Cascade-fail all cards depending (transitively) on a failed card. */\nexport function cascadeFail(failedId: number, projectCards: KanbanCard[]): void {\n for (const card of projectCards) {\n if (card.status !== \"queued\") continue;\n if (!card.blocked_by) continue;\n const deps = card.blocked_by.split(\",\").map(Number).filter(n => !isNaN(n));\n if (deps.includes(failedId)) {\n kanbanFail(card.id, `upstream #${failedId} failed`);\n cascadeFail(card.id, projectCards);\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/components/tasks/kanban-channel.ts"],
4
- "sourcesContent": ["/**\n * kanban-channel.ts \u2014 Agent Communication Platform (#891 Phase 1).\n * Card-scoped messaging for workers, Orc, and master.\n * Same DB as kanban-board (kanban.db).\n */\n\nimport { join } from \"node:path\";\nimport { mkdirSync } from \"node:fs\";\nimport { abtarsHome } from \"../../paths.js\";\nimport { nerve } from \"../nerve.js\";\nimport { logInfo, logWarn } from \"../logger.js\";\n\ntype SqliteDb = { prepare(sql: string): any; exec(sql: string): void; pragma(s: string): void };\n\nlet _db: SqliteDb | null = null;\n\nfunction db(): SqliteDb {\n if (!_db) {\n const dir = join(abtarsHome(), \"kanban\");\n mkdirSync(dir, { recursive: true });\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const Database = require(\"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 agent_channel (\n id INTEGER PRIMARY KEY,\n card_id INTEGER NOT NULL,\n from_agent TEXT NOT NULL,\n to_agent TEXT DEFAULT 'ALL',\n message TEXT NOT NULL,\n directive INTEGER DEFAULT 0,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n last_seen_by TEXT DEFAULT ''\n )`);\n _db.exec(`CREATE INDEX IF NOT EXISTS idx_ac_card ON agent_channel(card_id, created_at)`);\n _db.exec(`CREATE INDEX IF NOT EXISTS idx_ac_to ON agent_channel(card_id, to_agent)`);\n // #949: remote sync columns\n try { _db.exec(`ALTER TABLE agent_channel ADD COLUMN remote_peer TEXT DEFAULT NULL`); } catch { /* already exists */ }\n try { _db.exec(`ALTER TABLE agent_channel ADD COLUMN synced INTEGER DEFAULT 1`); } catch { /* already exists */ }\n try { _db.exec(`ALTER TABLE agent_channel ADD COLUMN msg_type TEXT DEFAULT 'progress'`); } catch { /* already exists */ }\n // #949: dedup index only enforced via INSERT OR IGNORE in channelPostFromRemote\n try { _db.exec(`CREATE INDEX IF NOT EXISTS idx_ac_dedup ON agent_channel(card_id, from_agent, created_at)`); } catch { /* already exists */ }\n }\n return _db;\n}\n\nexport interface ChannelMessage {\n id: number;\n card_id: number;\n from_agent: string;\n to_agent: string;\n message: string;\n directive: number;\n created_at: string;\n remote_peer: string | null;\n msg_type: string;\n}\n\nconst MAX_MESSAGE_LEN = 1000;\n\nexport function channelPost(cardId: number, from: string, to: string, message: string, directive = false, msgType = \"progress\"): number {\n if (message.length > MAX_MESSAGE_LEN) message = message.slice(0, MAX_MESSAGE_LEN) + \"\u2026\";\n const stmt = db().prepare(\"INSERT INTO agent_channel (card_id, from_agent, to_agent, message, directive, msg_type) VALUES (?, ?, ?, ?, ?, ?)\");\n const result = stmt.run(cardId, from, to || \"ALL\", message, directive ? 1 : 0, msgType);\n nerve.fire(\"channel:message\", cardId, { from, to: to || \"ALL\", message });\n logInfo(\"channel\", `[${from}\u2192${to || \"ALL\"}] card:${cardId} (${message.length} chars${directive ? \", directive\" : \"\"})`);\n return result.lastInsertRowid as number;\n}\n\nexport function channelRead(cardId: number, opts?: { since?: string; from?: string }): ChannelMessage[] {\n let sql = \"SELECT id, card_id, from_agent, to_agent, message, directive, created_at, remote_peer, msg_type FROM agent_channel WHERE card_id = ?\";\n const params: any[] = [cardId];\n if (opts?.since) { sql += \" AND created_at > ?\"; params.push(opts.since); }\n if (opts?.from) { sql += \" AND from_agent = ?\"; params.push(opts.from); }\n sql += \" ORDER BY created_at ASC\";\n return db().prepare(sql).all(...params) as ChannelMessage[];\n}\n\n/** Get unread messages for an agent (for auto-inject). Marks as seen. */\nexport function channelUnread(cardId: number, agentName: string): ChannelMessage[] {\n const sql = `SELECT id, card_id, from_agent, to_agent, message, directive, created_at \n FROM agent_channel \n WHERE card_id = ? AND to_agent IN ('ALL', ?) AND last_seen_by NOT LIKE ?\n ORDER BY directive DESC, created_at DESC LIMIT 10`;\n const rows = db().prepare(sql).all(cardId, agentName, `%${agentName}%`) as ChannelMessage[];\n\n // Mark as seen\n if (rows.length > 0) {\n const markStmt = db().prepare(\"UPDATE agent_channel SET last_seen_by = last_seen_by || ? WHERE id = ?\");\n for (const row of rows) markStmt.run(`${agentName},`, row.id);\n }\n return rows;\n}\n\n/** GC: delete messages for completed/archived cards. */\nexport function channelGc(completedCardIds: number[]): number {\n if (completedCardIds.length === 0) return 0;\n const placeholders = completedCardIds.map(() => \"?\").join(\",\");\n const result = db().prepare(`DELETE FROM agent_channel WHERE card_id IN (${placeholders})`).run(...completedCardIds);\n return result.changes as number;\n}\n\n/** GC: age + row cap enforcement. Only targets non-active cards. */\nexport function channelRetentionGc(activeCardIds: number[]): number {\n const activeSet = activeCardIds.length ? activeCardIds.map(() => \"?\").join(\",\") : \"0\";\n // Age: 3 days, skip active\n const aged = db().prepare(`DELETE FROM agent_channel WHERE created_at < datetime('now', '-3 days') AND card_id NOT IN (${activeSet})`).run(...activeCardIds);\n // Row cap: keep under 1000\n const count = (db().prepare(\"SELECT count(*) as c FROM agent_channel\").get() as any).c;\n let capped = 0;\n if (count > 1000) {\n const excess = count - 800;\n capped = (db().prepare(`DELETE FROM agent_channel WHERE id IN (SELECT id FROM agent_channel WHERE card_id NOT IN (${activeSet}) ORDER BY created_at ASC LIMIT ?)`).run(...activeCardIds, excess)).changes as number;\n }\n return (aged.changes as number) + capped;\n}\n\n/** #949: Insert a message pushed from a remote peer. Dedup via existence check. */\nexport function channelPostFromRemote(cardId: number, from: string, message: string, createdAt: string, peer: string): boolean {\n if (message.length > MAX_MESSAGE_LEN) message = message.slice(0, MAX_MESSAGE_LEN) + \"\u2026\";\n try {\n const exists = db().prepare(\"SELECT 1 FROM agent_channel WHERE card_id = ? AND from_agent = ? AND created_at = ?\").get(cardId, from, createdAt);\n if (exists) return true; // already have it\n db().prepare(\"INSERT INTO agent_channel (card_id, from_agent, to_agent, message, created_at, remote_peer, synced) VALUES (?, ?, 'ALL', ?, ?, ?, 1)\")\n .run(cardId, from, message, createdAt, peer);\n nerve.fire(\"channel:message\", cardId, { from, to: \"ALL\", message });\n return true;\n } catch { return false; }\n}\n\n/** #949: Get messages since a given timestamp (for pull catch-up). */\nexport function channelGetSince(cardId: number, since: string): ChannelMessage[] {\n return db().prepare(\"SELECT id, card_id, from_agent, to_agent, message, directive, created_at FROM agent_channel WHERE card_id = ? AND created_at > ? ORDER BY created_at ASC\")\n .all(cardId, since) as ChannelMessage[];\n}\n\n/** #949: Push channel messages to remote Orc when card has source_peer. */\nexport function initChannelSync(): void {\n nerve.on(\"channel:message\", (cardId: number, meta?: { from: string; to: string; message: string }) => {\n if (!meta) return;\n // Lazy import to avoid circular deps\n const { kanbanGetCard } = require(\"./kanban-board.js\") as typeof import(\"./kanban-board.js\");\n const card = kanbanGetCard(cardId);\n if (!card?.source_peer) return;\n // Don't push messages that came from remote (avoid echo loop)\n const lastRow = db().prepare(\"SELECT remote_peer FROM agent_channel WHERE card_id = ? ORDER BY id DESC LIMIT 1\").get(cardId) as { remote_peer: string | null } | undefined;\n if (lastRow?.remote_peer) return;\n // Push to source peer\n pushToRemote(card.source_peer, cardId, meta.from, meta.message).catch(err =>\n logWarn(\"channel-sync\", `Push to ${card.source_peer} failed: ${err instanceof Error ? err.message : String(err)}`)\n );\n });\n}\n\nasync function pushToRemote(peer: string, cardId: number, from: string, message: string): Promise<void> {\n const { getPeerTransport } = await import(\"../peer-transport/index.js\");\n const transport = getPeerTransport();\n const createdAt = new Date().toISOString().replace(\"T\", \" \").slice(0, 19);\n await transport.pushChannelMessage(peer, cardId, from, message, createdAt);\n db().prepare(\"UPDATE agent_channel SET synced = 1 WHERE card_id = ? AND synced = 0\").run(cardId);\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/cli/commands/restart.ts"],
4
- "sourcesContent": ["import { printBanner } from './banner.js';\n/**\n * abtars restart [--cold] \u2014 unified restart command.\n * Warm (default): writeRestartRequested \u2192 main.ts internal loop restarts.\n * Cold (--cold): kill process, then start fresh.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { abtarsHome } from \"../../paths.js\";\nimport { logAndSwallow } from \"../../components/log-and-swallow.js\";\n\nfunction readJsonField(file: string, field: string): unknown {\n try { return JSON.parse(readFileSync(file, \"utf-8\"))[field]; } catch { return undefined; }\n}\n\nfunction pidAlive(pid: number): boolean {\n try { process.kill(pid, 0); return true; } catch { return false; }\n}\n\nasync function killBridge(pid: number): Promise<void> {\n try { process.kill(pid, \"SIGTERM\"); } catch { return; }\n process.stdout.write(`\uD83D\uDED1 Killing bridge (PID ${pid})...\\n`);\n for (let i = 0; i < 20; i++) {\n await new Promise(r => setTimeout(r, 500));\n if (!pidAlive(pid)) return;\n }\n try { process.kill(pid, \"SIGKILL\"); } catch (err) { logAndSwallow(\"restart\", \"op\", err); }\n await new Promise(r => setTimeout(r, 1000));\n}\n\nexport async function restart(opts: { cold?: boolean }): Promise<number> {\n await printBanner(\"restart\");\n const home = abtarsHome();\n const lockFile = join(home, \"bridge.lock\");\n const cold = opts.cold ?? false;\n\n const bridgePid = readJsonField(lockFile, \"pid\") as number | undefined;\n const bridgeAlive = bridgePid != null && bridgePid > 0 && pidAlive(bridgePid);\n\n if (cold) {\n if (bridgeAlive) await killBridge(bridgePid!);\n\n // Clear circuit breaker \u2014 intentional restart = clean slate\n try {\n const s = JSON.parse(readFileSync(join(home, \"deploy.state\"), \"utf-8\"));\n s.restartCount = 0;\n (await import(\"node:fs\")).writeFileSync(join(home, \"deploy.state\"), JSON.stringify(s) + \"\\n\");\n } catch {}\n\n // Start via the start command (handles both modes)\n const { start } = await import(\"./start.js\");\n return start();\n }\n\n // Warm restart\n if (bridgeAlive) {\n const { writeRestartRequested } = await import(\"../../components/transport/bridge-lock-transport.js\");\n writeRestartRequested(\"restart\");\n process.stdout.write(`\u267B\uFE0F Restart requested (PID ${bridgePid}) \u2014 bridge will restart within 30s\\n`);\n return 0;\n }\n\n process.stdout.write(\"Bridge not running. Use --cold to start fresh.\\n\");\n return 1;\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;AASA;AACA;AAHA,SAAqB,oBAAoB;AACzC,SAAS,YAAY;AAIrB,SAAS,cAAc,MAAc,OAAwB;AAC3D,MAAI;AAAE,WAAO,KAAK,MAAM,aAAa,MAAM,OAAO,CAAC,EAAE,KAAK;AAAA,EAAG,QAAQ;AAAE,WAAO;AAAA,EAAW;AAC3F;AAEA,SAAS,SAAS,KAAsB;AACtC,MAAI;AAAE,YAAQ,KAAK,KAAK,CAAC;AAAG,WAAO;AAAA,EAAM,QAAQ;AAAE,WAAO;AAAA,EAAO;AACnE;AAEA,eAAe,WAAW,KAA4B;AACpD,MAAI;AAAE,YAAQ,KAAK,KAAK,SAAS;AAAA,EAAG,QAAQ;AAAE;AAAA,EAAQ;AACtD,UAAQ,OAAO,MAAM,iCAA0B,GAAG;AAAA,CAAQ;AAC1D,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAM,IAAI,QAAQ,OAAK,WAAW,GAAG,GAAG,CAAC;AACzC,QAAI,CAAC,SAAS,GAAG,EAAG;AAAA,EACtB;AACA,MAAI;AAAE,YAAQ,KAAK,KAAK,SAAS;AAAA,EAAG,SAAS,KAAK;AAAE,kBAAc,WAAW,MAAM,GAAG;AAAA,EAAG;AACzF,QAAM,IAAI,QAAQ,OAAK,WAAW,GAAG,GAAI,CAAC;AAC5C;AAEA,eAAsB,QAAQ,MAA2C;AACvE,QAAM,YAAY,SAAS;AAC3B,QAAM,OAAO,WAAW;AACxB,QAAM,WAAW,KAAK,MAAM,aAAa;AACzC,QAAM,OAAO,KAAK,QAAQ;AAE1B,QAAM,YAAY,cAAc,UAAU,KAAK;AAC/C,QAAM,cAAc,aAAa,QAAQ,YAAY,KAAK,SAAS,SAAS;AAE5E,MAAI,MAAM;AACR,QAAI,YAAa,OAAM,WAAW,SAAU;AAG5C,QAAI;AACF,YAAM,IAAI,KAAK,MAAM,aAAa,KAAK,MAAM,cAAc,GAAG,OAAO,CAAC;AACtE,QAAE,eAAe;AACjB,OAAC,MAAM,OAAO,SAAS,GAAG,cAAc,KAAK,MAAM,cAAc,GAAG,KAAK,UAAU,CAAC,IAAI,IAAI;AAAA,IAC9F,QAAQ;AAAA,IAAC;AAGT,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO,qBAAY;AAC3C,WAAO,MAAM;AAAA,EACf;AAGA,MAAI,aAAa;AACf,UAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,qCAAqD;AACpG,0BAAsB,SAAS;AAC/B,YAAQ,OAAO,MAAM,uCAA6B,SAAS;AAAA,CAAsC;AACjG,WAAO;AAAA,EACT;AAEA,UAAQ,OAAO,MAAM,kDAAkD;AACvE,SAAO;AACT;",
6
- "names": []
7
- }