abtars 0.2.1-alpha.9 → 0.2.2

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 (309) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/README.md +93 -34
  3. package/bundle/{_registry.generated-ADOYFJJ4.js → _registry.generated-KYX63MGY.js} +19 -16
  4. package/bundle/{_registry.generated-ADOYFJJ4.js.map → _registry.generated-KYX63MGY.js.map} +1 -1
  5. package/bundle/abtars-browser.js +5 -6
  6. package/bundle/abtars-browser.js.map +2 -2
  7. package/bundle/abtars-cli.js +205 -179
  8. package/bundle/abtars-cli.js.map +4 -4
  9. package/bundle/abtars-restart.js +4 -4
  10. package/bundle/abtars-rss.js +25 -81
  11. package/bundle/abtars-rss.js.map +2 -2
  12. package/bundle/abtars-task.js +4 -5
  13. package/bundle/abtars-task.js.map +2 -2
  14. package/bundle/abtars-todo.js +133 -0
  15. package/bundle/abtars-todo.js.map +7 -0
  16. package/bundle/abtars.js +305 -182
  17. package/bundle/abtars.js.map +3 -3
  18. package/bundle/action-gate-DYV2XQBP.js +191 -0
  19. package/bundle/action-gate-DYV2XQBP.js.map +7 -0
  20. package/bundle/{agent-api-rate-limit-C25WGSFF.js → agent-api-rate-limit-R2OFAQ3N.js} +4 -4
  21. package/bundle/{agent-registry-SYUFNSVB.js → agent-registry-5VL5KI6U.js} +8 -8
  22. package/bundle/agent-registry-PIS5XJHX.js +19 -0
  23. package/bundle/{bridge-lock-transport-HO545SBK.js → bridge-lock-transport-N6OGDOSE.js} +5 -5
  24. package/bundle/{browse-delivery-VTLEAVYA.js → browse-delivery-DXGMDMXA.js} +8 -7
  25. package/bundle/{browser-REIXOJ6S.js → browser-QMYGSP5W.js} +11 -10
  26. package/bundle/{capability-ILW3D5HS.js → capability-733TLH4W.js} +6 -6
  27. package/bundle/chunk-3IPMKYYH.js +672 -0
  28. package/bundle/chunk-3IPMKYYH.js.map +7 -0
  29. package/bundle/{chunk-PZE3J7ER.js → chunk-3OXQWII3.js} +2 -2
  30. package/bundle/{chunk-X5FBUA53.js → chunk-4WKWPU6U.js} +137 -30
  31. package/bundle/chunk-4WKWPU6U.js.map +7 -0
  32. package/bundle/{chunk-4KJ76TTE.js → chunk-4XW7YA3K.js} +3 -3
  33. package/bundle/{chunk-A5OJYQNU.js → chunk-5WFIAUQC.js} +49 -22
  34. package/bundle/chunk-5WFIAUQC.js.map +7 -0
  35. package/bundle/{chunk-ZVDVNSXK.js → chunk-7WFE2JI5.js} +7 -7
  36. package/bundle/{chunk-R36WIOYX.js → chunk-B52YRWR6.js} +34 -6
  37. package/bundle/chunk-B52YRWR6.js.map +7 -0
  38. package/bundle/{chunk-Q62SXS73.js → chunk-BBDKU4EH.js} +9 -9
  39. package/bundle/chunk-BBTQKKDO.js +258 -0
  40. package/bundle/chunk-BBTQKKDO.js.map +7 -0
  41. package/bundle/{chunk-EX2SRTUE.js → chunk-CYSGXNBY.js} +2 -2
  42. package/bundle/{chunk-LYEAHE5V.js → chunk-DCY7DGMT.js} +2 -2
  43. package/bundle/chunk-DGS7J4P6.js +13 -0
  44. package/bundle/chunk-DGS7J4P6.js.map +7 -0
  45. package/bundle/{chunk-LDKSCXGL.js → chunk-DHPFI7OF.js} +8 -6
  46. package/bundle/{chunk-LDKSCXGL.js.map → chunk-DHPFI7OF.js.map} +1 -1
  47. package/bundle/{chunk-G6IXMYIO.js → chunk-DO4INSXE.js} +2 -2
  48. package/bundle/{chunk-VA5WKN3Z.js → chunk-EGA6JQVV.js} +4 -4
  49. package/bundle/chunk-EKHNWFEQ.js +85 -0
  50. package/bundle/chunk-EKHNWFEQ.js.map +7 -0
  51. package/bundle/{chunk-URAQLQ2U.js → chunk-F3HMZFIL.js} +4 -4
  52. package/bundle/{chunk-OOKLEC6V.js → chunk-FY3QUO2L.js} +7 -7
  53. package/bundle/{chunk-2BY6I4P5.js → chunk-GUTRAMK3.js} +2 -2
  54. package/bundle/chunk-GXKJKYU4.js +1089 -0
  55. package/bundle/chunk-GXKJKYU4.js.map +7 -0
  56. package/bundle/{chunk-GPL57SRN.js → chunk-H7RX7UCR.js} +3 -3
  57. package/bundle/{chunk-BYDUMHXT.js → chunk-HAF2AFBW.js} +2 -2
  58. package/bundle/chunk-HAS5NEK7.js +189 -0
  59. package/bundle/chunk-HAS5NEK7.js.map +7 -0
  60. package/bundle/chunk-HB54S5OY.js +4036 -0
  61. package/bundle/chunk-HB54S5OY.js.map +7 -0
  62. package/bundle/{chunk-OZ4IZFV4.js → chunk-HJQZP5CK.js} +9 -9
  63. package/bundle/{chunk-OZ4IZFV4.js.map → chunk-HJQZP5CK.js.map} +2 -2
  64. package/bundle/{chunk-HEHD3GG5.js → chunk-ITB2K6LI.js} +6 -13
  65. package/bundle/{chunk-HEHD3GG5.js.map → chunk-ITB2K6LI.js.map} +3 -3
  66. package/bundle/{chunk-KSEIWT4T.js → chunk-JFKOPNKL.js} +10 -10
  67. package/bundle/chunk-JFKOPNKL.js.map +7 -0
  68. package/bundle/{chunk-KFENC7BM.js → chunk-L33WNMCP.js} +2 -2
  69. package/bundle/{chunk-JRG4EFMP.js → chunk-LBMETTUP.js} +3 -3
  70. package/bundle/{chunk-TYVI3ZWA.js → chunk-LJAG2URA.js} +10 -7
  71. package/bundle/chunk-LJAG2URA.js.map +7 -0
  72. package/bundle/{chunk-KWBGYWDO.js → chunk-N24ROESF.js} +15 -17
  73. package/bundle/chunk-N24ROESF.js.map +7 -0
  74. package/bundle/{chunk-P2BZSLJJ.js → chunk-N7UG4FID.js} +448 -129
  75. package/bundle/chunk-N7UG4FID.js.map +7 -0
  76. package/bundle/chunk-NIYVCGBC.js +330 -0
  77. package/bundle/chunk-NIYVCGBC.js.map +7 -0
  78. package/bundle/{chunk-TOUZC6NR.js → chunk-OKMN6J4Z.js} +3 -3
  79. package/bundle/{chunk-RV54J75Q.js → chunk-PKHYCNTT.js} +13 -12
  80. package/bundle/chunk-PKHYCNTT.js.map +7 -0
  81. package/bundle/{chunk-XZSYMCLF.js → chunk-PUDGA4RR.js} +7 -7
  82. package/bundle/{chunk-CELR236Q.js → chunk-Q7CH5DA3.js} +2 -2
  83. package/bundle/chunk-QSC6QZ44.js +183 -0
  84. package/bundle/chunk-QSC6QZ44.js.map +7 -0
  85. package/bundle/chunk-RITEGAW6.js +138 -0
  86. package/bundle/chunk-RITEGAW6.js.map +7 -0
  87. package/bundle/{chunk-UDZIZB5F.js → chunk-RTL7HO3N.js} +3 -3
  88. package/bundle/{chunk-ITG6XGBS.js → chunk-SA44ITVX.js} +10 -10
  89. package/bundle/{chunk-3MO2MDXJ.js → chunk-SA6YEFNG.js} +3 -3
  90. package/bundle/{chunk-4BUOO6WI.js → chunk-SMZQDMSZ.js} +31 -11
  91. package/bundle/chunk-SMZQDMSZ.js.map +7 -0
  92. package/bundle/{chunk-GBBTK6H2.js → chunk-SRFEIZQT.js} +4 -4
  93. package/bundle/{chunk-ELRAH7VL.js → chunk-VXUVKC66.js} +3 -3
  94. package/bundle/chunk-VY2BUO6L.js +4035 -0
  95. package/bundle/chunk-VY2BUO6L.js.map +7 -0
  96. package/bundle/chunk-W6ELWLAR.js +143 -0
  97. package/bundle/chunk-W6ELWLAR.js.map +7 -0
  98. package/bundle/{chunk-RSWUPUNA.js → chunk-WMWI3SJ7.js} +30 -6
  99. package/bundle/chunk-WMWI3SJ7.js.map +7 -0
  100. package/bundle/{chunk-MJ6PHMOK.js → chunk-WW5F2DCO.js} +11 -2
  101. package/bundle/chunk-WW5F2DCO.js.map +7 -0
  102. package/bundle/chunk-Y2XBDQP3.js +4055 -0
  103. package/bundle/chunk-Y2XBDQP3.js.map +7 -0
  104. package/bundle/chunk-YMGX6HNP.js +131 -0
  105. package/bundle/chunk-YMGX6HNP.js.map +7 -0
  106. package/bundle/chunk-YWZPKBO6.js +22 -0
  107. package/bundle/chunk-YWZPKBO6.js.map +7 -0
  108. package/bundle/chunk-ZAA7B5BN.js +22 -0
  109. package/bundle/chunk-ZAA7B5BN.js.map +7 -0
  110. package/bundle/{commands-WUGPBPHI.js → commands-IGRSOSK6.js} +15 -14
  111. package/bundle/commands-LAWVNQTO.js +34 -0
  112. package/bundle/commands-RBWY7YXB.js +34 -0
  113. package/bundle/commands-XFZNMZN6.js +34 -0
  114. package/bundle/{config-DQIGDX4W.js → config-NDEYF4AQ.js} +7 -7
  115. package/bundle/{daemon-NPKYZ3CJ.js → daemon-WOQXCKNL.js} +4 -4
  116. package/bundle/{delegation-tools-6FICZQ5G.js → delegation-tools-Z5OM3TXS.js} +5 -5
  117. package/bundle/{deploy-lib-import-SBKXDD3F.js → deploy-lib-import-6VJTYXEG.js} +2 -2
  118. package/bundle/{deps-HN6CEXA4.js → deps-65V7XXG4.js} +4 -4
  119. package/bundle/{direct-api-transport-TRV45NO6.js → direct-api-transport-OZICXTWQ.js} +43 -15
  120. package/bundle/direct-api-transport-OZICXTWQ.js.map +7 -0
  121. package/bundle/direct-api-transport-QIWA5ES2.js +889 -0
  122. package/bundle/direct-api-transport-QIWA5ES2.js.map +7 -0
  123. package/bundle/{discord-adapter-WA2MFRK3.js → discord-adapter-JFIIVG34.js} +27 -24
  124. package/bundle/discord-adapter-JFIIVG34.js.map +7 -0
  125. package/bundle/discord-adapter-U3FA5OTY.js +589 -0
  126. package/bundle/discord-adapter-U3FA5OTY.js.map +7 -0
  127. package/bundle/discord-adapter-W6L5KJ6T.js +589 -0
  128. package/bundle/discord-adapter-W6L5KJ6T.js.map +7 -0
  129. package/bundle/discord-adapter-WWM6ROTW.js +589 -0
  130. package/bundle/discord-adapter-WWM6ROTW.js.map +7 -0
  131. package/bundle/{dns-wakeup-RYOCQ6GR.js → dns-wakeup-N46RPU5E.js} +3 -3
  132. package/bundle/{doctor-R54GZPKL.js → doctor-PIPSGI3H.js} +18 -7
  133. package/bundle/{doctor-R54GZPKL.js.map → doctor-PIPSGI3H.js.map} +2 -2
  134. package/bundle/{ensure-invariants-BJIEOSJ2.js → ensure-invariants-3NOBCYWS.js} +4 -4
  135. package/bundle/{env-schema-XCPAJ6IZ.js → env-schema-T43X43BU.js} +4 -4
  136. package/bundle/{hook-system-POI5VRIX.js → hook-system-ZCVOFFRD.js} +4 -4
  137. package/bundle/hotskills-DTROJY6G.js +17 -0
  138. package/bundle/{install-SH4UVUXQ.js → install-I3CXVW52.js} +3 -3
  139. package/bundle/{install-manifest-QRWID3KZ.js → install-manifest-KBYD7SAY.js} +3 -3
  140. package/bundle/{irc-adapter-AIEP6OX6.js → irc-adapter-HXO5D4SW.js} +3 -3
  141. package/bundle/{irc-config-6VY67UPQ.js → irc-config-XN5VW2V4.js} +5 -5
  142. package/bundle/kanban-board-6Q5E5GEB.js +31 -0
  143. package/bundle/kanban-board-I52RHNHQ.js +31 -0
  144. package/bundle/{lazy-require-UFYFFX2R.js → lazy-require-R3JYCV5M.js} +4 -4
  145. package/bundle/{media-utils-MOE36VWY.js → media-utils-W7XW3SVV.js} +4 -4
  146. package/bundle/{message-pipeline-2MBT44FO.js → message-pipeline-4CTBJ6K2.js} +17 -14
  147. package/bundle/message-pipeline-4KL7OWUH.js +38 -0
  148. package/bundle/message-pipeline-GFKSHRFU.js +38 -0
  149. package/bundle/message-pipeline-TGI2WJJM.js +38 -0
  150. package/bundle/meta.json +3181 -2356
  151. package/bundle/{notification-U6F5ZBSG.js → notification-ULESRDHB.js} +7 -6
  152. package/bundle/{openrouter-credits-7XXO6QGQ.js → openrouter-credits-PLIKRY5D.js} +4 -4
  153. package/bundle/{paths-ZJYIDND2.js → paths-QQM74XYT.js} +4 -2
  154. package/bundle/{peer-client-T44VI7NB.js → peer-client-D2F5QWRV.js} +8 -8
  155. package/bundle/{peer-config-D5A4454H.js → peer-config-5SUIBJLG.js} +5 -5
  156. package/bundle/{phase-transport-FEZ4SIJJ.js → phase-transport-INFD6ELA.js} +10 -10
  157. package/bundle/phase-transport-KXFZ5BVF.js +23 -0
  158. package/bundle/{restore-MFSW3EBL.js → restore-Z6MF54HS.js} +4 -4
  159. package/bundle/{restore-MFSW3EBL.js.map → restore-Z6MF54HS.js.map} +2 -2
  160. package/bundle/{update-check-O5MS6B3L.js → rollback-5RXXLUD6.js} +5 -7
  161. package/bundle/{self-healer-utils-7NFH22VJ.js → self-healer-utils-WPKOVXJD.js} +4 -4
  162. package/bundle/{skill-stats-IPVKMWN3.js → skill-stats-NHNH47QW.js} +5 -5
  163. package/bundle/{sleep-BPWX3FCN.js → sleep-ENFZFUJJ.js} +8 -8
  164. package/bundle/sleep-ENFZFUJJ.js.map +7 -0
  165. package/bundle/{soul-bundle-BRIUDEQ2.js → soul-bundle-QTPWDJB2.js} +7 -7
  166. package/bundle/soul-bundle-QTPWDJB2.js.map +7 -0
  167. package/bundle/{soul-loader-GBXJ7EBH.js → soul-loader-LCPTN4PK.js} +8 -8
  168. package/bundle/soul-loader-LCPTN4PK.js.map +7 -0
  169. package/bundle/{sse-parser-anthropic-H42TTLBD.js → sse-parser-anthropic-PYDJM3UC.js} +4 -4
  170. package/bundle/{sse-parser-responses-WG2LY2ML.js → sse-parser-responses-FYT7A5WT.js} +4 -4
  171. package/bundle/{ssrf-guard-E2KBBC5E.js → ssrf-guard-R4P5OCTO.js} +4 -4
  172. package/bundle/{start-CBVKNEAT.js → start-4DNURGIY.js} +1 -1
  173. package/bundle/{stt-CF3CPFDC.js → stt-YN77NND6.js} +5 -5
  174. package/bundle/stt-YN77NND6.js.map +7 -0
  175. package/bundle/{subagent-runtime-4MTYUBIZ.js → subagent-runtime-5AYOXOU2.js} +5 -5
  176. package/bundle/subagent-runtime-5AYOXOU2.js.map +7 -0
  177. package/bundle/subagent-runtime-VKTX6Q2M.js +13 -0
  178. package/bundle/subagent-runtime-VKTX6Q2M.js.map +7 -0
  179. package/bundle/system-event-buffer-OEPPNUGK.js +17 -0
  180. package/bundle/system-event-buffer-OEPPNUGK.js.map +7 -0
  181. package/bundle/{system-message-TALP6GP2.js → system-message-BRU267FW.js} +3 -3
  182. package/bundle/{system-status-GLYXXDE3.js → system-status-7K2QTH3J.js} +58 -51
  183. package/bundle/system-status-7K2QTH3J.js.map +7 -0
  184. package/bundle/{hotskills-6ECHLXTJ.js → task-failure-buffer-DPM5MWZ5.js} +8 -7
  185. package/bundle/task-failure-buffer-DPM5MWZ5.js.map +7 -0
  186. package/bundle/{task-store-LC7ZMS72.js → task-store-VCBHAB43.js} +5 -5
  187. package/bundle/task-store-VCBHAB43.js.map +7 -0
  188. package/bundle/{telegram-adapter-BJJYXN7J.js → telegram-adapter-4KI4CJPG.js} +51 -33
  189. package/bundle/telegram-adapter-4KI4CJPG.js.map +7 -0
  190. package/bundle/telegram-adapter-76B4JRJJ.js +1080 -0
  191. package/bundle/telegram-adapter-76B4JRJJ.js.map +7 -0
  192. package/bundle/telegram-adapter-VZA74EMT.js +1080 -0
  193. package/bundle/telegram-adapter-VZA74EMT.js.map +7 -0
  194. package/bundle/telegram-adapter-ZO2CLU22.js +1080 -0
  195. package/bundle/telegram-adapter-ZO2CLU22.js.map +7 -0
  196. package/bundle/{tool-registry-T7XLTI2Q.js → tool-registry-CG7GIS64.js} +13 -9
  197. package/bundle/tool-registry-CG7GIS64.js.map +7 -0
  198. package/bundle/tool-registry-TGNU5AMG.js +43 -0
  199. package/bundle/tool-registry-TGNU5AMG.js.map +7 -0
  200. package/bundle/{tool-sandbox-OZMXJZLQ.js → tool-sandbox-TLAL55QP.js} +5 -5
  201. package/bundle/tool-sandbox-TLAL55QP.js.map +7 -0
  202. package/bundle/{transport-config-G5NKQXPJ.js → transport-config-JIKHB7GT.js} +8 -8
  203. package/bundle/transport-config-JIKHB7GT.js.map +7 -0
  204. package/bundle/update-check-AJMIBQGQ.js +81 -0
  205. package/bundle/update-check-AJMIBQGQ.js.map +7 -0
  206. package/bundle/{user-registry-NUVNEHJU.js → user-registry-PEFDZ5AV.js} +5 -5
  207. package/bundle/user-registry-PEFDZ5AV.js.map +7 -0
  208. package/core/skills/tools/gmail/SKILL.md +5 -14
  209. package/core/skills/tools/rss/SKILL.md +51 -0
  210. package/install-manifest.json +8 -2
  211. package/package.json +4 -2
  212. package/scripts/abtars-daemon.service +3 -0
  213. package/scripts/abtars@.service +3 -0
  214. package/scripts/build-and-deploy.sh +68 -0
  215. package/scripts/doctor.sh +38 -0
  216. package/scripts/emergency-deploy.sh +95 -0
  217. package/scripts/watchdog.sh +51 -5
  218. package/bundle/chunk-4BUOO6WI.js.map +0 -7
  219. package/bundle/chunk-A5OJYQNU.js.map +0 -7
  220. package/bundle/chunk-JX3ZZU3O.js +0 -82
  221. package/bundle/chunk-JX3ZZU3O.js.map +0 -7
  222. package/bundle/chunk-KJOCXWJ5.js +0 -131
  223. package/bundle/chunk-KJOCXWJ5.js.map +0 -7
  224. package/bundle/chunk-KSEIWT4T.js.map +0 -7
  225. package/bundle/chunk-KWBGYWDO.js.map +0 -7
  226. package/bundle/chunk-MJ6PHMOK.js.map +0 -7
  227. package/bundle/chunk-P2BZSLJJ.js.map +0 -7
  228. package/bundle/chunk-R36WIOYX.js.map +0 -7
  229. package/bundle/chunk-RE3F3CFW.js +0 -300
  230. package/bundle/chunk-RE3F3CFW.js.map +0 -7
  231. package/bundle/chunk-RSWUPUNA.js.map +0 -7
  232. package/bundle/chunk-RV54J75Q.js.map +0 -7
  233. package/bundle/chunk-TYVI3ZWA.js.map +0 -7
  234. package/bundle/chunk-X5FBUA53.js.map +0 -7
  235. package/bundle/direct-api-transport-TRV45NO6.js.map +0 -7
  236. package/bundle/discord-adapter-WA2MFRK3.js.map +0 -7
  237. package/bundle/system-status-GLYXXDE3.js.map +0 -7
  238. package/bundle/telegram-adapter-BJJYXN7J.js.map +0 -7
  239. /package/bundle/{agent-api-rate-limit-C25WGSFF.js.map → agent-api-rate-limit-R2OFAQ3N.js.map} +0 -0
  240. /package/bundle/{agent-registry-SYUFNSVB.js.map → agent-registry-5VL5KI6U.js.map} +0 -0
  241. /package/bundle/{bridge-lock-transport-HO545SBK.js.map → agent-registry-PIS5XJHX.js.map} +0 -0
  242. /package/bundle/{browse-delivery-VTLEAVYA.js.map → bridge-lock-transport-N6OGDOSE.js.map} +0 -0
  243. /package/bundle/{browser-REIXOJ6S.js.map → browse-delivery-DXGMDMXA.js.map} +0 -0
  244. /package/bundle/{capability-ILW3D5HS.js.map → browser-QMYGSP5W.js.map} +0 -0
  245. /package/bundle/{commands-WUGPBPHI.js.map → capability-733TLH4W.js.map} +0 -0
  246. /package/bundle/{chunk-PZE3J7ER.js.map → chunk-3OXQWII3.js.map} +0 -0
  247. /package/bundle/{chunk-4KJ76TTE.js.map → chunk-4XW7YA3K.js.map} +0 -0
  248. /package/bundle/{chunk-ZVDVNSXK.js.map → chunk-7WFE2JI5.js.map} +0 -0
  249. /package/bundle/{chunk-Q62SXS73.js.map → chunk-BBDKU4EH.js.map} +0 -0
  250. /package/bundle/{chunk-EX2SRTUE.js.map → chunk-CYSGXNBY.js.map} +0 -0
  251. /package/bundle/{chunk-LYEAHE5V.js.map → chunk-DCY7DGMT.js.map} +0 -0
  252. /package/bundle/{chunk-G6IXMYIO.js.map → chunk-DO4INSXE.js.map} +0 -0
  253. /package/bundle/{chunk-VA5WKN3Z.js.map → chunk-EGA6JQVV.js.map} +0 -0
  254. /package/bundle/{chunk-URAQLQ2U.js.map → chunk-F3HMZFIL.js.map} +0 -0
  255. /package/bundle/{chunk-OOKLEC6V.js.map → chunk-FY3QUO2L.js.map} +0 -0
  256. /package/bundle/{chunk-2BY6I4P5.js.map → chunk-GUTRAMK3.js.map} +0 -0
  257. /package/bundle/{chunk-GPL57SRN.js.map → chunk-H7RX7UCR.js.map} +0 -0
  258. /package/bundle/{chunk-BYDUMHXT.js.map → chunk-HAF2AFBW.js.map} +0 -0
  259. /package/bundle/{chunk-KFENC7BM.js.map → chunk-L33WNMCP.js.map} +0 -0
  260. /package/bundle/{chunk-JRG4EFMP.js.map → chunk-LBMETTUP.js.map} +0 -0
  261. /package/bundle/{chunk-TOUZC6NR.js.map → chunk-OKMN6J4Z.js.map} +0 -0
  262. /package/bundle/{chunk-XZSYMCLF.js.map → chunk-PUDGA4RR.js.map} +0 -0
  263. /package/bundle/{chunk-CELR236Q.js.map → chunk-Q7CH5DA3.js.map} +0 -0
  264. /package/bundle/{chunk-UDZIZB5F.js.map → chunk-RTL7HO3N.js.map} +0 -0
  265. /package/bundle/{chunk-ITG6XGBS.js.map → chunk-SA44ITVX.js.map} +0 -0
  266. /package/bundle/{chunk-3MO2MDXJ.js.map → chunk-SA6YEFNG.js.map} +0 -0
  267. /package/bundle/{chunk-GBBTK6H2.js.map → chunk-SRFEIZQT.js.map} +0 -0
  268. /package/bundle/{chunk-ELRAH7VL.js.map → chunk-VXUVKC66.js.map} +0 -0
  269. /package/bundle/{config-DQIGDX4W.js.map → commands-IGRSOSK6.js.map} +0 -0
  270. /package/bundle/{delegation-tools-6FICZQ5G.js.map → commands-LAWVNQTO.js.map} +0 -0
  271. /package/bundle/{deploy-lib-import-SBKXDD3F.js.map → commands-RBWY7YXB.js.map} +0 -0
  272. /package/bundle/{env-schema-XCPAJ6IZ.js.map → commands-XFZNMZN6.js.map} +0 -0
  273. /package/bundle/{hook-system-POI5VRIX.js.map → config-NDEYF4AQ.js.map} +0 -0
  274. /package/bundle/{daemon-NPKYZ3CJ.js.map → daemon-WOQXCKNL.js.map} +0 -0
  275. /package/bundle/{hotskills-6ECHLXTJ.js.map → delegation-tools-Z5OM3TXS.js.map} +0 -0
  276. /package/bundle/{install-SH4UVUXQ.js.map → deploy-lib-import-6VJTYXEG.js.map} +0 -0
  277. /package/bundle/{deps-HN6CEXA4.js.map → deps-65V7XXG4.js.map} +0 -0
  278. /package/bundle/{dns-wakeup-RYOCQ6GR.js.map → dns-wakeup-N46RPU5E.js.map} +0 -0
  279. /package/bundle/{ensure-invariants-BJIEOSJ2.js.map → ensure-invariants-3NOBCYWS.js.map} +0 -0
  280. /package/bundle/{lazy-require-UFYFFX2R.js.map → env-schema-T43X43BU.js.map} +0 -0
  281. /package/bundle/{message-pipeline-2MBT44FO.js.map → hook-system-ZCVOFFRD.js.map} +0 -0
  282. /package/bundle/{notification-U6F5ZBSG.js.map → hotskills-DTROJY6G.js.map} +0 -0
  283. /package/bundle/{paths-ZJYIDND2.js.map → install-I3CXVW52.js.map} +0 -0
  284. /package/bundle/{install-manifest-QRWID3KZ.js.map → install-manifest-KBYD7SAY.js.map} +0 -0
  285. /package/bundle/{irc-adapter-AIEP6OX6.js.map → irc-adapter-HXO5D4SW.js.map} +0 -0
  286. /package/bundle/{irc-config-6VY67UPQ.js.map → irc-config-XN5VW2V4.js.map} +0 -0
  287. /package/bundle/{peer-config-D5A4454H.js.map → kanban-board-6Q5E5GEB.js.map} +0 -0
  288. /package/bundle/{phase-transport-FEZ4SIJJ.js.map → kanban-board-I52RHNHQ.js.map} +0 -0
  289. /package/bundle/{skill-stats-IPVKMWN3.js.map → lazy-require-R3JYCV5M.js.map} +0 -0
  290. /package/bundle/{media-utils-MOE36VWY.js.map → media-utils-W7XW3SVV.js.map} +0 -0
  291. /package/bundle/{sleep-BPWX3FCN.js.map → message-pipeline-4CTBJ6K2.js.map} +0 -0
  292. /package/bundle/{soul-bundle-BRIUDEQ2.js.map → message-pipeline-4KL7OWUH.js.map} +0 -0
  293. /package/bundle/{soul-loader-GBXJ7EBH.js.map → message-pipeline-GFKSHRFU.js.map} +0 -0
  294. /package/bundle/{stt-CF3CPFDC.js.map → message-pipeline-TGI2WJJM.js.map} +0 -0
  295. /package/bundle/{subagent-runtime-4MTYUBIZ.js.map → notification-ULESRDHB.js.map} +0 -0
  296. /package/bundle/{openrouter-credits-7XXO6QGQ.js.map → openrouter-credits-PLIKRY5D.js.map} +0 -0
  297. /package/bundle/{task-store-LC7ZMS72.js.map → paths-QQM74XYT.js.map} +0 -0
  298. /package/bundle/{peer-client-T44VI7NB.js.map → peer-client-D2F5QWRV.js.map} +0 -0
  299. /package/bundle/{tool-registry-T7XLTI2Q.js.map → peer-config-5SUIBJLG.js.map} +0 -0
  300. /package/bundle/{tool-sandbox-OZMXJZLQ.js.map → phase-transport-INFD6ELA.js.map} +0 -0
  301. /package/bundle/{transport-config-G5NKQXPJ.js.map → phase-transport-KXFZ5BVF.js.map} +0 -0
  302. /package/bundle/{update-check-O5MS6B3L.js.map → rollback-5RXXLUD6.js.map} +0 -0
  303. /package/bundle/{self-healer-utils-7NFH22VJ.js.map → self-healer-utils-WPKOVXJD.js.map} +0 -0
  304. /package/bundle/{user-registry-NUVNEHJU.js.map → skill-stats-NHNH47QW.js.map} +0 -0
  305. /package/bundle/{sse-parser-anthropic-H42TTLBD.js.map → sse-parser-anthropic-PYDJM3UC.js.map} +0 -0
  306. /package/bundle/{sse-parser-responses-WG2LY2ML.js.map → sse-parser-responses-FYT7A5WT.js.map} +0 -0
  307. /package/bundle/{ssrf-guard-E2KBBC5E.js.map → ssrf-guard-R4P5OCTO.js.map} +0 -0
  308. /package/bundle/{start-CBVKNEAT.js.map → start-4DNURGIY.js.map} +0 -0
  309. /package/bundle/{system-message-TALP6GP2.js.map → system-message-BRU267FW.js.map} +0 -0
