abtars 0.3.3 → 0.3.4-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/{_registry.generated-7DRCE4V6.js → _registry.generated-ZJBAZMXN.js} +16 -15
- package/bundle/{_registry.generated-7DRCE4V6.js.map → _registry.generated-ZJBAZMXN.js.map} +1 -1
- package/bundle/abtars-browser.js +6 -5
- package/bundle/abtars-browser.js.map +1 -1
- package/bundle/abtars-cli.js +47 -39
- package/bundle/abtars-cli.js.map +2 -2
- package/bundle/abtars-restart.js +7 -7
- package/bundle/abtars-rss.js +2 -1
- package/bundle/abtars-rss.js.map +2 -2
- package/bundle/abtars-task.js +6 -5
- package/bundle/abtars-task.js.map +1 -1
- package/bundle/abtars-todo.js +2 -1
- package/bundle/abtars-todo.js.map +1 -1
- package/bundle/abtars.js +299 -209
- package/bundle/abtars.js.map +4 -4
- package/bundle/{acp-raw-client-AZJCEB6S.js → acp-raw-client-YTBGFN4S.js} +4 -3
- package/bundle/{acp-raw-client-AZJCEB6S.js.map → acp-raw-client-YTBGFN4S.js.map} +1 -1
- package/bundle/{action-gate-QYJL57IX.js → action-gate-YISTP773.js} +4 -3
- package/bundle/{action-gate-QYJL57IX.js.map → action-gate-YISTP773.js.map} +1 -1
- package/bundle/{agent-api-adapter-PYMNQXHE.js → agent-api-adapter-E4HWVJ32.js} +5 -4
- package/bundle/{agent-api-adapter-PYMNQXHE.js.map → agent-api-adapter-E4HWVJ32.js.map} +1 -1
- package/bundle/{agent-api-rate-limit-4GEZ4YN5.js → agent-api-rate-limit-VENFGOAD.js} +6 -5
- package/bundle/{agent-registry-563P4EUJ.js → agent-registry-DL7UT272.js} +9 -8
- package/bundle/bootstrap-V5MROD3X.js +62 -0
- package/bundle/bootstrap-V5MROD3X.js.map +7 -0
- package/bundle/{bridge-lock-transport-LXCF2IVN.js → bridge-lock-transport-BJAMHMXW.js} +6 -5
- package/bundle/{browser-2VZOGOGX.js → browser-PT54UWSW.js} +8 -7
- package/bundle/{budget-PPA7WY3D.js → budget-QNK6IIT6.js} +5 -4
- package/bundle/{budget-PPA7WY3D.js.map → budget-QNK6IIT6.js.map} +1 -1
- package/bundle/{capability-WXEA2WFK.js → capability-EKPGHQIO.js} +7 -6
- package/bundle/{chunk-C3EYYJN3.js → chunk-2BXXQG7P.js} +16 -4
- package/bundle/chunk-2BXXQG7P.js.map +7 -0
- package/bundle/{chunk-4PIVWXUJ.js → chunk-2ZD7VQRW.js} +2 -2
- package/bundle/{chunk-OY2HAK33.js → chunk-36ZEYDKZ.js} +1 -1
- package/bundle/chunk-36ZEYDKZ.js.map +7 -0
- package/bundle/{chunk-3QW2K53E.js → chunk-4IGLXZCC.js} +11 -19
- package/bundle/chunk-4IGLXZCC.js.map +7 -0
- package/bundle/{chunk-T7TAWGBX.js → chunk-52PQM4EZ.js} +2 -2
- package/bundle/{chunk-2RGR3LSV.js → chunk-5P5HF7IJ.js} +2 -2
- package/bundle/{chunk-LE23VPN3.js → chunk-63A7ZRIH.js} +4 -4
- package/bundle/{chunk-LE23VPN3.js.map → chunk-63A7ZRIH.js.map} +1 -1
- package/bundle/chunk-6IB3GVXK.js +77 -0
- package/bundle/chunk-6IB3GVXK.js.map +7 -0
- package/bundle/{chunk-OOKNHOCB.js → chunk-6S3G6GPO.js} +2 -2
- package/bundle/{chunk-E7MV7WFT.js → chunk-6VTHSN4V.js} +6 -6
- package/bundle/{chunk-NGZVJ52F.js → chunk-76YN7O3U.js} +7 -7
- package/bundle/{chunk-43DKPXTP.js → chunk-7LORCJCQ.js} +4 -4
- package/bundle/{chunk-HDOFJVFS.js → chunk-7OI46MH7.js} +3 -3
- package/bundle/{chunk-H2K23MOF.js → chunk-7XXISOHU.js} +21 -5
- package/bundle/chunk-7XXISOHU.js.map +7 -0
- package/bundle/{chunk-CB6S3ZRF.js → chunk-AFFW2LRY.js} +3 -3
- package/bundle/{chunk-TCI6FZTP.js → chunk-AHJDG6OM.js} +9 -9
- package/bundle/{chunk-NP72ZB7P.js → chunk-AMUJEP6L.js} +45 -45
- package/bundle/{chunk-NP72ZB7P.js.map → chunk-AMUJEP6L.js.map} +2 -2
- package/bundle/{chunk-BU7LTI2W.js → chunk-AWCO3DQ3.js} +6 -7
- package/bundle/chunk-AWCO3DQ3.js.map +7 -0
- package/bundle/{chunk-YME7NRGP.js → chunk-B2TIRDZC.js} +2 -2
- package/bundle/{chunk-SSCGWDIC.js → chunk-BWJ37KMW.js} +2 -2
- package/bundle/{chunk-ULO2PX3T.js → chunk-CCZ43JB7.js} +3 -3
- package/bundle/{chunk-FVUL44T4.js → chunk-CNENVY37.js} +2 -2
- package/bundle/{chunk-J5NOL4DB.js → chunk-DJOSXXM2.js} +2 -2
- package/bundle/{chunk-7RAGSHSH.js → chunk-DMDX35YT.js} +12 -10
- package/bundle/chunk-DMDX35YT.js.map +7 -0
- package/bundle/{chunk-DNDYD5SL.js → chunk-E7DZYCSF.js} +3 -3
- package/bundle/{chunk-M6Q3IQ4H.js → chunk-FF2F7ENH.js} +250 -118
- package/bundle/chunk-FF2F7ENH.js.map +7 -0
- package/bundle/{chunk-GCFIK6OB.js → chunk-FSGICOCX.js} +21 -21
- package/bundle/{chunk-IXKQ4JMX.js → chunk-GFAJSPMD.js} +33 -17
- package/bundle/chunk-GFAJSPMD.js.map +7 -0
- package/bundle/{chunk-FJF42RZY.js → chunk-GHRLO2UL.js} +3 -3
- package/bundle/{chunk-3LQOJVTB.js → chunk-HFOCNYEO.js} +1842 -1220
- package/bundle/{chunk-3LQOJVTB.js.map → chunk-HFOCNYEO.js.map} +4 -4
- package/bundle/{chunk-7WHXTCVD.js → chunk-HWFN7JGU.js} +2 -2
- package/bundle/{chunk-KBPVJGD7.js → chunk-IXGDDDAB.js} +3 -3
- package/bundle/chunk-JHLKEUHE.js +37 -0
- package/bundle/chunk-JHLKEUHE.js.map +7 -0
- package/bundle/{chunk-YEOZN5IE.js → chunk-JRGEEGZF.js} +2 -2
- package/bundle/{chunk-56D3Y44D.js → chunk-KLG4SCF7.js} +10 -10
- package/bundle/{chunk-ASYX43OU.js → chunk-LB43Q7G6.js} +26 -26
- package/bundle/{chunk-TVSPVZTX.js → chunk-LN5MNDSA.js} +3 -3
- package/bundle/{chunk-RJX45XIC.js → chunk-LPF2HELD.js} +9 -4
- package/bundle/chunk-LPF2HELD.js.map +7 -0
- package/bundle/{chunk-72T2Q7IG.js → chunk-MJACYH7A.js} +270 -282
- package/bundle/chunk-MJACYH7A.js.map +7 -0
- package/bundle/{chunk-SESM4GBM.js → chunk-MPQ2PJQX.js} +52 -25
- package/bundle/chunk-MPQ2PJQX.js.map +7 -0
- package/bundle/{chunk-FIAVVKGN.js → chunk-MTE32OQH.js} +3 -3
- package/bundle/{chunk-MV5KOWOR.js → chunk-N3Q3TASM.js} +7 -7
- package/bundle/{chunk-IQKADER4.js → chunk-O4YBJS2K.js} +2 -2
- package/bundle/{chunk-VJATH7AN.js → chunk-OOUCUCUW.js} +9 -8
- package/bundle/chunk-OOUCUCUW.js.map +7 -0
- package/bundle/{chunk-5V4VHKEA.js → chunk-OT6HLPEA.js} +3 -3
- package/bundle/{chunk-V6CV3QPH.js → chunk-OWPQIBAO.js} +2 -2
- package/bundle/{chunk-EDZGF6BC.js → chunk-QJPDBJDP.js} +11 -4
- package/bundle/chunk-QJPDBJDP.js.map +7 -0
- package/bundle/{chunk-N5VROZ7A.js → chunk-QMP2KC4W.js} +5 -5
- package/bundle/{chunk-4HNCOQSK.js → chunk-QOGZ7BFL.js} +7 -7
- package/bundle/{chunk-2LKQV2ND.js → chunk-R23FHZRY.js} +3 -3
- package/bundle/{chunk-SXNY6HC4.js → chunk-R4GYWVCR.js} +6 -6
- package/bundle/chunk-R4GYWVCR.js.map +7 -0
- package/bundle/{chunk-S7ZIGIR5.js → chunk-R76K6L6H.js} +27 -27
- package/bundle/{chunk-S7ZIGIR5.js.map → chunk-R76K6L6H.js.map} +1 -1
- package/bundle/{chunk-TY26WMQY.js → chunk-RCWQ34QR.js} +2 -2
- package/bundle/{chunk-MQJG7OJX.js → chunk-RJ2OUNFU.js} +38 -36
- package/bundle/chunk-RJ2OUNFU.js.map +7 -0
- package/bundle/{chunk-S6HEHCCG.js → chunk-RO3TAYBR.js} +83 -46
- package/bundle/chunk-RO3TAYBR.js.map +7 -0
- package/bundle/{chunk-ZOCEBV62.js → chunk-UU3RLJSD.js} +3 -3
- package/bundle/{chunk-P5O6QZDC.js → chunk-V7Y2LFO4.js} +10 -6
- package/bundle/chunk-V7Y2LFO4.js.map +7 -0
- package/bundle/{chunk-WP7FZHMI.js → chunk-W2PSVV2T.js} +2 -2
- package/bundle/{chunk-V2QIAXWZ.js → chunk-WEGFRA6G.js} +3 -3
- package/bundle/{chunk-ZY6DH2S4.js → chunk-WTIGZO3N.js} +80 -70
- package/bundle/chunk-WTIGZO3N.js.map +7 -0
- package/bundle/{chunk-O4GKI3Q3.js → chunk-X7DLKIQM.js} +4 -4
- package/bundle/{chunk-BNBC4T45.js → chunk-XZ4ZBDM5.js} +3 -3
- package/bundle/{chunk-24V4A6RP.js → chunk-YI2KSYB4.js} +4 -4
- package/bundle/{chunk-37EX63K4.js → chunk-YWHJJHJ2.js} +6998 -3621
- package/bundle/chunk-YWHJJHJ2.js.map +7 -0
- package/bundle/{chunk-IK4R3RBZ.js → chunk-YZCOA4DC.js} +3 -3
- package/bundle/{chunk-2FZJDMAF.js → chunk-ZGNSCJWH.js} +10 -10
- package/bundle/{chunk-W726UGI6.js → chunk-ZKMKAO75.js} +3 -3
- package/bundle/{chunk-WGWM4IZM.js → chunk-ZT5ZBGWS.js} +4 -4
- package/bundle/{chunk-WGWM4IZM.js.map → chunk-ZT5ZBGWS.js.map} +1 -1
- package/bundle/{commands-XXFU2ZF7.js → commands-2JQ5YTJX.js} +20 -20
- package/bundle/{config-EWDZ234X.js → config-ZEWIM5Z2.js} +8 -7
- package/bundle/{config-show-6J33O4TE.js → config-show-WBJPQPRD.js} +5 -5
- package/bundle/{context-OCS7HLJP.js → context-V75QNXB5.js} +5 -2
- package/bundle/{context-OCS7HLJP.js.map → context-V75QNXB5.js.map} +1 -1
- package/bundle/{daemon-LTDAXNA2.js → daemon-W7VQOSZC.js} +7 -7
- package/bundle/{delegation-tools-YDTWQMZD.js → delegation-tools-VGTRFQBF.js} +13 -11
- package/bundle/{registry-client-VN2MM2HI.js → deploy-5AGIULM2.js} +10 -6
- package/bundle/{deploy-lib-import-RGZJ3CGC.js → deploy-lib-import-ZBDYORN4.js} +5 -3
- package/bundle/{deps-PHSLIA77.js → deps-VB3S3RLF.js} +21 -19
- package/bundle/deps-VB3S3RLF.js.map +7 -0
- package/bundle/{direct-api-transport-OAKYQBJR.js → direct-api-transport-YSROTC35.js} +30 -28
- package/bundle/direct-api-transport-YSROTC35.js.map +7 -0
- package/bundle/{discord-adapter-WUNYPTDE.js → discord-adapter-LKBSIFLV.js} +26 -26
- package/bundle/{dist-7HEHHQI2.js → dist-KMK7TZGN.js} +376 -348
- package/bundle/dist-KMK7TZGN.js.map +7 -0
- package/bundle/{dns-wakeup-F55ALHXJ.js → dns-wakeup-KIURCCFJ.js} +4 -3
- package/bundle/{dns-wakeup-F55ALHXJ.js.map → dns-wakeup-KIURCCFJ.js.map} +1 -1
- package/bundle/{doctor-probes-3SLIUGKS.js → doctor-probes-46UKIROK.js} +4 -3
- package/bundle/{env-schema-MSDP2YBO.js → env-schema-YGHCKX5B.js} +5 -4
- package/bundle/{gossip-CS3G3447.js → gossip-VSEY2HSE.js} +7 -6
- package/bundle/{guardrails-24XK2COI.js → guardrails-U7M6H2GE.js} +6 -5
- package/bundle/{health-check-FRUNRVNQ.js → health-check-ASRLUJE5.js} +6 -2
- package/bundle/health-check-ASRLUJE5.js.map +7 -0
- package/bundle/{heartbeat-system-G4IFQXT6.js → heartbeat-system-MUXLT4E6.js} +7 -6
- package/bundle/{heartbeat-tier3-3ZO3EVXP.js → heartbeat-tier3-636ZMM4E.js} +45 -44
- package/bundle/heartbeat-tier3-636ZMM4E.js.map +7 -0
- package/bundle/{hook-system-X6INNJGV.js → hook-system-Z4XD6IM5.js} +5 -4
- package/bundle/{hotskills-6FQYTJIO.js → hotskills-AOUWVTQB.js} +7 -6
- package/bundle/{install-ZAHTZ5M5.js → install-3GGZUN22.js} +23 -20
- package/bundle/install-3GGZUN22.js.map +7 -0
- package/bundle/{install-manifest-QX7KVDCA.js → install-manifest-624KOB4S.js} +4 -3
- package/bundle/{install-manifest-QX7KVDCA.js.map → install-manifest-624KOB4S.js.map} +1 -1
- package/bundle/{irc-adapter-IEJQKKJF.js → irc-adapter-SA7GLJGR.js} +5 -4
- package/bundle/{irc-adapter-IEJQKKJF.js.map → irc-adapter-SA7GLJGR.js.map} +1 -1
- package/bundle/{irc-config-TTWNYFLH.js → irc-config-PG4X2I4M.js} +6 -5
- package/bundle/{irc-config-TTWNYFLH.js.map → irc-config-PG4X2I4M.js.map} +1 -1
- package/bundle/{kanban-board-J6RO3ZU7.js → kanban-board-4AI5Z6B5.js} +7 -5
- package/bundle/{kanban-channel-5EIXBFSA.js → kanban-channel-JMBYWGWD.js} +8 -6
- package/bundle/{lazy-require-V6EFUATC.js → lazy-require-GURNBC3C.js} +11 -6
- package/bundle/{logger-Y3VILPRH.js → logger-UQJPZMYV.js} +4 -3
- package/bundle/{logs-YS3GDURO.js → logs-2WTDLMB5.js} +5 -5
- package/bundle/{main-chat-YLZDNQPO.js → main-chat-EID5Y6H2.js} +6 -5
- package/bundle/{master-user-Z4M7KCJE.js → master-user-TKA7M2GL.js} +7 -6
- package/bundle/{media-utils-P6RZ2K3U.js → media-utils-X3UN342B.js} +44 -43
- package/bundle/{media-utils-P6RZ2K3U.js.map → media-utils-X3UN342B.js.map} +2 -2
- package/bundle/{message-pipeline-MHEBDJLH.js → message-pipeline-TAWXNEVS.js} +20 -20
- package/bundle/meta.json +9264 -8575
- package/bundle/{migrate-layout-RJJQLVGR.js → migrate-layout-KEAIIN26.js} +8 -4
- package/bundle/migrate-layout-KEAIIN26.js.map +7 -0
- package/bundle/{nerve-VZNMFDGY.js → nerve-TC34H4EL.js} +5 -4
- package/bundle/{notification-VV2OR6NW.js → notification-JQNVGICN.js} +8 -7
- package/bundle/{openrouter-credits-LXC7P4G6.js → openrouter-credits-5Q3EYWE5.js} +5 -4
- package/bundle/{openrouter-credits-LXC7P4G6.js.map → openrouter-credits-5Q3EYWE5.js.map} +1 -1
- package/bundle/{orc-KC4USP55.js → orc-74Z62W7B.js} +4 -4
- package/bundle/{orc-tools-CHRSXSAS.js → orc-tools-GME3DKIN.js} +5 -4
- package/bundle/{paths-EDK6KWHG.js → paths-BAUNPLNJ.js} +6 -2
- package/bundle/{paths-RZF6WDMG.js → paths-MZC2KU2C.js} +3 -2
- package/bundle/{peer-auth-SRONOLNG.js → peer-auth-VRO3JYL5.js} +9 -8
- package/bundle/{peer-client-VOF77T6C.js → peer-client-WLK5GZQS.js} +9 -8
- package/bundle/{peer-client-VOF77T6C.js.map → peer-client-WLK5GZQS.js.map} +1 -1
- package/bundle/{peer-config-FRWLEYQ5.js → peer-config-24WILLCJ.js} +6 -5
- package/bundle/{peer-jwt-XY3XRIA2.js → peer-jwt-ZR6RF3XM.js} +6 -5
- package/bundle/{peer-transport-UBBXTDRP.js → peer-transport-BK5VHI2M.js} +8 -7
- package/bundle/{phase-transport-4NQHZX75.js → phase-transport-7QJM7J6V.js} +18 -16
- package/bundle/{reconcile-2EUXJ6W5.js → reconcile-7N7OE2GU.js} +5 -4
- package/bundle/{reconciler-FFQGV4DO.js → reconciler-7LOOUK43.js} +13 -11
- package/bundle/{reconciler-FFQGV4DO.js.map → reconciler-7LOOUK43.js.map} +1 -1
- package/bundle/{restore-NFDE2RG6.js → restore-MENZ3I3K.js} +13 -9
- package/bundle/{restore-NFDE2RG6.js.map → restore-MENZ3I3K.js.map} +3 -3
- package/bundle/{rollback-MVZ53XS4.js → rollback-JOHY6KWW.js} +5 -5
- package/bundle/{chunk-SKY6656M.js → sandbox-runtime-T7RF4WJD.js} +11 -28
- package/bundle/{chunk-SKY6656M.js.map → sandbox-runtime-T7RF4WJD.js.map} +1 -1
- package/bundle/{self-healer-utils-KD6LV63S.js → self-healer-utils-OR2N6RLD.js} +5 -4
- package/bundle/{self-healer-utils-KD6LV63S.js.map → self-healer-utils-OR2N6RLD.js.map} +1 -1
- package/bundle/{sha-tracker-2DB4R2TW.js → sha-tracker-BXOLWZJL.js} +5 -4
- package/bundle/{skill-session-BPDVA6ZG.js → skill-session-H6EQ4NGN.js} +5 -4
- package/bundle/{skill-session-BPDVA6ZG.js.map → skill-session-H6EQ4NGN.js.map} +1 -1
- package/bundle/{skill-stats-TPD2NROA.js → skill-stats-7O777ZSZ.js} +6 -5
- package/bundle/{skill-watcher-D7QYYYON.js → skill-watcher-ZGLTDPG5.js} +6 -5
- package/bundle/{sleep-GH6DLBJJ.js → sleep-3LFZH727.js} +10 -9
- package/bundle/{soul-bundle-GXLMDBCC.js → soul-bundle-RQ2YQMJW.js} +10 -9
- package/bundle/{spin-4DBYHS3E.js → spin-76K4R6FK.js} +12 -10
- package/bundle/{spin-notifications-IKYJPER5.js → spin-notifications-LD46B4K5.js} +7 -5
- package/bundle/{spin-notifications-IKYJPER5.js.map → spin-notifications-LD46B4K5.js.map} +1 -1
- package/bundle/{spin-types-PLJH3SIK.js → spin-types-MOKTZXGB.js} +5 -4
- package/bundle/{src-SUFZ27S5.js → src-6BTCMOD3.js} +4 -4
- package/bundle/{sse-parser-anthropic-U7ILHOY5.js → sse-parser-anthropic-NV2CGBIT.js} +5 -4
- package/bundle/{sse-parser-anthropic-U7ILHOY5.js.map → sse-parser-anthropic-NV2CGBIT.js.map} +1 -1
- package/bundle/{sse-parser-responses-OI73R3AH.js → sse-parser-responses-FC3PFHQ5.js} +5 -4
- package/bundle/{sse-parser-responses-OI73R3AH.js.map → sse-parser-responses-FC3PFHQ5.js.map} +1 -1
- package/bundle/{ssrf-guard-6GP4QYVA.js → ssrf-guard-E2YPLW6G.js} +5 -4
- package/bundle/{ssrf-guard-6GP4QYVA.js.map → ssrf-guard-E2YPLW6G.js.map} +1 -1
- package/bundle/{start-JT2BPMSW.js → start-HPO5LYJP.js} +5 -5
- package/bundle/start-HPO5LYJP.js.map +7 -0
- package/bundle/{stt-KD3AABKG.js → stt-UE7EOYD7.js} +6 -5
- package/bundle/{subagent-runtime-LVECAUPV.js → subagent-runtime-4X3UHF4H.js} +6 -5
- package/bundle/system-status-PLPWV4RF.js +346 -0
- package/bundle/system-status-PLPWV4RF.js.map +7 -0
- package/bundle/{task-store-2XRDM3AW.js → task-store-RAFMDQ7N.js} +6 -5
- package/bundle/{telegram-adapter-UJ3RYYV6.js → telegram-adapter-PPXKTGOP.js} +35 -35
- package/bundle/{tool-registry-YU6WBXPA.js → tool-registry-NKIPNJZ5.js} +25 -23
- package/bundle/{tool-sandbox-RNNPDR5M.js → tool-sandbox-DQCP3UTU.js} +6 -5
- package/bundle/{transport-config-OK3MZPJK.js → transport-config-SF6GBV47.js} +9 -8
- package/bundle/{update-ENNPRW7Y.js → update-QOOGMFSJ.js} +6 -6
- package/bundle/{update-check-SJB6GV3A.js → update-check-LPZG3K5P.js} +3 -2
- package/bundle/{update-check-SJB6GV3A.js.map → update-check-LPZG3K5P.js.map} +1 -1
- package/bundle/{usage-tracker-HRSGC7QC.js → usage-tracker-TBDM4KE6.js} +2 -2
- package/bundle/{user-registry-6PUJJ5J2.js → user-registry-OYJVAHDD.js} +6 -5
- package/bundle/{wrapper-WLHLG4MI.js → wrapper-W66YICNZ.js} +3 -3
- package/bundle/{ws-peer-client-WHW3RJTD.js → ws-peer-client-G5QHOF6K.js} +15 -14
- package/bundle/{ws-peer-client-WHW3RJTD.js.map → ws-peer-client-G5QHOF6K.js.map} +2 -2
- package/package.json +3 -7
- package/scripts/emergency-deploy.sh +11 -8
- package/scripts/emergency-update.sh +156 -23
- package/templates/config/.env +1 -1
- package/templates/config/models.json +13 -0
- package/bundle/chunk-37EX63K4.js.map +0 -7
- package/bundle/chunk-3QW2K53E.js.map +0 -7
- package/bundle/chunk-72T2Q7IG.js.map +0 -7
- package/bundle/chunk-7RAGSHSH.js.map +0 -7
- package/bundle/chunk-BU7LTI2W.js.map +0 -7
- package/bundle/chunk-C3EYYJN3.js.map +0 -7
- package/bundle/chunk-CAOIIVFP.js +0 -110
- package/bundle/chunk-CAOIIVFP.js.map +0 -7
- package/bundle/chunk-EDZGF6BC.js.map +0 -7
- package/bundle/chunk-H2K23MOF.js.map +0 -7
- package/bundle/chunk-HAZHNBBY.js +0 -156
- package/bundle/chunk-HAZHNBBY.js.map +0 -7
- package/bundle/chunk-IXKQ4JMX.js.map +0 -7
- package/bundle/chunk-JAJ3DUQ2.js +0 -30
- package/bundle/chunk-JAJ3DUQ2.js.map +0 -7
- package/bundle/chunk-KMFR5AVY.js +0 -45
- package/bundle/chunk-KMFR5AVY.js.map +0 -7
- package/bundle/chunk-M6Q3IQ4H.js.map +0 -7
- package/bundle/chunk-MQJG7OJX.js.map +0 -7
- package/bundle/chunk-OY2HAK33.js.map +0 -7
- package/bundle/chunk-P5O6QZDC.js.map +0 -7
- package/bundle/chunk-RJX45XIC.js.map +0 -7
- package/bundle/chunk-S6HEHCCG.js.map +0 -7
- package/bundle/chunk-SESM4GBM.js.map +0 -7
- package/bundle/chunk-SXNY6HC4.js.map +0 -7
- package/bundle/chunk-VJATH7AN.js.map +0 -7
- package/bundle/chunk-ZY6DH2S4.js.map +0 -7
- package/bundle/deps-PHSLIA77.js.map +0 -7
- package/bundle/direct-api-transport-OAKYQBJR.js.map +0 -7
- package/bundle/dist-7HEHHQI2.js.map +0 -7
- package/bundle/health-check-FRUNRVNQ.js.map +0 -7
- package/bundle/heartbeat-tier3-3ZO3EVXP.js.map +0 -7
- package/bundle/install-ZAHTZ5M5.js.map +0 -7
- package/bundle/migrate-layout-RJJQLVGR.js.map +0 -7
- package/bundle/phase-config-V4XETN5F.js +0 -18
- package/bundle/sandbox-runtime-WHACQLLN.js +0 -22
- package/bundle/start-JT2BPMSW.js.map +0 -7
- package/bundle/system-status-XXJWTVJN.js +0 -243
- package/bundle/system-status-XXJWTVJN.js.map +0 -7
- package/bundle/user-registry-6PUJJ5J2.js.map +0 -7
- package/bundle/wrapper-WLHLG4MI.js.map +0 -7
- /package/bundle/{agent-api-rate-limit-4GEZ4YN5.js.map → agent-api-rate-limit-VENFGOAD.js.map} +0 -0
- /package/bundle/{agent-registry-563P4EUJ.js.map → agent-registry-DL7UT272.js.map} +0 -0
- /package/bundle/{bridge-lock-transport-LXCF2IVN.js.map → bridge-lock-transport-BJAMHMXW.js.map} +0 -0
- /package/bundle/{browser-2VZOGOGX.js.map → browser-PT54UWSW.js.map} +0 -0
- /package/bundle/{capability-WXEA2WFK.js.map → capability-EKPGHQIO.js.map} +0 -0
- /package/bundle/{chunk-4PIVWXUJ.js.map → chunk-2ZD7VQRW.js.map} +0 -0
- /package/bundle/{chunk-T7TAWGBX.js.map → chunk-52PQM4EZ.js.map} +0 -0
- /package/bundle/{chunk-2RGR3LSV.js.map → chunk-5P5HF7IJ.js.map} +0 -0
- /package/bundle/{chunk-OOKNHOCB.js.map → chunk-6S3G6GPO.js.map} +0 -0
- /package/bundle/{chunk-E7MV7WFT.js.map → chunk-6VTHSN4V.js.map} +0 -0
- /package/bundle/{chunk-NGZVJ52F.js.map → chunk-76YN7O3U.js.map} +0 -0
- /package/bundle/{chunk-43DKPXTP.js.map → chunk-7LORCJCQ.js.map} +0 -0
- /package/bundle/{chunk-HDOFJVFS.js.map → chunk-7OI46MH7.js.map} +0 -0
- /package/bundle/{chunk-CB6S3ZRF.js.map → chunk-AFFW2LRY.js.map} +0 -0
- /package/bundle/{chunk-TCI6FZTP.js.map → chunk-AHJDG6OM.js.map} +0 -0
- /package/bundle/{chunk-YME7NRGP.js.map → chunk-B2TIRDZC.js.map} +0 -0
- /package/bundle/{chunk-SSCGWDIC.js.map → chunk-BWJ37KMW.js.map} +0 -0
- /package/bundle/{chunk-ULO2PX3T.js.map → chunk-CCZ43JB7.js.map} +0 -0
- /package/bundle/{chunk-FVUL44T4.js.map → chunk-CNENVY37.js.map} +0 -0
- /package/bundle/{chunk-J5NOL4DB.js.map → chunk-DJOSXXM2.js.map} +0 -0
- /package/bundle/{chunk-DNDYD5SL.js.map → chunk-E7DZYCSF.js.map} +0 -0
- /package/bundle/{chunk-GCFIK6OB.js.map → chunk-FSGICOCX.js.map} +0 -0
- /package/bundle/{chunk-FJF42RZY.js.map → chunk-GHRLO2UL.js.map} +0 -0
- /package/bundle/{chunk-7WHXTCVD.js.map → chunk-HWFN7JGU.js.map} +0 -0
- /package/bundle/{chunk-KBPVJGD7.js.map → chunk-IXGDDDAB.js.map} +0 -0
- /package/bundle/{chunk-YEOZN5IE.js.map → chunk-JRGEEGZF.js.map} +0 -0
- /package/bundle/{chunk-56D3Y44D.js.map → chunk-KLG4SCF7.js.map} +0 -0
- /package/bundle/{chunk-ASYX43OU.js.map → chunk-LB43Q7G6.js.map} +0 -0
- /package/bundle/{chunk-TVSPVZTX.js.map → chunk-LN5MNDSA.js.map} +0 -0
- /package/bundle/{chunk-FIAVVKGN.js.map → chunk-MTE32OQH.js.map} +0 -0
- /package/bundle/{chunk-MV5KOWOR.js.map → chunk-N3Q3TASM.js.map} +0 -0
- /package/bundle/{chunk-IQKADER4.js.map → chunk-O4YBJS2K.js.map} +0 -0
- /package/bundle/{chunk-5V4VHKEA.js.map → chunk-OT6HLPEA.js.map} +0 -0
- /package/bundle/{chunk-V6CV3QPH.js.map → chunk-OWPQIBAO.js.map} +0 -0
- /package/bundle/{chunk-N5VROZ7A.js.map → chunk-QMP2KC4W.js.map} +0 -0
- /package/bundle/{chunk-4HNCOQSK.js.map → chunk-QOGZ7BFL.js.map} +0 -0
- /package/bundle/{chunk-2LKQV2ND.js.map → chunk-R23FHZRY.js.map} +0 -0
- /package/bundle/{chunk-TY26WMQY.js.map → chunk-RCWQ34QR.js.map} +0 -0
- /package/bundle/{chunk-ZOCEBV62.js.map → chunk-UU3RLJSD.js.map} +0 -0
- /package/bundle/{chunk-WP7FZHMI.js.map → chunk-W2PSVV2T.js.map} +0 -0
- /package/bundle/{chunk-V2QIAXWZ.js.map → chunk-WEGFRA6G.js.map} +0 -0
- /package/bundle/{chunk-O4GKI3Q3.js.map → chunk-X7DLKIQM.js.map} +0 -0
- /package/bundle/{chunk-BNBC4T45.js.map → chunk-XZ4ZBDM5.js.map} +0 -0
- /package/bundle/{chunk-24V4A6RP.js.map → chunk-YI2KSYB4.js.map} +0 -0
- /package/bundle/{chunk-IK4R3RBZ.js.map → chunk-YZCOA4DC.js.map} +0 -0
- /package/bundle/{chunk-2FZJDMAF.js.map → chunk-ZGNSCJWH.js.map} +0 -0
- /package/bundle/{chunk-W726UGI6.js.map → chunk-ZKMKAO75.js.map} +0 -0
- /package/bundle/{commands-XXFU2ZF7.js.map → commands-2JQ5YTJX.js.map} +0 -0
- /package/bundle/{config-EWDZ234X.js.map → config-ZEWIM5Z2.js.map} +0 -0
- /package/bundle/{config-show-6J33O4TE.js.map → config-show-WBJPQPRD.js.map} +0 -0
- /package/bundle/{daemon-LTDAXNA2.js.map → daemon-W7VQOSZC.js.map} +0 -0
- /package/bundle/{delegation-tools-YDTWQMZD.js.map → delegation-tools-VGTRFQBF.js.map} +0 -0
- /package/bundle/{deploy-lib-import-RGZJ3CGC.js.map → deploy-5AGIULM2.js.map} +0 -0
- /package/bundle/{doctor-probes-3SLIUGKS.js.map → deploy-lib-import-ZBDYORN4.js.map} +0 -0
- /package/bundle/{discord-adapter-WUNYPTDE.js.map → discord-adapter-LKBSIFLV.js.map} +0 -0
- /package/bundle/{env-schema-MSDP2YBO.js.map → doctor-probes-46UKIROK.js.map} +0 -0
- /package/bundle/{gossip-CS3G3447.js.map → env-schema-YGHCKX5B.js.map} +0 -0
- /package/bundle/{guardrails-24XK2COI.js.map → gossip-VSEY2HSE.js.map} +0 -0
- /package/bundle/{heartbeat-system-G4IFQXT6.js.map → guardrails-U7M6H2GE.js.map} +0 -0
- /package/bundle/{hook-system-X6INNJGV.js.map → heartbeat-system-MUXLT4E6.js.map} +0 -0
- /package/bundle/{hotskills-6FQYTJIO.js.map → hook-system-Z4XD6IM5.js.map} +0 -0
- /package/bundle/{kanban-board-J6RO3ZU7.js.map → hotskills-AOUWVTQB.js.map} +0 -0
- /package/bundle/{kanban-channel-5EIXBFSA.js.map → kanban-board-4AI5Z6B5.js.map} +0 -0
- /package/bundle/{lazy-require-V6EFUATC.js.map → kanban-channel-JMBYWGWD.js.map} +0 -0
- /package/bundle/{logger-Y3VILPRH.js.map → lazy-require-GURNBC3C.js.map} +0 -0
- /package/bundle/{main-chat-YLZDNQPO.js.map → logger-UQJPZMYV.js.map} +0 -0
- /package/bundle/{logs-YS3GDURO.js.map → logs-2WTDLMB5.js.map} +0 -0
- /package/bundle/{master-user-Z4M7KCJE.js.map → main-chat-EID5Y6H2.js.map} +0 -0
- /package/bundle/{message-pipeline-MHEBDJLH.js.map → master-user-TKA7M2GL.js.map} +0 -0
- /package/bundle/{nerve-VZNMFDGY.js.map → message-pipeline-TAWXNEVS.js.map} +0 -0
- /package/bundle/{notification-VV2OR6NW.js.map → nerve-TC34H4EL.js.map} +0 -0
- /package/bundle/{orc-tools-CHRSXSAS.js.map → notification-JQNVGICN.js.map} +0 -0
- /package/bundle/{orc-KC4USP55.js.map → orc-74Z62W7B.js.map} +0 -0
- /package/bundle/{paths-EDK6KWHG.js.map → orc-tools-GME3DKIN.js.map} +0 -0
- /package/bundle/{paths-RZF6WDMG.js.map → paths-BAUNPLNJ.js.map} +0 -0
- /package/bundle/{peer-auth-SRONOLNG.js.map → paths-MZC2KU2C.js.map} +0 -0
- /package/bundle/{peer-config-FRWLEYQ5.js.map → peer-auth-VRO3JYL5.js.map} +0 -0
- /package/bundle/{peer-jwt-XY3XRIA2.js.map → peer-config-24WILLCJ.js.map} +0 -0
- /package/bundle/{peer-transport-UBBXTDRP.js.map → peer-jwt-ZR6RF3XM.js.map} +0 -0
- /package/bundle/{phase-config-V4XETN5F.js.map → peer-transport-BK5VHI2M.js.map} +0 -0
- /package/bundle/{phase-transport-4NQHZX75.js.map → phase-transport-7QJM7J6V.js.map} +0 -0
- /package/bundle/{reconcile-2EUXJ6W5.js.map → reconcile-7N7OE2GU.js.map} +0 -0
- /package/bundle/{registry-client-VN2MM2HI.js.map → rollback-JOHY6KWW.js.map} +0 -0
- /package/bundle/{rollback-MVZ53XS4.js.map → sha-tracker-BXOLWZJL.js.map} +0 -0
- /package/bundle/{sandbox-runtime-WHACQLLN.js.map → skill-stats-7O777ZSZ.js.map} +0 -0
- /package/bundle/{sha-tracker-2DB4R2TW.js.map → skill-watcher-ZGLTDPG5.js.map} +0 -0
- /package/bundle/{skill-stats-TPD2NROA.js.map → sleep-3LFZH727.js.map} +0 -0
- /package/bundle/{skill-watcher-D7QYYYON.js.map → soul-bundle-RQ2YQMJW.js.map} +0 -0
- /package/bundle/{sleep-GH6DLBJJ.js.map → spin-76K4R6FK.js.map} +0 -0
- /package/bundle/{soul-bundle-GXLMDBCC.js.map → spin-types-MOKTZXGB.js.map} +0 -0
- /package/bundle/{spin-4DBYHS3E.js.map → src-6BTCMOD3.js.map} +0 -0
- /package/bundle/{spin-types-PLJH3SIK.js.map → stt-UE7EOYD7.js.map} +0 -0
- /package/bundle/{src-SUFZ27S5.js.map → subagent-runtime-4X3UHF4H.js.map} +0 -0
- /package/bundle/{stt-KD3AABKG.js.map → task-store-RAFMDQ7N.js.map} +0 -0
- /package/bundle/{telegram-adapter-UJ3RYYV6.js.map → telegram-adapter-PPXKTGOP.js.map} +0 -0
- /package/bundle/{subagent-runtime-LVECAUPV.js.map → tool-registry-NKIPNJZ5.js.map} +0 -0
- /package/bundle/{task-store-2XRDM3AW.js.map → tool-sandbox-DQCP3UTU.js.map} +0 -0
- /package/bundle/{tool-registry-YU6WBXPA.js.map → transport-config-SF6GBV47.js.map} +0 -0
- /package/bundle/{tool-sandbox-RNNPDR5M.js.map → update-QOOGMFSJ.js.map} +0 -0
- /package/bundle/{transport-config-OK3MZPJK.js.map → usage-tracker-TBDM4KE6.js.map} +0 -0
- /package/bundle/{update-ENNPRW7Y.js.map → user-registry-OYJVAHDD.js.map} +0 -0
- /package/bundle/{usage-tracker-HRSGC7QC.js.map → wrapper-W66YICNZ.js.map} +0 -0
|
@@ -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 \"../../types/browser.js\";\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 = \"cloakbrowser\";\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 = \"cloakbrowser\" 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 { launch } = await import(\"cloakbrowser\");\n const headed = getEnv().browserHeaded;\n const args = headed ? [] : [\"--headless=new\"];\n if (getEnv().browserNoSandbox) args.push(\"--no-sandbox\");\n return launch({\n headless: !headed,\n channel: getEnv().browserChannel, // #1203: cloakbrowser LaunchOptions omits 'channel'; passed through to Playwright\n args,\n } as Parameters<typeof launch>[0]);\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: unknown) => { 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 \"../types/browser.js\";\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 \"&\": \"&\",\n \"<\": \"<\",\n \">\": \">\",\n \""\": '\"',\n \"'\": \"'\",\n \" \": \" \",\n};\n\nconst ENTITY_REGEX = /&|<|>|"|'| /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
|
+
}
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
import {
|
|
4
4
|
init_log_and_swallow,
|
|
5
5
|
logAndSwallow
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-W2PSVV2T.js";
|
|
7
7
|
import {
|
|
8
8
|
abtarsHome,
|
|
9
9
|
init_paths
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-7XXISOHU.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-
|
|
130
|
+
//# sourceMappingURL=chunk-OT6HLPEA.js.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import {
|
|
4
4
|
init_logger,
|
|
5
5
|
logTrace
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-6S3G6GPO.js";
|
|
7
7
|
|
|
8
8
|
// src/components/env.ts
|
|
9
9
|
init_logger();
|
|
@@ -26,4 +26,4 @@ export {
|
|
|
26
26
|
readEnv,
|
|
27
27
|
readEnvWithDefault
|
|
28
28
|
};
|
|
29
|
-
//# sourceMappingURL=chunk-
|
|
29
|
+
//# sourceMappingURL=chunk-OWPQIBAO.js.map
|
|
@@ -1,5 +1,11 @@
|
|
|
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_paths
|
|
5
|
+
} from "./chunk-2BXXQG7P.js";
|
|
6
|
+
|
|
7
|
+
// src/cli/deploy-lib/index.ts
|
|
8
|
+
init_paths();
|
|
3
9
|
|
|
4
10
|
// src/cli/deploy-lib/manifest.ts
|
|
5
11
|
import { readFile, writeFile } from "node:fs/promises";
|
|
@@ -165,19 +171,20 @@ function configSnapshot(configDir) {
|
|
|
165
171
|
}
|
|
166
172
|
}
|
|
167
173
|
}
|
|
168
|
-
async function healthProbe(home, afterTimestamp, timeoutMs = 6e4) {
|
|
174
|
+
async function healthProbe(home, afterTimestamp, timeoutMs = 6e4, opts) {
|
|
169
175
|
const lockPath = join(home, "bridge.lock");
|
|
170
176
|
const deadline = Date.now() + timeoutMs;
|
|
177
|
+
const readLock2 = opts?.lockReader ?? ((p) => readFileSync(p, "utf-8"));
|
|
171
178
|
const oldPid = (() => {
|
|
172
179
|
try {
|
|
173
|
-
return JSON.parse(
|
|
180
|
+
return JSON.parse(readLock2(lockPath)).pid;
|
|
174
181
|
} catch {
|
|
175
182
|
return 0;
|
|
176
183
|
}
|
|
177
184
|
})();
|
|
178
185
|
while (Date.now() < deadline) {
|
|
179
186
|
try {
|
|
180
|
-
const content = JSON.parse(
|
|
187
|
+
const content = JSON.parse(readLock2(lockPath));
|
|
181
188
|
if (content.pid !== oldPid && content.lastHeartbeat && content.lastHeartbeat > afterTimestamp) {
|
|
182
189
|
return { healthy: true, pid: content.pid, heartbeat: content.lastHeartbeat };
|
|
183
190
|
}
|
|
@@ -303,4 +310,4 @@ export {
|
|
|
303
310
|
removePath,
|
|
304
311
|
safeCopyTree
|
|
305
312
|
};
|
|
306
|
-
//# sourceMappingURL=chunk-
|
|
313
|
+
//# sourceMappingURL=chunk-QJPDBJDP.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/cli/deploy-lib/index.ts", "../src/cli/deploy-lib/manifest.ts", "../src/cli/deploy-lib/lock.ts", "../src/cli/deploy-lib/releases.ts", "../src/cli/deploy-lib/cleanup.ts", "../src/cli/deploy-lib/safe-copy.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Deploy-lib: shared install/update/rollback primitives.\n *\n * Consumed by both `abmind` CLI (its own runtime at ~/.abmind) and by\n * `abtars` (via file:../abmind dependency, managing ~/.abtars).\n *\n * Entry points are the module files directly:\n * import { resolveAbtarsHome } from 'abmind/deploy-lib/paths.js'\n * import { readManifest, writeManifest } from 'abmind/deploy-lib/manifest.js'\n * etc.\n *\n * See abproject/docs/plans/158-deploy-rewrite.md for the full contract.\n */\n\nexport * from './paths.js';\nexport * from './manifest.js';\nexport * from './lock.js';\nexport * from './releases.js';\nexport * from './cleanup.js';\nexport * from './safe-copy.js';\n", "/**\n * Runtime manifest: the single source of truth for \"what's installed\".\n *\n * Location: $HOME/manifest.json (per packagePaths().manifest).\n * Read by: `status`, cross-package compatibility checks, doctor.\n * Written by: `install`, `update`, `rollback`, migrations.\n */\n\nimport { readFile, writeFile } from 'node:fs/promises';\n\nexport interface Manifest {\n readonly package: 'abtars' | 'abmind';\n /** Currently active release version. */\n readonly version: string;\n /** Git SHA of the source that produced the active release, if known. */\n readonly commit: string | null;\n /** Git branch, if known. */\n readonly branch: string | null;\n /** Hash of package-lock.json at time of last install. */\n readonly packageLockHash: string | null;\n /** ISO timestamp of when the active release became active. */\n readonly activatedAt: string;\n /** Hostname where install lives (informational). */\n readonly host: string;\n /** Source adapter that produced the current release. */\n readonly source: 'dev' | 'alpha' | 'stable' | 'local' | 'npm' | 'github';\n /** Applied migrations (ordered). */\n readonly migrationsApplied: readonly string[];\n /** Previous version (for rollback). Null on first install. */\n readonly previousVersion: string | null;\n /** Previous commit (for rollback reference). */\n readonly previousCommit: string | null;\n /** Install mode: simple (manual) or daemon (watchdog + OS integration if available). */\n readonly installMode?: 'simple' | 'daemon';\n /** Repo root path (set when source=local). Null for npm installs. */\n readonly repoRoot?: string | null;\n}\n\nexport async function readManifest(path: string): Promise<Manifest | null> {\n try {\n const raw = await readFile(path, 'utf-8');\n return JSON.parse(raw) as Manifest;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw err;\n }\n}\n\nexport async function writeManifest(path: string, manifest: Manifest): Promise<void> {\n await writeFile(path, JSON.stringify(manifest, null, 2) + '\\n', 'utf-8');\n}\n\nexport function emptyManifest(pkg: 'abtars' | 'abmind', host: string): Manifest {\n return {\n package: pkg,\n version: '',\n commit: null,\n branch: null,\n packageLockHash: null,\n activatedAt: new Date().toISOString(),\n host,\n source: 'dev',\n migrationsApplied: [],\n previousVersion: null,\n previousCommit: null,\n };\n}\n", "/**\n * Update lock: prevents concurrent `install` / `update` / `rollback` runs\n * in the same runtime from colliding.\n *\n * Mechanism: write a JSON pidfile at packagePaths().lock. If file exists and\n * the PID is alive and the mtime is recent (<1h), refuse to proceed. Otherwise\n * take the lock.\n *\n * Stale timeout matches plan: 1 hour (our updates take minutes). Compared to\n * claude-code's 7-day timeout which accommodates laptop sleep during a long\n * install \u2014 not applicable for our short-lived updates.\n */\n\nimport { readFile, unlink, writeFile } from 'node:fs/promises';\nimport { unlinkSync } from 'node:fs';\nimport { hostname } from 'node:os';\n\nconst STALE_MS = 5 * 60 * 1000; // 5 minutes \u2014 deploys take <2min\n\nexport interface LockContent {\n readonly pid: number;\n readonly host: string;\n readonly startedAt: string;\n readonly cmd: string;\n}\n\nexport class LockHeldError extends Error {\n constructor(\n public readonly content: LockContent,\n public readonly isStale: boolean,\n ) {\n const staleMsg = isStale ? ' (appears stale \u2014 process may have crashed)' : '';\n super(\n `Lock held by pid ${content.pid} since ${content.startedAt} ` +\n `(cmd: ${content.cmd})${staleMsg}`,\n );\n this.name = 'LockHeldError';\n }\n}\n\nfunction isPidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === 'EPERM';\n }\n}\n\nasync function readLock(path: string): Promise<LockContent | null> {\n try {\n return JSON.parse(await readFile(path, 'utf-8')) as LockContent;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw err;\n }\n}\n\n/**\n * Acquire the lock or throw LockHeldError. Returns a release function.\n * Caller must call release() on both success and failure; the returned\n * function is idempotent.\n */\nexport async function acquireLock(path: string, cmd: string): Promise<() => Promise<void>> {\n const existing = await readLock(path);\n if (existing) {\n const alive = isPidAlive(existing.pid);\n const started = Date.parse(existing.startedAt);\n const age = Date.now() - (Number.isFinite(started) ? started : 0);\n const stale = !alive || age > STALE_MS;\n if (!stale) {\n throw new LockHeldError(existing, false);\n }\n // Stale: fall through and take it, but tell the caller so doctor can surface.\n }\n\n const content: LockContent = {\n pid: process.pid,\n host: hostname(),\n startedAt: new Date().toISOString(),\n cmd,\n };\n await writeFile(path, JSON.stringify(content, null, 2) + '\\n', 'utf-8');\n\n let released = false;\n const release = async (): Promise<void> => {\n if (released) return;\n released = true;\n try {\n await unlink(path);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n };\n\n // Best-effort cleanup on unexpected exit.\n const exitHandler = (): void => {\n try {\n unlinkSync(path);\n } catch {\n /* ignore \u2014 stale detection handles orphans next run */\n }\n };\n process.once('exit', exitHandler);\n\n return release;\n}\n\nexport async function inspectLock(path: string): Promise<\n | { held: false }\n | { held: true; content: LockContent; stale: boolean }\n> {\n const content = await readLock(path);\n if (!content) return { held: false };\n const alive = isPidAlive(content.pid);\n const started = Date.parse(content.startedAt);\n const age = Date.now() - (Number.isFinite(started) ? started : 0);\n const stale = !alive || age > STALE_MS;\n return { held: true, content, stale };\n}\n", "/**\n * Deploy primitives: atomic swap, config snapshot, health probe, hash.\n *\n * #785: replaces the old releases/current symlink model with\n * app/ + app.prev/ atomic rename swap.\n */\n\nimport { createHash } from 'node:crypto';\nimport { existsSync, mkdirSync, rmSync, renameSync, readdirSync, cpSync, readFileSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\n/**\n * Atomic swap with 3-prior rotation.\n * app.prev.3/ \u2192 delete, app.prev.2/ \u2192 .3, app.prev.1/ \u2192 .2, app/ \u2192 .prev.1, staging/ \u2192 app/\n * Backward compat: migrates old app.prev/ \u2192 app.prev.1/ if found.\n */\nexport function atomicSwap(appDir: string, _appPrevLegacy: string, appStagingDir: string): void {\n const prev1 = appDir.replace(/\\/app$/, '/app.prev.1');\n const prev2 = appDir.replace(/\\/app$/, '/app.prev.2');\n const prev3 = appDir.replace(/\\/app$/, '/app.prev.3');\n const legacyPrev = _appPrevLegacy; // app.prev/ (old format)\n\n // Migrate old app.prev/ \u2192 app.prev.1/ if exists\n if (existsSync(legacyPrev) && !existsSync(prev1)) {\n renameSync(legacyPrev, prev1);\n } else if (existsSync(legacyPrev)) {\n rmSync(legacyPrev, { recursive: true, force: true });\n }\n\n // Skip rotation if current app/ has same version as staging (no-op redeploy)\n try {\n const curPkg = join(appDir, \"package.json\");\n const stagePkg = join(appStagingDir, \"package.json\");\n if (existsSync(curPkg) && existsSync(stagePkg)) {\n const curVer = JSON.parse(readFileSync(curPkg, \"utf-8\")).version;\n const stageVer = JSON.parse(readFileSync(stagePkg, \"utf-8\")).version;\n if (curVer && curVer === stageVer) {\n // Same version \u2014 just replace app/ without rotating priors\n rmSync(appDir, { recursive: true, force: true });\n renameSync(appStagingDir, appDir);\n return;\n }\n }\n } catch { /* proceed with normal rotation if read fails */ }\n\n // Rotate: 3 \u2192 delete, 2 \u2192 3, 1 \u2192 2\n if (existsSync(prev3)) rmSync(prev3, { recursive: true, force: true });\n if (existsSync(prev2)) renameSync(prev2, prev3);\n if (existsSync(prev1)) renameSync(prev1, prev2);\n\n // app/ \u2192 app.prev.1/\n if (existsSync(appDir)) renameSync(appDir, prev1);\n\n // app.staging/ \u2192 app/\n renameSync(appStagingDir, appDir);\n}\n\n/**\n * Rotate config snapshots (3 slots) and create a fresh snapshot.\n * Excludes .pre-update* dirs from the copy to avoid recursion.\n */\nexport function configSnapshot(configDir: string): void {\n const slot0 = join(configDir, '.pre-update');\n const slot1 = join(configDir, '.pre-update.1');\n const slot2 = join(configDir, '.pre-update.2');\n\n // Rotate\n if (existsSync(slot2)) rmSync(slot2, { recursive: true, force: true });\n if (existsSync(slot1)) renameSync(slot1, slot2);\n if (existsSync(slot0)) renameSync(slot0, slot1);\n\n // Fresh snapshot \u2014 copy config/ contents excluding .pre-update* dirs\n mkdirSync(slot0, { recursive: true });\n if (!existsSync(configDir)) return;\n for (const entry of readdirSync(configDir, { withFileTypes: true })) {\n if (entry.name.startsWith('.pre-update')) continue;\n const src = join(configDir, entry.name);\n const dst = join(slot0, entry.name);\n if (entry.isDirectory()) {\n cpSync(src, dst, { recursive: true });\n } else {\n cpSync(src, dst);\n }\n }\n}\n\n/**\n * Poll bridge.lock for a fresh lastHeartbeat after restart.\n * Returns true if healthy within timeoutMs, false otherwise.\n */\nexport async function healthProbe(\n home: string,\n afterTimestamp: number,\n timeoutMs: number = 60_000,\n opts?: { lockReader?: (path: string) => string },\n): Promise<{ healthy: boolean; pid?: number; heartbeat?: number }> {\n const lockPath = join(home, 'bridge.lock');\n const deadline = Date.now() + timeoutMs;\n const readLock = opts?.lockReader ?? ((p: string) => readFileSync(p, 'utf-8'));\n const oldPid = (() => { try { return JSON.parse(readLock(lockPath)).pid; } catch { return 0; } })();\n while (Date.now() < deadline) {\n try {\n const content = JSON.parse(readLock(lockPath));\n // Verify bridge restarted (new PID) AND is healthy (fresh heartbeat)\n if (content.pid !== oldPid && content.lastHeartbeat && content.lastHeartbeat > afterTimestamp) {\n return { healthy: true, pid: content.pid, heartbeat: content.lastHeartbeat };\n }\n } catch {}\n await new Promise(r => setTimeout(r, 3000));\n }\n return { healthy: false };\n}\n\n/**\n * Write/read/clear the update sentinel.\n */\nexport interface UpdateSentinel {\n version: string;\n previousVersion: string | null;\n startedAt: string;\n status: 'pending' | 'success';\n}\n\nexport function writeSentinel(home: string, sentinel: UpdateSentinel): void {\n const dir = join(home, 'state');\n mkdirSync(dir, { recursive: true });\n writeFileSync(join(dir, 'update.sentinel'), JSON.stringify(sentinel, null, 2) + '\\n');\n}\n\nexport function readSentinel(home: string): UpdateSentinel | null {\n try {\n const content = readFileSync(join(home, 'state', 'update.sentinel'), 'utf-8');\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport function clearSentinel(home: string, _version: string): void {\n const path = join(home, 'state', 'update.sentinel');\n if (!existsSync(path)) return;\n try {\n const sentinel: UpdateSentinel = JSON.parse(readFileSync(path, 'utf-8'));\n sentinel.status = 'success';\n writeFileSync(path, JSON.stringify(sentinel, null, 2) + '\\n');\n } catch {\n // Best effort\n }\n}\n\nexport async function hashFile(path: string): Promise<string | null> {\n try {\n const buf = await readFile(path);\n return createHash('sha256').update(buf).digest('hex');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw err;\n }\n}\n\n/**\n * Clean up stale app.staging/ from a previously interrupted update.\n */\nexport function cleanStaleStaging(stagingDir: string): void {\n if (existsSync(stagingDir)) {\n rmSync(stagingDir, { recursive: true, force: true });\n }\n}\n", "/**\n * Safety-guarded destructive ops for `reset` / `uninstall`.\n *\n * Cleanup utilities for deploy operations.\n * Key primitive: isUnsafeRemovalTarget() rejects catastrophic paths ('/',\n * '~', empty, etc.) BEFORE any caller invokes rm. Caller must always check.\n */\n\nimport { rm } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { resolve } from 'node:path';\n\n/**\n * True if the path is something we refuse to remove, regardless of flags.\n *\n * Rejects:\n * - empty / whitespace-only strings\n * - '/', '\\\\', or any path that resolves to root\n * - '~' (home), home dir itself, or parents of home\n * - Anything not under the user's home dir (defense-in-depth against\n * config pointing at /etc/... by mistake)\n *\n * Callers SHOULD still confirm with the user before removing even \"safe\"\n * paths; this function is a hard floor, not a substitute for confirmation.\n */\nexport function isUnsafeRemovalTarget(path: string): boolean {\n const trimmed = path.trim();\n if (trimmed === '') return true;\n if (trimmed === '~' || trimmed === '/' || trimmed === '\\\\') return true;\n const abs = resolve(trimmed);\n if (abs === '/' || abs === '') return true;\n const home = homedir();\n if (abs === home) return true;\n // Must be under home (defense in depth).\n const homeWithSep = home.endsWith('/') ? home : home + '/';\n if (!abs.startsWith(homeWithSep)) return true;\n return false;\n}\n\nexport interface RemovePlan {\n readonly path: string;\n readonly willRemove: boolean;\n readonly reason: string;\n}\n\n/**\n * Plan a remove without executing. Used by --dry-run flows in reset/uninstall.\n */\nexport function planRemoval(path: string): RemovePlan {\n if (isUnsafeRemovalTarget(path)) {\n return { path, willRemove: false, reason: 'refused: unsafe target' };\n }\n return { path, willRemove: true, reason: 'would remove recursively' };\n}\n\n/**\n * Remove a path after validating safety. Throws if the target is unsafe.\n * Returns true if the path was removed, false if it didn't exist.\n */\nexport async function removePath(path: string, opts: { dryRun?: boolean } = {}): Promise<boolean> {\n if (isUnsafeRemovalTarget(path)) {\n throw new Error(`Refused to remove unsafe target: ${path}`);\n }\n if (opts.dryRun) return true;\n try {\n await rm(path, { recursive: true });\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return false;\n throw err;\n }\n}\n", "/**\n * Safe recursive copy that skips non-regular-file entries Node's cp()\n * refuses to handle (EINVAL on sockets). Real runtime roots can contain\n * UNIX sockets (browser.sock, memory.sock, etc.) which are ephemeral IPC\n * endpoints \u2014 not data we want or can back up.\n *\n * Skipped: sockets, FIFOs, block devices, character devices.\n * Copied: regular files, directories, symlinks.\n */\n\nimport { cp, lstat } from 'node:fs/promises';\n\nexport interface SafeCopyOptions {\n readonly preserveTimestamps?: boolean;\n /** Overwrite existing entries at the destination. Default: false. */\n readonly force?: boolean;\n}\n\nasync function shouldCopy(src: string): Promise<boolean> {\n try {\n const s = await lstat(src);\n if (s.isSocket() || s.isFIFO() || s.isBlockDevice() || s.isCharacterDevice()) {\n return false;\n }\n return true;\n } catch {\n // Let the subsequent cp call surface the real error if any.\n return true;\n }\n}\n\nexport async function safeCopyTree(src: string, dst: string, opts: SafeCopyOptions = {}): Promise<void> {\n await cp(src, dst, {\n recursive: true,\n preserveTimestamps: opts.preserveTimestamps === true,\n force: opts.force === true,\n filter: shouldCopy,\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["readFile", "writeFile", "readFile", "readLock"]
|
|
7
|
+
}
|
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
import {
|
|
4
4
|
init_spin,
|
|
5
5
|
spin
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-FSGICOCX.js";
|
|
7
7
|
import {
|
|
8
8
|
addCompletion
|
|
9
9
|
} from "./chunk-MV6CJFWR.js";
|
|
10
10
|
import {
|
|
11
11
|
getEnv,
|
|
12
12
|
init_env_schema
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BWJ37KMW.js";
|
|
14
14
|
import {
|
|
15
15
|
init_logger,
|
|
16
16
|
logInfo,
|
|
17
17
|
logWarn
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-6S3G6GPO.js";
|
|
19
19
|
|
|
20
20
|
// src/components/transport/delegation-tools.ts
|
|
21
21
|
init_spin();
|
|
@@ -56,7 +56,7 @@ var spawnSessionTool = {
|
|
|
56
56
|
if (running.length >= MAX_BACKGROUND) {
|
|
57
57
|
return JSON.stringify({ error: `Max ${MAX_BACKGROUND} concurrent background sessions. Wait for one to finish or terminate it.` });
|
|
58
58
|
}
|
|
59
|
-
const masterUid = (await import("./master-user-
|
|
59
|
+
const masterUid = (await import("./master-user-TKA7M2GL.js")).getMasterUserId();
|
|
60
60
|
const session = spin.createSubSession(masterUid, "telegram", typeInfo.sessionType);
|
|
61
61
|
if (typeof session === "string") return JSON.stringify({ error: session });
|
|
62
62
|
const goal = args.goal ?? "No goal specified";
|
|
@@ -216,4 +216,4 @@ export {
|
|
|
216
216
|
consumePendingInstruction,
|
|
217
217
|
getDelegationTools
|
|
218
218
|
};
|
|
219
|
-
//# sourceMappingURL=chunk-
|
|
219
|
+
//# sourceMappingURL=chunk-QMP2KC4W.js.map
|
|
@@ -2,30 +2,30 @@
|
|
|
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
|
readEnvWithDefault
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-OWPQIBAO.js";
|
|
6
6
|
import {
|
|
7
7
|
TRANSPORT_SCHEMA,
|
|
8
8
|
init_config_validator,
|
|
9
9
|
validateShape
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2ZD7VQRW.js";
|
|
11
11
|
import {
|
|
12
12
|
getEnv,
|
|
13
13
|
init_env_schema
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-BWJ37KMW.js";
|
|
15
15
|
import {
|
|
16
16
|
init_log_and_swallow,
|
|
17
17
|
logAndSwallow
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-W2PSVV2T.js";
|
|
19
19
|
import {
|
|
20
20
|
init_logger,
|
|
21
21
|
logError,
|
|
22
22
|
logInfo,
|
|
23
23
|
logWarn
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-6S3G6GPO.js";
|
|
25
25
|
import {
|
|
26
26
|
abtarsHome,
|
|
27
27
|
init_paths
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-7XXISOHU.js";
|
|
29
29
|
import {
|
|
30
30
|
__require
|
|
31
31
|
} from "./chunk-7K2YZTLD.js";
|
|
@@ -411,4 +411,4 @@ export {
|
|
|
411
411
|
validateProviderReady,
|
|
412
412
|
formatValidationError
|
|
413
413
|
};
|
|
414
|
-
//# sourceMappingURL=chunk-
|
|
414
|
+
//# sourceMappingURL=chunk-QOGZ7BFL.js.map
|
|
@@ -6,12 +6,12 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
getEnv,
|
|
8
8
|
init_env_schema
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-BWJ37KMW.js";
|
|
10
10
|
import {
|
|
11
11
|
init_logger,
|
|
12
12
|
logError,
|
|
13
13
|
logWarn
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-6S3G6GPO.js";
|
|
15
15
|
|
|
16
16
|
// src/components/main-chat.ts
|
|
17
17
|
init_env_schema();
|
|
@@ -40,4 +40,4 @@ async function sendToMainChat(adapters, text, opts) {
|
|
|
40
40
|
export {
|
|
41
41
|
sendToMainChat
|
|
42
42
|
};
|
|
43
|
-
//# sourceMappingURL=chunk-
|
|
43
|
+
//# sourceMappingURL=chunk-R23FHZRY.js.map
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
|
|
3
3
|
import {
|
|
4
4
|
printBanner
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-LN5MNDSA.js";
|
|
6
6
|
import {
|
|
7
7
|
init_log_and_swallow,
|
|
8
8
|
logAndSwallow
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-W2PSVV2T.js";
|
|
10
10
|
import {
|
|
11
11
|
abtarsHome,
|
|
12
12
|
init_paths
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-7XXISOHU.js";
|
|
14
14
|
|
|
15
15
|
// src/cli/commands/restart.ts
|
|
16
16
|
init_paths();
|
|
@@ -66,11 +66,11 @@ async function restart(opts) {
|
|
|
66
66
|
(await import("node:fs")).writeFileSync(join(home, "deploy.state"), JSON.stringify(s) + "\n");
|
|
67
67
|
} catch {
|
|
68
68
|
}
|
|
69
|
-
const { start } = await import("./start-
|
|
69
|
+
const { start } = await import("./start-HPO5LYJP.js");
|
|
70
70
|
return start();
|
|
71
71
|
}
|
|
72
72
|
if (bridgeAlive) {
|
|
73
|
-
const { writeRestartRequested } = await import("./bridge-lock-transport-
|
|
73
|
+
const { writeRestartRequested } = await import("./bridge-lock-transport-BJAMHMXW.js");
|
|
74
74
|
writeRestartRequested("restart");
|
|
75
75
|
process.stdout.write(`\u267B\uFE0F Restart requested (PID ${bridgePid}) \u2014 bridge will restart within 30s
|
|
76
76
|
`);
|
|
@@ -83,4 +83,4 @@ async function restart(opts) {
|
|
|
83
83
|
export {
|
|
84
84
|
restart
|
|
85
85
|
};
|
|
86
|
-
//# sourceMappingURL=chunk-
|
|
86
|
+
//# sourceMappingURL=chunk-R4GYWVCR.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/cli/commands/restart.ts"],
|
|
4
|
+
"sourcesContent": ["import { printBanner } from './banner.js';\n/**\n * abtars restart [--cold] \u2014 unified restart command.\n * Warm (default): writeRestartRequested \u2192 main.ts internal loop restarts.\n * Cold (--cold): kill process, then start fresh.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { abtarsHome } from \"../../paths.js\";\nimport { logAndSwallow } from \"../../components/log-and-swallow.js\";\n\nfunction readJsonField(file: string, field: string): unknown {\n try { return JSON.parse(readFileSync(file, \"utf-8\"))[field]; } catch { return undefined; }\n}\n\nfunction pidAlive(pid: number): boolean {\n try { process.kill(pid, 0); return true; } catch { return false; }\n}\n\nasync function killBridge(pid: number): Promise<void> {\n try { process.kill(pid, \"SIGTERM\"); } catch { return; }\n process.stdout.write(`\uD83D\uDED1 Killing bridge (PID ${pid})...\\n`);\n for (let i = 0; i < 20; i++) {\n await new Promise(r => setTimeout(r, 500));\n if (!pidAlive(pid)) return;\n }\n try { process.kill(pid, \"SIGKILL\"); } catch (err) { logAndSwallow(\"restart\", \"op\", err); }\n await new Promise(r => setTimeout(r, 1000));\n}\n\nexport async function restart(opts: { cold?: boolean }): Promise<number> {\n await printBanner(\"restart\");\n const home = abtarsHome();\n const lockFile = join(home, \"bridge.lock\");\n const cold = opts.cold ?? false;\n\n const bridgePid = readJsonField(lockFile, \"pid\") as number | undefined;\n const bridgeAlive = bridgePid != null && bridgePid > 0 && pidAlive(bridgePid);\n\n if (cold) {\n if (bridgeAlive) await killBridge(bridgePid!);\n\n // Clear circuit breaker \u2014 intentional restart = clean slate\n try {\n const s = JSON.parse(readFileSync(join(home, \"deploy.state\"), \"utf-8\"));\n s.restartCount = 0;\n (await import(\"node:fs\")).writeFileSync(join(home, \"deploy.state\"), JSON.stringify(s) + \"\\n\");\n } catch {}\n\n // Start via the start command (handles both modes)\n const { start } = await import(\"./start.js\");\n return start();\n }\n\n // Warm restart\n if (bridgeAlive) {\n const { writeRestartRequested } = await import(\"../../components/transport/bridge-lock-transport.js\");\n writeRestartRequested(\"restart\");\n process.stdout.write(`\u267B\uFE0F Restart requested (PID ${bridgePid}) \u2014 bridge will restart within 30s\\n`);\n return 0;\n }\n\n process.stdout.write(\"Bridge not running. Use --cold to start fresh.\\n\");\n return 1;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;AASA;AACA;AAHA,SAAS,oBAAoB;AAC7B,SAAS,YAAY;AAIrB,SAAS,cAAc,MAAc,OAAwB;AAC3D,MAAI;AAAE,WAAO,KAAK,MAAM,aAAa,MAAM,OAAO,CAAC,EAAE,KAAK;AAAA,EAAG,QAAQ;AAAE,WAAO;AAAA,EAAW;AAC3F;AAEA,SAAS,SAAS,KAAsB;AACtC,MAAI;AAAE,YAAQ,KAAK,KAAK,CAAC;AAAG,WAAO;AAAA,EAAM,QAAQ;AAAE,WAAO;AAAA,EAAO;AACnE;AAEA,eAAe,WAAW,KAA4B;AACpD,MAAI;AAAE,YAAQ,KAAK,KAAK,SAAS;AAAA,EAAG,QAAQ;AAAE;AAAA,EAAQ;AACtD,UAAQ,OAAO,MAAM,iCAA0B,GAAG;AAAA,CAAQ;AAC1D,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAM,IAAI,QAAQ,OAAK,WAAW,GAAG,GAAG,CAAC;AACzC,QAAI,CAAC,SAAS,GAAG,EAAG;AAAA,EACtB;AACA,MAAI;AAAE,YAAQ,KAAK,KAAK,SAAS;AAAA,EAAG,SAAS,KAAK;AAAE,kBAAc,WAAW,MAAM,GAAG;AAAA,EAAG;AACzF,QAAM,IAAI,QAAQ,OAAK,WAAW,GAAG,GAAI,CAAC;AAC5C;AAEA,eAAsB,QAAQ,MAA2C;AACvE,QAAM,YAAY,SAAS;AAC3B,QAAM,OAAO,WAAW;AACxB,QAAM,WAAW,KAAK,MAAM,aAAa;AACzC,QAAM,OAAO,KAAK,QAAQ;AAE1B,QAAM,YAAY,cAAc,UAAU,KAAK;AAC/C,QAAM,cAAc,aAAa,QAAQ,YAAY,KAAK,SAAS,SAAS;AAE5E,MAAI,MAAM;AACR,QAAI,YAAa,OAAM,WAAW,SAAU;AAG5C,QAAI;AACF,YAAM,IAAI,KAAK,MAAM,aAAa,KAAK,MAAM,cAAc,GAAG,OAAO,CAAC;AACtE,QAAE,eAAe;AACjB,OAAC,MAAM,OAAO,SAAS,GAAG,cAAc,KAAK,MAAM,cAAc,GAAG,KAAK,UAAU,CAAC,IAAI,IAAI;AAAA,IAC9F,QAAQ;AAAA,IAAC;AAGT,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO,qBAAY;AAC3C,WAAO,MAAM;AAAA,EACf;AAGA,MAAI,aAAa;AACf,UAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,qCAAqD;AACpG,0BAAsB,SAAS;AAC/B,YAAQ,OAAO,MAAM,uCAA6B,SAAS;AAAA,CAAsC;AACjG,WAAO;AAAA,EACT;AAEA,UAAQ,OAAO,MAAM,kDAAkD;AACvE,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
__require
|
|
6
6
|
} from "./chunk-7K2YZTLD.js";
|
|
7
7
|
|
|
8
|
-
// node_modules
|
|
8
|
+
// node_modules/ws/lib/constants.js
|
|
9
9
|
var require_constants = __commonJS({
|
|
10
|
-
"node_modules
|
|
10
|
+
"node_modules/ws/lib/constants.js"(exports, module) {
|
|
11
11
|
"use strict";
|
|
12
12
|
var BINARY_TYPES = ["nodebuffer", "arraybuffer", "fragments"];
|
|
13
13
|
var hasBlob = typeof Blob !== "undefined";
|
|
@@ -28,9 +28,9 @@ var require_constants = __commonJS({
|
|
|
28
28
|
}
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
-
// node_modules
|
|
31
|
+
// node_modules/ws/lib/buffer-util.js
|
|
32
32
|
var require_buffer_util = __commonJS({
|
|
33
|
-
"node_modules
|
|
33
|
+
"node_modules/ws/lib/buffer-util.js"(exports, module) {
|
|
34
34
|
"use strict";
|
|
35
35
|
var { EMPTY_BUFFER } = require_constants();
|
|
36
36
|
var FastBuffer = Buffer[Symbol.species];
|
|
@@ -103,9 +103,9 @@ var require_buffer_util = __commonJS({
|
|
|
103
103
|
}
|
|
104
104
|
});
|
|
105
105
|
|
|
106
|
-
// node_modules
|
|
106
|
+
// node_modules/ws/lib/limiter.js
|
|
107
107
|
var require_limiter = __commonJS({
|
|
108
|
-
"node_modules
|
|
108
|
+
"node_modules/ws/lib/limiter.js"(exports, module) {
|
|
109
109
|
"use strict";
|
|
110
110
|
var kDone = Symbol("kDone");
|
|
111
111
|
var kRun = Symbol("kRun");
|
|
@@ -153,9 +153,9 @@ var require_limiter = __commonJS({
|
|
|
153
153
|
}
|
|
154
154
|
});
|
|
155
155
|
|
|
156
|
-
// node_modules
|
|
156
|
+
// node_modules/ws/lib/permessage-deflate.js
|
|
157
157
|
var require_permessage_deflate = __commonJS({
|
|
158
|
-
"node_modules
|
|
158
|
+
"node_modules/ws/lib/permessage-deflate.js"(exports, module) {
|
|
159
159
|
"use strict";
|
|
160
160
|
var zlib = __require("zlib");
|
|
161
161
|
var bufferUtil = require_buffer_util();
|
|
@@ -536,9 +536,9 @@ var require_permessage_deflate = __commonJS({
|
|
|
536
536
|
}
|
|
537
537
|
});
|
|
538
538
|
|
|
539
|
-
// node_modules
|
|
539
|
+
// node_modules/ws/lib/validation.js
|
|
540
540
|
var require_validation = __commonJS({
|
|
541
|
-
"node_modules
|
|
541
|
+
"node_modules/ws/lib/validation.js"(exports, module) {
|
|
542
542
|
"use strict";
|
|
543
543
|
var { isUtf8 } = __require("buffer");
|
|
544
544
|
var { hasBlob } = require_constants();
|
|
@@ -737,9 +737,9 @@ var require_validation = __commonJS({
|
|
|
737
737
|
}
|
|
738
738
|
});
|
|
739
739
|
|
|
740
|
-
// node_modules
|
|
740
|
+
// node_modules/ws/lib/receiver.js
|
|
741
741
|
var require_receiver = __commonJS({
|
|
742
|
-
"node_modules
|
|
742
|
+
"node_modules/ws/lib/receiver.js"(exports, module) {
|
|
743
743
|
"use strict";
|
|
744
744
|
var { Writable } = __require("stream");
|
|
745
745
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -1369,9 +1369,9 @@ var require_receiver = __commonJS({
|
|
|
1369
1369
|
}
|
|
1370
1370
|
});
|
|
1371
1371
|
|
|
1372
|
-
// node_modules
|
|
1372
|
+
// node_modules/ws/lib/sender.js
|
|
1373
1373
|
var require_sender = __commonJS({
|
|
1374
|
-
"node_modules
|
|
1374
|
+
"node_modules/ws/lib/sender.js"(exports, module) {
|
|
1375
1375
|
"use strict";
|
|
1376
1376
|
var { Duplex } = __require("stream");
|
|
1377
1377
|
var { randomFillSync } = __require("crypto");
|
|
@@ -1862,9 +1862,9 @@ var require_sender = __commonJS({
|
|
|
1862
1862
|
}
|
|
1863
1863
|
});
|
|
1864
1864
|
|
|
1865
|
-
// node_modules
|
|
1865
|
+
// node_modules/ws/lib/extension.js
|
|
1866
1866
|
var require_extension = __commonJS({
|
|
1867
|
-
"node_modules
|
|
1867
|
+
"node_modules/ws/lib/extension.js"(exports, module) {
|
|
1868
1868
|
"use strict";
|
|
1869
1869
|
var { tokenChars } = require_validation();
|
|
1870
1870
|
function push(dest, name, elem) {
|
|
@@ -2015,9 +2015,9 @@ var require_extension = __commonJS({
|
|
|
2015
2015
|
}
|
|
2016
2016
|
});
|
|
2017
2017
|
|
|
2018
|
-
// node_modules
|
|
2018
|
+
// node_modules/ws/lib/event-target.js
|
|
2019
2019
|
var require_event_target = __commonJS({
|
|
2020
|
-
"node_modules
|
|
2020
|
+
"node_modules/ws/lib/event-target.js"(exports, module) {
|
|
2021
2021
|
"use strict";
|
|
2022
2022
|
var { kForOnEventAttribute, kListener } = require_constants();
|
|
2023
2023
|
var kCode = Symbol("kCode");
|
|
@@ -2244,9 +2244,9 @@ var require_event_target = __commonJS({
|
|
|
2244
2244
|
}
|
|
2245
2245
|
});
|
|
2246
2246
|
|
|
2247
|
-
// node_modules
|
|
2247
|
+
// node_modules/ws/lib/websocket.js
|
|
2248
2248
|
var require_websocket = __commonJS({
|
|
2249
|
-
"node_modules
|
|
2249
|
+
"node_modules/ws/lib/websocket.js"(exports, module) {
|
|
2250
2250
|
"use strict";
|
|
2251
2251
|
var EventEmitter = __require("events");
|
|
2252
2252
|
var https = __require("https");
|
|
@@ -3140,9 +3140,9 @@ var require_websocket = __commonJS({
|
|
|
3140
3140
|
}
|
|
3141
3141
|
});
|
|
3142
3142
|
|
|
3143
|
-
// node_modules
|
|
3143
|
+
// node_modules/ws/lib/stream.js
|
|
3144
3144
|
var require_stream = __commonJS({
|
|
3145
|
-
"node_modules
|
|
3145
|
+
"node_modules/ws/lib/stream.js"(exports, module) {
|
|
3146
3146
|
"use strict";
|
|
3147
3147
|
var WebSocket = require_websocket();
|
|
3148
3148
|
var { Duplex } = __require("stream");
|
|
@@ -3238,9 +3238,9 @@ var require_stream = __commonJS({
|
|
|
3238
3238
|
}
|
|
3239
3239
|
});
|
|
3240
3240
|
|
|
3241
|
-
// node_modules
|
|
3241
|
+
// node_modules/ws/lib/subprotocol.js
|
|
3242
3242
|
var require_subprotocol = __commonJS({
|
|
3243
|
-
"node_modules
|
|
3243
|
+
"node_modules/ws/lib/subprotocol.js"(exports, module) {
|
|
3244
3244
|
"use strict";
|
|
3245
3245
|
var { tokenChars } = require_validation();
|
|
3246
3246
|
function parse(header) {
|
|
@@ -3283,9 +3283,9 @@ var require_subprotocol = __commonJS({
|
|
|
3283
3283
|
}
|
|
3284
3284
|
});
|
|
3285
3285
|
|
|
3286
|
-
// node_modules
|
|
3286
|
+
// node_modules/ws/lib/websocket-server.js
|
|
3287
3287
|
var require_websocket_server = __commonJS({
|
|
3288
|
-
"node_modules
|
|
3288
|
+
"node_modules/ws/lib/websocket-server.js"(exports, module) {
|
|
3289
3289
|
"use strict";
|
|
3290
3290
|
var EventEmitter = __require("events");
|
|
3291
3291
|
var http = __require("http");
|
|
@@ -3694,4 +3694,4 @@ export {
|
|
|
3694
3694
|
require_subprotocol,
|
|
3695
3695
|
require_websocket_server
|
|
3696
3696
|
};
|
|
3697
|
-
//# sourceMappingURL=chunk-
|
|
3697
|
+
//# sourceMappingURL=chunk-R76K6L6H.js.map
|