abtars 0.2.1-alpha.9 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +64 -0
- package/README.md +93 -34
- package/bundle/{_registry.generated-ADOYFJJ4.js → _registry.generated-KYX63MGY.js} +19 -16
- package/bundle/{_registry.generated-ADOYFJJ4.js.map → _registry.generated-KYX63MGY.js.map} +1 -1
- package/bundle/abtars-browser.js +5 -6
- package/bundle/abtars-browser.js.map +2 -2
- package/bundle/abtars-cli.js +205 -179
- package/bundle/abtars-cli.js.map +4 -4
- package/bundle/abtars-restart.js +4 -4
- package/bundle/abtars-rss.js +25 -81
- package/bundle/abtars-rss.js.map +2 -2
- package/bundle/abtars-task.js +4 -5
- package/bundle/abtars-task.js.map +2 -2
- package/bundle/abtars-todo.js +133 -0
- package/bundle/abtars-todo.js.map +7 -0
- package/bundle/abtars.js +305 -182
- package/bundle/abtars.js.map +3 -3
- package/bundle/action-gate-DYV2XQBP.js +191 -0
- package/bundle/action-gate-DYV2XQBP.js.map +7 -0
- package/bundle/{agent-api-rate-limit-C25WGSFF.js → agent-api-rate-limit-R2OFAQ3N.js} +4 -4
- package/bundle/{agent-registry-SYUFNSVB.js → agent-registry-5VL5KI6U.js} +8 -8
- package/bundle/agent-registry-PIS5XJHX.js +19 -0
- package/bundle/{bridge-lock-transport-HO545SBK.js → bridge-lock-transport-N6OGDOSE.js} +5 -5
- package/bundle/{browse-delivery-VTLEAVYA.js → browse-delivery-DXGMDMXA.js} +8 -7
- package/bundle/{browser-REIXOJ6S.js → browser-QMYGSP5W.js} +11 -10
- package/bundle/{capability-ILW3D5HS.js → capability-733TLH4W.js} +6 -6
- package/bundle/chunk-3IPMKYYH.js +672 -0
- package/bundle/chunk-3IPMKYYH.js.map +7 -0
- package/bundle/{chunk-PZE3J7ER.js → chunk-3OXQWII3.js} +2 -2
- package/bundle/{chunk-X5FBUA53.js → chunk-4WKWPU6U.js} +137 -30
- package/bundle/chunk-4WKWPU6U.js.map +7 -0
- package/bundle/{chunk-4KJ76TTE.js → chunk-4XW7YA3K.js} +3 -3
- package/bundle/{chunk-A5OJYQNU.js → chunk-5WFIAUQC.js} +49 -22
- package/bundle/chunk-5WFIAUQC.js.map +7 -0
- package/bundle/{chunk-ZVDVNSXK.js → chunk-7WFE2JI5.js} +7 -7
- package/bundle/{chunk-R36WIOYX.js → chunk-B52YRWR6.js} +34 -6
- package/bundle/chunk-B52YRWR6.js.map +7 -0
- package/bundle/{chunk-Q62SXS73.js → chunk-BBDKU4EH.js} +9 -9
- package/bundle/chunk-BBTQKKDO.js +258 -0
- package/bundle/chunk-BBTQKKDO.js.map +7 -0
- package/bundle/{chunk-EX2SRTUE.js → chunk-CYSGXNBY.js} +2 -2
- package/bundle/{chunk-LYEAHE5V.js → chunk-DCY7DGMT.js} +2 -2
- package/bundle/chunk-DGS7J4P6.js +13 -0
- package/bundle/chunk-DGS7J4P6.js.map +7 -0
- package/bundle/{chunk-LDKSCXGL.js → chunk-DHPFI7OF.js} +8 -6
- package/bundle/{chunk-LDKSCXGL.js.map → chunk-DHPFI7OF.js.map} +1 -1
- package/bundle/{chunk-G6IXMYIO.js → chunk-DO4INSXE.js} +2 -2
- package/bundle/{chunk-VA5WKN3Z.js → chunk-EGA6JQVV.js} +4 -4
- package/bundle/chunk-EKHNWFEQ.js +85 -0
- package/bundle/chunk-EKHNWFEQ.js.map +7 -0
- package/bundle/{chunk-URAQLQ2U.js → chunk-F3HMZFIL.js} +4 -4
- package/bundle/{chunk-OOKLEC6V.js → chunk-FY3QUO2L.js} +7 -7
- package/bundle/{chunk-2BY6I4P5.js → chunk-GUTRAMK3.js} +2 -2
- package/bundle/chunk-GXKJKYU4.js +1089 -0
- package/bundle/chunk-GXKJKYU4.js.map +7 -0
- package/bundle/{chunk-GPL57SRN.js → chunk-H7RX7UCR.js} +3 -3
- package/bundle/{chunk-BYDUMHXT.js → chunk-HAF2AFBW.js} +2 -2
- package/bundle/chunk-HAS5NEK7.js +189 -0
- package/bundle/chunk-HAS5NEK7.js.map +7 -0
- package/bundle/chunk-HB54S5OY.js +4036 -0
- package/bundle/chunk-HB54S5OY.js.map +7 -0
- package/bundle/{chunk-OZ4IZFV4.js → chunk-HJQZP5CK.js} +9 -9
- package/bundle/{chunk-OZ4IZFV4.js.map → chunk-HJQZP5CK.js.map} +2 -2
- package/bundle/{chunk-HEHD3GG5.js → chunk-ITB2K6LI.js} +6 -13
- package/bundle/{chunk-HEHD3GG5.js.map → chunk-ITB2K6LI.js.map} +3 -3
- package/bundle/{chunk-KSEIWT4T.js → chunk-JFKOPNKL.js} +10 -10
- package/bundle/chunk-JFKOPNKL.js.map +7 -0
- package/bundle/{chunk-KFENC7BM.js → chunk-L33WNMCP.js} +2 -2
- package/bundle/{chunk-JRG4EFMP.js → chunk-LBMETTUP.js} +3 -3
- package/bundle/{chunk-TYVI3ZWA.js → chunk-LJAG2URA.js} +10 -7
- package/bundle/chunk-LJAG2URA.js.map +7 -0
- package/bundle/{chunk-KWBGYWDO.js → chunk-N24ROESF.js} +15 -17
- package/bundle/chunk-N24ROESF.js.map +7 -0
- package/bundle/{chunk-P2BZSLJJ.js → chunk-N7UG4FID.js} +448 -129
- package/bundle/chunk-N7UG4FID.js.map +7 -0
- package/bundle/chunk-NIYVCGBC.js +330 -0
- package/bundle/chunk-NIYVCGBC.js.map +7 -0
- package/bundle/{chunk-TOUZC6NR.js → chunk-OKMN6J4Z.js} +3 -3
- package/bundle/{chunk-RV54J75Q.js → chunk-PKHYCNTT.js} +13 -12
- package/bundle/chunk-PKHYCNTT.js.map +7 -0
- package/bundle/{chunk-XZSYMCLF.js → chunk-PUDGA4RR.js} +7 -7
- package/bundle/{chunk-CELR236Q.js → chunk-Q7CH5DA3.js} +2 -2
- package/bundle/chunk-QSC6QZ44.js +183 -0
- package/bundle/chunk-QSC6QZ44.js.map +7 -0
- package/bundle/chunk-RITEGAW6.js +138 -0
- package/bundle/chunk-RITEGAW6.js.map +7 -0
- package/bundle/{chunk-UDZIZB5F.js → chunk-RTL7HO3N.js} +3 -3
- package/bundle/{chunk-ITG6XGBS.js → chunk-SA44ITVX.js} +10 -10
- package/bundle/{chunk-3MO2MDXJ.js → chunk-SA6YEFNG.js} +3 -3
- package/bundle/{chunk-4BUOO6WI.js → chunk-SMZQDMSZ.js} +31 -11
- package/bundle/chunk-SMZQDMSZ.js.map +7 -0
- package/bundle/{chunk-GBBTK6H2.js → chunk-SRFEIZQT.js} +4 -4
- package/bundle/{chunk-ELRAH7VL.js → chunk-VXUVKC66.js} +3 -3
- package/bundle/chunk-VY2BUO6L.js +4035 -0
- package/bundle/chunk-VY2BUO6L.js.map +7 -0
- package/bundle/chunk-W6ELWLAR.js +143 -0
- package/bundle/chunk-W6ELWLAR.js.map +7 -0
- package/bundle/{chunk-RSWUPUNA.js → chunk-WMWI3SJ7.js} +30 -6
- package/bundle/chunk-WMWI3SJ7.js.map +7 -0
- package/bundle/{chunk-MJ6PHMOK.js → chunk-WW5F2DCO.js} +11 -2
- package/bundle/chunk-WW5F2DCO.js.map +7 -0
- package/bundle/chunk-Y2XBDQP3.js +4055 -0
- package/bundle/chunk-Y2XBDQP3.js.map +7 -0
- package/bundle/chunk-YMGX6HNP.js +131 -0
- package/bundle/chunk-YMGX6HNP.js.map +7 -0
- package/bundle/chunk-YWZPKBO6.js +22 -0
- package/bundle/chunk-YWZPKBO6.js.map +7 -0
- package/bundle/chunk-ZAA7B5BN.js +22 -0
- package/bundle/chunk-ZAA7B5BN.js.map +7 -0
- package/bundle/{commands-WUGPBPHI.js → commands-IGRSOSK6.js} +15 -14
- package/bundle/commands-LAWVNQTO.js +34 -0
- package/bundle/commands-RBWY7YXB.js +34 -0
- package/bundle/commands-XFZNMZN6.js +34 -0
- package/bundle/{config-DQIGDX4W.js → config-NDEYF4AQ.js} +7 -7
- package/bundle/{daemon-NPKYZ3CJ.js → daemon-WOQXCKNL.js} +4 -4
- package/bundle/{delegation-tools-6FICZQ5G.js → delegation-tools-Z5OM3TXS.js} +5 -5
- package/bundle/{deploy-lib-import-SBKXDD3F.js → deploy-lib-import-6VJTYXEG.js} +2 -2
- package/bundle/{deps-HN6CEXA4.js → deps-65V7XXG4.js} +4 -4
- package/bundle/{direct-api-transport-TRV45NO6.js → direct-api-transport-OZICXTWQ.js} +43 -15
- package/bundle/direct-api-transport-OZICXTWQ.js.map +7 -0
- package/bundle/direct-api-transport-QIWA5ES2.js +889 -0
- package/bundle/direct-api-transport-QIWA5ES2.js.map +7 -0
- package/bundle/{discord-adapter-WA2MFRK3.js → discord-adapter-JFIIVG34.js} +27 -24
- package/bundle/discord-adapter-JFIIVG34.js.map +7 -0
- package/bundle/discord-adapter-U3FA5OTY.js +589 -0
- package/bundle/discord-adapter-U3FA5OTY.js.map +7 -0
- package/bundle/discord-adapter-W6L5KJ6T.js +589 -0
- package/bundle/discord-adapter-W6L5KJ6T.js.map +7 -0
- package/bundle/discord-adapter-WWM6ROTW.js +589 -0
- package/bundle/discord-adapter-WWM6ROTW.js.map +7 -0
- package/bundle/{dns-wakeup-RYOCQ6GR.js → dns-wakeup-N46RPU5E.js} +3 -3
- package/bundle/{doctor-R54GZPKL.js → doctor-PIPSGI3H.js} +18 -7
- package/bundle/{doctor-R54GZPKL.js.map → doctor-PIPSGI3H.js.map} +2 -2
- package/bundle/{ensure-invariants-BJIEOSJ2.js → ensure-invariants-3NOBCYWS.js} +4 -4
- package/bundle/{env-schema-XCPAJ6IZ.js → env-schema-T43X43BU.js} +4 -4
- package/bundle/{hook-system-POI5VRIX.js → hook-system-ZCVOFFRD.js} +4 -4
- package/bundle/hotskills-DTROJY6G.js +17 -0
- package/bundle/{install-SH4UVUXQ.js → install-I3CXVW52.js} +3 -3
- package/bundle/{install-manifest-QRWID3KZ.js → install-manifest-KBYD7SAY.js} +3 -3
- package/bundle/{irc-adapter-AIEP6OX6.js → irc-adapter-HXO5D4SW.js} +3 -3
- package/bundle/{irc-config-6VY67UPQ.js → irc-config-XN5VW2V4.js} +5 -5
- package/bundle/kanban-board-6Q5E5GEB.js +31 -0
- package/bundle/kanban-board-I52RHNHQ.js +31 -0
- package/bundle/{lazy-require-UFYFFX2R.js → lazy-require-R3JYCV5M.js} +4 -4
- package/bundle/{media-utils-MOE36VWY.js → media-utils-W7XW3SVV.js} +4 -4
- package/bundle/{message-pipeline-2MBT44FO.js → message-pipeline-4CTBJ6K2.js} +17 -14
- package/bundle/message-pipeline-4KL7OWUH.js +38 -0
- package/bundle/message-pipeline-GFKSHRFU.js +38 -0
- package/bundle/message-pipeline-TGI2WJJM.js +38 -0
- package/bundle/meta.json +3181 -2356
- package/bundle/{notification-U6F5ZBSG.js → notification-ULESRDHB.js} +7 -6
- package/bundle/{openrouter-credits-7XXO6QGQ.js → openrouter-credits-PLIKRY5D.js} +4 -4
- package/bundle/{paths-ZJYIDND2.js → paths-QQM74XYT.js} +4 -2
- package/bundle/{peer-client-T44VI7NB.js → peer-client-D2F5QWRV.js} +8 -8
- package/bundle/{peer-config-D5A4454H.js → peer-config-5SUIBJLG.js} +5 -5
- package/bundle/{phase-transport-FEZ4SIJJ.js → phase-transport-INFD6ELA.js} +10 -10
- package/bundle/phase-transport-KXFZ5BVF.js +23 -0
- package/bundle/{restore-MFSW3EBL.js → restore-Z6MF54HS.js} +4 -4
- package/bundle/{restore-MFSW3EBL.js.map → restore-Z6MF54HS.js.map} +2 -2
- package/bundle/{update-check-O5MS6B3L.js → rollback-5RXXLUD6.js} +5 -7
- package/bundle/{self-healer-utils-7NFH22VJ.js → self-healer-utils-WPKOVXJD.js} +4 -4
- package/bundle/{skill-stats-IPVKMWN3.js → skill-stats-NHNH47QW.js} +5 -5
- package/bundle/{sleep-BPWX3FCN.js → sleep-ENFZFUJJ.js} +8 -8
- package/bundle/sleep-ENFZFUJJ.js.map +7 -0
- package/bundle/{soul-bundle-BRIUDEQ2.js → soul-bundle-QTPWDJB2.js} +7 -7
- package/bundle/soul-bundle-QTPWDJB2.js.map +7 -0
- package/bundle/{soul-loader-GBXJ7EBH.js → soul-loader-LCPTN4PK.js} +8 -8
- package/bundle/soul-loader-LCPTN4PK.js.map +7 -0
- package/bundle/{sse-parser-anthropic-H42TTLBD.js → sse-parser-anthropic-PYDJM3UC.js} +4 -4
- package/bundle/{sse-parser-responses-WG2LY2ML.js → sse-parser-responses-FYT7A5WT.js} +4 -4
- package/bundle/{ssrf-guard-E2KBBC5E.js → ssrf-guard-R4P5OCTO.js} +4 -4
- package/bundle/{start-CBVKNEAT.js → start-4DNURGIY.js} +1 -1
- package/bundle/{stt-CF3CPFDC.js → stt-YN77NND6.js} +5 -5
- package/bundle/stt-YN77NND6.js.map +7 -0
- package/bundle/{subagent-runtime-4MTYUBIZ.js → subagent-runtime-5AYOXOU2.js} +5 -5
- package/bundle/subagent-runtime-5AYOXOU2.js.map +7 -0
- package/bundle/subagent-runtime-VKTX6Q2M.js +13 -0
- package/bundle/subagent-runtime-VKTX6Q2M.js.map +7 -0
- package/bundle/system-event-buffer-OEPPNUGK.js +17 -0
- package/bundle/system-event-buffer-OEPPNUGK.js.map +7 -0
- package/bundle/{system-message-TALP6GP2.js → system-message-BRU267FW.js} +3 -3
- package/bundle/{system-status-GLYXXDE3.js → system-status-7K2QTH3J.js} +58 -51
- package/bundle/system-status-7K2QTH3J.js.map +7 -0
- package/bundle/{hotskills-6ECHLXTJ.js → task-failure-buffer-DPM5MWZ5.js} +8 -7
- package/bundle/task-failure-buffer-DPM5MWZ5.js.map +7 -0
- package/bundle/{task-store-LC7ZMS72.js → task-store-VCBHAB43.js} +5 -5
- package/bundle/task-store-VCBHAB43.js.map +7 -0
- package/bundle/{telegram-adapter-BJJYXN7J.js → telegram-adapter-4KI4CJPG.js} +51 -33
- package/bundle/telegram-adapter-4KI4CJPG.js.map +7 -0
- package/bundle/telegram-adapter-76B4JRJJ.js +1080 -0
- package/bundle/telegram-adapter-76B4JRJJ.js.map +7 -0
- package/bundle/telegram-adapter-VZA74EMT.js +1080 -0
- package/bundle/telegram-adapter-VZA74EMT.js.map +7 -0
- package/bundle/telegram-adapter-ZO2CLU22.js +1080 -0
- package/bundle/telegram-adapter-ZO2CLU22.js.map +7 -0
- package/bundle/{tool-registry-T7XLTI2Q.js → tool-registry-CG7GIS64.js} +13 -9
- package/bundle/tool-registry-CG7GIS64.js.map +7 -0
- package/bundle/tool-registry-TGNU5AMG.js +43 -0
- package/bundle/tool-registry-TGNU5AMG.js.map +7 -0
- package/bundle/{tool-sandbox-OZMXJZLQ.js → tool-sandbox-TLAL55QP.js} +5 -5
- package/bundle/tool-sandbox-TLAL55QP.js.map +7 -0
- package/bundle/{transport-config-G5NKQXPJ.js → transport-config-JIKHB7GT.js} +8 -8
- package/bundle/transport-config-JIKHB7GT.js.map +7 -0
- package/bundle/update-check-AJMIBQGQ.js +81 -0
- package/bundle/update-check-AJMIBQGQ.js.map +7 -0
- package/bundle/{user-registry-NUVNEHJU.js → user-registry-PEFDZ5AV.js} +5 -5
- package/bundle/user-registry-PEFDZ5AV.js.map +7 -0
- package/core/skills/tools/gmail/SKILL.md +5 -14
- package/core/skills/tools/rss/SKILL.md +51 -0
- package/install-manifest.json +8 -2
- package/package.json +4 -2
- package/scripts/abtars-daemon.service +3 -0
- package/scripts/abtars@.service +3 -0
- package/scripts/build-and-deploy.sh +68 -0
- package/scripts/doctor.sh +38 -0
- package/scripts/emergency-deploy.sh +95 -0
- package/scripts/watchdog.sh +51 -5
- package/bundle/chunk-4BUOO6WI.js.map +0 -7
- package/bundle/chunk-A5OJYQNU.js.map +0 -7
- package/bundle/chunk-JX3ZZU3O.js +0 -82
- package/bundle/chunk-JX3ZZU3O.js.map +0 -7
- package/bundle/chunk-KJOCXWJ5.js +0 -131
- package/bundle/chunk-KJOCXWJ5.js.map +0 -7
- package/bundle/chunk-KSEIWT4T.js.map +0 -7
- package/bundle/chunk-KWBGYWDO.js.map +0 -7
- package/bundle/chunk-MJ6PHMOK.js.map +0 -7
- package/bundle/chunk-P2BZSLJJ.js.map +0 -7
- package/bundle/chunk-R36WIOYX.js.map +0 -7
- package/bundle/chunk-RE3F3CFW.js +0 -300
- package/bundle/chunk-RE3F3CFW.js.map +0 -7
- package/bundle/chunk-RSWUPUNA.js.map +0 -7
- package/bundle/chunk-RV54J75Q.js.map +0 -7
- package/bundle/chunk-TYVI3ZWA.js.map +0 -7
- package/bundle/chunk-X5FBUA53.js.map +0 -7
- package/bundle/direct-api-transport-TRV45NO6.js.map +0 -7
- package/bundle/discord-adapter-WA2MFRK3.js.map +0 -7
- package/bundle/system-status-GLYXXDE3.js.map +0 -7
- package/bundle/telegram-adapter-BJJYXN7J.js.map +0 -7
- /package/bundle/{agent-api-rate-limit-C25WGSFF.js.map → agent-api-rate-limit-R2OFAQ3N.js.map} +0 -0
- /package/bundle/{agent-registry-SYUFNSVB.js.map → agent-registry-5VL5KI6U.js.map} +0 -0
- /package/bundle/{bridge-lock-transport-HO545SBK.js.map → agent-registry-PIS5XJHX.js.map} +0 -0
- /package/bundle/{browse-delivery-VTLEAVYA.js.map → bridge-lock-transport-N6OGDOSE.js.map} +0 -0
- /package/bundle/{browser-REIXOJ6S.js.map → browse-delivery-DXGMDMXA.js.map} +0 -0
- /package/bundle/{capability-ILW3D5HS.js.map → browser-QMYGSP5W.js.map} +0 -0
- /package/bundle/{commands-WUGPBPHI.js.map → capability-733TLH4W.js.map} +0 -0
- /package/bundle/{chunk-PZE3J7ER.js.map → chunk-3OXQWII3.js.map} +0 -0
- /package/bundle/{chunk-4KJ76TTE.js.map → chunk-4XW7YA3K.js.map} +0 -0
- /package/bundle/{chunk-ZVDVNSXK.js.map → chunk-7WFE2JI5.js.map} +0 -0
- /package/bundle/{chunk-Q62SXS73.js.map → chunk-BBDKU4EH.js.map} +0 -0
- /package/bundle/{chunk-EX2SRTUE.js.map → chunk-CYSGXNBY.js.map} +0 -0
- /package/bundle/{chunk-LYEAHE5V.js.map → chunk-DCY7DGMT.js.map} +0 -0
- /package/bundle/{chunk-G6IXMYIO.js.map → chunk-DO4INSXE.js.map} +0 -0
- /package/bundle/{chunk-VA5WKN3Z.js.map → chunk-EGA6JQVV.js.map} +0 -0
- /package/bundle/{chunk-URAQLQ2U.js.map → chunk-F3HMZFIL.js.map} +0 -0
- /package/bundle/{chunk-OOKLEC6V.js.map → chunk-FY3QUO2L.js.map} +0 -0
- /package/bundle/{chunk-2BY6I4P5.js.map → chunk-GUTRAMK3.js.map} +0 -0
- /package/bundle/{chunk-GPL57SRN.js.map → chunk-H7RX7UCR.js.map} +0 -0
- /package/bundle/{chunk-BYDUMHXT.js.map → chunk-HAF2AFBW.js.map} +0 -0
- /package/bundle/{chunk-KFENC7BM.js.map → chunk-L33WNMCP.js.map} +0 -0
- /package/bundle/{chunk-JRG4EFMP.js.map → chunk-LBMETTUP.js.map} +0 -0
- /package/bundle/{chunk-TOUZC6NR.js.map → chunk-OKMN6J4Z.js.map} +0 -0
- /package/bundle/{chunk-XZSYMCLF.js.map → chunk-PUDGA4RR.js.map} +0 -0
- /package/bundle/{chunk-CELR236Q.js.map → chunk-Q7CH5DA3.js.map} +0 -0
- /package/bundle/{chunk-UDZIZB5F.js.map → chunk-RTL7HO3N.js.map} +0 -0
- /package/bundle/{chunk-ITG6XGBS.js.map → chunk-SA44ITVX.js.map} +0 -0
- /package/bundle/{chunk-3MO2MDXJ.js.map → chunk-SA6YEFNG.js.map} +0 -0
- /package/bundle/{chunk-GBBTK6H2.js.map → chunk-SRFEIZQT.js.map} +0 -0
- /package/bundle/{chunk-ELRAH7VL.js.map → chunk-VXUVKC66.js.map} +0 -0
- /package/bundle/{config-DQIGDX4W.js.map → commands-IGRSOSK6.js.map} +0 -0
- /package/bundle/{delegation-tools-6FICZQ5G.js.map → commands-LAWVNQTO.js.map} +0 -0
- /package/bundle/{deploy-lib-import-SBKXDD3F.js.map → commands-RBWY7YXB.js.map} +0 -0
- /package/bundle/{env-schema-XCPAJ6IZ.js.map → commands-XFZNMZN6.js.map} +0 -0
- /package/bundle/{hook-system-POI5VRIX.js.map → config-NDEYF4AQ.js.map} +0 -0
- /package/bundle/{daemon-NPKYZ3CJ.js.map → daemon-WOQXCKNL.js.map} +0 -0
- /package/bundle/{hotskills-6ECHLXTJ.js.map → delegation-tools-Z5OM3TXS.js.map} +0 -0
- /package/bundle/{install-SH4UVUXQ.js.map → deploy-lib-import-6VJTYXEG.js.map} +0 -0
- /package/bundle/{deps-HN6CEXA4.js.map → deps-65V7XXG4.js.map} +0 -0
- /package/bundle/{dns-wakeup-RYOCQ6GR.js.map → dns-wakeup-N46RPU5E.js.map} +0 -0
- /package/bundle/{ensure-invariants-BJIEOSJ2.js.map → ensure-invariants-3NOBCYWS.js.map} +0 -0
- /package/bundle/{lazy-require-UFYFFX2R.js.map → env-schema-T43X43BU.js.map} +0 -0
- /package/bundle/{message-pipeline-2MBT44FO.js.map → hook-system-ZCVOFFRD.js.map} +0 -0
- /package/bundle/{notification-U6F5ZBSG.js.map → hotskills-DTROJY6G.js.map} +0 -0
- /package/bundle/{paths-ZJYIDND2.js.map → install-I3CXVW52.js.map} +0 -0
- /package/bundle/{install-manifest-QRWID3KZ.js.map → install-manifest-KBYD7SAY.js.map} +0 -0
- /package/bundle/{irc-adapter-AIEP6OX6.js.map → irc-adapter-HXO5D4SW.js.map} +0 -0
- /package/bundle/{irc-config-6VY67UPQ.js.map → irc-config-XN5VW2V4.js.map} +0 -0
- /package/bundle/{peer-config-D5A4454H.js.map → kanban-board-6Q5E5GEB.js.map} +0 -0
- /package/bundle/{phase-transport-FEZ4SIJJ.js.map → kanban-board-I52RHNHQ.js.map} +0 -0
- /package/bundle/{skill-stats-IPVKMWN3.js.map → lazy-require-R3JYCV5M.js.map} +0 -0
- /package/bundle/{media-utils-MOE36VWY.js.map → media-utils-W7XW3SVV.js.map} +0 -0
- /package/bundle/{sleep-BPWX3FCN.js.map → message-pipeline-4CTBJ6K2.js.map} +0 -0
- /package/bundle/{soul-bundle-BRIUDEQ2.js.map → message-pipeline-4KL7OWUH.js.map} +0 -0
- /package/bundle/{soul-loader-GBXJ7EBH.js.map → message-pipeline-GFKSHRFU.js.map} +0 -0
- /package/bundle/{stt-CF3CPFDC.js.map → message-pipeline-TGI2WJJM.js.map} +0 -0
- /package/bundle/{subagent-runtime-4MTYUBIZ.js.map → notification-ULESRDHB.js.map} +0 -0
- /package/bundle/{openrouter-credits-7XXO6QGQ.js.map → openrouter-credits-PLIKRY5D.js.map} +0 -0
- /package/bundle/{task-store-LC7ZMS72.js.map → paths-QQM74XYT.js.map} +0 -0
- /package/bundle/{peer-client-T44VI7NB.js.map → peer-client-D2F5QWRV.js.map} +0 -0
- /package/bundle/{tool-registry-T7XLTI2Q.js.map → peer-config-5SUIBJLG.js.map} +0 -0
- /package/bundle/{tool-sandbox-OZMXJZLQ.js.map → phase-transport-INFD6ELA.js.map} +0 -0
- /package/bundle/{transport-config-G5NKQXPJ.js.map → phase-transport-KXFZ5BVF.js.map} +0 -0
- /package/bundle/{update-check-O5MS6B3L.js.map → rollback-5RXXLUD6.js.map} +0 -0
- /package/bundle/{self-healer-utils-7NFH22VJ.js.map → self-healer-utils-WPKOVXJD.js.map} +0 -0
- /package/bundle/{user-registry-NUVNEHJU.js.map → skill-stats-NHNH47QW.js.map} +0 -0
- /package/bundle/{sse-parser-anthropic-H42TTLBD.js.map → sse-parser-anthropic-PYDJM3UC.js.map} +0 -0
- /package/bundle/{sse-parser-responses-WG2LY2ML.js.map → sse-parser-responses-FYT7A5WT.js.map} +0 -0
- /package/bundle/{ssrf-guard-E2KBBC5E.js.map → ssrf-guard-R4P5OCTO.js.map} +0 -0
- /package/bundle/{start-CBVKNEAT.js.map → start-4DNURGIY.js.map} +0 -0
- /package/bundle/{system-message-TALP6GP2.js.map → system-message-BRU267FW.js.map} +0 -0
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/components/command-registry.ts", "../src/components/security-gate.ts", "../src/components/response-formatter.ts", "../src/utils/emoji-score.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * command-registry.ts \u2014 Shared bot command definitions for all platforms.\n * Both Telegram (setMyCommands) and Discord (application commands) import from here.\n */\n\nexport interface BotCommand {\n readonly name: string;\n readonly description: string;\n}\n\n/** All registered bot commands. Discord requires: name \u226432 chars lowercase, description \u2264100 chars. */\nexport const BOT_COMMANDS: readonly BotCommand[] = [\n { name: \"reset\", description: \"Fresh session + exit coding\" },\n { name: \"session\", description: \"Session management\" },\n { name: \"compact\", description: \"Compact context window\" },\n { name: \"status\", description: \"Bridge status\" },\n { name: \"doctor\", description: \"Deep healthcheck (probes all subsystems)\" },\n { name: \"mcp\", description: \"MCP server status\" },\n { name: \"hooks\", description: \"List configured hooks\" },\n { name: \"stop\", description: \"Stop current response\" },\n { name: \"wait\", description: \"Inject message mid-run (non-interrupting)\" },\n { name: \"models\", description: \"Model, transport & agents\" },\n { name: \"change\", description: \"Switch model/provider\" },\n { name: \"emergency\", description: \"Activate paid hailMary model\" },\n { name: \"heartbeat\", description: \"Heartbeat diagnostics\" },\n { name: \"memory\", description: \"Memory stats\" },\n { name: \"skills\", description: \"List skills\" },\n { name: \"skill\", description: \"Reload skills catalog\" },\n { name: \"tasks\", description: \"Scheduled tasks\" },\n { name: \"facts\", description: \"Core knowledge\" },\n { name: \"nlm\", description: \"Knowledge base\" },\n { name: \"restart\", description: \"Restart bridge\" },\n { name: \"wakeup\", description: \"Wake Mac from sleep\" },\n { name: \"sleep\", description: \"Sleep status / resume / now\" },\n { name: \"help\", description: \"Show all commands\" },\n];\n", "/**\n * Fail-closed security gate that authorizes messages against the user registry.\n * Unauthorized messages are silently dropped \u2014 no response, no side effects.\n * Per-user channel gating via UserEntry.allowedChats.\n */\nimport type { UserEntry, UserRegistry } from \"./user-registry.js\";\n\nexport interface AuthResult {\n authorized: boolean;\n user?: UserEntry;\n}\n\nexport class SecurityGate {\n private readonly registry: UserRegistry;\n\n constructor(registry: UserRegistry) {\n if (registry.users.length === 0) {\n throw new Error(\"SecurityGate requires at least one user in registry\");\n }\n this.registry = registry;\n }\n\n /** Authorize a platform user. Checks allowedChats if set. */\n authorize(platformUserId: string, platform: string, channelId?: string): AuthResult {\n const key = `${platform}:${platformUserId}`;\n const user = this.registry.byPlatformId.get(key);\n if (!user) return { authorized: false };\n if (!this.chatAllowed(user, channelId)) return { authorized: false };\n return { authorized: true, user };\n }\n\n /** Authorize by platform user ID string (tries both platforms). */\n authorizeById(userId: string, channelId?: string): boolean {\n const tg = this.registry.byPlatformId.get(`telegram:${userId}`);\n const dc = this.registry.byPlatformId.get(`discord:${userId}`);\n const user = tg ?? dc;\n if (!user) return false;\n return this.chatAllowed(user, channelId);\n }\n\n private chatAllowed(user: UserEntry, channelId?: string): boolean {\n if (!user.allowedChats || user.allowedChats.length === 0) return true;\n if (!channelId) return true;\n return user.allowedChats.includes(channelId);\n }\n}\n", "import type { Platform } from \"../types/index.js\";\n\nconst TELEGRAM_MAX_LENGTH = 4096;\nconst DISCORD_MAX_LENGTH = 2000;\n\n/** Characters that must be escaped in Telegram MarkdownV2. */\nconst MARKDOWN_V2_ESCAPE = /([_*\\[\\]()~`>#+\\-=|{}.!\\\\])/g;\n\n/**\n * Collects streaming ACP response chunks and formats them\n * for Telegram delivery (chunking, Markdown conversion).\n */\nexport class ResponseFormatter {\n private buffers = new Map<string, string[]>();\n\n /** Accumulate a chunk for a session. */\n collectChunk(sessionId: string, chunk: string): void {\n const existing = this.buffers.get(sessionId);\n if (existing) {\n existing.push(chunk);\n } else {\n this.buffers.set(sessionId, [chunk]);\n }\n }\n\n /** Flush accumulated chunks for a session, returning Telegram-ready messages. */\n flush(sessionId: string): string[] {\n const chunks = this.buffers.get(sessionId);\n this.buffers.delete(sessionId);\n if (!chunks || chunks.length === 0) return [];\n const full = chunks.join(\"\");\n return this.chunkText(full);\n }\n\n /** Split text into chunks that fit Telegram's 4096-char limit. */\n chunkText(text: string): string[] {\n if (text.length <= TELEGRAM_MAX_LENGTH) {\n return [text];\n }\n\n const result: string[] = [];\n let remaining = text;\n\n while (remaining.length > 0) {\n if (remaining.length <= TELEGRAM_MAX_LENGTH) {\n result.push(remaining);\n break;\n }\n\n // Try to split at paragraph boundary\n let splitAt = remaining.lastIndexOf(\"\\n\\n\", TELEGRAM_MAX_LENGTH);\n if (splitAt <= 0) {\n // Try single newline\n splitAt = remaining.lastIndexOf(\"\\n\", TELEGRAM_MAX_LENGTH);\n }\n if (splitAt <= 0) {\n // Try space\n splitAt = remaining.lastIndexOf(\" \", TELEGRAM_MAX_LENGTH);\n }\n if (splitAt <= 0) {\n // Hard split\n splitAt = TELEGRAM_MAX_LENGTH;\n }\n\n result.push(remaining.slice(0, splitAt));\n remaining = remaining.slice(splitAt).trimStart();\n }\n\n return result;\n }\n\n /** Escape text for Telegram MarkdownV2 parse mode. */\n toTelegramMarkdown(markdown: string): string {\n // Preserve code blocks \u2014 don't escape inside them\n const parts = markdown.split(/(```[\\s\\S]*?```|`[^`]+`)/);\n return parts\n .map((part, i) => {\n // Odd indices are code blocks/inline code \u2014 leave as-is\n if (i % 2 === 1) return part;\n return part.replace(MARKDOWN_V2_ESCAPE, \"\\\\$1\");\n })\n .join(\"\");\n }\n\n /** Split text into chunks for Discord's 2000-char limit.\n * Respects paragraph and code block boundaries \u2014 never splits inside a fenced code block. */\n chunkTextForDiscord(text: string): string[] {\n if (text.length <= DISCORD_MAX_LENGTH) {\n return [text];\n }\n\n const result: string[] = [];\n let remaining = text;\n\n while (remaining.length > 0) {\n if (remaining.length <= DISCORD_MAX_LENGTH) {\n result.push(remaining);\n break;\n }\n\n // Check if there's an open code block in the window we're about to cut\n const window = remaining.slice(0, DISCORD_MAX_LENGTH);\n const fenceMatches = window.match(/```/g);\n const hasOpenCodeBlock = fenceMatches != null && fenceMatches.length % 2 !== 0;\n\n if (hasOpenCodeBlock) {\n // Find the start of the open code block (last unmatched ```)\n const lastFenceIdx = window.lastIndexOf(\"```\");\n // Try to split before the code block at a paragraph boundary\n let splitAt = remaining.lastIndexOf(\"\\n\\n\", lastFenceIdx);\n if (splitAt <= 0) {\n splitAt = remaining.lastIndexOf(\"\\n\", lastFenceIdx);\n }\n if (splitAt <= 0) {\n // Can't avoid splitting inside the code block \u2014 close and reopen\n splitAt = remaining.lastIndexOf(\"\\n\", DISCORD_MAX_LENGTH - 4); // leave room for closing ```\n if (splitAt <= 0) {\n splitAt = DISCORD_MAX_LENGTH - 4;\n }\n // Find the code fence language specifier for reopening\n const fenceStart = remaining.lastIndexOf(\"```\", splitAt);\n const fenceLine = remaining.slice(fenceStart, remaining.indexOf(\"\\n\", fenceStart));\n result.push(remaining.slice(0, splitAt) + \"\\n```\");\n remaining = fenceLine + \"\\n\" + remaining.slice(splitAt).trimStart();\n continue;\n }\n result.push(remaining.slice(0, splitAt));\n remaining = remaining.slice(splitAt).trimStart();\n continue;\n }\n\n // No open code block \u2014 split normally at paragraph/line boundaries\n let splitAt = remaining.lastIndexOf(\"\\n\\n\", DISCORD_MAX_LENGTH);\n if (splitAt <= 0) {\n splitAt = remaining.lastIndexOf(\"\\n\", DISCORD_MAX_LENGTH);\n }\n if (splitAt <= 0) {\n splitAt = remaining.lastIndexOf(\" \", DISCORD_MAX_LENGTH);\n }\n if (splitAt <= 0) {\n splitAt = DISCORD_MAX_LENGTH;\n }\n\n result.push(remaining.slice(0, splitAt));\n remaining = remaining.slice(splitAt).trimStart();\n }\n\n return result;\n }\n\n /** Split text for the appropriate platform. */\n chunkForPlatform(text: string, platform: Platform): string[] {\n if (platform === \"discord\") {\n return this.chunkTextForDiscord(text);\n }\n return this.chunkText(text);\n }\n\n /** Convert standard Markdown to Discord-compatible Markdown (mostly passthrough). */\n toDiscordMarkdown(text: string): string {\n return text;\n }\n\n /** Format a tool status update for the user. */\n formatToolStatus(toolName: string, status: \"start\" | \"done\" | \"error\"): string {\n switch (status) {\n case \"start\":\n return `\uD83D\uDD27 ${toolName}...`;\n case \"done\":\n return `\u2705 ${toolName}`;\n case \"error\":\n return `\u274C ${toolName} failed`;\n }\n }\n}\n", "/** Inline emoji-to-score map (avoids hard dep on abmind for adapters). */\nconst EMOJI_SCORES: Record<string, number> = {\n \"\u2764\uFE0F\": 4, \"\uD83D\uDD25\": 4, \"\uD83C\uDF89\": 3, \"\uD83D\uDC4F\": 4, \"\u2764\": 4,\n \"\uD83D\uDC4D\": 3, \"\uD83D\uDE02\": 3, \"\uD83E\uDD29\": 4, \"\uD83D\uDCAF\": 3, \"\u26A1\": 3,\n \"\uD83D\uDE0A\": 2, \"\uD83D\uDE4F\": 2, \"\uD83E\uDD14\": 1, \"\uD83D\uDE2E\": 1,\n \"\uD83D\uDC4E\": -3, \"\uD83D\uDE22\": -3, \"\uD83D\uDE21\": -4, \"\uD83E\uDD2E\": -4, \"\uD83D\uDCA9\": -5,\n};\n\nexport function emojiToScore(emoji: string): number {\n return EMOJI_SCORES[emoji] ?? 1;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["splitAt"]
|
|
7
|
-
}
|
package/bundle/chunk-RE3F3CFW.js
DELETED
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
|
|
3
|
-
import {
|
|
4
|
-
init_log_and_swallow,
|
|
5
|
-
logAndSwallow
|
|
6
|
-
} from "./chunk-EX2SRTUE.js";
|
|
7
|
-
import {
|
|
8
|
-
init_logger,
|
|
9
|
-
logInfo,
|
|
10
|
-
logWarn
|
|
11
|
-
} from "./chunk-2BY6I4P5.js";
|
|
12
|
-
import {
|
|
13
|
-
abtarsHome,
|
|
14
|
-
init_paths
|
|
15
|
-
} from "./chunk-MJ6PHMOK.js";
|
|
16
|
-
import {
|
|
17
|
-
__export,
|
|
18
|
-
__require
|
|
19
|
-
} from "./chunk-7K2YZTLD.js";
|
|
20
|
-
|
|
21
|
-
// src/capabilities/hotskills/index.ts
|
|
22
|
-
var hotskills_exports = {};
|
|
23
|
-
__export(hotskills_exports, {
|
|
24
|
-
register: () => register
|
|
25
|
-
});
|
|
26
|
-
import { join as join2 } from "node:path";
|
|
27
|
-
|
|
28
|
-
// src/components/skill-watcher.ts
|
|
29
|
-
init_log_and_swallow();
|
|
30
|
-
init_logger();
|
|
31
|
-
import { readdirSync, readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
32
|
-
import { join, basename, dirname, resolve } from "node:path";
|
|
33
|
-
import { execFileSync } from "node:child_process";
|
|
34
|
-
import { homedir } from "node:os";
|
|
35
|
-
var TAG = "skill-reloader";
|
|
36
|
-
var SkillWatcher = class {
|
|
37
|
-
constructor(skillsDir, catalogPath) {
|
|
38
|
-
this.skillsDir = skillsDir;
|
|
39
|
-
this.catalogPath = catalogPath;
|
|
40
|
-
}
|
|
41
|
-
/** Per-instance cache of `which <bin>` results. Avoids repeated execFileSync on heartbeat ticks (#369). */
|
|
42
|
-
binaryCache = /* @__PURE__ */ new Map();
|
|
43
|
-
/** Generate skills_catalog.md from all skill files. Called on startup + when skills change. */
|
|
44
|
-
generateCatalog() {
|
|
45
|
-
const files = this.scanMdFiles(this.skillsDir);
|
|
46
|
-
const entries = [];
|
|
47
|
-
const skipped = [];
|
|
48
|
-
const skillsCfg = this.loadSkillsConfig();
|
|
49
|
-
for (const filepath of files) {
|
|
50
|
-
const header = this.parseSkillHeader(filepath);
|
|
51
|
-
if (!header.name) continue;
|
|
52
|
-
if (header.primaryEnv && !process.env[header.primaryEnv]) {
|
|
53
|
-
const entry2 = skillsCfg.entries?.[header.name];
|
|
54
|
-
if (entry2?.apiKey) process.env[header.primaryEnv] = entry2.apiKey;
|
|
55
|
-
}
|
|
56
|
-
const entry = skillsCfg.entries?.[header.name];
|
|
57
|
-
if (entry?.env) {
|
|
58
|
-
for (const [k, v] of Object.entries(entry.env)) {
|
|
59
|
-
if (!process.env[k]) process.env[k] = v;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
if (header.requires) {
|
|
63
|
-
const { eligible, missing } = this.checkEligibility(header.requires);
|
|
64
|
-
if (!eligible) {
|
|
65
|
-
skipped.push(`${header.name} (missing: ${missing.join(", ")})`);
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
entries.push(`- [${this.getSourceDir(filepath)}] ${header.name}: ${header.description}`);
|
|
70
|
-
}
|
|
71
|
-
const guidance = [
|
|
72
|
-
"",
|
|
73
|
-
"## Skill maintenance",
|
|
74
|
-
"- If you solved something non-trivial (multi-step, error-prone, or likely to recur), save it as a skill with skill_create.",
|
|
75
|
-
"- If a skill you just used was wrong or incomplete, fix it with skill_patch before moving on.",
|
|
76
|
-
""
|
|
77
|
-
].join("\n");
|
|
78
|
-
const content = `# Skills Catalog
|
|
79
|
-
|
|
80
|
-
When a user request matches a skill below, read its SKILL.md at ~/.abtars/skills/<dir>/SKILL.md for detailed instructions before acting.
|
|
81
|
-
|
|
82
|
-
${entries.join("\n")}
|
|
83
|
-
${guidance}`;
|
|
84
|
-
try {
|
|
85
|
-
writeFileSync(this.catalogPath, content, "utf-8");
|
|
86
|
-
const skippedStr = skipped.length > 0 ? `, ${skipped.length} skipped \u2014 ${skipped.join(", ")}` : "";
|
|
87
|
-
logInfo(TAG, `Generated skills_catalog.md (${entries.length} skills${skippedStr})`);
|
|
88
|
-
} catch (err) {
|
|
89
|
-
logWarn(TAG, `Failed to write skills_catalog.md: ${err instanceof Error ? err.message : String(err)}`);
|
|
90
|
-
}
|
|
91
|
-
return entries.length;
|
|
92
|
-
}
|
|
93
|
-
/** Check all requirements. Returns eligible=true only if ALL pass. */
|
|
94
|
-
checkEligibility(requires) {
|
|
95
|
-
const missing = [];
|
|
96
|
-
for (const bin of requires.bins ?? []) {
|
|
97
|
-
if (!this.binaryAvailable(bin)) missing.push(`bin:${bin}`);
|
|
98
|
-
}
|
|
99
|
-
for (const pkg of requires.npm ?? []) {
|
|
100
|
-
if (!this.npmAvailable(pkg)) missing.push(`npm:${pkg}`);
|
|
101
|
-
}
|
|
102
|
-
for (const key of requires.env ?? []) {
|
|
103
|
-
if (!process.env[key]) missing.push(`env:${key}`);
|
|
104
|
-
}
|
|
105
|
-
for (const file of requires.files ?? []) {
|
|
106
|
-
const resolved = resolve(file.replace(/^~/, homedir()));
|
|
107
|
-
if (!existsSync(resolved)) missing.push(`file:${file}`);
|
|
108
|
-
}
|
|
109
|
-
return { eligible: missing.length === 0, missing };
|
|
110
|
-
}
|
|
111
|
-
/** Check if an npm package is resolvable from the abtars node_modules. */
|
|
112
|
-
npmAvailable(pkg) {
|
|
113
|
-
try {
|
|
114
|
-
__require.resolve(pkg);
|
|
115
|
-
return true;
|
|
116
|
-
} catch (err) {
|
|
117
|
-
logAndSwallow(TAG, `require.resolve ${pkg}`, err);
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
/** Check if a binary is on PATH. Cached per-instance so hot-reload ticks don't respawn `which`. */
|
|
122
|
-
binaryAvailable(bin) {
|
|
123
|
-
if (!this.binaryCache.has(bin)) {
|
|
124
|
-
try {
|
|
125
|
-
execFileSync("which", [bin], { timeout: 1e3, stdio: "pipe" });
|
|
126
|
-
this.binaryCache.set(bin, true);
|
|
127
|
-
} catch (err) {
|
|
128
|
-
logAndSwallow(TAG, `which ${bin}`, err);
|
|
129
|
-
this.binaryCache.set(bin, false);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return this.binaryCache.get(bin);
|
|
133
|
-
}
|
|
134
|
-
getSourceDir(filepath) {
|
|
135
|
-
const rel = filepath.slice(this.skillsDir.length + 1);
|
|
136
|
-
const first = rel.split("/")[0] ?? "core";
|
|
137
|
-
if (["core", "custom", "downloaded", "self"].includes(first)) return first;
|
|
138
|
-
return "core";
|
|
139
|
-
}
|
|
140
|
-
scanMdFiles(dir) {
|
|
141
|
-
const results = [];
|
|
142
|
-
try {
|
|
143
|
-
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
144
|
-
const full = join(dir, entry.name);
|
|
145
|
-
if (entry.isDirectory()) results.push(...this.scanMdFiles(full));
|
|
146
|
-
else if (entry.name === "SKILL.md") results.push(full);
|
|
147
|
-
}
|
|
148
|
-
} catch (err) {
|
|
149
|
-
logAndSwallow("skill_watcher", "op", err);
|
|
150
|
-
}
|
|
151
|
-
return results;
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Parse a skill file's header.
|
|
155
|
-
*
|
|
156
|
-
* Preferred: YAML-style frontmatter block at the top of the file:
|
|
157
|
-
* ---
|
|
158
|
-
* name: mcporter
|
|
159
|
-
* description: Call external MCP servers via the mcporter CLI.
|
|
160
|
-
* requires: mcporter
|
|
161
|
-
* ---
|
|
162
|
-
*
|
|
163
|
-
* Supports only single-line `key: value` pairs. No arrays, no nested
|
|
164
|
-
* objects, no multi-line strings, no comments. Values are trimmed.
|
|
165
|
-
*
|
|
166
|
-
* Fallback (no frontmatter): first `#` heading → name, first non-heading
|
|
167
|
-
* line > 10 chars → description. Preserves pre-#369 behavior for any
|
|
168
|
-
* skills that don't yet have frontmatter.
|
|
169
|
-
*/
|
|
170
|
-
parseSkillHeader(filepath) {
|
|
171
|
-
try {
|
|
172
|
-
const content = readFileSync(filepath, "utf-8");
|
|
173
|
-
const fm = this.parseFrontmatter(content);
|
|
174
|
-
if (fm) {
|
|
175
|
-
return {
|
|
176
|
-
name: String(fm["name"] ?? "") || basename(dirname(filepath)),
|
|
177
|
-
description: String(fm["description"] ?? "").slice(0, 120),
|
|
178
|
-
...fm["requires"] ? { requires: this.parseRequires(fm["requires"]) } : {},
|
|
179
|
-
...fm["primaryEnv"] ? { primaryEnv: String(fm["primaryEnv"]) } : {}
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
const lines = content.split("\n").filter((l) => l.trim());
|
|
183
|
-
const heading = lines.find((l) => l.startsWith("#"));
|
|
184
|
-
const name = heading?.replace(/^#+\s*/, "").trim() ?? basename(dirname(filepath));
|
|
185
|
-
const desc = lines.find((l) => !l.startsWith("#") && l.trim().length > 10)?.trim() ?? "";
|
|
186
|
-
return { name, description: desc.slice(0, 120) };
|
|
187
|
-
} catch (err) {
|
|
188
|
-
logAndSwallow(TAG, "parseSkillMeta", err);
|
|
189
|
-
return { name: basename(dirname(filepath)), description: "" };
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
/** Load ~/.abtars/config/skills.json (per-skill secrets). */
|
|
193
|
-
loadSkillsConfig() {
|
|
194
|
-
try {
|
|
195
|
-
const p = join(homedir(), ".abtars", "config", "skills.json");
|
|
196
|
-
if (!existsSync(p)) return {};
|
|
197
|
-
return JSON.parse(readFileSync(p, "utf-8"));
|
|
198
|
-
} catch (err) {
|
|
199
|
-
logAndSwallow("skill_watcher", "op", err);
|
|
200
|
-
return {};
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
/** Parse requires field: string → { bins: [str] }, object → SkillRequires. */
|
|
204
|
-
parseRequires(raw) {
|
|
205
|
-
if (typeof raw === "string") return { bins: [raw] };
|
|
206
|
-
if (typeof raw === "object" && raw !== null) {
|
|
207
|
-
const obj = raw;
|
|
208
|
-
return {
|
|
209
|
-
...obj["bins"] ? { bins: toStringArray(obj["bins"]) } : {},
|
|
210
|
-
...obj["npm"] ? { npm: toStringArray(obj["npm"]) } : {},
|
|
211
|
-
...obj["env"] ? { env: toStringArray(obj["env"]) } : {},
|
|
212
|
-
...obj["files"] ? { files: toStringArray(obj["files"]) } : {}
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
return {};
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Extract frontmatter key/value pairs. Returns null if the file doesn't
|
|
219
|
-
* start with a `---` fence.
|
|
220
|
-
*
|
|
221
|
-
* Supports: flat `key: value`, inline arrays `key: [a, b]`, and one level
|
|
222
|
-
* of nesting via indented keys under a parent.
|
|
223
|
-
*/
|
|
224
|
-
parseFrontmatter(content) {
|
|
225
|
-
const lines = content.split("\n");
|
|
226
|
-
let i = 0;
|
|
227
|
-
while (i < lines.length && lines[i].trim() === "") i++;
|
|
228
|
-
if (i >= lines.length || lines[i].trim() !== "---") return null;
|
|
229
|
-
const start = i + 1;
|
|
230
|
-
let end = -1;
|
|
231
|
-
for (let j = start; j < lines.length; j++) {
|
|
232
|
-
if (lines[j].trim() === "---") {
|
|
233
|
-
end = j;
|
|
234
|
-
break;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
if (end === -1) return null;
|
|
238
|
-
const result = {};
|
|
239
|
-
let currentParent = null;
|
|
240
|
-
let currentObj = {};
|
|
241
|
-
for (let j = start; j < end; j++) {
|
|
242
|
-
const line = lines[j];
|
|
243
|
-
if (line.trim() === "") continue;
|
|
244
|
-
const indent = line.length - line.trimStart().length;
|
|
245
|
-
const colonIdx = line.indexOf(":");
|
|
246
|
-
if (colonIdx < 1) continue;
|
|
247
|
-
const key = line.slice(0, colonIdx).trim().toLowerCase();
|
|
248
|
-
const rawValue = line.slice(colonIdx + 1).trim();
|
|
249
|
-
if (indent > 0 && currentParent) {
|
|
250
|
-
currentObj[key] = parseYamlValue(rawValue);
|
|
251
|
-
} else {
|
|
252
|
-
if (currentParent) {
|
|
253
|
-
result[currentParent] = currentObj;
|
|
254
|
-
currentParent = null;
|
|
255
|
-
currentObj = {};
|
|
256
|
-
}
|
|
257
|
-
if (rawValue === "" || rawValue === "|" || rawValue === ">") {
|
|
258
|
-
currentParent = key;
|
|
259
|
-
currentObj = {};
|
|
260
|
-
} else {
|
|
261
|
-
result[key] = parseYamlValue(rawValue);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
if (currentParent) result[currentParent] = currentObj;
|
|
266
|
-
return result;
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
function parseYamlValue(raw) {
|
|
270
|
-
if (raw.startsWith("[") && raw.endsWith("]")) {
|
|
271
|
-
return raw.slice(1, -1).split(",").map((s) => s.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
|
|
272
|
-
}
|
|
273
|
-
return raw;
|
|
274
|
-
}
|
|
275
|
-
function toStringArray(val) {
|
|
276
|
-
if (Array.isArray(val)) return val.map(String);
|
|
277
|
-
if (typeof val === "string") return [val];
|
|
278
|
-
return [];
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// src/capabilities/hotskills/index.ts
|
|
282
|
-
init_paths();
|
|
283
|
-
function register(api) {
|
|
284
|
-
const skillWatcher = new SkillWatcher(
|
|
285
|
-
join2(abtarsHome(), "skills"),
|
|
286
|
-
join2(abtarsHome(), "core", "skills_catalog.md")
|
|
287
|
-
);
|
|
288
|
-
skillWatcher.generateCatalog();
|
|
289
|
-
api.registerCommand("skill", async (_text, ctx) => {
|
|
290
|
-
const count = skillWatcher.generateCatalog();
|
|
291
|
-
await ctx.reply(`Reloaded \u2014 ${count} skills available.`);
|
|
292
|
-
return true;
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
export {
|
|
297
|
-
register,
|
|
298
|
-
hotskills_exports
|
|
299
|
-
};
|
|
300
|
-
//# sourceMappingURL=chunk-RE3F3CFW.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/capabilities/hotskills/index.ts", "../src/components/skill-watcher.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Skills capability \u2014 on-demand skill catalog reload via /skill command.\n */\n\nimport { join } from \"node:path\";\nimport { SkillWatcher } from \"../../components/skill-watcher.js\";\nimport { abtarsHome } from \"../../paths.js\";\nimport type { CapabilityApi } from \"../capability.js\";\n\nexport function register(api: CapabilityApi): void {\n const skillWatcher = new SkillWatcher(\n join(abtarsHome(), \"skills\"),\n join(abtarsHome(), \"core\", \"skills_catalog.md\"),\n );\n\n // Generate catalog on startup\n skillWatcher.generateCatalog();\n\n api.registerCommand(\"skill\", async (_text, ctx) => {\n const count = skillWatcher.generateCatalog();\n await ctx.reply(`Reloaded \u2014 ${count} skills available.`);\n return true;\n });\n}\n", "/**\n * SkillWatcher \u2014 generates skills_catalog.md on startup and on-demand via /skill reload.\n *\n * #369 \u2014 Parses YAML-style frontmatter to extract name/description/requires.\n * #412 \u2014 Structured requires: bins/npm/env/files.\n * Skills declare their own deps; loader checks eligibility at boot.\n */\n\nimport { logAndSwallow } from \"./log-and-swallow.js\";\nimport { readdirSync, readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { join, basename, dirname, resolve } from \"node:path\";\nimport { execFileSync } from \"node:child_process\";\nimport { homedir } from \"node:os\";\nimport { logInfo, logWarn } from \"./logger.js\";\n\nimport type { ISkillSlot } from \"./skeleton.js\";\n\nconst TAG = \"skill-reloader\";\n\n/** Structured skill requirements (#412). */\ninterface SkillRequires {\n bins?: string[];\n npm?: string[];\n env?: string[];\n files?: string[];\n}\n\ninterface SkillHeader {\n name: string;\n description: string;\n requires?: SkillRequires;\n primaryEnv?: string;\n}\n\n/** Per-skill config from ~/.abtars/config/skills.json */\ninterface SkillsConfig {\n entries?: Record<string, { apiKey?: string; env?: Record<string, string> }>;\n}\n\nexport class SkillWatcher implements ISkillSlot {\n /** Per-instance cache of `which <bin>` results. Avoids repeated execFileSync on heartbeat ticks (#369). */\n private binaryCache = new Map<string, boolean>();\n\n constructor(private skillsDir: string, private catalogPath: string) {}\n\n /** Generate skills_catalog.md from all skill files. Called on startup + when skills change. */\n generateCatalog(): number {\n const files = this.scanMdFiles(this.skillsDir);\n const entries: string[] = [];\n const skipped: string[] = [];\n const skillsCfg = this.loadSkillsConfig();\n for (const filepath of files) {\n const header = this.parseSkillHeader(filepath);\n if (!header.name) continue;\n // Inject per-skill env from skills.json before eligibility check\n if (header.primaryEnv && !process.env[header.primaryEnv]) {\n const entry = skillsCfg.entries?.[header.name];\n if (entry?.apiKey) process.env[header.primaryEnv] = entry.apiKey;\n }\n const entry = skillsCfg.entries?.[header.name];\n if (entry?.env) {\n for (const [k, v] of Object.entries(entry.env)) {\n if (!process.env[k]) process.env[k] = v;\n }\n }\n if (header.requires) {\n const { eligible, missing } = this.checkEligibility(header.requires);\n if (!eligible) {\n skipped.push(`${header.name} (missing: ${missing.join(\", \")})`);\n continue;\n }\n }\n entries.push(`- [${this.getSourceDir(filepath)}] ${header.name}: ${header.description}`);\n }\n const guidance = [\n \"\",\n \"## Skill maintenance\",\n \"- If you solved something non-trivial (multi-step, error-prone, or likely to recur), save it as a skill with skill_create.\",\n \"- If a skill you just used was wrong or incomplete, fix it with skill_patch before moving on.\",\n \"\",\n ].join(\"\\n\");\n const content = `# Skills Catalog\\n\\nWhen a user request matches a skill below, read its SKILL.md at ~/.abtars/skills/<dir>/SKILL.md for detailed instructions before acting.\\n\\n${entries.join(\"\\n\")}\\n${guidance}`;\n try {\n writeFileSync(this.catalogPath, content, \"utf-8\");\n const skippedStr = skipped.length > 0 ? `, ${skipped.length} skipped \u2014 ${skipped.join(\", \")}` : \"\";\n logInfo(TAG, `Generated skills_catalog.md (${entries.length} skills${skippedStr})`);\n } catch (err) {\n logWarn(TAG, `Failed to write skills_catalog.md: ${err instanceof Error ? err.message : String(err)}`);\n }\n return entries.length;\n }\n\n /** Check all requirements. Returns eligible=true only if ALL pass. */\n private checkEligibility(requires: SkillRequires): { eligible: boolean; missing: string[] } {\n const missing: string[] = [];\n for (const bin of requires.bins ?? []) {\n if (!this.binaryAvailable(bin)) missing.push(`bin:${bin}`);\n }\n for (const pkg of requires.npm ?? []) {\n if (!this.npmAvailable(pkg)) missing.push(`npm:${pkg}`);\n }\n for (const key of requires.env ?? []) {\n if (!process.env[key]) missing.push(`env:${key}`);\n }\n for (const file of requires.files ?? []) {\n const resolved = resolve(file.replace(/^~/, homedir()));\n if (!existsSync(resolved)) missing.push(`file:${file}`);\n }\n return { eligible: missing.length === 0, missing };\n }\n\n /** Check if an npm package is resolvable from the abtars node_modules. */\n private npmAvailable(pkg: string): boolean {\n try {\n require.resolve(pkg);\n return true;\n } catch (err) {\n logAndSwallow(TAG, `require.resolve ${pkg}`, err);\n return false;\n }\n }\n\n /** Check if a binary is on PATH. Cached per-instance so hot-reload ticks don't respawn `which`. */\n private binaryAvailable(bin: string): boolean {\n if (!this.binaryCache.has(bin)) {\n try {\n // execFileSync (not execSync) \u2014 no shell interpolation on untrusted `requires:` values.\n execFileSync(\"which\", [bin], { timeout: 1000, stdio: \"pipe\" });\n this.binaryCache.set(bin, true);\n } catch (err) {\n logAndSwallow(TAG, `which ${bin}`, err);\n this.binaryCache.set(bin, false);\n }\n }\n return this.binaryCache.get(bin)!;\n }\n\n private getSourceDir(filepath: string): string {\n const rel = filepath.slice(this.skillsDir.length + 1);\n const first = rel.split(\"/\")[0] ?? \"core\";\n if ([\"core\", \"custom\", \"downloaded\", \"self\"].includes(first)) return first;\n return \"core\";\n }\n\n private scanMdFiles(dir: string): string[] {\n const results: string[] = [];\n try {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name);\n if (entry.isDirectory()) results.push(...this.scanMdFiles(full));\n else if (entry.name === \"SKILL.md\") results.push(full);\n }\n } catch (err) { logAndSwallow(\"skill_watcher\", \"op\", err); }\n return results;\n }\n\n /**\n * Parse a skill file's header.\n *\n * Preferred: YAML-style frontmatter block at the top of the file:\n * ---\n * name: mcporter\n * description: Call external MCP servers via the mcporter CLI.\n * requires: mcporter\n * ---\n *\n * Supports only single-line `key: value` pairs. No arrays, no nested\n * objects, no multi-line strings, no comments. Values are trimmed.\n *\n * Fallback (no frontmatter): first `#` heading \u2192 name, first non-heading\n * line > 10 chars \u2192 description. Preserves pre-#369 behavior for any\n * skills that don't yet have frontmatter.\n */\n private parseSkillHeader(filepath: string): SkillHeader {\n try {\n const content = readFileSync(filepath, \"utf-8\");\n const fm = this.parseFrontmatter(content);\n if (fm) {\n return {\n name: String(fm[\"name\"] ?? \"\") || basename(dirname(filepath)),\n description: String(fm[\"description\"] ?? \"\").slice(0, 120),\n ...(fm[\"requires\"] ? { requires: this.parseRequires(fm[\"requires\"]) } : {}),\n ...(fm[\"primaryEnv\"] ? { primaryEnv: String(fm[\"primaryEnv\"]) } : {}),\n };\n }\n\n // Fallback for skill files without frontmatter\n const lines = content.split(\"\\n\").filter(l => l.trim());\n const heading = lines.find(l => l.startsWith(\"#\"));\n const name = heading?.replace(/^#+\\s*/, \"\").trim() ?? basename(dirname(filepath));\n const desc = lines.find(l => !l.startsWith(\"#\") && l.trim().length > 10)?.trim() ?? \"\";\n return { name, description: desc.slice(0, 120) };\n } catch (err) {\n logAndSwallow(TAG, \"parseSkillMeta\", err);\n return { name: basename(dirname(filepath)), description: \"\" };\n }\n }\n\n /** Load ~/.abtars/config/skills.json (per-skill secrets). */\n private loadSkillsConfig(): SkillsConfig {\n try {\n const p = join(homedir(), \".abtars\", \"config\", \"skills.json\");\n if (!existsSync(p)) return {};\n return JSON.parse(readFileSync(p, \"utf-8\")) as SkillsConfig;\n } catch (err) {\n logAndSwallow(\"skill_watcher\", \"op\", err);\n return {};\n }\n }\n\n /** Parse requires field: string \u2192 { bins: [str] }, object \u2192 SkillRequires. */\n private parseRequires(raw: unknown): SkillRequires {\n if (typeof raw === \"string\") return { bins: [raw] };\n if (typeof raw === \"object\" && raw !== null) {\n const obj = raw as Record<string, unknown>;\n return {\n ...(obj[\"bins\"] ? { bins: toStringArray(obj[\"bins\"]) } : {}),\n ...(obj[\"npm\"] ? { npm: toStringArray(obj[\"npm\"]) } : {}),\n ...(obj[\"env\"] ? { env: toStringArray(obj[\"env\"]) } : {}),\n ...(obj[\"files\"] ? { files: toStringArray(obj[\"files\"]) } : {}),\n };\n }\n return {};\n }\n\n /**\n * Extract frontmatter key/value pairs. Returns null if the file doesn't\n * start with a `---` fence.\n *\n * Supports: flat `key: value`, inline arrays `key: [a, b]`, and one level\n * of nesting via indented keys under a parent.\n */\n private parseFrontmatter(content: string): Record<string, unknown> | null {\n const lines = content.split(\"\\n\");\n let i = 0;\n while (i < lines.length && lines[i]!.trim() === \"\") i++;\n if (i >= lines.length || lines[i]!.trim() !== \"---\") return null;\n\n const start = i + 1;\n let end = -1;\n for (let j = start; j < lines.length; j++) {\n if (lines[j]!.trim() === \"---\") { end = j; break; }\n }\n if (end === -1) return null;\n\n const result: Record<string, unknown> = {};\n let currentParent: string | null = null;\n let currentObj: Record<string, unknown> = {};\n\n for (let j = start; j < end; j++) {\n const line = lines[j]!;\n if (line.trim() === \"\") continue;\n\n const indent = line.length - line.trimStart().length;\n const colonIdx = line.indexOf(\":\");\n if (colonIdx < 1) continue;\n\n const key = line.slice(0, colonIdx).trim().toLowerCase();\n const rawValue = line.slice(colonIdx + 1).trim();\n\n if (indent > 0 && currentParent) {\n // Nested key under parent\n currentObj[key] = parseYamlValue(rawValue);\n } else {\n // Top-level key\n if (currentParent) {\n result[currentParent] = currentObj;\n currentParent = null;\n currentObj = {};\n }\n if (rawValue === \"\" || rawValue === \"|\" || rawValue === \">\") {\n // Start of nested object\n currentParent = key;\n currentObj = {};\n } else {\n result[key] = parseYamlValue(rawValue);\n }\n }\n }\n if (currentParent) result[currentParent] = currentObj;\n\n return result;\n }\n}\n\n/** Parse a YAML value: inline array [a, b] \u2192 string[], otherwise string. */\nfunction parseYamlValue(raw: string): unknown {\n if (raw.startsWith(\"[\") && raw.endsWith(\"]\")) {\n return raw.slice(1, -1).split(\",\").map(s => s.trim().replace(/^[\"']|[\"']$/g, \"\")).filter(Boolean);\n }\n return raw;\n}\n\n/** Coerce unknown to string[]. */\nfunction toStringArray(val: unknown): string[] {\n if (Array.isArray(val)) return val.map(String);\n if (typeof val === \"string\") return [val];\n return [];\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["join", "entry", "join"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/cli/deploy-lib/paths.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 * Runtime directory resolution for deploy-lib consumers.\n *\n * Rules:\n * - abtars runtime root: $ABTARS_HOME ?? ~/.abtars\n * - abmind runtime root: $ABMIND_HOME ?? ~/.abmind\n * - user bin dir: ~/.local/bin (always, XDG convention)\n *\n * All callers use these resolvers \u2014 never hardcode paths. Required by\n * plan #158 v7 (Ag2 round-2 nit): cross-repo manifest reads must respect\n * env-var overrides, not assume default locations.\n */\n\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport type PackageName = 'abtars' | 'abmind';\n\nexport function resolveAbtarsHome(): string {\n return process.env['ABTARS_HOME'] ?? join(homedir(), '.abtars');\n}\n\nexport function resolveAbmindHome(): string {\n return process.env['ABMIND_HOME'] ?? join(homedir(), '.abmind');\n}\n\nexport function resolvePackageHome(pkg: PackageName): string {\n return pkg === 'abtars' ? resolveAbtarsHome() : resolveAbmindHome();\n}\n\nexport function resolveUserBinDir(): string {\n return join(homedir(), '.local', 'bin');\n}\n\nexport interface PackagePaths {\n readonly home: string;\n readonly config: string;\n readonly app: string;\n readonly appPrev: string;\n readonly appStaging: string;\n readonly bin: string;\n readonly manifest: string;\n readonly lock: string;\n // Legacy \u2014 kept for migration detection only. Remove after all hosts migrated.\n readonly releases: string;\n readonly current: string;\n}\n\nexport function packagePaths(pkg: PackageName): PackagePaths {\n const home = resolvePackageHome(pkg);\n return {\n home,\n config: join(home, 'config'),\n app: join(home, 'app'),\n appPrev: join(home, 'app.prev'),\n appStaging: join(home, 'app.staging'),\n bin: join(home, 'bin'),\n manifest: join(home, 'manifest.json'),\n lock: join(home, '.update.lock'),\n // Legacy\n releases: join(home, 'releases'),\n current: join(home, 'current'),\n };\n}\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 (local | npm | github). */\n readonly source: '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), supervised (launchd/systemd user-scope), or supervised-daemon (system-scope). */\n readonly installMode?: 'simple' | 'supervised' | 'supervised-daemon';\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: 'local',\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 = 60 * 60 * 1000; // 1 hour\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: app.staging/ \u2192 app/, old app/ \u2192 app.prev/.\n * Two renames (~instant). Caller must ensure app.staging/ is fully built.\n */\nexport function atomicSwap(appDir: string, appPrevDir: string, appStagingDir: string): void {\n // Remove old prev\n if (existsSync(appPrevDir)) {\n rmSync(appPrevDir, { recursive: true, force: true });\n }\n // app/ \u2192 app.prev/\n if (existsSync(appDir)) {\n renameSync(appDir, appPrevDir);\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): Promise<{ healthy: boolean; pid?: number; heartbeat?: number }> {\n const lockPath = join(home, 'bridge.lock');\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n try {\n const content = JSON.parse(await readFile(lockPath, 'utf-8'));\n if (content.lastHeartbeat && content.lastHeartbeat > afterTimestamp) {\n return { healthy: true, pid: content.pid, heartbeat: content.lastHeartbeat };\n }\n } catch {\n // File doesn't exist yet or invalid JSON \u2014 keep polling\n }\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", "join", "homedir"]
|
|
7
|
-
}
|