@@ -3,25 +3,25 @@
3
3
  import {
4
4
  buildUsersBlock,
5
5
  loadUsers
6
- } from "./chunk-GBBTK6H2.js";
7
- import {
8
- init_log_and_swallow,
9
- logAndSwallow
10
- } from "./chunk-EX2SRTUE.js";
6
+ } from "./chunk-SRFEIZQT.js";
11
7
  import {
12
8
  getEnv,
13
9
  init_env_schema
14
- } from "./chunk-PZE3J7ER.js";
10
+ } from "./chunk-3OXQWII3.js";
11
+ import {
12
+ init_log_and_swallow,
13
+ logAndSwallow
14
+ } from "./chunk-CYSGXNBY.js";
15
15
  import {
16
16
  init_logger,
17
17
  logDebug,
18
18
  logInfo,
19
19
  logWarn
20
- } from "./chunk-2BY6I4P5.js";
20
+ } from "./chunk-GUTRAMK3.js";
21
21
  import {
22
22
  abtarsHome,
23
23
  init_paths
24
- } from "./chunk-MJ6PHMOK.js";
24
+ } from "./chunk-WW5F2DCO.js";
25
25
 
26
26
  // src/components/soul-bundle.ts
27
27
  init_log_and_swallow();
@@ -123,4 +123,4 @@ ${lines.join("\n")}`);
123
123
  export {
124
124
  buildSoulBundle
125
125
  };
126
- //# sourceMappingURL=chunk-OZ4IZFV4.js.map
126
+ //# sourceMappingURL=chunk-HJQZP5CK.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/components/soul-bundle.ts"],
4
- "sourcesContent": ["/**\n * soul-bundle.ts \u2014 Unified SOUL bundle builder for all session types.\n * One function, one matrix. Replaces scattered injection logic.\n */\nimport { logAndSwallow } from \"./log-and-swallow.js\";\nimport { getEnv } from \"./env-schema.js\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { logInfo, logDebug, logWarn } from \"./logger.js\";\nimport { abtarsHome } from \"../paths.js\";\nimport { loadUsers, buildUsersBlock } from \"./user-registry.js\";\nimport type { MemoryManager } from \"abmind\";\nimport type { SessionType } from \"./session-manager.js\";\n\nconst TAG = \"soul-bundle\";\nconst HOST_CORE_DIR = join(abtarsHome(), \"core\");\n\nfunction readOr(path: string): string {\n try { return existsSync(path) ? readFileSync(path, \"utf-8\").trim() : \"\"; } catch { return \"\"; }\n}\n\n/** Type identity \u2014 hardcoded one-liners for non-Main sessions. */\nconst TYPE_IDENTITY: Record<SessionType, string | null> = {\n A: null, // uses full SOUL.md\n B: \"I am a browse agent. I fetch web content and return results. No memory access.\",\n C: \"I am a coding agent. I write and fix code. Be concise.\",\n T: \"I am a task agent. I execute scheduled tasks. Write all output to $WORKSPACE.\",\n S: \"I am the self-healing agent. I diagnose and fix system failures. If unfixable, state: Requires human intervention.\",\n P: \"I am responding to a peer agent request. Be precise and technical.\",\n};\n\nfunction buildModelInstructions(): string {\n const lines: string[] = [];\n if (getEnv().primingModelTopics) {\n lines.push(\"End each response with [TOPICS: kw1, kw2, kw3] \u2014 your top 3 topics from this exchange. Keep them English, lowercase, concise.\");\n }\n return lines.length > 0 ? `# Model Instructions\\n\\n${lines.join(\"\\n\")}` : \"\";\n}\n\nfunction buildCurrentTime(): string {\n const now = new Date();\n const days = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\n return `[CURRENT TIME] ${now.toLocaleDateString(\"en-GB\")} ${days[now.getDay()]}, ${now.toLocaleTimeString(\"en-GB\", { hour: \"2-digit\", minute: \"2-digit\" })}`;\n}\n\n/**\n * Build the SOUL bundle for any session type.\n *\n * Main (A): full 9-part bundle (identity, tools, profile, notes, facts, skills, model-instructions, emotional, users, time)\n * Others: identity one-liner + core facts + skills + time\n */\nexport function buildSoulBundle(type: SessionType, memory?: MemoryManager | null): string | null {\n const parts: string[] = [];\n\n if (type === \"A\") {\n // Full Main bundle\n let bundle: { soul: string; profile: string; notes: string; memoryTools: string; coreFacts: string } | null = null;\n try { bundle = memory?.getSessionBundle() ?? null; } catch (err) { logAndSwallow(TAG, \"op\", err); }\n\n const soul = bundle?.soul || readOr(join(HOST_CORE_DIR, \"SOUL.md\"));\n const memoryTools = bundle?.profile || readOr(join(HOST_CORE_DIR, \"user_profile.md\"));\n const userProfile = bundle?.notes || readOr(join(HOST_CORE_DIR, \"agent_notes.md\"));\n const agentNotes = bundle?.memoryTools || readOr(join(HOST_CORE_DIR, \"TOOLS.md\"));\n const coreFacts = bundle?.coreFacts || readOr(join(HOST_CORE_DIR, \"core_facts.md\"));\n\n if (soul) parts.push(soul);\n if (memoryTools) parts.push(memoryTools);\n if (userProfile) parts.push(userProfile);\n if (agentNotes) parts.push(agentNotes);\n if (coreFacts) parts.push(coreFacts);\n\n const skillsCatalog = readOr(join(HOST_CORE_DIR, \"skills_catalog.md\"));\n if (skillsCatalog) parts.push(skillsCatalog);\n\n const modelInstructions = buildModelInstructions();\n if (modelInstructions) parts.push(modelInstructions);\n\n try {\n const arcs = memory?.getEmotionalArcs() ?? [];\n if (arcs.length > 0) {\n const ARC_LABELS: Record<string, string> = { \"\u2191\": \"user sentiment improving\", \"\u2193\": \"user sentiment worsening \u2014 be careful\", \"\u2195\": \"volatile \u2014 user feelings fluctuate\", \"\u2192\": \"stable\" };\n const lines = arcs.map(a => `- ${a.topic}: ${a.arc} (${ARC_LABELS[a.arc] ?? \"unknown\"})`);\n parts.push(`[EMOTIONAL CONTEXT]\\n${lines.join(\"\\n\")}`);\n }\n } catch (err) { logAndSwallow(TAG, \"op\", err); }\n\n try {\n const registry = loadUsers();\n if (registry.users.length > 0) parts.push(buildUsersBlock(registry));\n } catch (err) { logAndSwallow(TAG, \"op\", err); }\n } else {\n // Lightweight bundle: identity + core facts + skills\n const identity = TYPE_IDENTITY[type];\n if (identity) parts.push(identity);\n\n const coreFacts = readOr(join(HOST_CORE_DIR, \"core_facts.md\"));\n if (coreFacts) parts.push(coreFacts);\n\n const skillsCatalog = readOr(join(HOST_CORE_DIR, \"skills_catalog.md\"));\n if (skillsCatalog) parts.push(skillsCatalog);\n }\n\n parts.push(buildCurrentTime());\n\n if (parts.length === 0) {\n logWarn(TAG, \"No bundle parts generated\");\n return null;\n }\n\n logInfo(TAG, `Bundle [${type}]: ${parts.length} parts`);\n logDebug(TAG, `Parts: ${parts.map((p, i) => `${i}:${p.length}ch`).join(\", \")}`);\n return parts.join(\"\\n\\n---\\n\\n\");\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * soul-bundle.ts \u2014 Unified SOUL bundle builder for all session types.\n * One function, one matrix. Replaces scattered injection logic.\n */\nimport { logAndSwallow } from \"./log-and-swallow.js\";\nimport { getEnv } from \"./env-schema.js\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { logInfo, logDebug, logWarn } from \"./logger.js\";\nimport { abtarsHome } from \"../paths.js\";\nimport { loadUsers, buildUsersBlock } from \"./user-registry.js\";\nimport type { MemoryManager } from \"abmind\";\nimport type { SessionType } from \"./session-manager.js\";\n\nconst TAG = \"soul-bundle\";\nconst HOST_CORE_DIR = join(abtarsHome(), \"core\");\n\nfunction readOr(path: string): string {\n try { return existsSync(path) ? readFileSync(path, \"utf-8\").trim() : \"\"; } catch { return \"\"; }\n}\n\n/** Type identity \u2014 hardcoded one-liners for non-Main sessions. */\nconst TYPE_IDENTITY: Record<SessionType, string | null> = {\n A: null, // uses full SOUL.md\n B: \"I am a browse agent. I fetch web content and return results. No memory access.\",\n C: \"I am a coding agent. I write and fix code. Be concise.\",\n T: \"I am a task agent. I execute scheduled tasks. Write all output to $WORKSPACE.\",\n S: \"I am the self-healing agent. I diagnose and fix system failures. If unfixable, state: Requires human intervention.\",\n P: \"I am responding to a peer agent request. Be precise and technical.\",\n};\n\nfunction buildModelInstructions(): string {\n const lines: string[] = [];\n if (getEnv().primingModelTopics) {\n lines.push(\"End each response with [TOPICS: kw1, kw2, kw3] \u2014 your top 3 topics from this exchange. Keep them English, lowercase, concise.\");\n }\n return lines.length > 0 ? `# Model Instructions\\n\\n${lines.join(\"\\n\")}` : \"\";\n}\n\nfunction buildCurrentTime(): string {\n const now = new Date();\n const days = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\n return `[CURRENT TIME] ${now.toLocaleDateString(\"en-GB\")} ${days[now.getDay()]}, ${now.toLocaleTimeString(\"en-GB\", { hour: \"2-digit\", minute: \"2-digit\" })}`;\n}\n\n/**\n * Build the SOUL bundle for any session type.\n *\n * Main (A): full 9-part bundle (identity, tools, profile, notes, facts, skills, model-instructions, emotional, users, time)\n * Others: identity one-liner + core facts + skills + time\n */\nexport function buildSoulBundle(type: SessionType, memory?: MemoryManager | null): string | null {\n const parts: string[] = [];\n\n if (type === \"A\") {\n // Full Main bundle\n let bundle: { soul: string; profile: string; notes: string; memoryTools: string; coreFacts: string } | null = null;\n try { bundle = memory?.getSessionBundle() ?? null; } catch (err) { logAndSwallow(TAG, \"op\", err); }\n\n const soul = bundle?.soul || readOr(join(HOST_CORE_DIR, \"SOUL.md\"));\n const memoryTools = bundle?.profile || readOr(join(HOST_CORE_DIR, \"user_profile.md\"));\n const userProfile = bundle?.notes || readOr(join(HOST_CORE_DIR, \"agent_notes.md\"));\n const agentNotes = bundle?.memoryTools || readOr(join(HOST_CORE_DIR, \"TOOLS.md\"));\n const coreFacts = bundle?.coreFacts || readOr(join(HOST_CORE_DIR, \"core_facts.md\"));\n\n if (soul) parts.push(soul);\n if (memoryTools) parts.push(memoryTools);\n if (userProfile) parts.push(userProfile);\n if (agentNotes) parts.push(agentNotes);\n if (coreFacts) parts.push(coreFacts);\n\n const skillsCatalog = readOr(join(HOST_CORE_DIR, \"skills_catalog.md\"));\n if (skillsCatalog) parts.push(skillsCatalog);\n\n const modelInstructions = buildModelInstructions();\n if (modelInstructions) parts.push(modelInstructions);\n\n try {\n const arcs = memory?.getEmotionalArcs() ?? [];\n if (arcs.length > 0) {\n const ARC_LABELS: Record<string, string> = { \"\u2191\": \"user sentiment improving\", \"\u2193\": \"user sentiment worsening \u2014 be careful\", \"\u2195\": \"volatile \u2014 user feelings fluctuate\", \"\u2192\": \"stable\" };\n const lines = arcs.map((a: { topic: string; arc: string }) => `- ${a.topic}: ${a.arc} (${ARC_LABELS[a.arc] ?? \"unknown\"})`);\n parts.push(`[EMOTIONAL CONTEXT]\\n${lines.join(\"\\n\")}`);\n }\n } catch (err) { logAndSwallow(TAG, \"op\", err); }\n\n try {\n const registry = loadUsers();\n if (registry.users.length > 0) parts.push(buildUsersBlock(registry));\n } catch (err) { logAndSwallow(TAG, \"op\", err); }\n } else {\n // Lightweight bundle: identity + core facts + skills\n const identity = TYPE_IDENTITY[type];\n if (identity) parts.push(identity);\n\n const coreFacts = readOr(join(HOST_CORE_DIR, \"core_facts.md\"));\n if (coreFacts) parts.push(coreFacts);\n\n const skillsCatalog = readOr(join(HOST_CORE_DIR, \"skills_catalog.md\"));\n if (skillsCatalog) parts.push(skillsCatalog);\n }\n\n parts.push(buildCurrentTime());\n\n if (parts.length === 0) {\n logWarn(TAG, \"No bundle parts generated\");\n return null;\n }\n\n logInfo(TAG, `Bundle [${type}]: ${parts.length} parts`);\n logDebug(TAG, `Parts: ${parts.map((p, i) => `${i}:${p.length}ch`).join(\", \")}`);\n return parts.join(\"\\n\\n---\\n\\n\");\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -7,19 +7,19 @@ import {
7
7
  readEntries,
8
8
  removeEntry,
9
9
  writeEntry
10
- } from "./chunk-GPL57SRN.js";
10
+ } from "./chunk-H7RX7UCR.js";
11
11
  import {
12
12
  init_log_and_swallow,
13
13
  logAndSwallow
14
- } from "./chunk-EX2SRTUE.js";
14
+ } from "./chunk-CYSGXNBY.js";
15
15
  import {
16
16
  init_logger,
17
17
  logInfo
18
- } from "./chunk-2BY6I4P5.js";
18
+ } from "./chunk-GUTRAMK3.js";
19
19
  import {
20
20
  abtarsHome,
21
21
  init_paths
22
- } from "./chunk-MJ6PHMOK.js";
22
+ } from "./chunk-WW5F2DCO.js";
23
23
  import {
24
24
  __commonJS,
25
25
  __require,
@@ -490,19 +490,12 @@ function checkCron() {
490
490
  return dueTasks;
491
491
  }
492
492
 
493
- // src/utils/date.ts
494
- function localDate() {
495
- const d = /* @__PURE__ */ new Date();
496
- return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
497
- }
498
-
499
493
  export {
500
494
  require_main,
501
495
  readPendingReminders,
502
496
  clearPendingReminders,
503
497
  appendReminder,
504
498
  recordRun,
505
- checkCron,
506
- localDate
499
+ checkCron
507
500
  };
508
- //# sourceMappingURL=chunk-HEHD3GG5.js.map
501
+ //# sourceMappingURL=chunk-ITB2K6LI.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../node_modules/dotenv/package.json", "../node_modules/dotenv/lib/main.js", "../src/components/tasks/task-checker.ts", "../src/utils/date.ts"],
4
- "sourcesContent": ["{\n \"name\": \"dotenv\",\n \"version\": \"16.6.1\",\n \"description\": \"Loads environment variables from .env file\",\n \"main\": \"lib/main.js\",\n \"types\": \"lib/main.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./lib/main.d.ts\",\n \"require\": \"./lib/main.js\",\n \"default\": \"./lib/main.js\"\n },\n \"./config\": \"./config.js\",\n \"./config.js\": \"./config.js\",\n \"./lib/env-options\": \"./lib/env-options.js\",\n \"./lib/env-options.js\": \"./lib/env-options.js\",\n \"./lib/cli-options\": \"./lib/cli-options.js\",\n \"./lib/cli-options.js\": \"./lib/cli-options.js\",\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"dts-check\": \"tsc --project tests/types/tsconfig.json\",\n \"lint\": \"standard\",\n \"pretest\": \"npm run lint && npm run dts-check\",\n \"test\": \"tap run --allow-empty-coverage --disable-coverage --timeout=60000\",\n \"test:coverage\": \"tap run --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov\",\n \"prerelease\": \"npm test\",\n \"release\": \"standard-version\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git://github.com/motdotla/dotenv.git\"\n },\n \"homepage\": \"https://github.com/motdotla/dotenv#readme\",\n \"funding\": \"https://dotenvx.com\",\n \"keywords\": [\n \"dotenv\",\n \"env\",\n \".env\",\n \"environment\",\n \"variables\",\n \"config\",\n \"settings\"\n ],\n \"readmeFilename\": \"README.md\",\n \"license\": \"BSD-2-Clause\",\n \"devDependencies\": {\n \"@types/node\": \"^18.11.3\",\n \"decache\": \"^4.6.2\",\n \"sinon\": \"^14.0.1\",\n \"standard\": \"^17.0.0\",\n \"standard-version\": \"^9.5.0\",\n \"tap\": \"^19.2.0\",\n \"typescript\": \"^4.8.4\"\n },\n \"engines\": {\n \"node\": \">=12\"\n },\n \"browser\": {\n \"fs\": false\n }\n}\n", "const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\nconst packageJson = require('../package.json')\n\nconst version = packageJson.version\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n const obj = {}\n\n // Convert buffer to string\n let lines = src.toString()\n\n // Convert line breaks to same format\n lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n let match\n while ((match = LINE.exec(lines)) != null) {\n const key = match[1]\n\n // Default undefined or null to empty string\n let value = (match[2] || '')\n\n // Remove whitespace\n value = value.trim()\n\n // Check if double quoted\n const maybeQuote = value[0]\n\n // Remove surrounding quotes\n value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n // Expand newlines if double quoted\n if (maybeQuote === '\"') {\n value = value.replace(/\\\\n/g, '\\n')\n value = value.replace(/\\\\r/g, '\\r')\n }\n\n // Add to object\n obj[key] = value\n }\n\n return obj\n}\n\nfunction _parseVault (options) {\n options = options || {}\n\n const vaultPath = _vaultPath(options)\n options.path = vaultPath // parse .env.vault\n const result = DotenvModule.configDotenv(options)\n if (!result.parsed) {\n const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n err.code = 'MISSING_DATA'\n throw err\n }\n\n // handle scenario for comma separated keys - for use with key rotation\n // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n const keys = _dotenvKey(options).split(',')\n const length = keys.length\n\n let decrypted\n for (let i = 0; i < length; i++) {\n try {\n // Get full key\n const key = keys[i].trim()\n\n // Get instructions for decrypt\n const attrs = _instructions(result, key)\n\n // Decrypt\n decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n break\n } catch (error) {\n // last key\n if (i + 1 >= length) {\n throw error\n }\n // try next key\n }\n }\n\n // Parse decrypted .env string\n return DotenvModule.parse(decrypted)\n}\n\nfunction _warn (message) {\n console.log(`[dotenv@${version}][WARN] ${message}`)\n}\n\nfunction _debug (message) {\n console.log(`[dotenv@${version}][DEBUG] ${message}`)\n}\n\nfunction _log (message) {\n console.log(`[dotenv@${version}] ${message}`)\n}\n\nfunction _dotenvKey (options) {\n // prioritize developer directly setting options.DOTENV_KEY\n if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n return options.DOTENV_KEY\n }\n\n // secondary infra already contains a DOTENV_KEY environment variable\n if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n return process.env.DOTENV_KEY\n }\n\n // fallback to empty string\n return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n // Parse DOTENV_KEY. Format is a URI\n let uri\n try {\n uri = new URL(dotenvKey)\n } catch (error) {\n if (error.code === 'ERR_INVALID_URL') {\n const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n throw error\n }\n\n // Get decrypt key\n const key = uri.password\n if (!key) {\n const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get environment\n const environment = uri.searchParams.get('environment')\n if (!environment) {\n const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get ciphertext payload\n const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n if (!ciphertext) {\n const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n throw err\n }\n\n return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n let possibleVaultPath = null\n\n if (options && options.path && options.path.length > 0) {\n if (Array.isArray(options.path)) {\n for (const filepath of options.path) {\n if (fs.existsSync(filepath)) {\n possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n }\n }\n } else {\n possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n }\n } else {\n possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n }\n\n if (fs.existsSync(possibleVaultPath)) {\n return possibleVaultPath\n }\n\n return null\n}\n\nfunction _resolveHome (envPath) {\n return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (debug || !quiet) {\n _log('Loading env from encrypted .env.vault')\n }\n\n const parsed = DotenvModule._parseVault(options)\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsed, options)\n\n return { parsed }\n}\n\nfunction configDotenv (options) {\n const dotenvPath = path.resolve(process.cwd(), '.env')\n let encoding = 'utf8'\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (options && options.encoding) {\n encoding = options.encoding\n } else {\n if (debug) {\n _debug('No encoding is specified. UTF-8 is used by default')\n }\n }\n\n let optionPaths = [dotenvPath] // default, look for .env\n if (options && options.path) {\n if (!Array.isArray(options.path)) {\n optionPaths = [_resolveHome(options.path)]\n } else {\n optionPaths = [] // reset default\n for (const filepath of options.path) {\n optionPaths.push(_resolveHome(filepath))\n }\n }\n }\n\n // Build the parsed data in a temporary object (because we need to return it). Once we have the final\n // parsed data, we will combine it with process.env (or options.processEnv if provided).\n let lastError\n const parsedAll = {}\n for (const path of optionPaths) {\n try {\n // Specifying an encoding returns a string instead of a buffer\n const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n DotenvModule.populate(parsedAll, parsed, options)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${path} ${e.message}`)\n }\n lastError = e\n }\n }\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsedAll, options)\n\n if (debug || !quiet) {\n const keysCount = Object.keys(parsedAll).length\n const shortPaths = []\n for (const filePath of optionPaths) {\n try {\n const relative = path.relative(process.cwd(), filePath)\n shortPaths.push(relative)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${filePath} ${e.message}`)\n }\n lastError = e\n }\n }\n\n _log(`injecting env (${keysCount}) from ${shortPaths.join(',')}`)\n }\n\n if (lastError) {\n return { parsed: parsedAll, error: lastError }\n } else {\n return { parsed: parsedAll }\n }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n // fallback to original dotenv if DOTENV_KEY is not set\n if (_dotenvKey(options).length === 0) {\n return DotenvModule.configDotenv(options)\n }\n\n const vaultPath = _vaultPath(options)\n\n // dotenvKey exists but .env.vault file does not exist\n if (!vaultPath) {\n _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`)\n\n return DotenvModule.configDotenv(options)\n }\n\n return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n const key = Buffer.from(keyStr.slice(-64), 'hex')\n let ciphertext = Buffer.from(encrypted, 'base64')\n\n const nonce = ciphertext.subarray(0, 12)\n const authTag = ciphertext.subarray(-16)\n ciphertext = ciphertext.subarray(12, -16)\n\n try {\n const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n aesgcm.setAuthTag(authTag)\n return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n } catch (error) {\n const isRange = error instanceof RangeError\n const invalidKeyLength = error.message === 'Invalid key length'\n const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n if (isRange || invalidKeyLength) {\n const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n } else if (decryptionFailed) {\n const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n err.code = 'DECRYPTION_FAILED'\n throw err\n } else {\n throw error\n }\n }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n const debug = Boolean(options && options.debug)\n const override = Boolean(options && options.override)\n\n if (typeof parsed !== 'object') {\n const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n err.code = 'OBJECT_REQUIRED'\n throw err\n }\n\n // Set process.env\n for (const key of Object.keys(parsed)) {\n if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n if (override === true) {\n processEnv[key] = parsed[key]\n }\n\n if (debug) {\n if (override === true) {\n _debug(`\"${key}\" is already defined and WAS overwritten`)\n } else {\n _debug(`\"${key}\" is already defined and was NOT overwritten`)\n }\n }\n } else {\n processEnv[key] = parsed[key]\n }\n }\n}\n\nconst DotenvModule = {\n configDotenv,\n _configVault,\n _parseVault,\n config,\n decrypt,\n parse,\n populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n", "/**\n * cron-checker \u2014 heartbeat task that fires due cron entries.\n *\n * Reminders \u2192 pending_reminders.json (picked up by main.ts message loop)\n * Tasks \u2192 spawns kiro-cli subprocess, calls onTaskComplete callback\n */\n\nimport { logAndSwallow } from \"../log-and-swallow.js\";\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { abtarsHome } from \"../../paths.js\";\nimport { logInfo } from \"../logger.js\";\nimport { CronExpressionParser } from \"cron-parser\";\nimport { readEntries as dbReadEntries, writeEntry, removeEntry as dbRemoveEntry } from \"./task-store.js\";\nimport type { CronEntry } from \"../../cli/abtars-task.js\";\n\nconst TAG = \"cron-checker\";\nconst memoryDir = (): string => join(abtarsHome(), \"state\");\nconst remindersPath = (): string => join(memoryDir(), \"pending_reminders.json\");\n\nexport interface PendingReminder {\n chatId: number;\n message: string;\n createdAt: number;\n threadId?: number;\n}\n\nexport function readPendingReminders(): PendingReminder[] {\n if (!existsSync(remindersPath())) return [];\n try { return JSON.parse(readFileSync(remindersPath(), \"utf-8\")) as PendingReminder[]; }\n catch (err) { logAndSwallow(TAG, \"readPendingReminders\", err); return []; }\n}\n\nexport function clearPendingReminders(): void {\n if (existsSync(remindersPath())) writeFileSync(remindersPath(), \"[]\", \"utf-8\");\n}\n\nexport function appendReminder(r: PendingReminder): void {\n mkdirSync(memoryDir(), { recursive: true });\n const existing = readPendingReminders();\n existing.push(r);\n writeFileSync(remindersPath(), JSON.stringify(existing, null, 2), \"utf-8\");\n}\n\nconst MAX_HISTORY = 10;\nconst GC_AGE_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\n/** Record a run in the entry's history (keeps last MAX_HISTORY). */\nexport function recordRun(entry: CronEntry, exitCode?: number): void {\n if (!entry.history) entry.history = [];\n entry.history.push({ ts: Date.now(), ...(exitCode !== undefined ? { exitCode } : {}) });\n if (entry.history.length > MAX_HISTORY) entry.history = entry.history.slice(-MAX_HISTORY);\n}\n\n\n/**\n * Scan tasks.json for due entries. Fires reminders directly.\n * Returns due task entries (script + agent) for the CronQueue to process.\n * Advances fireAt and writes tasks.json.\n */\nexport function checkCron(): CronEntry[] {\n let entries = dbReadEntries();\n const now = Date.now();\n const dueTasks: CronEntry[] = [];\n\n // GC: remove fired one-shots older than 7 days\n for (const e of entries) {\n if (e.fired && !e.schedule && now - e.createdAt > GC_AGE_MS) {\n dbRemoveEntry(e.id);\n logInfo(TAG, `\uD83D\uDDD1\uFE0F GC: pruned old fired entry ${e.id}`);\n }\n }\n entries = entries.filter(e => !(e.fired && !e.schedule && now - e.createdAt > GC_AGE_MS));\n\n for (const entry of entries) {\n if (entry.fired || entry.paused || entry.fireAt > now) continue;\n\n // #692: daily rate limit \u2014 skip if maxRunsPerDay reached (count only successful runs)\n if (entry.maxRunsPerDay && entry.history) {\n const todayStart = new Date().setHours(0, 0, 0, 0);\n const todaySuccesses = entry.history.filter(h => h.ts >= todayStart && h.exitCode !== 1).length;\n if (todaySuccesses >= entry.maxRunsPerDay) {\n // Advance to next occurrence without running\n if (entry.schedule) {\n try {\n const expr = CronExpressionParser.parse(entry.schedule);\n entry.fireAt = expr.next().getTime();\n writeEntry(entry);\n } catch (err) { logAndSwallow(\"cron_checker\", \"op\", err); }\n }\n continue;\n }\n }\n\n // #327: stale detection \u2014 if past the catch-up window, advance to next occurrence\n if (entry.schedule && entry.fireAt <= now) {\n const maxDelay = (entry.catchUp ?? 0) * 3600_000;\n // Only consider stale if missed by more than one full interval (at minimum 5 min)\n const MIN_STALE_MS = 5 * 60_000;\n const staleThreshold = Math.max(maxDelay, MIN_STALE_MS);\n if (now - entry.fireAt > staleThreshold) {\n try {\n const expr = CronExpressionParser.parse(entry.schedule);\n entry.fireAt = expr.next().getTime();\n writeEntry(entry);\n logInfo(TAG, `\u23ED\uFE0F Stale \"${entry.id}\" \u2014 advanced to next occurrence`);\n } catch (err) { logAndSwallow(\"cron_checker\", \"op\", err); }\n continue;\n }\n }\n\n entry.lastRanAt = now;\n const wasRetry = !!entry._retrying;\n if (entry.schedule) {\n try {\n const expr = CronExpressionParser.parse(entry.schedule);\n entry.fireAt = expr.next().getTime();\n } catch (err) { logAndSwallow(TAG, \"cron parse next\", err); entry.fired = true; }\n } else {\n entry.fired = true;\n }\n delete entry._retrying;\n\n if (entry.type === \"reminder\") {\n appendReminder({ chatId: entry.chatId, message: entry.message, createdAt: now });\n recordRun(entry);\n logInfo(TAG, `\u23F0 Reminder fired: \"${entry.message}\" \u2192 chat ${entry.chatId}`);\n } else {\n dueTasks.push({ ...entry, _retrying: wasRetry || undefined });\n }\n\n writeEntry(entry);\n }\n\n return dueTasks;\n}\n", "/** Local date as YYYY-MM-DD (not UTC). */\nexport function localDate(): string {\n const d = new Date();\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, \"0\")}-${String(d.getDate()).padStart(2, \"0\")}`;\n}\n"],
5
- "mappings": "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",
3
+ "sources": ["../node_modules/dotenv/package.json", "../node_modules/dotenv/lib/main.js", "../src/components/tasks/task-checker.ts"],
4
+ "sourcesContent": ["{\n \"name\": \"dotenv\",\n \"version\": \"16.6.1\",\n \"description\": \"Loads environment variables from .env file\",\n \"main\": \"lib/main.js\",\n \"types\": \"lib/main.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./lib/main.d.ts\",\n \"require\": \"./lib/main.js\",\n \"default\": \"./lib/main.js\"\n },\n \"./config\": \"./config.js\",\n \"./config.js\": \"./config.js\",\n \"./lib/env-options\": \"./lib/env-options.js\",\n \"./lib/env-options.js\": \"./lib/env-options.js\",\n \"./lib/cli-options\": \"./lib/cli-options.js\",\n \"./lib/cli-options.js\": \"./lib/cli-options.js\",\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"dts-check\": \"tsc --project tests/types/tsconfig.json\",\n \"lint\": \"standard\",\n \"pretest\": \"npm run lint && npm run dts-check\",\n \"test\": \"tap run --allow-empty-coverage --disable-coverage --timeout=60000\",\n \"test:coverage\": \"tap run --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov\",\n \"prerelease\": \"npm test\",\n \"release\": \"standard-version\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git://github.com/motdotla/dotenv.git\"\n },\n \"homepage\": \"https://github.com/motdotla/dotenv#readme\",\n \"funding\": \"https://dotenvx.com\",\n \"keywords\": [\n \"dotenv\",\n \"env\",\n \".env\",\n \"environment\",\n \"variables\",\n \"config\",\n \"settings\"\n ],\n \"readmeFilename\": \"README.md\",\n \"license\": \"BSD-2-Clause\",\n \"devDependencies\": {\n \"@types/node\": \"^18.11.3\",\n \"decache\": \"^4.6.2\",\n \"sinon\": \"^14.0.1\",\n \"standard\": \"^17.0.0\",\n \"standard-version\": \"^9.5.0\",\n \"tap\": \"^19.2.0\",\n \"typescript\": \"^4.8.4\"\n },\n \"engines\": {\n \"node\": \">=12\"\n },\n \"browser\": {\n \"fs\": false\n }\n}\n", "const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\nconst packageJson = require('../package.json')\n\nconst version = packageJson.version\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n const obj = {}\n\n // Convert buffer to string\n let lines = src.toString()\n\n // Convert line breaks to same format\n lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n let match\n while ((match = LINE.exec(lines)) != null) {\n const key = match[1]\n\n // Default undefined or null to empty string\n let value = (match[2] || '')\n\n // Remove whitespace\n value = value.trim()\n\n // Check if double quoted\n const maybeQuote = value[0]\n\n // Remove surrounding quotes\n value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n // Expand newlines if double quoted\n if (maybeQuote === '\"') {\n value = value.replace(/\\\\n/g, '\\n')\n value = value.replace(/\\\\r/g, '\\r')\n }\n\n // Add to object\n obj[key] = value\n }\n\n return obj\n}\n\nfunction _parseVault (options) {\n options = options || {}\n\n const vaultPath = _vaultPath(options)\n options.path = vaultPath // parse .env.vault\n const result = DotenvModule.configDotenv(options)\n if (!result.parsed) {\n const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n err.code = 'MISSING_DATA'\n throw err\n }\n\n // handle scenario for comma separated keys - for use with key rotation\n // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n const keys = _dotenvKey(options).split(',')\n const length = keys.length\n\n let decrypted\n for (let i = 0; i < length; i++) {\n try {\n // Get full key\n const key = keys[i].trim()\n\n // Get instructions for decrypt\n const attrs = _instructions(result, key)\n\n // Decrypt\n decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n break\n } catch (error) {\n // last key\n if (i + 1 >= length) {\n throw error\n }\n // try next key\n }\n }\n\n // Parse decrypted .env string\n return DotenvModule.parse(decrypted)\n}\n\nfunction _warn (message) {\n console.log(`[dotenv@${version}][WARN] ${message}`)\n}\n\nfunction _debug (message) {\n console.log(`[dotenv@${version}][DEBUG] ${message}`)\n}\n\nfunction _log (message) {\n console.log(`[dotenv@${version}] ${message}`)\n}\n\nfunction _dotenvKey (options) {\n // prioritize developer directly setting options.DOTENV_KEY\n if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n return options.DOTENV_KEY\n }\n\n // secondary infra already contains a DOTENV_KEY environment variable\n if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n return process.env.DOTENV_KEY\n }\n\n // fallback to empty string\n return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n // Parse DOTENV_KEY. Format is a URI\n let uri\n try {\n uri = new URL(dotenvKey)\n } catch (error) {\n if (error.code === 'ERR_INVALID_URL') {\n const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n throw error\n }\n\n // Get decrypt key\n const key = uri.password\n if (!key) {\n const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get environment\n const environment = uri.searchParams.get('environment')\n if (!environment) {\n const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get ciphertext payload\n const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n if (!ciphertext) {\n const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n throw err\n }\n\n return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n let possibleVaultPath = null\n\n if (options && options.path && options.path.length > 0) {\n if (Array.isArray(options.path)) {\n for (const filepath of options.path) {\n if (fs.existsSync(filepath)) {\n possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n }\n }\n } else {\n possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n }\n } else {\n possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n }\n\n if (fs.existsSync(possibleVaultPath)) {\n return possibleVaultPath\n }\n\n return null\n}\n\nfunction _resolveHome (envPath) {\n return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (debug || !quiet) {\n _log('Loading env from encrypted .env.vault')\n }\n\n const parsed = DotenvModule._parseVault(options)\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsed, options)\n\n return { parsed }\n}\n\nfunction configDotenv (options) {\n const dotenvPath = path.resolve(process.cwd(), '.env')\n let encoding = 'utf8'\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (options && options.encoding) {\n encoding = options.encoding\n } else {\n if (debug) {\n _debug('No encoding is specified. UTF-8 is used by default')\n }\n }\n\n let optionPaths = [dotenvPath] // default, look for .env\n if (options && options.path) {\n if (!Array.isArray(options.path)) {\n optionPaths = [_resolveHome(options.path)]\n } else {\n optionPaths = [] // reset default\n for (const filepath of options.path) {\n optionPaths.push(_resolveHome(filepath))\n }\n }\n }\n\n // Build the parsed data in a temporary object (because we need to return it). Once we have the final\n // parsed data, we will combine it with process.env (or options.processEnv if provided).\n let lastError\n const parsedAll = {}\n for (const path of optionPaths) {\n try {\n // Specifying an encoding returns a string instead of a buffer\n const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n DotenvModule.populate(parsedAll, parsed, options)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${path} ${e.message}`)\n }\n lastError = e\n }\n }\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsedAll, options)\n\n if (debug || !quiet) {\n const keysCount = Object.keys(parsedAll).length\n const shortPaths = []\n for (const filePath of optionPaths) {\n try {\n const relative = path.relative(process.cwd(), filePath)\n shortPaths.push(relative)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${filePath} ${e.message}`)\n }\n lastError = e\n }\n }\n\n _log(`injecting env (${keysCount}) from ${shortPaths.join(',')}`)\n }\n\n if (lastError) {\n return { parsed: parsedAll, error: lastError }\n } else {\n return { parsed: parsedAll }\n }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n // fallback to original dotenv if DOTENV_KEY is not set\n if (_dotenvKey(options).length === 0) {\n return DotenvModule.configDotenv(options)\n }\n\n const vaultPath = _vaultPath(options)\n\n // dotenvKey exists but .env.vault file does not exist\n if (!vaultPath) {\n _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`)\n\n return DotenvModule.configDotenv(options)\n }\n\n return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n const key = Buffer.from(keyStr.slice(-64), 'hex')\n let ciphertext = Buffer.from(encrypted, 'base64')\n\n const nonce = ciphertext.subarray(0, 12)\n const authTag = ciphertext.subarray(-16)\n ciphertext = ciphertext.subarray(12, -16)\n\n try {\n const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n aesgcm.setAuthTag(authTag)\n return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n } catch (error) {\n const isRange = error instanceof RangeError\n const invalidKeyLength = error.message === 'Invalid key length'\n const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n if (isRange || invalidKeyLength) {\n const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n } else if (decryptionFailed) {\n const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n err.code = 'DECRYPTION_FAILED'\n throw err\n } else {\n throw error\n }\n }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n const debug = Boolean(options && options.debug)\n const override = Boolean(options && options.override)\n\n if (typeof parsed !== 'object') {\n const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n err.code = 'OBJECT_REQUIRED'\n throw err\n }\n\n // Set process.env\n for (const key of Object.keys(parsed)) {\n if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n if (override === true) {\n processEnv[key] = parsed[key]\n }\n\n if (debug) {\n if (override === true) {\n _debug(`\"${key}\" is already defined and WAS overwritten`)\n } else {\n _debug(`\"${key}\" is already defined and was NOT overwritten`)\n }\n }\n } else {\n processEnv[key] = parsed[key]\n }\n }\n}\n\nconst DotenvModule = {\n configDotenv,\n _configVault,\n _parseVault,\n config,\n decrypt,\n parse,\n populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n", "/**\n * cron-checker \u2014 heartbeat task that fires due cron entries.\n *\n * Reminders \u2192 pending_reminders.json (picked up by main.ts message loop)\n * Tasks \u2192 spawns kiro-cli subprocess, calls onTaskComplete callback\n */\n\nimport { logAndSwallow } from \"../log-and-swallow.js\";\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { abtarsHome } from \"../../paths.js\";\nimport { logInfo } from \"../logger.js\";\nimport { CronExpressionParser } from \"cron-parser\";\nimport { readEntries as dbReadEntries, writeEntry, removeEntry as dbRemoveEntry } from \"./task-store.js\";\nimport type { CronEntry } from \"../../cli/abtars-task.js\";\n\nconst TAG = \"cron-checker\";\nconst memoryDir = (): string => join(abtarsHome(), \"state\");\nconst remindersPath = (): string => join(memoryDir(), \"pending_reminders.json\");\n\nexport interface PendingReminder {\n chatId: number;\n message: string;\n createdAt: number;\n threadId?: number;\n}\n\nexport function readPendingReminders(): PendingReminder[] {\n if (!existsSync(remindersPath())) return [];\n try { return JSON.parse(readFileSync(remindersPath(), \"utf-8\")) as PendingReminder[]; }\n catch (err) { logAndSwallow(TAG, \"readPendingReminders\", err); return []; }\n}\n\nexport function clearPendingReminders(): void {\n if (existsSync(remindersPath())) writeFileSync(remindersPath(), \"[]\", \"utf-8\");\n}\n\nexport function appendReminder(r: PendingReminder): void {\n mkdirSync(memoryDir(), { recursive: true });\n const existing = readPendingReminders();\n existing.push(r);\n writeFileSync(remindersPath(), JSON.stringify(existing, null, 2), \"utf-8\");\n}\n\nconst MAX_HISTORY = 10;\nconst GC_AGE_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\n/** Record a run in the entry's history (keeps last MAX_HISTORY). */\nexport function recordRun(entry: CronEntry, exitCode?: number): void {\n if (!entry.history) entry.history = [];\n entry.history.push({ ts: Date.now(), ...(exitCode !== undefined ? { exitCode } : {}) });\n if (entry.history.length > MAX_HISTORY) entry.history = entry.history.slice(-MAX_HISTORY);\n}\n\n\n/**\n * Scan tasks.json for due entries. Fires reminders directly.\n * Returns due task entries (script + agent) for the CronQueue to process.\n * Advances fireAt and writes tasks.json.\n */\nexport function checkCron(): CronEntry[] {\n let entries = dbReadEntries();\n const now = Date.now();\n const dueTasks: CronEntry[] = [];\n\n // GC: remove fired one-shots older than 7 days\n for (const e of entries) {\n if (e.fired && !e.schedule && now - e.createdAt > GC_AGE_MS) {\n dbRemoveEntry(e.id);\n logInfo(TAG, `\uD83D\uDDD1\uFE0F GC: pruned old fired entry ${e.id}`);\n }\n }\n entries = entries.filter(e => !(e.fired && !e.schedule && now - e.createdAt > GC_AGE_MS));\n\n for (const entry of entries) {\n if (entry.fired || entry.paused || entry.fireAt > now) continue;\n\n // #692: daily rate limit \u2014 skip if maxRunsPerDay reached (count only successful runs)\n if (entry.maxRunsPerDay && entry.history) {\n const todayStart = new Date().setHours(0, 0, 0, 0);\n const todaySuccesses = entry.history.filter(h => h.ts >= todayStart && h.exitCode !== 1).length;\n if (todaySuccesses >= entry.maxRunsPerDay) {\n // Advance to next occurrence without running\n if (entry.schedule) {\n try {\n const expr = CronExpressionParser.parse(entry.schedule);\n entry.fireAt = expr.next().getTime();\n writeEntry(entry);\n } catch (err) { logAndSwallow(\"cron_checker\", \"op\", err); }\n }\n continue;\n }\n }\n\n // #327: stale detection \u2014 if past the catch-up window, advance to next occurrence\n if (entry.schedule && entry.fireAt <= now) {\n const maxDelay = (entry.catchUp ?? 0) * 3600_000;\n // Only consider stale if missed by more than one full interval (at minimum 5 min)\n const MIN_STALE_MS = 5 * 60_000;\n const staleThreshold = Math.max(maxDelay, MIN_STALE_MS);\n if (now - entry.fireAt > staleThreshold) {\n try {\n const expr = CronExpressionParser.parse(entry.schedule);\n entry.fireAt = expr.next().getTime();\n writeEntry(entry);\n logInfo(TAG, `\u23ED\uFE0F Stale \"${entry.id}\" \u2014 advanced to next occurrence`);\n } catch (err) { logAndSwallow(\"cron_checker\", \"op\", err); }\n continue;\n }\n }\n\n entry.lastRanAt = now;\n const wasRetry = !!entry._retrying;\n if (entry.schedule) {\n try {\n const expr = CronExpressionParser.parse(entry.schedule);\n entry.fireAt = expr.next().getTime();\n } catch (err) { logAndSwallow(TAG, \"cron parse next\", err); entry.fired = true; }\n } else {\n entry.fired = true;\n }\n delete entry._retrying;\n\n if (entry.type === \"reminder\") {\n appendReminder({ chatId: entry.chatId, message: entry.message, createdAt: now });\n recordRun(entry);\n logInfo(TAG, `\u23F0 Reminder fired: \"${entry.message}\" \u2192 chat ${entry.chatId}`);\n } else {\n dueTasks.push({ ...entry, _retrying: wasRetry || undefined });\n }\n\n writeEntry(entry);\n }\n\n return dueTasks;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["path"]
7
7
  }
@@ -1,29 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
3
- import {
4
- init_log_and_swallow,
5
- logAndSwallow
6
- } from "./chunk-EX2SRTUE.js";
7
3
  import {
8
4
  getEnv,
9
5
  init_env_schema
10
- } from "./chunk-PZE3J7ER.js";
6
+ } from "./chunk-3OXQWII3.js";
7
+ import {
8
+ init_log_and_swallow,
9
+ logAndSwallow
10
+ } from "./chunk-CYSGXNBY.js";
11
11
  import {
12
12
  init_logger,
13
13
  logDebug,
14
14
  logInfo,
15
15
  logWarn
16
- } from "./chunk-2BY6I4P5.js";
16
+ } from "./chunk-GUTRAMK3.js";
17
17
  import {
18
18
  abtarsHome,
19
19
  init_paths
20
- } from "./chunk-MJ6PHMOK.js";
20
+ } from "./chunk-WW5F2DCO.js";
21
21
 
22
22
  // src/capabilities/browser/browser-manager.ts
23
23
  init_log_and_swallow();
24
24
  init_logger();
25
25
  init_env_schema();
26
- import { chromium } from "patchright";
27
26
  import { execFileSync } from "node:child_process";
28
27
  var TAG = "browser_mgr";
29
28
  function readPositiveInt(key, fallback) {
@@ -97,6 +96,7 @@ var BrowserManager = class _BrowserManager {
97
96
  return this._launching;
98
97
  }
99
98
  async _launchPatchright() {
99
+ const { chromium } = await import("patchright");
100
100
  const headed = getEnv().browserHeaded;
101
101
  const args = headed ? [] : ["--headless=new"];
102
102
  if (getEnv().browserNoSandbox) args.push("--no-sandbox");
@@ -361,7 +361,7 @@ var BrowserTool = class {
361
361
  if (getEnv().ssrfCheck) {
362
362
  try {
363
363
  const { hostname } = new URL(url);
364
- const { isPrivateHost } = await import("./ssrf-guard-E2KBBC5E.js");
364
+ const { isPrivateHost } = await import("./ssrf-guard-R4P5OCTO.js");
365
365
  if (await isPrivateHost(hostname)) {
366
366
  return { success: false, error: `Blocked: "${hostname}" resolves to a private/internal IP address` };
367
367
  }
@@ -756,4 +756,4 @@ export {
756
756
  BrowserIpcServer,
757
757
  DomainAllowlist
758
758
  };
759
- //# sourceMappingURL=chunk-KSEIWT4T.js.map
759
+ //# sourceMappingURL=chunk-JFKOPNKL.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/capabilities/browser/browser-manager.ts", "../src/capabilities/browser/browser-tool.ts", "../src/components/content-extractor.ts", "../src/capabilities/browser/browser-ipc-server.ts", "../src/capabilities/browser/domain-allowlist.ts"],
4
+ "sourcesContent": ["import { logAndSwallow } from \"../../components/log-and-swallow.js\";\nimport { logInfo, logWarn } from \"../../components/logger.js\";\nimport { getEnv } from \"../../components/env-schema.js\";\nimport type { Browser, BrowserContext, Page } from \"patchright\";\nimport { execFileSync } from \"node:child_process\";\nimport type { BrowserSession } from \"../../types/browser.js\";\n\nconst TAG = \"browser_mgr\";\n\n// ---------------------------------------------------------------------------\n// Environment variable parsing\n\nfunction readPositiveInt(key: string, fallback: number): number {\n const raw = process.env[key];\n if (!raw) return fallback;\n const n = Number(raw);\n return Number.isFinite(n) && Number.isInteger(n) && n > 0 ? n : fallback;\n}\n// ---------------------------------------------------------------------------\n\n\nconst DEFAULTS = {\n BROWSER_SESSION_TIMEOUT_MS: 300_000,\n BROWSER_MAX_SESSIONS: 3,\n WEB_SCRAPE_USER_AGENT: \"Mozilla/5.0 (compatible; Abtars/1.0)\",\n} as const;\n\nexport type BrowserEngine = \"patchright\";\n\nexport interface BrowserConfig {\n sessionTimeoutMs: number;\n maxSessions: number;\n userAgent: string;\n engine: BrowserEngine;\n}\n\n/**\n * Read and validate browser-related env vars, returning resolved config.\n * Invalid values trigger a console.warn and fall back to defaults.\n * Exported for testability (Property 16).\n */\nexport function parseBrowserConfig(): BrowserConfig {\n const sessionTimeoutMs = readPositiveInt(\n \"BROWSER_SESSION_TIMEOUT_MS\",\n DEFAULTS.BROWSER_SESSION_TIMEOUT_MS,\n );\n const maxSessions = readPositiveInt(\n \"BROWSER_MAX_SESSIONS\",\n DEFAULTS.BROWSER_MAX_SESSIONS,\n );\n // Intentional: raw process.env \u2014 tests mutate this at runtime, getEnv() cache won't reflect changes\n const userAgent = process.env[\"WEB_SCRAPE_USER_AGENT\"]?.trim() || DEFAULTS.WEB_SCRAPE_USER_AGENT;\n\n const engine = \"patchright\" as BrowserEngine;\n\n return { sessionTimeoutMs, maxSessions, userAgent, engine };\n}\n\n// ---------------------------------------------------------------------------\n// BrowserManager singleton\n// ---------------------------------------------------------------------------\n\nexport class BrowserManager {\n private static _instance: BrowserManager | null = null;\n\n private _browser: Browser | null = null;\n private _launching: Promise<Browser> | null = null;\n private readonly _sessions = new Map<string, BrowserSession>();\n private _idleTimer: ReturnType<typeof setInterval> | null = null;\n private readonly _config: BrowserConfig;\n private _lastActivityAt = 0;\n private readonly _containerIdleStopMs: number;\n\n constructor(config?: BrowserConfig) {\n this._config = config ?? parseBrowserConfig();\n this._containerIdleStopMs = getEnv().browserIdleStopMin * 60_000;\n this._startIdleCheck();\n }\n\n /** Get (or create) the singleton instance. */\n static getInstance(): BrowserManager {\n if (!BrowserManager._instance) {\n BrowserManager._instance = new BrowserManager();\n }\n return BrowserManager._instance;\n }\n\n /** Reset singleton \u2014 primarily for testing. */\n static resetInstance(): void {\n BrowserManager._instance = null;\n }\n\n // -------------------------------------------------------------------------\n // Browser lifecycle\n // -------------------------------------------------------------------------\n\n /** Lazily launch or return the existing browser instance. */\n private async _ensureBrowser(): Promise<Browser> {\n if (this._browser?.isConnected()) return this._browser;\n\n // Avoid duplicate launches if multiple callers race.\n if (this._launching) return this._launching;\n\n this._launching = this._launchPatchright().then((browser) => {\n this._browser = browser;\n this._launching = null;\n browser.on(\"disconnected\", () => {\n this._browser = null;\n this._sessions.clear();\n });\n return browser;\n }).catch((err) => {\n this._launching = null;\n throw err;\n });\n\n return this._launching;\n }\n\n private async _launchPatchright(): Promise<Browser> {\n const { chromium } = await import(\"patchright\");\n const headed = getEnv().browserHeaded;\n const args = headed ? [] : [\"--headless=new\"];\n if (getEnv().browserNoSandbox) args.push(\"--no-sandbox\");\n return chromium.launch({\n headless: !headed,\n channel: getEnv().browserChannel,\n args,\n });\n }\n\n // -------------------------------------------------------------------------\n // Named sessions\n // -------------------------------------------------------------------------\n\n /**\n * Get or create a named browser session.\n * Reusing an existing session updates `lastActivityAt`.\n */\n async getSession(sessionId: string): Promise<BrowserSession> {\n const existing = this._sessions.get(sessionId);\n if (existing) {\n existing.lastActivityAt = Date.now();\n return existing;\n }\n\n // Enforce max sessions.\n if (this._sessions.size >= this._config.maxSessions) {\n const activeIds = [...this._sessions.keys()].join(\", \");\n throw new Error(\n `Maximum concurrent sessions (${this._config.maxSessions}) reached. ` +\n `Close an existing session first. Active sessions: ${activeIds}`,\n );\n }\n\n const browser = await this._ensureBrowser();\n const context = await browser.newContext({\n userAgent: this._config.userAgent,\n });\n const page = await context.newPage();\n const now = Date.now();\n\n const session: BrowserSession = {\n sessionId,\n context,\n page,\n createdAt: now,\n lastActivityAt: now,\n };\n\n this._sessions.set(sessionId, session);\n this._lastActivityAt = now;\n return session;\n }\n\n /** Close a named session and release its resources. */\n async closeSession(sessionId: string): Promise<void> {\n const session = this._sessions.get(sessionId);\n if (!session) return;\n\n this._sessions.delete(sessionId);\n try {\n await session.context.close();\n } catch (err) {\n logAndSwallow(TAG, \"closeSession context.close\", err);\n }\n }\n\n // -------------------------------------------------------------------------\n // One-off contexts (ingestion scrapes)\n // -------------------------------------------------------------------------\n\n /** Create a disposable context + page for ingestion. No session tracking. */\n async createOneOffContext(): Promise<{ context: BrowserContext; page: Page }> {\n const browser = await this._ensureBrowser();\n const context = await browser.newContext({\n userAgent: this._config.userAgent,\n });\n const page = await context.newPage();\n return { context, page };\n }\n\n /** Close a one-off context after use. */\n async closeContext(context: BrowserContext): Promise<void> {\n try {\n await context.close();\n } catch (err) {\n logAndSwallow(TAG, \"closeContext\", err);\n }\n }\n\n // -------------------------------------------------------------------------\n // Shutdown & cleanup\n // -------------------------------------------------------------------------\n\n /** Shut down everything: all sessions, the browser, cleanup timers. */\n async shutdown(): Promise<void> {\n this._stopIdleCheck();\n\n // Close all named sessions.\n const closePromises = [...this._sessions.keys()].map((id) =>\n this.closeSession(id),\n );\n await Promise.all(closePromises);\n\n // Close the browser itself.\n if (this._browser) {\n try {\n await this._browser.close();\n } catch (err) {\n logAndSwallow(TAG, \"browser.close shutdown\", err);\n }\n this._browser = null;\n }\n }\n\n // -------------------------------------------------------------------------\n // Idle-check interval\n // -------------------------------------------------------------------------\n\n private _startIdleCheck(): void {\n // Check every 30 seconds for idle sessions.\n this._idleTimer = setInterval(() => {\n void this._sweepIdleSessions();\n }, 30_000);\n\n // Don't prevent Node from exiting.\n if (this._idleTimer && typeof this._idleTimer === \"object\" && \"unref\" in this._idleTimer) {\n this._idleTimer.unref();\n }\n }\n\n private _stopIdleCheck(): void {\n if (this._idleTimer) {\n clearInterval(this._idleTimer);\n this._idleTimer = null;\n }\n }\n\n private async _sweepIdleSessions(): Promise<void> {\n const now = Date.now();\n const expired: string[] = [];\n\n for (const [id, session] of this._sessions) {\n if (now - session.lastActivityAt > this._config.sessionTimeoutMs) {\n expired.push(id);\n }\n }\n\n for (const id of expired) {\n logWarn(\"browser\", `Closing idle session \"${id}\".`);\n await this.closeSession(id);\n }\n\n // Stop container if no sessions and idle long enough\n if (this._sessions.size === 0 && this._browser && this._lastActivityAt > 0 && now - this._lastActivityAt > this._containerIdleStopMs) {\n logInfo(\"browser\", `No sessions for ${Math.round((now - this._lastActivityAt) / 60_000)}min \u2014 stopping container.`);\n await this.shutdown();\n this._stopContainer();\n }\n }\n\n private _stopContainer(): void {\n try {\n execFileSync(\"docker\", [\"stop\", \"abtars-browser\"], { stdio: \"pipe\", timeout: 10_000 });\n } catch (err) { logAndSwallow(\"browser_manager\", \"op\", err); }\n }\n\n // -------------------------------------------------------------------------\n // Accessors\n // -------------------------------------------------------------------------\n\n /** Number of active named sessions. */\n get activeSessionCount(): number {\n return this._sessions.size;\n }\n\n /** Exposed for testing \u2014 the resolved config. */\n get config(): BrowserConfig {\n return this._config;\n }\n}\n", "import { logDebug } from \"../../components/logger.js\";\nimport { logAndSwallow } from \"../../components/log-and-swallow.js\";\nimport { getEnv } from \"../../components/env-schema.js\";\n\nconst TAG = \"browser_tool\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { readFileSync } from \"node:fs\";\nimport type { BrowserAction, BrowserToolResult, PageElement } from \"../../types/browser.js\";\nimport type { BrowserManager } from \"./browser-manager.js\";\nimport type { DomainAllowlist } from \"./domain-allowlist.js\";\nimport { extractTextFromPage } from \"../../components/content-extractor.js\";\n\nconst LOG_PREFIX = \"[browser-tool]\";\n\n/** Max characters returned by extract_text before truncation. */\nconst TEXT_TRUNCATION_LIMIT = 4000;\n\n/** Max interactive elements returned by get_page_info. */\nconst MAX_PAGE_ELEMENTS = 50;\n\n/** Read navigation timeout from env, default 30 000 ms. */\nfunction getNavigationTimeout(): number {\n const raw = String(getEnv().webScrapePlaywrightTimeoutMs);\n if (raw === undefined || raw === \"\") return 30_000;\n const n = Number(raw);\n if (!Number.isFinite(n) || n <= 0) return 30_000;\n return n;\n}\n\n/**\n * Implements the seven browser actions (navigate, click, fill, extract_text,\n * screenshot, get_page_info, close_session). Pure action dispatch \u2014 receives\n * parsed args, calls BrowserManager + Playwright APIs, returns structured JSON.\n */\nexport class BrowserTool {\n private readonly _browserManager: BrowserManager;\n private readonly _domainAllowlist: DomainAllowlist;\n\n constructor(browserManager: BrowserManager, domainAllowlist: DomainAllowlist) {\n this._browserManager = browserManager;\n this._domainAllowlist = domainAllowlist;\n }\n\n /** Execute a browser action and return a JSON-serializable result. */\n async execute(action: BrowserAction): Promise<BrowserToolResult> {\n try {\n switch (action.action) {\n case \"navigate\":\n return await this._handleNavigate(action);\n case \"click\":\n return await this._handleClick(action);\n case \"fill\":\n return await this._handleFill(action);\n case \"extract_text\":\n return await this._handleExtractText(action);\n case \"screenshot\":\n return await this._handleScreenshot(action);\n case \"get_page_info\":\n return await this._handleGetPageInfo(action);\n case \"close_session\":\n return await this._handleCloseSession(action);\n case \"set_cookie\":\n return await this._handleSetCookie(action);\n default:\n return { success: false, error: `Unknown action: ${String((action as BrowserAction).action)}` };\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { success: false, error: message };\n }\n }\n\n // -------------------------------------------------------------------------\n // navigate\n // -------------------------------------------------------------------------\n\n private async _handleNavigate(action: BrowserAction): Promise<BrowserToolResult> {\n const url = action.url;\n if (!url) {\n return { success: false, error: \"navigate action requires a url\" };\n }\n\n // Domain allowlist check\n if (!this._domainAllowlist.isAllowed(url)) {\n let hostname: string;\n try {\n hostname = new URL(url).hostname;\n } catch (err) {\n logAndSwallow(TAG, \"parse URL hostname\", err);\n hostname = url;\n }\n return {\n success: false,\n error: `Domain \"${hostname}\" is not in the allowed list. Allowed patterns: ${this._domainAllowlist.patterns.join(\", \")}`,\n };\n }\n\n // SSRF protection: reject private/internal IPs\n if (getEnv().ssrfCheck) {\n try {\n const { hostname } = new URL(url);\n const { isPrivateHost } = await import(\"./ssrf-guard.js\");\n if (await isPrivateHost(hostname)) {\n return { success: false, error: `Blocked: \"${hostname}\" resolves to a private/internal IP address` };\n }\n } catch (err) {\n logAndSwallow(TAG, \"SSRF check\", err);\n return { success: false, error: \"Invalid URL\" };\n }\n }\n\n const session = await this._browserManager.getSession(action.sessionId);\n const timeout = getNavigationTimeout();\n\n logDebug(\"browser\", `${LOG_PREFIX} navigate session=\"${action.sessionId}\" url=\"${url}\"`);\n\n try {\n const response = await session.page.goto(url, {\n waitUntil: \"domcontentloaded\",\n timeout,\n });\n\n const title = await session.page.title();\n const finalUrl = session.page.url();\n const status = response?.status();\n\n return { success: true, title, url: finalUrl, status };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { success: false, error: `Navigation failed for ${url}: ${message}` };\n }\n }\n\n // -------------------------------------------------------------------------\n // click\n // -------------------------------------------------------------------------\n\n private async _handleClick(action: BrowserAction): Promise<BrowserToolResult> {\n const selector = action.selector;\n if (!selector) {\n return { success: false, error: \"click action requires a selector\" };\n }\n\n const session = await this._browserManager.getSession(action.sessionId);\n\n logDebug(\"browser\", `${LOG_PREFIX} click session=\"${action.sessionId}\" selector=\"${selector}\"`);\n\n try {\n // Use Promise.race to detect if click triggers navigation\n const navigationPromise = session.page\n .waitForNavigation({ waitUntil: \"domcontentloaded\", timeout: 5000 })\n .catch(err => { logAndSwallow(TAG, \"waitForNavigation click\", err); return null; });\n\n await session.page.click(selector);\n\n const navResult = await navigationPromise;\n\n if (navResult) {\n const title = await session.page.title();\n const url = session.page.url();\n return { success: true, navigated: true, title, url };\n }\n\n return { success: true, navigated: false };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes(\"waiting for selector\") || message.includes(\"No element\")) {\n return { success: false, error: `Selector not found: \"${selector}\"` };\n }\n return { success: false, error: `Click failed for selector \"${selector}\": ${message}` };\n }\n }\n\n // -------------------------------------------------------------------------\n // fill\n // -------------------------------------------------------------------------\n\n private async _handleFill(action: BrowserAction): Promise<BrowserToolResult> {\n const selector = action.selector;\n const value = action.value;\n if (!selector) {\n return { success: false, error: \"fill action requires a selector\" };\n }\n if (value === undefined) {\n return { success: false, error: \"fill action requires a value\" };\n }\n\n const session = await this._browserManager.getSession(action.sessionId);\n\n // Check if the target is a password field to mask in logs\n let isPassword = false;\n try {\n isPassword = await session.page.evaluate(\n `(sel) => { const el = document.querySelector(sel); return el instanceof HTMLInputElement && el.type === \"password\"; }`,\n selector,\n ) as boolean;\n } catch (err) {\n logAndSwallow(TAG, \"evaluate isPassword\", err);\n }\n\n const logValue = isPassword ? \"***\" : value;\n logDebug(\"browser\",\n `${LOG_PREFIX} fill session=\"${action.sessionId}\" selector=\"${selector}\" value=\"${logValue}\"`,\n );\n\n try {\n await session.page.fill(selector, value);\n return { success: true };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes(\"waiting for selector\") || message.includes(\"No element\")) {\n return { success: false, error: `Selector not found: \"${selector}\"` };\n }\n return { success: false, error: `Fill failed for selector \"${selector}\": ${message}` };\n }\n }\n\n // -------------------------------------------------------------------------\n // extract_text\n // -------------------------------------------------------------------------\n\n private async _handleExtractText(action: BrowserAction): Promise<BrowserToolResult> {\n const session = await this._browserManager.getSession(action.sessionId);\n\n logDebug(\"browser\",\n `${LOG_PREFIX} extract_text session=\"${action.sessionId}\" selector=\"${action.selector ?? \"(full page)\"}\"`,\n );\n\n try {\n const text = await extractTextFromPage(session.page, action.selector ?? undefined);\n\n if (!text || text.trim().length === 0) {\n return { success: false, error: \"No text content found on the page\" };\n }\n\n const truncated = text.length > TEXT_TRUNCATION_LIMIT;\n const resultText = truncated ? text.slice(0, TEXT_TRUNCATION_LIMIT) : text;\n\n return { success: true, text: resultText, truncated };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes(\"waiting for selector\") || message.includes(\"No element\")) {\n return { success: false, error: `Selector not found: \"${action.selector}\"` };\n }\n return { success: false, error: `Text extraction failed: ${message}` };\n }\n }\n\n // -------------------------------------------------------------------------\n // screenshot\n // -------------------------------------------------------------------------\n\n private async _handleScreenshot(action: BrowserAction): Promise<BrowserToolResult> {\n const session = await this._browserManager.getSession(action.sessionId);\n\n const tmpFile = path.join(\n os.tmpdir(),\n `abtars-screenshot-${Date.now()}.png`,\n );\n\n logDebug(\"browser\",\n `${LOG_PREFIX} screenshot session=\"${action.sessionId}\" fullPage=${action.fullPage ?? false} path=\"${tmpFile}\"`,\n );\n\n await session.page.screenshot({\n fullPage: action.fullPage ?? false,\n path: tmpFile,\n });\n\n return { success: true, filePath: tmpFile };\n }\n\n // -------------------------------------------------------------------------\n // get_page_info\n // -------------------------------------------------------------------------\n\n private async _handleGetPageInfo(action: BrowserAction): Promise<BrowserToolResult> {\n const session = await this._browserManager.getSession(action.sessionId);\n\n logDebug(\"browser\", `${LOG_PREFIX} get_page_info session=\"${action.sessionId}\"`);\n\n const title = await session.page.title();\n const url = session.page.url();\n\n const elements = await session.page.evaluate(`(maxElements) => {\n const selectors = \"a, button, input, select, textarea, [role='button'], [role='link']\";\n const nodes = document.querySelectorAll(selectors);\n const results = [];\n\n for (let i = 0; i < nodes.length && results.length < maxElements; i++) {\n const el = nodes[i];\n if (!el || !(el instanceof HTMLElement)) continue;\n\n const style = window.getComputedStyle(el);\n if (style.display === \"none\" || style.visibility === \"hidden\") continue;\n\n let selector = el.tagName.toLowerCase();\n if (el.id) {\n selector = \"#\" + el.id;\n } else if (el.className && typeof el.className === \"string\" && el.className.trim()) {\n const cls = el.className.trim().split(/\\\\s+/).slice(0, 2).join(\".\");\n selector = el.tagName.toLowerCase() + \".\" + cls;\n } else {\n const parent = el.parentElement;\n if (parent) {\n const siblings = parent.querySelectorAll(\":scope > \" + el.tagName.toLowerCase());\n if (siblings.length > 1) {\n const idx = Array.from(siblings).indexOf(el) + 1;\n selector = el.tagName.toLowerCase() + \":nth-of-type(\" + idx + \")\";\n }\n }\n }\n\n const entry = { tag: el.tagName.toLowerCase(), selector };\n const text = (el.textContent || \"\").trim().slice(0, 100);\n if (text) entry.text = text;\n\n if (el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement) {\n if (el instanceof HTMLInputElement && el.type) entry.type = el.type;\n if (el.name) entry.name = el.name;\n if (el instanceof HTMLInputElement && el.placeholder) entry.placeholder = el.placeholder;\n if (el instanceof HTMLTextAreaElement && el.placeholder) entry.placeholder = el.placeholder;\n }\n\n if (el instanceof HTMLAnchorElement && el.href) {\n entry.href = el.href;\n }\n\n results.push(entry);\n }\n\n return results;\n }`, MAX_PAGE_ELEMENTS) as PageElement[];\n\n return {\n success: true,\n url,\n title,\n elements,\n };\n }\n\n // -------------------------------------------------------------------------\n // close_session\n // -------------------------------------------------------------------------\n\n private async _handleCloseSession(action: BrowserAction): Promise<BrowserToolResult> {\n logDebug(\"browser\", `${LOG_PREFIX} close_session session=\"${action.sessionId}\"`);\n await this._browserManager.closeSession(action.sessionId);\n return { success: true };\n }\n\n // -------------------------------------------------------------------------\n // set_cookie\n // -------------------------------------------------------------------------\n\n private async _handleSetCookie(action: BrowserAction): Promise<BrowserToolResult> {\n const file = action.cookieFile;\n if (!file) return { success: false, error: \"set_cookie requires --cookie-file\" };\n\n // Only allow files under /run/browser/cookies (mounted read-only)\n const COOKIES_DIR = \"/run/browser/cookies\";\n const resolved = path.resolve(file);\n if (!resolved.startsWith(COOKIES_DIR)) {\n return { success: false, error: `cookie file must be under ${COOKIES_DIR}` };\n }\n\n const raw = readFileSync(resolved, \"utf-8\");\n const json = JSON.parse(raw) as Record<string, string>;\n\n const session = await this._browserManager.getSession(action.sessionId);\n const url = action.url ?? session.page.url();\n let domain: string;\n try { domain = new URL(url).hostname; } catch (err) { logAndSwallow(TAG, \"parse cookie domain\", err); domain = \"\"; }\n\n const cookies = Object.entries(json).map(([name, value]) => ({\n name, value: String(value), domain, path: \"/\",\n }));\n\n await session.context.addCookies(cookies);\n logDebug(\"browser\", `${LOG_PREFIX} set_cookie session=\"${action.sessionId}\" loaded ${cookies.length} cookies for ${domain}`);\n return { success: true, text: `Loaded ${cookies.length} cookies for ${domain}` };\n }}\n", "import type { Page } from \"patchright\";\n\n/**\n * Strips non-content HTML elements and returns clean plain text.\n * Shared by both the agent tool's extract_text action and the ingestion WebScraper.\n *\n * Uses regex-based approach for raw HTML strings (no DOM available in Node.js).\n * Uses page.evaluate() for live Playwright pages (DOM APIs available in browser).\n */\n\n/** Tags whose entire content (including children) should be removed. */\nconst STRIPPED_TAGS = [\"script\", \"style\", \"nav\", \"footer\", \"header\", \"aside\"];\n\n/** Build a regex that matches an opening tag through its closing tag (non-greedy, case-insensitive). */\nfunction buildTagStripRegex(tag: string): RegExp {\n return new RegExp(`<${tag}[^>]*>[\\\\s\\\\S]*?<\\\\/${tag}>`, \"gi\");\n}\n\n/** Regex to match elements with role=\"navigation\" or role=\"banner\". */\nconst ROLE_STRIP_REGEX =\n /<[a-z][a-z0-9]*\\s[^>]*?\\brole\\s*=\\s*[\"'](navigation|banner)[\"'][^>]*>[\\s\\S]*?<\\/[a-z][a-z0-9]*>/gi;\n\n/** Regex to match any remaining HTML tag. */\nconst HTML_TAG_REGEX = /<[^>]+>/g;\n\n/** Common HTML entities to decode. */\nconst ENTITY_MAP: Record<string, string> = {\n \"&amp;\": \"&\",\n \"&lt;\": \"<\",\n \"&gt;\": \">\",\n \"&quot;\": '\"',\n \"&#39;\": \"'\",\n \"&nbsp;\": \" \",\n};\n\nconst ENTITY_REGEX = /&amp;|&lt;|&gt;|&quot;|&#39;|&nbsp;/g;\n\n/**\n * Parse raw HTML string and return clean text.\n * Removes non-content elements, strips tags, decodes entities, collapses whitespace.\n * Returns empty string on empty/whitespace-only input.\n */\nexport function extractTextFromHtml(html: string): string {\n if (!html || !html.trim()) return \"\";\n\n let text = html;\n\n // 1. Remove stripped tag elements and their content\n for (const tag of STRIPPED_TAGS) {\n text = text.replace(buildTagStripRegex(tag), \"\");\n }\n\n // 2. Remove elements with role=\"navigation\" or role=\"banner\"\n text = text.replace(ROLE_STRIP_REGEX, \"\");\n\n // 3. Strip all remaining HTML tags\n text = text.replace(HTML_TAG_REGEX, \" \");\n\n // 4. Decode common HTML entities\n text = text.replace(ENTITY_REGEX, (match) => ENTITY_MAP[match] ?? match);\n\n // 5. Collapse consecutive whitespace into single spaces/newlines\n // First normalize newlines, then collapse blank lines, then collapse spaces\n text = text.replace(/\\r\\n/g, \"\\n\");\n text = text.replace(/[ \\t]+/g, \" \");\n text = text.replace(/\\n[ ]+/g, \"\\n\");\n text = text.replace(/[ ]+\\n/g, \"\\n\");\n text = text.replace(/\\n{2,}/g, \"\\n\");\n\n return text.trim();\n}\n\n/**\n * JavaScript source executed inside the browser context via page.evaluate().\n * Uses DOM APIs (document, HTMLElement, etc.) which are only available at runtime.\n * Accepts a single argument: the CSS selector string or null for full-page extraction.\n */\nconst BROWSER_EXTRACT_FN = `\n(sel) => {\n const TAGS = [\"script\", \"style\", \"nav\", \"footer\", \"header\", \"aside\"];\n const ROLES = [\"navigation\", \"banner\"];\n\n const root = sel ? document.querySelector(sel) : document.body;\n if (!root) return \"\";\n\n const clone = root.cloneNode(true);\n\n for (const tag of TAGS) {\n for (const el of clone.querySelectorAll(tag)) el.remove();\n }\n for (const role of ROLES) {\n for (const el of clone.querySelectorAll('[role=\"' + role + '\"]')) el.remove();\n }\n\n let text = clone.textContent || \"\";\n text = text.replace(/\\\\u00a0/g, \" \");\n text = text.replace(/[ \\\\t]+/g, \" \");\n text = text.replace(/\\\\n[ ]+/g, \"\\\\n\");\n text = text.replace(/[ ]+\\\\n/g, \"\\\\n\");\n text = text.replace(/\\\\n{2,}/g, \"\\\\n\");\n return text.trim();\n}\n`;\n\n/**\n * Extract clean text from a live Playwright Page (runs in browser context).\n * Optionally scoped to a CSS selector. Returns empty string on failure.\n */\nexport async function extractTextFromPage(\n page: Page,\n selector?: string,\n): Promise<string> {\n const text = await page.evaluate<string, string | null>(\n new Function(\"sel\", `return (${BROWSER_EXTRACT_FN})(sel)`) as (sel: string | null) => string,\n selector ?? null,\n );\n\n return text ?? \"\";\n}\n", "import { logDebug } from \"../../components/logger.js\";\nimport { logAndSwallow } from \"../../components/log-and-swallow.js\";\nimport * as net from \"node:net\";\n\nconst TAG = \"browser_ipc\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { BrowserAction, BrowserToolResult } from \"../../types/browser.js\";\nimport type { BrowserTool } from \"./browser-tool.js\";\nimport { abtarsHome } from \"../../paths.js\";\n\nconst LOG_PREFIX = \"[browser-ipc]\";\n\n/** Default socket path: ~/.abtars/browser.sock */\nexport function getDefaultSocketPath(): string {\n return path.join(abtarsHome(), \"browser-socket\", \"browser.sock\");\n}\n\n/**\n * Unix domain socket server that routes BrowserAction requests\n * to a BrowserTool instance, enabling session persistence across\n * CLI invocations.\n *\n * Protocol: client connects \u2192 sends one JSON line \u2192 receives one JSON line \u2192 connection closes.\n */\nexport class BrowserIpcServer {\n private _server: net.Server | null = null;\n private readonly _tool: BrowserTool;\n private readonly _socketPath: string;\n\n constructor(tool: BrowserTool, socketPath?: string) {\n this._tool = tool;\n this._socketPath = socketPath ?? getDefaultSocketPath();\n }\n\n get socketPath(): string {\n return this._socketPath;\n }\n\n get isListening(): boolean {\n return this._server?.listening ?? false;\n }\n\n /** Start listening. Removes stale socket file if present. */\n async start(): Promise<void> {\n // Ensure parent directory exists.\n const dir = path.dirname(this._socketPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Remove stale socket file from a previous run.\n this._removeSocketFile();\n\n return new Promise<void>((resolve, reject) => {\n const server = net.createServer({ allowHalfOpen: true }, (conn) => {\n this._handleConnection(conn);\n });\n\n server.on(\"error\", (err) => {\n console.error(`${LOG_PREFIX} Server error: ${err.message}`);\n reject(err);\n });\n\n server.listen(this._socketPath, () => {\n this._server = server;\n logDebug(\"browser\", `${LOG_PREFIX} Listening on ${this._socketPath}`);\n resolve();\n });\n });\n }\n\n /** Stop the server and remove the socket file. */\n async shutdown(): Promise<void> {\n return new Promise<void>((resolve) => {\n if (!this._server) {\n this._removeSocketFile();\n resolve();\n return;\n }\n\n this._server.close(() => {\n this._server = null;\n this._removeSocketFile();\n logDebug(\"browser\", `${LOG_PREFIX} Shut down`);\n resolve();\n });\n });\n }\n\n // \u2500\u2500 Connection handler \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n private _handleConnection(conn: net.Socket): void {\n let data = \"\";\n\n conn.on(\"data\", (chunk) => {\n data += chunk.toString();\n });\n\n conn.on(\"end\", () => {\n void this._processRequest(data, conn);\n });\n\n conn.on(\"error\", (err) => {\n console.error(`${LOG_PREFIX} Connection error: ${err.message}`);\n });\n }\n\n private async _processRequest(\n raw: string,\n conn: net.Socket,\n ): Promise<void> {\n let result: BrowserToolResult;\n\n try {\n const action = JSON.parse(raw.trim()) as BrowserAction;\n result = await this._tool.execute(action);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n result = { success: false, error: `IPC parse/execute error: ${message}` };\n }\n\n conn.end(JSON.stringify(result) + \"\\n\");\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\n\n private _removeSocketFile(): void {\n try {\n if (fs.existsSync(this._socketPath)) {\n fs.unlinkSync(this._socketPath);\n }\n } catch (err) {\n logAndSwallow(TAG, \"unlink socket\", err);\n }\n }\n}\n", "import { getEnv } from \"../../components/env-schema.js\";\nimport { logAndSwallow } from \"../../components/log-and-swallow.js\";\n\nconst TAG = \"domain_allowlist\";\n/**\n * Validates URLs against a configurable allowlist of domain patterns.\n * Prevents the agent from navigating to arbitrary domains.\n *\n * Pattern matching:\n * - `*.example.com` \u2192 matches any subdomain of example.com\n * - `example.com` \u2192 exact match only\n * - Empty list \u2192 open mode (all domains allowed)\n */\nexport class DomainAllowlist {\n private readonly _patterns: string[];\n\n constructor(patterns: string[]) {\n this._patterns = patterns\n .map((p) => p.trim().toLowerCase())\n .filter((p) => p.length > 0);\n }\n\n /** Check if a URL's hostname matches the allowlist. Returns true if allowed. */\n isAllowed(url: string): boolean {\n if (this._patterns.length === 0) return true;\n\n let hostname: string;\n try {\n hostname = new URL(url).hostname.toLowerCase();\n } catch (err) {\n logAndSwallow(TAG, \"parse URL\", err);\n return false;\n }\n\n return this._patterns.some((pattern) => {\n if (pattern.startsWith(\"*.\")) {\n const suffix = pattern.slice(2); // e.g. \"example.com\"\n return hostname === suffix || hostname.endsWith(`.${suffix}`);\n }\n return hostname === pattern;\n });\n }\n\n /** Get the list of configured patterns (for error messages). */\n get patterns(): string[] {\n return [...this._patterns];\n }\n\n /** True if no patterns configured (open mode). */\n get isOpenMode(): boolean {\n return this._patterns.length === 0;\n }\n\n /** Create a DomainAllowlist from the BROWSER_ALLOWED_DOMAINS env var. */\n static fromEnv(): DomainAllowlist {\n const raw = getEnv().browserAllowedDomains;\n const patterns = raw.split(\",\").map((s) => s.trim()).filter((s) => s.length > 0);\n return new DomainAllowlist(patterns);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["TAG", "path", "TAG", "LOG_PREFIX", "resolve", "TAG"]
7
+ }
@@ -2,7 +2,7 @@
2
2
  import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
3
3
  import {
4
4
  buildSoulBundle
5
- } from "./chunk-OZ4IZFV4.js";
5
+ } from "./chunk-HJQZP5CK.js";
6
6
 
7
7
  // src/components/soul-loader.ts
8
8
  function loadSoulBundle(memory) {
@@ -16,4 +16,4 @@ export {
16
16
  loadSoulBundle,
17
17
  loadMinimalSoul
18
18
  };
19
- //# sourceMappingURL=chunk-KFENC7BM.js.map
19
+ //# sourceMappingURL=chunk-L33WNMCP.js.map
@@ -3,11 +3,11 @@
3
3
  import {
4
4
  init_log_and_swallow,
5
5
  logAndSwallow
6
- } from "./chunk-EX2SRTUE.js";
6
+ } from "./chunk-CYSGXNBY.js";
7
7
  import {
8
8
  abtarsHome,
9
9
  init_paths
10
- } from "./chunk-MJ6PHMOK.js";
10
+ } from "./chunk-WW5F2DCO.js";
11
11
 
12
12
  // src/components/tool-sandbox.ts
13
13
  init_paths();
@@ -127,4 +127,4 @@ export {
127
127
  auditDeny,
128
128
  ToolLoopGuard
129
129
  };
130
- //# sourceMappingURL=chunk-JRG4EFMP.js.map
130
+ //# sourceMappingURL=chunk-LBMETTUP.js.map
@@ -1,18 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
3
3
  import {
4
- init_log_and_swallow,
5
- logAndSwallow
6
- } from "./chunk-EX2SRTUE.js";
4
+ sanitizeOutbound
5
+ } from "./chunk-YWZPKBO6.js";
7
6
  import {
8
7
  getEnv,
9
8
  init_env_schema
10
- } from "./chunk-PZE3J7ER.js";
9
+ } from "./chunk-3OXQWII3.js";
10
+ import {
11
+ init_log_and_swallow,
12
+ logAndSwallow
13
+ } from "./chunk-CYSGXNBY.js";
11
14
  import {
12
15
  init_logger,
13
16
  logError,
14
17
  logWarn
15
- } from "./chunk-2BY6I4P5.js";
18
+ } from "./chunk-GUTRAMK3.js";
16
19
 
17
20
  // src/components/main-chat.ts
18
21
  init_env_schema();
@@ -30,7 +33,7 @@ async function sendToMainChat(adapters, text, opts) {
30
33
  return { ok: false, reason: "adapter-missing" };
31
34
  }
32
35
  try {
33
- await adapter.sendMessage(chatId, text, opts);
36
+ await adapter.sendMessage(chatId, sanitizeOutbound(text), opts);
34
37
  return { ok: true };
35
38
  } catch (err) {
36
39
  logError("main-chat", `send failed: ${err}`);
@@ -52,4 +55,4 @@ export {
52
55
  sendToMainChat,
53
56
  sendNotification
54
57
  };
55
- //# sourceMappingURL=chunk-TYVI3ZWA.js.map
58
+ //# sourceMappingURL=chunk-LJAG2URA.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/main-chat.ts", "../src/components/notification.ts"],
4
+ "sourcesContent": ["/**\n * main-chat.ts \u2014 Route operator messages to the correct platform.\n * Uses MAIN_CHAT_PROVIDER to decide telegram vs discord.\n */\n\nimport { getEnv } from \"./env-schema.js\";\nimport { logWarn, logError } from \"./logger.js\";\nimport { sanitizeOutbound } from \"./sanitize-outbound.js\";\n\nexport interface SendOpts {\n threadId?: number;\n}\n\nexport interface SendResult {\n ok: boolean;\n reason?: \"no-chat-id\" | \"adapter-missing\" | \"send-failed\";\n}\n\nexport type ChatAdapter = {\n sendMessage(chatId: string, text: string, opts?: any): Promise<unknown>;\n};\n\nexport async function sendToMainChat(\n adapters: { telegram?: ChatAdapter | null; discord?: ChatAdapter | null },\n text: string,\n opts?: SendOpts,\n): Promise<SendResult> {\n const chatId = getEnv().mainChatId;\n if (!chatId) {\n logWarn(\"main-chat\", \"no MAIN_CHAT_ID, skipping\");\n return { ok: false, reason: \"no-chat-id\" };\n }\n const provider = getEnv().mainChatProvider;\n const adapter = provider === \"discord\" ? adapters.discord : adapters.telegram;\n if (!adapter) {\n logWarn(\"main-chat\", `${provider} adapter not running, skipping`);\n return { ok: false, reason: \"adapter-missing\" };\n }\n try {\n await adapter.sendMessage(chatId, sanitizeOutbound(text), opts);\n return { ok: true };\n } catch (err) {\n logError(\"main-chat\", `send failed: ${err}`);\n return { ok: false, reason: \"send-failed\" };\n }\n}\n", "/**\n * sendNotification \u2014 send a notification to the operator's main channel.\n * Routes via MAIN_CHAT_PROVIDER. Fire-and-forget.\n */\n\nimport type { BootCtx } from \"../boot/context.js\";\nimport { sendToMainChat } from \"./main-chat.js\";\nimport { logAndSwallow } from \"./log-and-swallow.js\";\n\nconst TAG = \"notification\";\n\nexport function sendNotification(ctx: BootCtx, msg: string): void {\n sendToMainChat(\n { telegram: ctx.telegramAdapter, discord: ctx.discordAdapter },\n msg,\n ).catch(err => logAndSwallow(TAG, \"sendToMainChat\", err));\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAKA;AACA;AAgBA,eAAsB,eACpB,UACA,MACA,MACqB;AACrB,QAAM,SAAS,OAAO,EAAE;AACxB,MAAI,CAAC,QAAQ;AACX,YAAQ,aAAa,2BAA2B;AAChD,WAAO,EAAE,IAAI,OAAO,QAAQ,aAAa;AAAA,EAC3C;AACA,QAAM,WAAW,OAAO,EAAE;AAC1B,QAAM,UAAU,aAAa,YAAY,SAAS,UAAU,SAAS;AACrE,MAAI,CAAC,SAAS;AACZ,YAAQ,aAAa,GAAG,QAAQ,gCAAgC;AAChE,WAAO,EAAE,IAAI,OAAO,QAAQ,kBAAkB;AAAA,EAChD;AACA,MAAI;AACF,UAAM,QAAQ,YAAY,QAAQ,iBAAiB,IAAI,GAAG,IAAI;AAC9D,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,SAAS,KAAK;AACZ,aAAS,aAAa,gBAAgB,GAAG,EAAE;AAC3C,WAAO,EAAE,IAAI,OAAO,QAAQ,cAAc;AAAA,EAC5C;AACF;;;ACtCA;AAEA,IAAM,MAAM;AAEL,SAAS,iBAAiB,KAAc,KAAmB;AAChE;AAAA,IACE,EAAE,UAAU,IAAI,iBAAiB,SAAS,IAAI,eAAe;AAAA,IAC7D;AAAA,EACF,EAAE,MAAM,SAAO,cAAc,KAAK,kBAAkB,GAAG,CAAC;AAC1D;",
6
+ "names": []
7
+ }