abtars 0.2.1-alpha.8 → 0.2.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/README.md +98 -42
- package/bundle/{_registry.generated-ADOYFJJ4.js → _registry.generated-FNJOX7VV.js} +19 -16
- package/bundle/{_registry.generated-ADOYFJJ4.js.map → _registry.generated-FNJOX7VV.js.map} +1 -1
- package/bundle/abtars-browser.js +5 -6
- package/bundle/abtars-browser.js.map +2 -2
- package/bundle/abtars-cli.js +339 -271
- 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 +239 -155
- 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-S2MNHQYQ.js} +8 -8
- 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-ZVDVNSXK.js → chunk-2SWKJX64.js} +7 -7
- package/bundle/{chunk-PZE3J7ER.js → chunk-3OXQWII3.js} +2 -2
- package/bundle/{chunk-R36WIOYX.js → chunk-3X6VGRL6.js} +33 -6
- package/bundle/chunk-3X6VGRL6.js.map +7 -0
- package/bundle/{chunk-4KJ76TTE.js → chunk-4XW7YA3K.js} +3 -3
- package/bundle/{chunk-Q62SXS73.js → chunk-BBDKU4EH.js} +9 -9
- 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-GPL57SRN.js → chunk-H7RX7UCR.js} +3 -3
- package/bundle/{chunk-BYDUMHXT.js → chunk-HAF2AFBW.js} +2 -2
- package/bundle/{chunk-A5OJYQNU.js → chunk-HCYENZAB.js} +49 -22
- package/bundle/chunk-HCYENZAB.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-4BUOO6WI.js → chunk-KL5QRHHK.js} +31 -11
- package/bundle/chunk-KL5QRHHK.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-RV54J75Q.js → chunk-MHK4UPM6.js} +13 -12
- package/bundle/chunk-MHK4UPM6.js.map +7 -0
- package/bundle/chunk-NIYVCGBC.js +330 -0
- package/bundle/chunk-NIYVCGBC.js.map +7 -0
- package/bundle/{chunk-P2BZSLJJ.js → chunk-OGZXYN6E.js} +392 -125
- package/bundle/chunk-OGZXYN6E.js.map +7 -0
- package/bundle/{chunk-TOUZC6NR.js → chunk-OKMN6J4Z.js} +3 -3
- package/bundle/{chunk-CELR236Q.js → chunk-Q7CH5DA3.js} +2 -2
- package/bundle/{chunk-XZSYMCLF.js → chunk-QIAFGDRL.js} +7 -7
- 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-GBBTK6H2.js → chunk-SRFEIZQT.js} +4 -4
- package/bundle/{chunk-ELRAH7VL.js → chunk-VXUVKC66.js} +3 -3
- package/bundle/{chunk-X5FBUA53.js → chunk-WLAVZSVZ.js} +69 -30
- package/bundle/chunk-WLAVZSVZ.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-YWZPKBO6.js +22 -0
- package/bundle/chunk-YWZPKBO6.js.map +7 -0
- package/bundle/{chunk-KWBGYWDO.js → chunk-Z4SWEFIY.js} +12 -14
- package/bundle/chunk-Z4SWEFIY.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-AXW7L2MZ.js} +15 -14
- 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-LSAUIP5S.js} +27 -15
- package/bundle/direct-api-transport-LSAUIP5S.js.map +7 -0
- package/bundle/{discord-adapter-WA2MFRK3.js → discord-adapter-LNWTIOUK.js} +27 -24
- package/bundle/discord-adapter-LNWTIOUK.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-GEXWJYJC.js → install-FZT43PTH.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/{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-QX272U5X.js} +17 -14
- package/bundle/meta.json +2965 -2294
- 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-BSGROTHY.js} +10 -10
- package/bundle/restore-Z6MF54HS.js +151 -0
- package/bundle/restore-Z6MF54HS.js.map +7 -0
- package/bundle/{install-SH4UVUXQ.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-K7EXAFGW.js} +8 -8
- package/bundle/{soul-bundle-BRIUDEQ2.js → soul-bundle-QTPWDJB2.js} +7 -7
- package/bundle/{soul-loader-GBXJ7EBH.js → soul-loader-LCPTN4PK.js} +8 -8
- 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/{subagent-runtime-4MTYUBIZ.js → subagent-runtime-FQAT3564.js} +5 -5
- 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-store-LC7ZMS72.js → task-store-VCBHAB43.js} +5 -5
- package/bundle/{telegram-adapter-BJJYXN7J.js → telegram-adapter-LXLSG4SK.js} +51 -33
- package/bundle/telegram-adapter-LXLSG4SK.js.map +7 -0
- package/bundle/{tool-registry-T7XLTI2Q.js → tool-registry-5PXNSYOI.js} +12 -9
- package/bundle/{tool-sandbox-OZMXJZLQ.js → tool-sandbox-TLAL55QP.js} +5 -5
- package/bundle/{transport-config-G5NKQXPJ.js → transport-config-JIKHB7GT.js} +8 -8
- 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/core/skills/tools/rss/SKILL.md +51 -0
- package/install-manifest.json +4 -2
- package/package.json +4 -4
- package/scripts/build-and-deploy.sh +28 -0
- package/scripts/daily-backup.sh +1 -79
- 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-RJJWPMUZ.js +0 -411
- package/bundle/chunk-RJJWPMUZ.js.map +0 -7
- package/bundle/chunk-RSWUPUNA.js.map +0 -7
- package/bundle/chunk-RV54J75Q.js.map +0 -7
- package/bundle/chunk-RVERPUHT.js +0 -289
- package/bundle/chunk-RVERPUHT.js.map +0 -7
- package/bundle/chunk-TYVI3ZWA.js.map +0 -7
- package/bundle/chunk-X5FBUA53.js.map +0 -7
- package/bundle/deploy-lib-import-HCMZCKZD.js +0 -50
- package/bundle/direct-api-transport-TRV45NO6.js.map +0 -7
- package/bundle/discord-adapter-WA2MFRK3.js.map +0 -7
- package/bundle/restore-ROJF22R2.js +0 -47
- package/bundle/restore-ROJF22R2.js.map +0 -7
- package/bundle/system-status-GLYXXDE3.js.map +0 -7
- package/bundle/telegram-adapter-BJJYXN7J.js.map +0 -7
- package/bundle/update-check-O5MS6B3L.js +0 -13
- package/bundle/user-registry-NUVNEHJU.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-S2MNHQYQ.js.map} +0 -0
- /package/bundle/{bridge-lock-transport-HO545SBK.js.map → bridge-lock-transport-N6OGDOSE.js.map} +0 -0
- /package/bundle/{browse-delivery-VTLEAVYA.js.map → browse-delivery-DXGMDMXA.js.map} +0 -0
- /package/bundle/{browser-REIXOJ6S.js.map → browser-QMYGSP5W.js.map} +0 -0
- /package/bundle/{capability-ILW3D5HS.js.map → capability-733TLH4W.js.map} +0 -0
- /package/bundle/{chunk-ZVDVNSXK.js.map → chunk-2SWKJX64.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-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-CELR236Q.js.map → chunk-Q7CH5DA3.js.map} +0 -0
- /package/bundle/{chunk-XZSYMCLF.js.map → chunk-QIAFGDRL.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/{commands-WUGPBPHI.js.map → commands-AXW7L2MZ.js.map} +0 -0
- /package/bundle/{config-DQIGDX4W.js.map → config-NDEYF4AQ.js.map} +0 -0
- /package/bundle/{daemon-NPKYZ3CJ.js.map → daemon-WOQXCKNL.js.map} +0 -0
- /package/bundle/{delegation-tools-6FICZQ5G.js.map → delegation-tools-Z5OM3TXS.js.map} +0 -0
- /package/bundle/{deploy-lib-import-HCMZCKZD.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/{deploy-lib-import-SBKXDD3F.js.map → env-schema-T43X43BU.js.map} +0 -0
- /package/bundle/{env-schema-XCPAJ6IZ.js.map → hook-system-ZCVOFFRD.js.map} +0 -0
- /package/bundle/{hook-system-POI5VRIX.js.map → hotskills-DTROJY6G.js.map} +0 -0
- /package/bundle/{hotskills-6ECHLXTJ.js.map → install-FZT43PTH.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/{install-GEXWJYJC.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/{install-SH4UVUXQ.js.map → message-pipeline-QX272U5X.js.map} +0 -0
- /package/bundle/{lazy-require-UFYFFX2R.js.map → notification-ULESRDHB.js.map} +0 -0
- /package/bundle/{openrouter-credits-7XXO6QGQ.js.map → openrouter-credits-PLIKRY5D.js.map} +0 -0
- /package/bundle/{message-pipeline-2MBT44FO.js.map → paths-QQM74XYT.js.map} +0 -0
- /package/bundle/{peer-client-T44VI7NB.js.map → peer-client-D2F5QWRV.js.map} +0 -0
- /package/bundle/{notification-U6F5ZBSG.js.map → peer-config-5SUIBJLG.js.map} +0 -0
- /package/bundle/{paths-ZJYIDND2.js.map → phase-transport-BSGROTHY.js.map} +0 -0
- /package/bundle/{peer-config-D5A4454H.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/{phase-transport-FEZ4SIJJ.js.map → skill-stats-NHNH47QW.js.map} +0 -0
- /package/bundle/{skill-stats-IPVKMWN3.js.map → sleep-K7EXAFGW.js.map} +0 -0
- /package/bundle/{sleep-BPWX3FCN.js.map → soul-bundle-QTPWDJB2.js.map} +0 -0
- /package/bundle/{soul-bundle-BRIUDEQ2.js.map → soul-loader-LCPTN4PK.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/{soul-loader-GBXJ7EBH.js.map → stt-YN77NND6.js.map} +0 -0
- /package/bundle/{stt-CF3CPFDC.js.map → subagent-runtime-FQAT3564.js.map} +0 -0
- /package/bundle/{system-message-TALP6GP2.js.map → system-message-BRU267FW.js.map} +0 -0
- /package/bundle/{subagent-runtime-4MTYUBIZ.js.map → task-failure-buffer-DPM5MWZ5.js.map} +0 -0
- /package/bundle/{task-store-LC7ZMS72.js.map → task-store-VCBHAB43.js.map} +0 -0
- /package/bundle/{tool-registry-T7XLTI2Q.js.map → tool-registry-5PXNSYOI.js.map} +0 -0
- /package/bundle/{tool-sandbox-OZMXJZLQ.js.map → tool-sandbox-TLAL55QP.js.map} +0 -0
- /package/bundle/{transport-config-G5NKQXPJ.js.map → transport-config-JIKHB7GT.js.map} +0 -0
- /package/bundle/{update-check-O5MS6B3L.js.map → user-registry-PEFDZ5AV.js.map} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/components/guardrails.ts", "../src/components/transport/tool-registry.ts", "../src/components/transport/skill-authoring.ts", "../src/components/transport/mcp-tool.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * guardrails.ts \u2014 path + command restrictions for SECURITY_MODE=guardrails.\n * Defense-in-depth: catches accidental/confused model behavior, NOT adversarial bypass.\n */\n\nimport { resolve, sep } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { getEnv } from \"./env-schema.js\";\nimport { logWarn } from \"./logger.js\";\n\nconst TAG = \"guardrails\";\nconst HOME = homedir();\n\nconst BLOCKED_PATHS = [\n `${HOME}/.ssh${sep}`,\n `${HOME}/.abtars/secret${sep}`,\n `/etc${sep}`,\n `/proc${sep}`,\n `/sys${sep}`,\n `/dev${sep}`,\n `/root${sep}`,\n `/run${sep}`,\n];\n\nconst WRITE_BLOCKED = [\n `${HOME}/.abtars/config/peers.json`,\n `${HOME}/.kiro${sep}`,\n];\n\nconst BLOCKED_COMMAND_PREFIXES = [\n \"rm -rf /\",\n];\n\nconst AUTH_REQUIRED_PATTERNS = [\n /\\brm\\s+(-[a-z]*f[a-z]*r|-[a-z]*r[a-z]*f)\\b/i,\n /\\bgit\\s+(reset\\s+--hard|push\\s+--force|clean\\s+-f|branch\\s+-D)/i,\n /\\bDROP\\s+(TABLE|DATABASE)\\b/i,\n /\\bTRUNCATE\\s/i,\n /\\bkill\\s+(-9|--signal\\s+(KILL|9))/i,\n /\\bsudo\\b/,\n /\\bchmod\\s+777\\b/,\n /\\bDELETE\\s+FROM\\s+\\w+\\s*;/i,\n];\n\nexport type CommandTier = \"block\" | \"auth-required\" | \"allow\";\n\n/** Classify a command into block / auth-required / allow. */\nexport function classifyCommand(cmd: string): CommandTier {\n const trimmed = cmd.trim();\n for (const prefix of BLOCKED_COMMAND_PREFIXES) {\n if (trimmed.toLowerCase().startsWith(prefix.toLowerCase())) return \"block\";\n }\n for (const re of AUTH_REQUIRED_PATTERNS) {\n if (re.test(trimmed)) return \"auth-required\";\n }\n return \"allow\";\n}\n\nexport type SecurityMode = \"off\" | \"guardrails\" | \"sandbox\";\n\nexport function getSecurityMode(): SecurityMode {\n const mode = getEnv().securityMode as SecurityMode;\n return mode || \"off\";\n}\n\nexport function isGuardrailsActive(): boolean {\n return getSecurityMode() !== \"off\";\n}\n\n/** Check if a file path is allowed. Returns error message or null if OK. */\nexport function checkPath(path: string, mode: \"read\" | \"write\"): string | null {\n if (!isGuardrailsActive()) return null;\n\n const resolved = resolve(path) + (path.endsWith(\"/\") ? sep : \"\");\n\n for (const blocked of BLOCKED_PATHS) {\n if (resolved.startsWith(blocked) || resolved === blocked.slice(0, -1)) {\n return `Path blocked by guardrails: ${path}`;\n }\n }\n\n if (mode === \"write\") {\n for (const wb of WRITE_BLOCKED) {\n if (resolved.startsWith(wb) || resolved === wb) {\n return `Write blocked by guardrails: ${path}`;\n }\n }\n }\n\n return null;\n}\n\n/** Check if a bash command is allowed. Returns error message or null if OK. */\nexport function checkCommand(cmd: string): string | null {\n if (!isGuardrailsActive()) return null;\n\n const tier = classifyCommand(cmd);\n if (tier === \"block\") {\n logWarn(TAG, `Blocked command: ${cmd.slice(0, 100)}`);\n return `Command blocked by guardrails: ${cmd.slice(0, 60)}`;\n }\n // \"auth-required\" is handled by action-gate at a higher level \u2014 not blocked here\n return null;\n}\n", "/**\n * Tool registry for DirectApiTransport.\n * Phase 2: native tool schemas. Phase 3: in-process memory when available.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { appendFileSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { MemoryBackend } from \"abmind\";\nimport type { InstantStoreParams } from \"../../types/index.js\";\nimport { logWarn, redactSecrets } from \"../logger.js\";\nimport { logAndSwallow } from \"../log-and-swallow.js\";\nimport { checkTool, checkPath, auditDeny, type SandboxPolicy } from \"../tool-sandbox.js\";\nimport { loadUsers } from \"../user-registry.js\";\n\nfunction getMasterUserId(): string {\n return loadUsers().users.find(u => u.role === \"master\")?.userId ?? \"aksika\";\n}\n\nconst TAG = \"tool_registry\";\n\n// #449: append-only audit log\nconst AUDIT_DIR = join(process.env[\"ABTARS_HOME\"] ?? join(homedir(), \".abtars\"), \"logs\");\nconst AUDIT_PATH = join(AUDIT_DIR, \"audit.jsonl\");\ntry { mkdirSync(AUDIT_DIR, { recursive: true }); } catch (err) { logAndSwallow(TAG, \"mkdirSync audit dir\", err); }\nfunction audit(entry: Record<string, unknown>): void {\n try { appendFileSync(AUDIT_PATH, JSON.stringify(entry) + \"\\n\"); } catch (err) { logAndSwallow(TAG, \"audit write\", err); }\n}\n\nexport type ToolDefinition = {\n readonly name: string;\n readonly description: string;\n readonly parameters: Record<string, unknown>;\n execute(args: Record<string, string>, context?: { userId: string; signal?: AbortSignal }): Promise<string>;\n};\n\nconst BASH_TIMEOUT_MS = 300_000;\nconst CLI_TIMEOUT_MS = 60_000;\n\n/**\n * Patterns that would spawn or restart a bridge/watchdog process.\n * Blocked to prevent the LLM (especially fallback models) from accidentally\n * starting a second bridge instance, which would cause port conflicts,\n * Telegram 409 errors, and bridge.lock PID confusion.\n *\n * See post-mortem of 2026-04-22 outage: cron agent ran execute_bash that\n * spawned a rogue bridge alongside the watchdog-supervised one.\n */\nconst BLOCKED_PATTERNS: readonly RegExp[] = [\n /\\bmain\\.js\\b/, // node .../current/dist/main.js ...\n /\\babtars\\.sh\\b/, // the launcher\n /\\bwatchdog\\.sh\\b/, // the watchdog\n /\\blaunchctl\\s+(load|bootstrap|kickstart|start)\\b/, // launchd bridge start\n];\n\nexport function isBridgeSpawnCommand(cmd: string): boolean {\n return BLOCKED_PATTERNS.some(p => p.test(cmd));\n}\n\n/** Block kill/pkill/killall targeting the bridge's own PID or process patterns (#414). */\nfunction isBridgeKillCommand(cmd: string): boolean {\n const pid = process.pid;\n const ppid = process.ppid;\n // Direct kill of own PID or parent\n if (new RegExp(`\\\\bkill\\\\s+(-\\\\d+\\\\s+)?${pid}\\\\b`).test(cmd)) return true;\n if (new RegExp(`\\\\bkill\\\\s+(-\\\\d+\\\\s+)?${ppid}\\\\b`).test(cmd)) return true;\n // pkill/killall targeting bridge patterns\n if (/\\b(pkill|killall)\\b.*\\b(abtars|main\\.js|watchdog)\\b/.test(cmd)) return true;\n if (/\\bkill\\b.*\\$\\(.*pgrep.*abtars/.test(cmd)) return true;\n return false;\n}\n\nfunction runBash(cmd: string, timeout = BASH_TIMEOUT_MS, signal?: AbortSignal): Promise<string> {\n // Guardrails: command check\n const { checkCommand, classifyCommand } = require(\"../guardrails.js\") as typeof import(\"../guardrails.js\");\n const cmdBlock = checkCommand(cmd);\n if (cmdBlock) {\n logWarn(\"tool-registry\", `Guardrails blocked: ${cmd.slice(0, 200)}`);\n return Promise.resolve(JSON.stringify({ stderr: cmdBlock, exit_code: 126 }));\n }\n\n // Action gate: auth-required commands\n const tier = classifyCommand(cmd);\n if (tier === \"auth-required\" && _actionGate) {\n return _actionGate.requestAuth(\"bash-auth\", cmd).then((granted) => {\n if (!granted) {\n logWarn(\"tool-registry\", `Auth denied for: ${cmd.slice(0, 200)}`);\n return JSON.stringify({ stderr: \"Command requires authorization. Master denied or timed out.\", exit_code: 126 });\n }\n return executeBash(cmd, timeout, signal);\n });\n }\n\n if (isBridgeSpawnCommand(cmd)) {\n logWarn(\"tool-registry\", `Blocked bridge-spawn command: ${cmd.slice(0, 200)}`);\n return Promise.resolve(JSON.stringify({\n stderr: \"Command blocked: this would spawn/restart a bridge or watchdog process. The bridge is already running under launchd+watchdog supervision; use launchctl inspection commands (launchctl list, launchctl print) or signal the existing process instead.\",\n exit_code: 126,\n }));\n }\n if (isBridgeKillCommand(cmd)) {\n logWarn(\"tool-registry\", `Blocked bridge-kill command: ${cmd.slice(0, 200)}`);\n return Promise.resolve(JSON.stringify({\n stderr: \"Command blocked: this would kill the bridge process (yourself). Ask the user to send /restart for a session reset or restart the bridge manually.\",\n exit_code: 126,\n }));\n }\n return executeBash(cmd, timeout, signal);\n}\n\nfunction executeBash(cmd: string, timeout: number, signal?: AbortSignal): Promise<string> {\n return new Promise((resolve) => {\n const child = execFile(\"bash\", [\"-c\", cmd], { timeout, maxBuffer: 1024 * 1024 }, (err, stdout, stderr) => {\n const result: Record<string, unknown> = {};\n if (stdout) result[\"stdout\"] = stdout.slice(0, 50_000);\n if (stderr) result[\"stderr\"] = stderr.slice(0, 10_000);\n if (err) result[\"exit_code\"] = (err as NodeJS.ErrnoException & { code?: number }).code ?? 1;\n else result[\"exit_code\"] = 0;\n resolve(JSON.stringify(result));\n });\n if (signal) {\n if (signal.aborted) { child.kill(\"SIGTERM\"); return; }\n const onAbort = (): void => { child.kill(\"SIGTERM\"); };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n child.on(\"exit\", () => signal.removeEventListener(\"abort\", onAbort));\n }\n });\n}\n\nlet memoryBackend: MemoryBackend | null = null;\n\n/** Wire in-process memory backend. Call once after memory init. */\nexport function setMemoryBackend(backend: MemoryBackend | null): void {\n memoryBackend = backend;\n}\n\nlet _actionGate: import(\"../action-gate.js\").ActionGate | null = null;\n\n/** Wire action gate for auth-required commands. */\nexport function setActionGate(gate: import(\"../action-gate.js\").ActionGate | null): void {\n _actionGate = gate;\n}\n\nlet _peerActivityCb: ((msg: string) => void) | null = null;\n\n/** Wire peer activity notification callback. */\nexport function setPeerActivityCallback(cb: ((msg: string) => void) | null): void {\n _peerActivityCb = cb;\n}\n\n// --- Tool definitions ---\n\nconst bashTool: ToolDefinition = {\n name: \"execute_bash\",\n description: \"Execute a bash command. Use for file operations, git, running scripts, and any shell command. Commands that would spawn or restart a bridge/watchdog process (node main.js, abtars.sh, watchdog.sh, launchctl load/bootstrap/kickstart/start) are blocked \u2014 the bridge is already supervised.\",\n parameters: {\n type: \"object\",\n properties: { command: { type: \"string\", description: \"The bash command to execute\" } },\n required: [\"command\"],\n },\n execute: (args, context) => runBash(args[\"command\"] ?? \"\", BASH_TIMEOUT_MS, context?.signal),\n};\n\nlet _storeCount = 0;\nconst STORE_CAP = 20;\n\n/** Reset store counter (called on new subagent session). */\nexport function resetStoreCounter(): void { _storeCount = 0; }\n\nconst memoryStoreTool: ToolDefinition = {\n name: \"memory_store\",\n description: \"Store a memory. Use after learning something about the user, their preferences, decisions, or facts worth remembering.\",\n parameters: {\n type: \"object\",\n properties: {\n translated: { type: \"string\", description: \"Memory content in English\" },\n original: { type: \"string\", description: \"Memory content in original language (if not English)\" },\n type: { type: \"string\", enum: [\"fact\", \"preference\", \"decision\", \"experience\", \"skill\", \"relationship\", \"goal\"], description: \"Memory type\" },\n emotion: { type: \"integer\", description: \"Emotion score -5 to +5 (0=neutral)\" },\n confidence: { type: \"integer\", description: \"Confidence 1-5 (3=default)\" },\n classification: { type: \"integer\", description: \"0=public (general knowledge), 1=internal (default), 2=confidential (personal preferences, habits, opinions about specific users), 3=secret (credentials, API keys, tokens, passwords \u2014 store IMMEDIATELY with exact string, never paraphrase, never wait for Dreamy)\" },\n },\n required: [\"translated\", \"type\"],\n },\n async execute(args, context): Promise<string> {\n if (++_storeCount > STORE_CAP) {\n return JSON.stringify({ stored: false, error: \"Store limit reached for this session. Move to next task.\" });\n }\n if (memoryBackend) {\n try {\n const params: InstantStoreParams = {\n userId: context?.userId ?? getMasterUserId(),\n contentEn: args[\"translated\"] ?? \"\",\n contentOriginal: args[\"original\"] ?? args[\"translated\"] ?? \"\",\n memoryType: (args[\"type\"] ?? \"fact\") as InstantStoreParams[\"memoryType\"],\n emotionScore: parseInt(args[\"emotion\"] ?? \"0\", 10),\n confidence: parseInt(args[\"confidence\"] ?? \"3\", 10),\n classification: parseInt(args[\"classification\"] ?? \"1\", 10),\n };\n const result = await memoryBackend.instantStore({ ...params, createdBy: \"tool:memory_store\" });\n return JSON.stringify(result);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n // #706: FTS5 corruption self-heal \u2014 rebuild indexes and retry once\n if (msg.includes(\"fts5\") || msg.includes(\"corruption\")) {\n try {\n memoryBackend.rebuildFtsIndexes();\n logWarn(\"tool-registry\", \"FTS corruption detected \u2014 rebuilt indexes, retrying store\");\n const params: InstantStoreParams = {\n userId: context?.userId ?? getMasterUserId(),\n contentEn: args[\"translated\"] ?? \"\",\n contentOriginal: args[\"original\"] ?? args[\"translated\"] ?? \"\",\n memoryType: (args[\"type\"] ?? \"fact\") as InstantStoreParams[\"memoryType\"],\n emotionScore: parseInt(args[\"emotion\"] ?? \"0\", 10),\n confidence: parseInt(args[\"confidence\"] ?? \"3\", 10),\n classification: parseInt(args[\"classification\"] ?? \"1\", 10),\n };\n const result = await memoryBackend.instantStore({ ...params, createdBy: \"tool:memory_store\" });\n return JSON.stringify(result);\n } catch (retryErr) { /* fall through */ }\n }\n return JSON.stringify({ error: msg });\n }\n }\n let cmd = `abmind store --translated ${JSON.stringify(args[\"translated\"] ?? \"\")} --type ${args[\"type\"] ?? \"fact\"}`;\n if (args[\"original\"]) cmd += ` --original ${JSON.stringify(args[\"original\"])}`;\n if (args[\"emotion\"]) cmd += ` --emotion-score ${args[\"emotion\"]}`;\n if (args[\"confidence\"]) cmd += ` --confidence ${args[\"confidence\"]}`;\n if (args[\"classification\"]) cmd += ` --classification ${args[\"classification\"]}`;\n return runBash(cmd, CLI_TIMEOUT_MS);\n },\n};\n\nconst memoryRecallTool: ToolDefinition = {\n name: \"memory_recall\",\n description: \"Search memories by keyword or semantic query. Returns relevant stored memories.\",\n parameters: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Search query\" },\n limit: { type: \"integer\", description: \"Max results (default 10)\" },\n },\n required: [\"query\"],\n },\n async execute(args, context): Promise<string> {\n if (memoryBackend) {\n try {\n const result = await memoryBackend.recall({\n translated: [args[\"query\"] ?? \"\"],\n original: args[\"query\"] ?? \"\",\n userId: context?.userId ?? getMasterUserId(),\n limit: parseInt(args[\"limit\"] ?? \"10\", 10),\n });\n return JSON.stringify(result);\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n }\n let cmd = `abmind recall ${JSON.stringify(args[\"query\"] ?? \"\")}`;\n if (args[\"limit\"]) cmd += ` --limit ${args[\"limit\"]}`;\n return runBash(cmd, CLI_TIMEOUT_MS);\n },\n};\n\nconst memoryEditTool: ToolDefinition = {\n name: \"memory_edit\",\n description: \"Edit an existing memory by ID. Change content, type, emotion, confidence, or classification.\",\n parameters: {\n type: \"object\",\n properties: {\n memory_id: { type: \"integer\", description: \"Memory ID to edit\" },\n translated: { type: \"string\", description: \"New English content\" },\n original: { type: \"string\", description: \"New original language content\" },\n type: { type: \"string\", description: \"New memory type\" },\n emotion: { type: \"integer\", description: \"New emotion score\" },\n confidence: { type: \"integer\", description: \"New confidence\" },\n classification: { type: \"integer\", description: \"New classification\" },\n caller: { type: \"string\", enum: [\"kp\", \"dreamy\"], description: \"Who is making the edit\" },\n },\n required: [\"memory_id\"],\n },\n async execute(args): Promise<string> {\n if (memoryBackend) {\n try {\n const result = await memoryBackend.editMemory({\n memoryId: parseInt(args[\"memory_id\"] ?? \"0\", 10),\n contentEn: args[\"translated\"],\n contentOriginal: args[\"original\"],\n memoryType: args[\"type\"] as \"fact\" | \"decision\" | \"preference\" | \"event\" | undefined,\n emotionScore: args[\"emotion\"] ? parseInt(args[\"emotion\"], 10) : undefined,\n confidence: args[\"confidence\"] ? parseInt(args[\"confidence\"], 10) : undefined,\n classification: args[\"classification\"] ? parseInt(args[\"classification\"], 10) : undefined,\n caller: (args[\"caller\"] ?? \"kp\") as \"kp\" | \"dreamy\",\n });\n return JSON.stringify(result);\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n }\n let cmd = `abmind edit --memory-id ${args[\"memory_id\"] ?? \"0\"}`;\n if (args[\"translated\"]) cmd += ` --translated ${JSON.stringify(args[\"translated\"])}`;\n if (args[\"original\"]) cmd += ` --original ${JSON.stringify(args[\"original\"])}`;\n if (args[\"type\"]) cmd += ` --type ${args[\"type\"]}`;\n if (args[\"emotion\"]) cmd += ` --emotion-score ${args[\"emotion\"]}`;\n if (args[\"confidence\"]) cmd += ` --confidence ${args[\"confidence\"]}`;\n if (args[\"classification\"]) cmd += ` --classification ${args[\"classification\"]}`;\n if (args[\"caller\"]) cmd += ` --caller ${args[\"caller\"]}`;\n return runBash(cmd, CLI_TIMEOUT_MS);\n },\n};\n\nconst webBrowseTool: ToolDefinition = {\n name: \"web_browse\",\n description: \"Browse a URL or perform a complex multi-step web task. For quick lookups use execute_bash with curl.\",\n parameters: {\n type: \"object\",\n properties: {\n task: { type: \"string\", description: \"What to do on the web\" },\n chat_id: { type: \"string\", description: \"Chat ID for result delivery\" },\n engine: { type: \"string\", enum: [\"patchright\"], description: \"Browser engine (default: patchright)\" },\n },\n required: [\"task\", \"chat_id\"],\n },\n execute: (args) => {\n let cmd = `abtars-browse --task ${JSON.stringify(args[\"task\"] ?? \"\")} --chat-id ${args[\"chat_id\"] ?? \"0\"}`;\n if (args[\"engine\"]) cmd += ` --engine ${args[\"engine\"]}`;\n return runBash(cmd, CLI_TIMEOUT_MS);\n },\n};\n\nconst todoTool: ToolDefinition = {\n name: \"todo_manage\",\n description: \"Manage TODO items. Add, complete, or list tasks.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", enum: [\"add\", \"done\", \"list\", \"remove\"], description: \"Action to perform\" },\n text: { type: \"string\", description: \"TODO text (for add)\" },\n id: { type: \"string\", description: \"TODO ID (for done/remove)\" },\n },\n required: [\"action\"],\n },\n execute: (args) => {\n const action = args[\"action\"] ?? \"list\";\n if (action === \"add\") return runBash(`abtars-todo add ${JSON.stringify(args[\"text\"] ?? \"\")}`, CLI_TIMEOUT_MS);\n if (action === \"done\") return runBash(`abtars-todo done ${args[\"id\"] ?? \"\"}`, CLI_TIMEOUT_MS);\n if (action === \"remove\") return runBash(`abtars-todo remove ${args[\"id\"] ?? \"\"}`, CLI_TIMEOUT_MS);\n return runBash(\"abtars-todo list\", CLI_TIMEOUT_MS);\n },\n};\n\nlet _enqueueCron: ((id: string, manual?: boolean) => string | null) | null = null;\n\n/** Inject enqueueCron from bridge for task_manage --run. */\nexport function setEnqueueCron(fn: (id: string, manual?: boolean) => string | null): void { _enqueueCron = fn; }\n\nlet _ircSend: ((channel: string, message: string) => void) | null = null;\n\n/** Inject IRC send from bridge for irc_send tool. */\nexport function setIrcSend(fn: (channel: string, message: string) => void): void { _ircSend = fn; }\n\n/** @deprecated \u2014 secret_get now reads from file, not DB. Kept for backward compat (callers may still call this). */\nexport function setSecretGetDb(_db: unknown): void { /* no-op */ }\n\nlet _sendDocument: ((path: string, caption?: string) => Promise<number>) | null = null;\n\n/**\n * Inject sendDocument from bridge for the send_document tool.\n * Caller binds main chat id + telegram adapter; tool is a thin wrapper around that.\n */\nexport function setSendDocument(fn: ((path: string, caption?: string) => Promise<number>) | null): void { _sendDocument = fn; }\n\nconst sendDocumentTool: ToolDefinition = {\n name: \"send_document\",\n description: \"Send a file from disk to the user's Telegram chat. Use for delivering reports, daily summaries, logs, or any .md file the user asks for. Do not summarize \u2014 the raw file is sent as an attachment.\",\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"Absolute path to the file\" },\n caption: { type: \"string\", description: \"Optional short caption (\u22641024 chars)\" },\n },\n required: [\"path\"],\n },\n execute: async (args) => {\n const path = args[\"path\"];\n if (!path) return JSON.stringify({ error: \"path is required\" });\n if (!_sendDocument) return JSON.stringify({ error: \"Telegram not configured (sendDocument unavailable)\" });\n try {\n const messageId = await _sendDocument(path, args[\"caption\"]);\n return JSON.stringify({ ok: true, message_id: messageId });\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n },\n};\n\nconst taskTool: ToolDefinition = {\n name: \"task_manage\",\n description: \"Manage scheduled/recurring tasks (cron). Add, list, remove, pause, resume, or run tasks. Use action=run to execute a task immediately via the cron queue (isolated subagent).\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", enum: [\"add\", \"list\", \"remove\", \"pause\", \"resume\", \"run\"], description: \"Action\" },\n message: { type: \"string\", description: \"Task message/command (for add)\" },\n schedule: { type: \"string\", description: \"Cron schedule expression (for add)\" },\n type: { type: \"string\", enum: [\"reminder\", \"script\", \"agent\"], description: \"Task type (for add)\" },\n chat_id: { type: \"string\", description: \"Chat ID (for add)\" },\n id: { type: \"string\", description: \"Task ID (for remove/pause/resume/run)\" },\n },\n required: [\"action\"],\n },\n execute: (args) => {\n const action = args[\"action\"] ?? \"list\";\n if (action === \"list\") return runBash(\"abtars-task list\", CLI_TIMEOUT_MS);\n if (action === \"remove\") return runBash(`abtars-task remove ${args[\"id\"] ?? \"\"}`, CLI_TIMEOUT_MS);\n if (action === \"pause\") return runBash(`abtars-task pause ${args[\"id\"] ?? \"\"}`, CLI_TIMEOUT_MS);\n if (action === \"resume\") return runBash(`abtars-task resume ${args[\"id\"] ?? \"\"}`, CLI_TIMEOUT_MS);\n if (action === \"run\") {\n if (!_enqueueCron) return Promise.resolve(JSON.stringify({ error: \"enqueueCron not available\" }));\n const err = _enqueueCron(args[\"id\"] ?? \"\", true);\n return Promise.resolve(JSON.stringify(err ? { error: err } : { ok: true, message: `Task ${args[\"id\"]} enqueued for immediate execution` }));\n }\n let cmd = `abtars-task add --message ${JSON.stringify(args[\"message\"] ?? \"\")}`;\n if (args[\"schedule\"]) cmd += ` --schedule ${JSON.stringify(args[\"schedule\"])}`;\n if (args[\"type\"]) cmd += ` --type ${args[\"type\"]}`;\n if (args[\"chat_id\"]) cmd += ` --chat-id ${args[\"chat_id\"]}`;\n return runBash(cmd, CLI_TIMEOUT_MS);\n },\n};\n\nconst peerSessionTool: ToolDefinition = {\n name: \"peer_session\",\n description: \"Open or continue a peer-to-peer session with another agent. Messages persist across turns. Use only when the user explicitly asks to contact another agent.\",\n parameters: {\n type: \"object\",\n properties: {\n peer_name: { type: \"string\", description: \"Name of the peer (as in peers.json)\" },\n message: { type: \"string\", description: \"Your message to the peer\" },\n session_id: { type: \"string\", description: \"Session ID from previous call (omit for new conversation)\" },\n },\n required: [\"peer_name\", \"message\"],\n },\n async execute(args) {\n const { callPeer } = await import(\"../peer-client.js\");\n const { loadPeerConfig } = await import(\"../peer-config.js\");\n const { getOrCreateSession, addTurn, isEnded, destroySession } = await import(\"../peer-sessions.js\");\n\n const peerName = args.peer_name?.trim();\n const message = args.message?.trim();\n if (!peerName || !message) return JSON.stringify({ error: \"peer_name and message required\" });\n\n const config = loadPeerConfig();\n if (peerName === config.self.name) return JSON.stringify({ error: \"Cannot chat with yourself\" });\n if (!config.peers[peerName]) return JSON.stringify({ error: `Unknown peer: ${peerName}` });\n\n const session = getOrCreateSession(args.session_id?.trim() || undefined, peerName);\n\n // Check turn cap before sending\n if (session.messages.length >= 20) {\n destroySession(session.id);\n return JSON.stringify({ session_id: session.id, response: \"[SESSION_END] Turn limit reached.\", ended: true, reason: \"max-turns\" });\n }\n\n addTurn(session, \"user\", message);\n\n // Build full conversation for peer (OpenAI messages format)\n const prompt = session.messages.map(m => `${m.role === \"user\" ? \"You\" : \"Peer\"}: ${m.content}`).join(\"\\n\") + \"\\n\\nRespond to the latest message.\";\n\n try {\n const response = await callPeer(peerName, prompt, config.maxHops);\n addTurn(session, \"assistant\", response);\n _peerActivityCb?.(`\uD83E\uDD16 Agents: ${config.self.name} \u2194 ${peerName} session. [turn ${session.messages.length}]`);\n\n const { ended, reason } = isEnded(session, response);\n if (ended) destroySession(session.id);\n\n return JSON.stringify({ session_id: session.id, response, ended, reason });\n } catch (err) {\n destroySession(session.id);\n return JSON.stringify({ error: `peer_session failed: ${err instanceof Error ? err.message : String(err)}`, session_id: session.id, ended: true });\n }\n },\n};\n\nconst peerWakeupTool: ToolDefinition = {\n name: \"peer_wakeup\",\n description: \"Send a wake-up signal to a peer that cannot reach us directly (firewall). The peer's bridge will call us back via A2A within seconds.\",\n parameters: {\n type: \"object\",\n properties: {\n peer_name: { type: \"string\", description: \"Name of the peer to wake up (as in peers.json)\" },\n },\n required: [\"peer_name\"],\n },\n async execute(args) {\n const { sendWakeup } = await import(\"../dns-wakeup.js\");\n const { loadPeerConfig } = await import(\"../peer-config.js\");\n const peerName = args.peer_name?.trim();\n if (!peerName) return JSON.stringify({ error: \"peer_name required\" });\n const config = loadPeerConfig();\n const peer = config.peers[peerName];\n if (!peer) return JSON.stringify({ error: `Unknown peer: ${peerName}` });\n const udpPort = peer.udpPort ?? 5353;\n sendWakeup(config.self.name, peer.host, udpPort, peer.token);\n return JSON.stringify({ ok: true, message: `Wake-up sent to ${peerName}. Expect callback within seconds.` });\n },\n};\n\nconst ircSendTool: ToolDefinition = {\n name: \"irc_send\",\n description: \"Send a message to an IRC channel (e.g. #bridges)\",\n parameters: {\n channel: { type: \"string\", description: \"IRC channel (e.g. #bridges)\" },\n message: { type: \"string\", description: \"Message text to send\" },\n },\n execute: async (args) => {\n if (!_ircSend) return JSON.stringify({ error: \"IRC adapter not connected\" });\n const channel = args[\"channel\"] ?? \"\";\n const message = args[\"message\"] ?? \"\";\n if (!channel || !message) return JSON.stringify({ error: \"channel and message are required\" });\n _ircSend(channel, message);\n return JSON.stringify({ ok: true, channel, sent: message.length + \" chars\" });\n },\n};\n\nconst secretGetTool: ToolDefinition = {\n name: \"secret_get\",\n description: \"Retrieve a secret from ~/.abtars/secret/. For env-var secrets (no extension), returns the value. For files (with extension like .json), returns the full decrypted content. NEVER echo the value to the user.\",\n parameters: {\n properties: {\n name: { type: \"string\", description: \"Exact filename in secret/ dir (e.g. 'OPENROUTER_API_KEY', 'x-cookies.json')\" },\n },\n required: [\"name\"],\n },\n execute: async (args) => {\n const name = args.name?.trim();\n if (!name) return JSON.stringify({ error: \"name is required\" });\n try {\n const { join } = await import(\"node:path\");\n const { homedir } = await import(\"node:os\");\n const { readFileSync, existsSync } = await import(\"node:fs\");\n const { createDecipheriv, hkdfSync } = await import(\"node:crypto\");\n const { loadKey } = await import(\"abmind\");\n\n const secretPath = join(homedir(), \".abtars\", \"secret\", name);\n if (!existsSync(secretPath)) return JSON.stringify({ error: `secret '${name}' not found` });\n\n const raw = readFileSync(secretPath, \"utf-8\").trim();\n if (!raw) return JSON.stringify({ error: `secret '${name}' is empty` });\n\n let value: string;\n if (raw.startsWith(\"ENC:\")) {\n const master = loadKey();\n const key = Buffer.from(hkdfSync(\"sha256\", master, \"\", \"abtars-secrets-files-v1\", 32));\n const buf = Buffer.from(raw.slice(4), \"base64\");\n const d = createDecipheriv(\"aes-256-gcm\", key, buf.subarray(1, 13));\n d.setAuthTag(buf.subarray(buf.length - 16));\n value = d.update(buf.subarray(13, buf.length - 16), undefined, \"utf-8\") + d.final(\"utf-8\");\n } else {\n value = raw;\n }\n\n // For env-var type (no extension): also inject into process.env\n if (!name.includes(\".\")) {\n process.env[name] = value;\n return JSON.stringify({ ok: true, env_var: `$${name}`, hint: `Use $${name} in commands. NEVER print or echo the value.` });\n }\n return JSON.stringify({ ok: true, content: value });\n } catch (err) {\n return JSON.stringify({ error: `secret_get failed: ${err instanceof Error ? err.message : String(err)}` });\n }\n },\n};\n\nimport { skillCreateTool, skillUpdateTool, skillPatchTool, skillRemoveTool } from \"./skill-authoring.js\";\nimport { mcpTool } from \"./mcp-tool.js\";\nimport { getDelegationTools } from \"./delegation-tools.js\";\n\nconst ALL_TOOLS: ToolDefinition[] = [bashTool, memoryStoreTool, memoryRecallTool, memoryEditTool, webBrowseTool, todoTool, taskTool, sendDocumentTool, peerSessionTool, peerWakeupTool, ircSendTool, secretGetTool, skillCreateTool, skillUpdateTool, skillPatchTool, skillRemoveTool, mcpTool, ...getDelegationTools()];\n\nexport function getToolDefinitions(): ToolDefinition[] { return ALL_TOOLS; }\n\nexport function getToolSchemas(policy?: SandboxPolicy): Array<{ type: \"function\"; function: { name: string; description: string; parameters: Record<string, unknown> } }> {\n const tools = policy ? ALL_TOOLS.filter(t => checkTool(t.name, policy).allowed) : ALL_TOOLS;\n return tools.map(t => ({\n type: \"function\" as const,\n function: { name: t.name, description: t.description, parameters: t.parameters },\n }));\n}\n\nimport { bumpRead } from \"../skill-stats.js\";\n\n/** Check if a bash command result indicates a skill file was read. */\nfunction checkSkillRead(toolName: string, args: Record<string, string>): void {\n if (toolName !== \"execute_bash\") return;\n const cmd = args[\"command\"] ?? \"\";\n if (cmd.includes(\"/.abtars/skills/\") && cmd.includes(\"/SKILL.md\")) {\n const match = cmd.match(/\\/.abtars\\/skills\\/[^/]+\\/([^/]+)\\/SKILL\\.md/);\n if (match) bumpRead(match[1]!);\n }\n}\n\nexport async function executeToolCall(name: string, args: Record<string, string>, context?: { userId: string; signal?: AbortSignal; sandboxPolicy?: SandboxPolicy }): Promise<string> {\n // Sandbox enforcement\n if (context?.sandboxPolicy) {\n const toolCheck = checkTool(name, context.sandboxPolicy);\n if (!toolCheck.allowed) {\n const available = ALL_TOOLS.filter(t => checkTool(t.name, context.sandboxPolicy!).allowed).map(t => t.name);\n auditDeny(name, undefined, \"session\", toolCheck.reason!);\n return JSON.stringify({ error: `Tool '${name}' not available in this session`, available_tools: available, reason: \"peer_sandbox\" });\n }\n const filePath = args[\"path\"] ?? args[\"file_path\"];\n if (filePath) {\n const mode = name.includes(\"read\") || name === \"memory_recall\" ? \"read\" as const : \"write\" as const;\n const pathCheck = checkPath(filePath, mode, context.sandboxPolicy);\n if (!pathCheck.allowed) {\n auditDeny(name, filePath, \"session\", pathCheck.reason!);\n return JSON.stringify({ error: pathCheck.reason, reason: \"peer_sandbox\" });\n }\n }\n }\n\n const tool = ALL_TOOLS.find(t => t.name === name);\n if (!tool) return JSON.stringify({ error: `Unknown tool: ${name}` });\n const ts = Date.now();\n\n // #621: redact abmind_store args based on classification\n const storeClass = (name === \"abmind_store\" || name === \"memory_store\") ? parseInt(args.classification ?? args.class ?? \"1\", 10) : 0;\n const auditArgs = storeClass >= 2\n ? `{\"class\":${storeClass},\"[REDACTED]\":true}`\n : redactSecrets(JSON.stringify(args));\n audit({ ts, tool: name, args: auditArgs, userId: context?.userId });\n\n try {\n const result = await tool.execute(args, context);\n audit({ ts, tool: name, status: \"ok\", chars: result.length });\n checkSkillRead(name, args);\n return result;\n } catch (err) {\n audit({ ts, tool: name, status: \"error\", error: err instanceof Error ? err.message : String(err) });\n throw err;\n }\n}\n", "/**\n * skill-authoring.ts \u2014 skill lifecycle tools (#381, #613, #614).\n * Agent persists procedural knowledge as skills under ~/.abtars/skills/self/.\n */\n\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, renameSync, appendFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { abmind } from \"../../utils/abmind-lazy.js\";\nimport { abtarsHome } from \"../../paths.js\";\nimport { logInfo } from \"../logger.js\";\nimport { logAndSwallow } from \"../log-and-swallow.js\";\nimport { setProvenance } from \"../skill-stats.js\";\nimport type { ToolDefinition } from \"./tool-registry.js\";\n\nconst TAG = \"skill-authoring\";\nconst NAME_RE = /^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/;\nconst MIN_BYTES = 100;\nconst MAX_BYTES = 50_000;\nconst MAX_TAGS = 5;\n\nfunction skillsDir(): string { return join(abtarsHome(), \"skills\"); }\nfunction selfDir(): string { return join(skillsDir(), \"self\"); }\nfunction trashDir(): string { return join(skillsDir(), \".trash\"); }\nfunction auditLogPath(): string { return join(abtarsHome(), \"logs\", \"skill-authoring.log\"); }\n\nfunction audit(entry: string): void {\n const line = `[${new Date().toISOString()}] ${entry}\\n`;\n try {\n const dir = join(abtarsHome(), \"logs\");\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n appendFileSync(auditLogPath(), line);\n } catch (err) { logAndSwallow(TAG, \"audit write\", err); }\n}\n\nfunction validate(name: string, description: string, content: string): string | null {\n if (!NAME_RE.test(name)) return `Invalid name \"${name}\". Must be 3-64 chars, lowercase alphanumeric + hyphens, no leading/trailing hyphens.`;\n const desc = description.trim();\n if (desc.length < 1 || desc.length > 120) return `Description must be 1-120 chars (got ${desc.length}).`;\n const bytes = Buffer.byteLength(content, \"utf-8\");\n if (bytes < MIN_BYTES) return `Content too short (${bytes} bytes, minimum ${MIN_BYTES}). Write a useful skill, not a one-liner.`;\n if (bytes > MAX_BYTES) return `Content too large (${bytes} bytes, maximum ${MAX_BYTES}). Split into a skill + references/ files.`;\n const path = join(selfDir(), name, \"SKILL.md\");\n if (existsSync(path)) return `Skill \"${name}\" already exists. Use skill_update to modify it.`;\n const scan = abmind()?.scanForInjection(content);\n if (scan && !scan.safe) return `Content blocked by injection scanner: ${scan.flags[0]?.category ?? \"unknown\"} (score=${scan.score}). Rephrase the content.`;\n return null;\n}\n\n/** Parse YAML-like frontmatter from SKILL.md content. */\nfunction parseFrontmatter(raw: string): { meta: Record<string, unknown>; body: string } {\n const match = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n\\n?([\\s\\S]*)$/);\n if (!match) return { meta: {}, body: raw };\n const meta: Record<string, unknown> = {};\n for (const line of match[1]!.split(\"\\n\")) {\n const idx = line.indexOf(\":\");\n if (idx < 0) continue;\n const key = line.slice(0, idx).trim();\n let val: unknown = line.slice(idx + 1).trim();\n // Parse array: [a, b, c]\n if (typeof val === \"string\" && val.startsWith(\"[\") && val.endsWith(\"]\")) {\n val = val.slice(1, -1).split(\",\").map(s => s.trim()).filter(Boolean);\n }\n meta[key] = val;\n }\n return { meta, body: match[2]! };\n}\n\n/** Serialize frontmatter fields back to YAML-like string. */\nfunction serializeFrontmatter(meta: Record<string, unknown>): string {\n const lines: string[] = [\"---\"];\n for (const [k, v] of Object.entries(meta)) {\n if (v === undefined || v === null) continue;\n if (Array.isArray(v) && v.length > 0) {\n lines.push(`${k}: [${v.join(\", \")}]`);\n } else if (!Array.isArray(v)) {\n lines.push(`${k}: ${v}`);\n }\n }\n lines.push(\"---\\n\\n\");\n return lines.join(\"\\n\");\n}\n\n/** Guard: skill must exist in self/ dir. Returns error string or null. */\nfunction guardSelfSkill(name: string): string | null {\n if (!NAME_RE.test(name)) return `Invalid name \"${name}\".`;\n const path = join(selfDir(), name, \"SKILL.md\");\n if (!existsSync(path)) return `Skill \"${name}\" not found in self/.`;\n return null;\n}\n\nexport const skillCreateTool: ToolDefinition = {\n name: \"skill_create\",\n description: \"Persist a new procedural skill to disk. Use when you've solved a novel task, discovered a workflow, or received a correction worth remembering as a repeatable recipe. Skills become available in future sessions via the skills_catalog.\",\n parameters: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Skill identifier, kebab-case, e.g. 'fix-pnpm-workspace-drift'. 3-64 chars, [a-z0-9-]+.\" },\n description: { type: \"string\", description: \"One-line description, max 120 chars. Shown in skills_catalog.\" },\n content: { type: \"string\", description: \"Skill body in Markdown. Starts with # <Title>. No frontmatter \u2014 the tool writes it.\" },\n tags: { type: \"array\", items: { type: \"string\" }, description: \"Optional tags for categorization (max 5). E.g. ['tools', 'browser', 'debugging'].\" },\n related: { type: \"array\", items: { type: \"string\" }, description: \"Optional related skill names.\" },\n },\n required: [\"name\", \"description\", \"content\"],\n },\n async execute(args) {\n const { name, description, content, tags, related } = args as unknown as { name: string; description: string; content: string; tags?: string[]; related?: string[] };\n const error = validate(name, description, content);\n if (error) {\n audit(`skill_create name=${name} bytes=${content.length} ok=false error=\"${error}\"`);\n return JSON.stringify({ error });\n }\n\n const tagList = (tags ?? []).slice(0, MAX_TAGS).map(t => t.toLowerCase().trim()).filter(Boolean);\n const relList = (related ?? []).filter(Boolean);\n const tagsLine = tagList.length > 0 ? `tags: [${tagList.join(\", \")}]\\n` : \"\";\n const relatedLine = relList.length > 0 ? `related: [${relList.join(\", \")}]\\n` : \"\";\n const frontmatter = `---\\nname: ${name}\\ndescription: ${description.trim()}\\n${tagsLine}${relatedLine}---\\n\\n`;\n const fullContent = frontmatter + content;\n const dir = join(selfDir(), name);\n const filePath = join(dir, \"SKILL.md\");\n const tmpPath = filePath + \".tmp\";\n\n try {\n mkdirSync(dir, { recursive: true });\n writeFileSync(tmpPath, fullContent, \"utf-8\");\n renameSync(tmpPath, filePath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n audit(`skill_create name=${name} bytes=${content.length} ok=false error=\"write failed: ${msg}\"`);\n return JSON.stringify({ error: `Write failed: ${msg}` });\n }\n\n setProvenance(name, \"agent\");\n audit(`skill_create name=${name} tags=[${tagList.join(\",\")}] bytes=${content.length} ok=true`);\n logInfo(TAG, `Created skill: self/${name} (${content.length} bytes)`);\n return JSON.stringify({ ok: true, path: filePath, message: `Skill \"${name}\" created in self/. Available in skills_catalog after /skill reload.` });\n },\n};\n\nexport const skillUpdateTool: ToolDefinition = {\n name: \"skill_update\",\n description: \"Full rewrite of an existing skill's SKILL.md in self/. Preserves frontmatter fields (tags, related, description) when omitted by caller.\",\n parameters: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Skill name (must exist in self/).\" },\n description: { type: \"string\", description: \"New description (optional \u2014 keeps existing if omitted).\" },\n content: { type: \"string\", description: \"New skill body in Markdown (no frontmatter).\" },\n tags: { type: \"array\", items: { type: \"string\" }, description: \"New tags (optional \u2014 keeps existing if omitted).\" },\n related: { type: \"array\", items: { type: \"string\" }, description: \"New related skills (optional \u2014 keeps existing if omitted).\" },\n },\n required: [\"name\", \"content\"],\n },\n async execute(args) {\n const { name, content, description, tags, related } = args as unknown as { name: string; content: string; description?: string; tags?: string[]; related?: string[] };\n const guard = guardSelfSkill(name);\n if (guard) { audit(`skill_update name=${name} ok=false error=\"${guard}\"`); return JSON.stringify({ error: guard }); }\n\n const bytes = Buffer.byteLength(content, \"utf-8\");\n if (bytes < MIN_BYTES) return JSON.stringify({ error: `Content too short (${bytes} bytes, minimum ${MIN_BYTES}).` });\n if (bytes > MAX_BYTES) return JSON.stringify({ error: `Content too large (${bytes} bytes, maximum ${MAX_BYTES}).` });\n\n const scan = abmind()?.scanForInjection(content);\n if (scan && !scan.safe) return JSON.stringify({ error: `Content blocked by injection scanner: ${scan.flags[0]?.category ?? \"unknown\"}.` });\n\n const filePath = join(selfDir(), name, \"SKILL.md\");\n const existing = readFileSync(filePath, \"utf-8\");\n const { meta } = parseFrontmatter(existing);\n\n // Merge: caller fields override, omitted fields preserved\n const merged: Record<string, unknown> = { ...meta, name };\n if (description !== undefined) merged[\"description\"] = description.trim();\n if (tags !== undefined) merged[\"tags\"] = tags.slice(0, MAX_TAGS).map(t => t.toLowerCase().trim()).filter(Boolean);\n if (related !== undefined) merged[\"related\"] = related.filter(Boolean);\n\n const fullContent = serializeFrontmatter(merged) + content;\n const tmpPath = filePath + \".tmp\";\n try {\n writeFileSync(tmpPath, fullContent, \"utf-8\");\n renameSync(tmpPath, filePath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n audit(`skill_update name=${name} ok=false error=\"write failed: ${msg}\"`);\n return JSON.stringify({ error: `Write failed: ${msg}` });\n }\n\n audit(`skill_update name=${name} bytes=${bytes} ok=true`);\n logInfo(TAG, `Updated skill: self/${name} (${bytes} bytes)`);\n return JSON.stringify({ ok: true, path: filePath, message: `Skill \"${name}\" updated.` });\n },\n};\n\nexport const skillPatchTool: ToolDefinition = {\n name: \"skill_patch\",\n description: \"Targeted find-and-replace within a skill's SKILL.md in self/. old_string must match exactly once.\",\n parameters: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Skill name (must exist in self/).\" },\n old_string: { type: \"string\", description: \"Exact string to find (must match once).\" },\n new_string: { type: \"string\", description: \"Replacement string.\" },\n },\n required: [\"name\", \"old_string\", \"new_string\"],\n },\n async execute(args) {\n const { name, old_string, new_string } = args as unknown as { name: string; old_string: string; new_string: string };\n const guard = guardSelfSkill(name);\n if (guard) { audit(`skill_patch name=${name} ok=false error=\"${guard}\"`); return JSON.stringify({ error: guard }); }\n\n const filePath = join(selfDir(), name, \"SKILL.md\");\n const existing = readFileSync(filePath, \"utf-8\");\n\n const count = existing.split(old_string).length - 1;\n if (count === 0) return JSON.stringify({ error: `old_string not found in skill \"${name}\".` });\n if (count > 1) return JSON.stringify({ error: `old_string matches ${count} times \u2014 must match exactly once.` });\n\n const patched = existing.replace(old_string, new_string);\n const scan = abmind()?.scanForInjection(patched);\n if (scan && !scan.safe) return JSON.stringify({ error: `Patched content blocked by injection scanner: ${scan.flags[0]?.category ?? \"unknown\"}.` });\n\n const tmpPath = filePath + \".tmp\";\n try {\n writeFileSync(tmpPath, patched, \"utf-8\");\n renameSync(tmpPath, filePath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n audit(`skill_patch name=${name} ok=false error=\"write failed: ${msg}\"`);\n return JSON.stringify({ error: `Write failed: ${msg}` });\n }\n\n audit(`skill_patch name=${name} ok=true`);\n logInfo(TAG, `Patched skill: self/${name}`);\n return JSON.stringify({ ok: true, path: filePath, message: `Skill \"${name}\" patched.` });\n },\n};\n\nexport const skillRemoveTool: ToolDefinition = {\n name: \"skill_remove\",\n description: \"Soft-delete a skill from self/ by moving it to .trash/ (recoverable for 7 days).\",\n parameters: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Skill name (must exist in self/).\" },\n },\n required: [\"name\"],\n },\n async execute(args) {\n const { name } = args as unknown as { name: string };\n const guard = guardSelfSkill(name);\n if (guard) { audit(`skill_remove name=${name} ok=false error=\"${guard}\"`); return JSON.stringify({ error: guard }); }\n\n const srcDir = join(selfDir(), name);\n const ts = Date.now();\n const destDir = join(trashDir(), `${name}-${ts}`);\n try {\n mkdirSync(trashDir(), { recursive: true });\n renameSync(srcDir, destDir);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n audit(`skill_remove name=${name} ok=false error=\"move failed: ${msg}\"`);\n return JSON.stringify({ error: `Move failed: ${msg}` });\n }\n\n audit(`skill_remove name=${name} dest=${destDir} ok=true`);\n logInfo(TAG, `Removed skill: self/${name} \u2192 .trash/`);\n return JSON.stringify({ ok: true, message: `Skill \"${name}\" moved to .trash/. Will be pruned after 7 days.` });\n },\n};\n", "/**\n * mcp-tool.ts \u2014 Generic MCP tool (#471 v2).\n * Single tool that routes to any mcporter server/tool. Daemon starts on-demand.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { logInfo, logWarn } from \"../logger.js\";\nimport { logAndSwallow } from \"../log-and-swallow.js\";\nimport type { ToolDefinition } from \"./tool-registry.js\";\n\nconst execFileAsync = promisify(execFile);\nconst TAG = \"mcp\";\nlet daemonStarted = false;\n\nasync function ensureDaemon(): Promise<void> {\n if (daemonStarted) return;\n try {\n await execFileAsync(\"mcporter\", [\"daemon\", \"start\"], { timeout: 10_000 });\n daemonStarted = true;\n logInfo(TAG, \"mcporter daemon started (on-demand)\");\n } catch {\n logWarn(TAG, \"mcporter daemon start failed \u2014 calls may still work if already running\");\n daemonStarted = true; // don't retry every call \u2014 assume already running\n }\n}\n\nexport const mcpTool: ToolDefinition = {\n name: \"mcp\",\n description: \"Call an MCP server tool via mcporter. Available servers shown by /mcp command. Use when you need JIRA, presentations, or other MCP-connected services.\",\n parameters: {\n type: \"object\",\n properties: {\n server: { type: \"string\", description: \"Server name (e.g. 'pptx', 'atlassian')\" },\n tool: { type: \"string\", description: \"Tool name (e.g. 'jira_search', 'create_presentation')\" },\n args: { type: \"string\", description: \"Tool arguments as JSON string (e.g. '{\\\"query\\\": \\\"assignee = me\\\"}')\" },\n },\n required: [\"server\", \"tool\"],\n },\n async execute(params) {\n await ensureDaemon();\n const { server, tool, args } = params as { server: string; tool: string; args?: string };\n const cliArgs = [\"call\", `${server}.${tool}`];\n if (args) {\n try {\n const parsed = JSON.parse(args) as Record<string, string>;\n for (const [k, v] of Object.entries(parsed)) cliArgs.push(`${k}=${v}`);\n } catch (err) {\n logAndSwallow(TAG, \"JSON.parse mcp args\", err);\n cliArgs.push(args);\n }\n }\n try {\n const { stdout } = await execFileAsync(\"mcporter\", cliArgs, { timeout: 30_000, encoding: \"utf-8\" });\n return stdout;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return JSON.stringify({ error: `mcp call failed: ${msg}` });\n }\n },\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["checkPath", "TAG", "execFile", "appendFileSync", "mkdirSync", "join", "homedir", "TAG", "TAG", "join", "homedir", "mkdirSync", "audit", "appendFileSync", "checkCommand", "classifyCommand", "resolve", "execFile", "readFileSync", "existsSync"]
|
|
7
|
+
}
|
|
@@ -23,6 +23,9 @@ function packagePaths(pkg) {
|
|
|
23
23
|
config: join(home, "config"),
|
|
24
24
|
app: join(home, "app"),
|
|
25
25
|
appPrev: join(home, "app.prev"),
|
|
26
|
+
appPrev1: join(home, "app.prev.1"),
|
|
27
|
+
appPrev2: join(home, "app.prev.2"),
|
|
28
|
+
appPrev3: join(home, "app.prev.3"),
|
|
26
29
|
appStaging: join(home, "app.staging"),
|
|
27
30
|
bin: join(home, "bin"),
|
|
28
31
|
manifest: join(home, "manifest.json"),
|
|
@@ -147,13 +150,34 @@ import { createHash } from "node:crypto";
|
|
|
147
150
|
import { existsSync, mkdirSync, rmSync, renameSync, readdirSync, cpSync, readFileSync, writeFileSync } from "node:fs";
|
|
148
151
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
149
152
|
import { join as join2 } from "node:path";
|
|
150
|
-
function atomicSwap(appDir,
|
|
151
|
-
|
|
152
|
-
|
|
153
|
+
function atomicSwap(appDir, _appPrevLegacy, appStagingDir) {
|
|
154
|
+
const prev1 = appDir.replace(/\/app$/, "/app.prev.1");
|
|
155
|
+
const prev2 = appDir.replace(/\/app$/, "/app.prev.2");
|
|
156
|
+
const prev3 = appDir.replace(/\/app$/, "/app.prev.3");
|
|
157
|
+
const legacyPrev = _appPrevLegacy;
|
|
158
|
+
if (existsSync(legacyPrev) && !existsSync(prev1)) {
|
|
159
|
+
renameSync(legacyPrev, prev1);
|
|
160
|
+
} else if (existsSync(legacyPrev)) {
|
|
161
|
+
rmSync(legacyPrev, { recursive: true, force: true });
|
|
153
162
|
}
|
|
154
|
-
|
|
155
|
-
|
|
163
|
+
try {
|
|
164
|
+
const curPkg = join2(appDir, "package.json");
|
|
165
|
+
const stagePkg = join2(appStagingDir, "package.json");
|
|
166
|
+
if (existsSync(curPkg) && existsSync(stagePkg)) {
|
|
167
|
+
const curVer = JSON.parse(readFileSync(curPkg, "utf-8")).version;
|
|
168
|
+
const stageVer = JSON.parse(readFileSync(stagePkg, "utf-8")).version;
|
|
169
|
+
if (curVer && curVer === stageVer) {
|
|
170
|
+
rmSync(appDir, { recursive: true, force: true });
|
|
171
|
+
renameSync(appStagingDir, appDir);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
} catch {
|
|
156
176
|
}
|
|
177
|
+
if (existsSync(prev3)) rmSync(prev3, { recursive: true, force: true });
|
|
178
|
+
if (existsSync(prev2)) renameSync(prev2, prev3);
|
|
179
|
+
if (existsSync(prev1)) renameSync(prev1, prev2);
|
|
180
|
+
if (existsSync(appDir)) renameSync(appDir, prev1);
|
|
157
181
|
renameSync(appStagingDir, appDir);
|
|
158
182
|
}
|
|
159
183
|
function configSnapshot(configDir) {
|
|
@@ -311,4 +335,4 @@ export {
|
|
|
311
335
|
removePath,
|
|
312
336
|
safeCopyTree
|
|
313
337
|
};
|
|
314
|
-
//# sourceMappingURL=chunk-
|
|
338
|
+
//# sourceMappingURL=chunk-WMWI3SJ7.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
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 appPrev1: string;\n readonly appPrev2: string;\n readonly appPrev3: 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 appPrev1: join(home, 'app.prev.1'),\n appPrev2: join(home, 'app.prev.2'),\n appPrev3: join(home, 'app.prev.3'),\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 /** 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: '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 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): 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
|
+
}
|
|
@@ -7,10 +7,18 @@ import {
|
|
|
7
7
|
// src/paths.ts
|
|
8
8
|
import { resolve, join, relative } from "node:path";
|
|
9
9
|
import { homedir } from "node:os";
|
|
10
|
-
import { mkdirSync } from "node:fs";
|
|
10
|
+
import { mkdirSync, readFileSync } from "node:fs";
|
|
11
11
|
function abtarsHome() {
|
|
12
12
|
return process.env.ABTARS_HOME ?? resolve(homedir(), ".abtars");
|
|
13
13
|
}
|
|
14
|
+
function getDeployedVersion() {
|
|
15
|
+
try {
|
|
16
|
+
const manifest = JSON.parse(readFileSync(join(abtarsHome(), "manifest.json"), "utf-8"));
|
|
17
|
+
return { version: manifest.version ?? "?", commit: manifest.commit ?? "" };
|
|
18
|
+
} catch {
|
|
19
|
+
return { version: "?", commit: "" };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
14
22
|
function setLazyRoots(roots) {
|
|
15
23
|
lazyRootsCache = roots;
|
|
16
24
|
}
|
|
@@ -40,9 +48,10 @@ var init_paths = __esm({
|
|
|
40
48
|
|
|
41
49
|
export {
|
|
42
50
|
abtarsHome,
|
|
51
|
+
getDeployedVersion,
|
|
43
52
|
setLazyRoots,
|
|
44
53
|
ensureDir,
|
|
45
54
|
reportsDir,
|
|
46
55
|
init_paths
|
|
47
56
|
};
|
|
48
|
-
//# sourceMappingURL=chunk-
|
|
57
|
+
//# sourceMappingURL=chunk-WW5F2DCO.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/paths.ts"],
|
|
4
|
+
"sourcesContent": ["import { resolve, join, relative } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { mkdirSync, readFileSync } from \"node:fs\";\n\n/** Base directory for all Abtars runtime data. Override with ABTARS_HOME env var. */\nexport function abtarsHome(): string {\n return process.env.ABTARS_HOME ?? resolve(homedir(), \".abtars\");\n}\n\n/** Single source of truth for deployed version. Reads ~/.abtars/manifest.json. */\nexport function getDeployedVersion(): { version: string; commit: string } {\n try {\n const manifest = JSON.parse(readFileSync(join(abtarsHome(), \"manifest.json\"), \"utf-8\"));\n return { version: manifest.version ?? \"?\", commit: manifest.commit ?? \"\" };\n } catch { return { version: \"?\", commit: \"\" }; }\n}\n\n// \u2500\u2500 Lazy directory creation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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\nlet lazyRootsCache: string[] | null = null;\n\n/** Set allowed lazy roots (called once at boot from manifest). */\nexport function setLazyRoots(roots: string[]): void { lazyRootsCache = roots; }\n\n/**\n * Create a directory under abtarsHome if it doesn't exist.\n * If lazyRoots are configured, warns on undeclared paths.\n */\nexport function ensureDir(absPath: string): void {\n const home = abtarsHome();\n const rel = relative(home, absPath);\n if (lazyRootsCache && !rel.startsWith(\"..\") && rel !== \"\") {\n const allowed = lazyRootsCache.some(root => rel === root || rel.startsWith(root + \"/\"));\n if (!allowed) {\n // Check if it's an eager dir (those are always allowed)\n const isEager = [\"config\", \"logs\", \"scripts\", \"bin\", \"releases\"].some(d => rel === d || rel.startsWith(d + \"/\"));\n if (!isEager) {\n // eslint-disable-next-line no-console\n console.warn(`[manifest] ensureDir: \"${rel}\" is not under a declared lazyRoot or eager directory`);\n }\n }\n }\n mkdirSync(absPath, { recursive: true });\n}\n\n/**\n * Canonical path for user-facing reports, grouped by category.\n * Example: reportsDir(\"tasks\") \u2192 ~/.abtars/reports/tasks/\n *\n * Callers are responsible for mkdirSync(dir, { recursive: true }).\n * All abtars-produced reports should live under this tree so they're\n * discoverable by the send-report skill and the future consolidation work.\n */\nexport function reportsDir(category: string): string {\n return join(abtarsHome(), \"reports\", category);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;AAAA,SAAS,SAAS,MAAM,gBAAgB;AACxC,SAAS,eAAe;AACxB,SAAS,WAAW,oBAAoB;AAGjC,SAAS,aAAqB;AACnC,SAAO,QAAQ,IAAI,eAAe,QAAQ,QAAQ,GAAG,SAAS;AAChE;AAGO,SAAS,qBAA0D;AACxE,MAAI;AACF,UAAM,WAAW,KAAK,MAAM,aAAa,KAAK,WAAW,GAAG,eAAe,GAAG,OAAO,CAAC;AACtF,WAAO,EAAE,SAAS,SAAS,WAAW,KAAK,QAAQ,SAAS,UAAU,GAAG;AAAA,EAC3E,QAAQ;AAAE,WAAO,EAAE,SAAS,KAAK,QAAQ,GAAG;AAAA,EAAG;AACjD;AAOO,SAAS,aAAa,OAAuB;AAAE,mBAAiB;AAAO;AAMvE,SAAS,UAAU,SAAuB;AAC/C,QAAM,OAAO,WAAW;AACxB,QAAM,MAAM,SAAS,MAAM,OAAO;AAClC,MAAI,kBAAkB,CAAC,IAAI,WAAW,IAAI,KAAK,QAAQ,IAAI;AACzD,UAAM,UAAU,eAAe,KAAK,UAAQ,QAAQ,QAAQ,IAAI,WAAW,OAAO,GAAG,CAAC;AACtF,QAAI,CAAC,SAAS;AAEZ,YAAM,UAAU,CAAC,UAAU,QAAQ,WAAW,OAAO,UAAU,EAAE,KAAK,OAAK,QAAQ,KAAK,IAAI,WAAW,IAAI,GAAG,CAAC;AAC/G,UAAI,CAAC,SAAS;AAEZ,gBAAQ,KAAK,0BAA0B,GAAG,uDAAuD;AAAA,MACnG;AAAA,IACF;AAAA,EACF;AACA,YAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AACxC;AAUO,SAAS,WAAW,UAA0B;AACnD,SAAO,KAAK,WAAW,GAAG,WAAW,QAAQ;AAC/C;AAvDA,IAmBI;AAnBJ;AAAA;AAmBA,IAAI,iBAAkC;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
|
|
4
|
+
// src/components/sanitize-outbound.ts
|
|
5
|
+
var STRIP = [
|
|
6
|
+
/\s*\[TOPICS:\s*.+?\]/gi,
|
|
7
|
+
/\s*\[NO_REPLY\]\s*/gi,
|
|
8
|
+
/\s*\[REACT:.+?\]\s*/gi
|
|
9
|
+
];
|
|
10
|
+
function sanitizeOutbound(text) {
|
|
11
|
+
let out = text;
|
|
12
|
+
for (const re of STRIP) {
|
|
13
|
+
re.lastIndex = 0;
|
|
14
|
+
out = out.replace(re, "");
|
|
15
|
+
}
|
|
16
|
+
return out.trim();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
sanitizeOutbound
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=chunk-YWZPKBO6.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/components/sanitize-outbound.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * sanitize-outbound.ts \u2014 Strip internal tags before delivering to user.\n */\nconst STRIP = [\n /\\s*\\[TOPICS:\\s*.+?\\]/gi,\n /\\s*\\[NO_REPLY\\]\\s*/gi,\n /\\s*\\[REACT:.+?\\]\\s*/gi,\n];\n\nexport function sanitizeOutbound(text: string): string {\n let out = text;\n for (const re of STRIP) { re.lastIndex = 0; out = out.replace(re, \"\"); }\n return out.trim();\n}\n"],
|
|
5
|
+
"mappings": ";;;;AAGA,IAAM,QAAQ;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,iBAAiB,MAAsB;AACrD,MAAI,MAAM;AACV,aAAW,MAAM,OAAO;AAAE,OAAG,YAAY;AAAG,UAAM,IAAI,QAAQ,IAAI,EAAE;AAAA,EAAG;AACvE,SAAO,IAAI,KAAK;AAClB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -6,25 +6,25 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
readEnv,
|
|
8
8
|
readEnvWithDefault
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-HAF2AFBW.js";
|
|
10
10
|
import {
|
|
11
11
|
readAndClearForceSleep,
|
|
12
12
|
writeSleepStatus
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import {
|
|
15
|
-
init_log_and_swallow,
|
|
16
|
-
logAndSwallow
|
|
17
|
-
} from "./chunk-EX2SRTUE.js";
|
|
13
|
+
} from "./chunk-RTL7HO3N.js";
|
|
18
14
|
import {
|
|
19
15
|
getEnv,
|
|
20
16
|
init_env_schema
|
|
21
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-3OXQWII3.js";
|
|
18
|
+
import {
|
|
19
|
+
init_log_and_swallow,
|
|
20
|
+
logAndSwallow
|
|
21
|
+
} from "./chunk-CYSGXNBY.js";
|
|
22
22
|
import {
|
|
23
23
|
init_logger,
|
|
24
24
|
logDebug,
|
|
25
25
|
logInfo,
|
|
26
26
|
logWarn
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-GUTRAMK3.js";
|
|
28
28
|
import {
|
|
29
29
|
__export
|
|
30
30
|
} from "./chunk-7K2YZTLD.js";
|
|
@@ -41,7 +41,6 @@ import { execSync } from "node:child_process";
|
|
|
41
41
|
import { join } from "node:path";
|
|
42
42
|
import { existsSync, readFileSync } from "node:fs";
|
|
43
43
|
init_logger();
|
|
44
|
-
var TAG = "sleep";
|
|
45
44
|
var MAX_RETRIES = 3;
|
|
46
45
|
var RETRY_MS = 5 * 60 * 1e3;
|
|
47
46
|
function createSleepHandle(opts) {
|
|
@@ -113,7 +112,7 @@ function createSleepHandle(opts) {
|
|
|
113
112
|
return abmind().DEFAULT_LEVEL;
|
|
114
113
|
}
|
|
115
114
|
})();
|
|
116
|
-
abmind().runSleepCycle({ runtime: opts.runtime, level }).then((result) => {
|
|
115
|
+
abmind().runSleepCycle({ runtime: opts.runtime, level }).then(async (result) => {
|
|
117
116
|
running = false;
|
|
118
117
|
progress = null;
|
|
119
118
|
logInfo("sleep", `\u{1F634} Sleep finished (ok=${result.ok}, failCount=${result.failCount}, attempt ${attempts})`);
|
|
@@ -134,9 +133,8 @@ function createSleepHandle(opts) {
|
|
|
134
133
|
const hwSleepMin = Math.round(quietTicks * hbInterval / 60);
|
|
135
134
|
const dreamReport = buildDreamReport();
|
|
136
135
|
const sleepNote = hwEnabled ? ` Hardware sleep in ~${hwSleepMin} minutes if no activity.` : "";
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
136
|
+
const { bufferSystemEvent } = await import("./system-event-buffer-OEPPNUGK.js");
|
|
137
|
+
bufferSystemEvent(`${dreamReport}${sleepNote}`);
|
|
140
138
|
if (hwEnabled) {
|
|
141
139
|
_awaitingHwSleep = true;
|
|
142
140
|
postSleepQuietTicks = 0;
|
|
@@ -213,4 +211,4 @@ export {
|
|
|
213
211
|
register,
|
|
214
212
|
sleep_exports
|
|
215
213
|
};
|
|
216
|
-
//# sourceMappingURL=chunk-
|
|
214
|
+
//# sourceMappingURL=chunk-Z4SWEFIY.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/capabilities/sleep/index.ts"],
|
|
4
|
+
"sourcesContent": ["import { logAndSwallow } from \"../../components/log-and-swallow.js\";\nimport { getEnv } from \"../../components/env-schema.js\";\nimport type { CapabilityApi } from \"../capability.js\";\n/**\n * Sleep capability \u2014 spawn nightly sleep cycle via tick system.\n * One path: BED_TIME + quiet ticks \u2192 Dreamy \u2192 quiet ticks \u2192 hardware sleep.\n * Parses PROGRESS:<pct>:<label> from stdout for visibility.\n */\n\nimport { execSync } from \"node:child_process\";\nimport { writeSleepStatus, readAndClearForceSleep } from \"../../components/transport/bridge-lock-transport.js\";\nimport { join } from \"node:path\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport type { Level } from \"abmind\";\nimport { abmind } from \"../../utils/abmind-lazy.js\";\nimport type { SleepRuntime } from \"abmind\";\nimport { logInfo, logWarn, logDebug } from \"../../components/logger.js\";\nimport { readEnv, readEnvWithDefault } from \"../../components/env.js\";\n\nconst TAG = \"sleep\";\n\nexport interface SleepOpts {\n sleepHour: number;\n sleepAuditDir: string;\n memoryEnabled: boolean;\n memoryDir?: string;\n /** LLM runtime adapter \u2014 bridge wraps its SubagentRuntime.complete(\"dreamy\", ...). */\n runtime: SleepRuntime;\n onComplete: () => void;\n getLastMsgTs?: () => number;\n sendSystemMessage?: (prompt: string) => Promise<void>;\n killWakeInhibit?: () => void;\n}\n\nexport interface SleepProgress {\n percent: number;\n step: string;\n}\n\nexport interface SleepHandle {\n /** True while a sleep cycle is running in-process. */\n readonly isActive: boolean;\n readonly progress: SleepProgress | null;\n readonly awaitingHwSleep: boolean;\n spawn(): void;\n /** Called by tick system to check if hardware sleep should fire. */\n checkHwSleep(): void;\n}\n\nconst MAX_RETRIES = 3;\nconst RETRY_MS = 5 * 60 * 1000;\n\nexport function createSleepHandle(opts: SleepOpts): SleepHandle {\n let running = false;\n let attempts = 0;\n let progress: SleepProgress | null = null;\n let _awaitingHwSleep = false;\n // Post-Dreamy hw-sleep quiet-tick tracking (internal to this closure \u2014 decoupled from\n // daily-cycle.quietTickCount which freezes once hasSleepAuditToday returns true).\n // Both reset when _awaitingHwSleep flips to true (see the onComplete handler below).\n let postSleepQuietTicks = 0;\n let lastMsgTsSeenByHwCheck = 0;\n\n function buildDreamReport(): string {\n let dreamReport = \"Dreamy finished nightly maintenance.\";\n try {\n const sleepDir = join(opts.memoryDir ?? \"\", \"sleep\");\n const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, \"\");\n const lockPath = join(sleepDir, `sleep_${dateStr}.lock`);\n if (existsSync(lockPath)) {\n const lockData = JSON.parse(readFileSync(lockPath, \"utf-8\")) as { steps: Record<string, { status: string }>; llmCalls?: number };\n const ok = Object.entries(lockData.steps).filter(([, s]) => s.status === \"ok\").map(([k]) => k);\n const skipped = Object.entries(lockData.steps).filter(([, s]) => s.status === \"skipped\").map(([k]) => k);\n const failed = Object.entries(lockData.steps).filter(([, s]) => s.status === \"failed\" || s.status === \"timeout\").map(([k]) => k);\n dreamReport = `Dreamy finished nightly maintenance (${lockData.llmCalls ?? \"?\"} LLM calls). Completed: ${ok.join(\", \") || \"none\"}.`;\n if (skipped.length > 0) dreamReport += ` Skipped: ${skipped.join(\", \")}.`;\n if (failed.length > 0) dreamReport += ` \u26A0\uFE0F FAILED: ${failed.join(\", \")}. Please review.`;\n }\n } catch (err) { logAndSwallow(\"index\", \"op\", err); }\n return dreamReport;\n }\n\n function spawnSleep(): void {\n const forceSleep = readAndClearForceSleep();\n const forced = forceSleep !== null;\n if (forced) {\n logInfo(\"sleep\", `\u26A1 forceSleep=${forceSleep} \u2014 bypassing time-window + audit-today guards`);\n }\n\n if (!forced) {\n const hour = new Date().getHours();\n const WAKE_HOUR = parseInt(readEnvWithDefault(\"WAKE_TIME\", \"7\", \"wake hour\").split(\":\")[0] ?? \"7\", 10);\n if (opts.sleepHour <= WAKE_HOUR) {\n if (hour < opts.sleepHour || hour >= WAKE_HOUR) {\n logDebug(\"sleep\", `\uD83D\uDE34 Outside sleep window (${opts.sleepHour}:00-${WAKE_HOUR}:00) \u2014 skip`);\n return;\n }\n } else {\n if (hour < opts.sleepHour && hour >= WAKE_HOUR) {\n logDebug(\"sleep\", `\uD83D\uDE34 Outside sleep window (${opts.sleepHour}:00-${WAKE_HOUR}:00) \u2014 skip`);\n return;\n }\n }\n if (abmind()?.hasSleepAuditToday(opts.sleepAuditDir)) {\n logDebug(\"sleep\", \"\uD83D\uDE34 Sleep already done today \u2014 skip\");\n return;\n }\n }\n if (running) return;\n attempts++;\n progress = null;\n running = true;\n writeSleepStatus(\"sleeping\");\n logInfo(\"sleep\", `\uD83D\uDE34 Sleep started in-process (attempt ${attempts}, model=dreamy)`);\n\n const level = (() => {\n if (forced && forceSleep?.includes(\"fresh\")) return \"ultimate\" as Level;\n const raw = getEnv().sleepQuality;\n if (!raw) return abmind()!.DEFAULT_LEVEL;\n try { return abmind()!.parseLevel(raw); }\n catch (err) { logWarn(\"sleep\", `Invalid SLEEP_QUALITY='${raw}', using ${abmind()!.DEFAULT_LEVEL}: ${err instanceof Error ? err.message : String(err)}`); return abmind()!.DEFAULT_LEVEL; }\n })();\n\n abmind()!.runSleepCycle({ runtime: opts.runtime, level })\n .then(async (result: { ok: boolean; failCount: number }) => {\n running = false;\n progress = null;\n logInfo(\"sleep\", `\uD83D\uDE34 Sleep finished (ok=${result.ok}, failCount=${result.failCount}, attempt ${attempts})`);\n writeSleepStatus(\"awake\");\n if (!result.ok) {\n if (attempts < MAX_RETRIES) {\n logWarn(\"sleep\", `\uD83D\uDE34 Sleep had ${result.failCount} failures (attempt ${attempts}/${MAX_RETRIES}) \u2014 retry in 5min`);\n setTimeout(spawnSleep, RETRY_MS);\n } else {\n logWarn(\"sleep\", `\uD83D\uDE34 Sleep failures persist \u2014 exhausted ${MAX_RETRIES} attempts`);\n }\n return;\n }\n\n if (opts.memoryEnabled) opts.onComplete();\n\n // Force-sleep runs are explicit test/verify triggers \u2014 skip hw-sleep even if env enabled.\n const hwEnabled = !forced && readEnv(\"HARDWARE_SLEEP_AFTER_DREAMY\", \"hardware sleep after Dreamy disabled\") === \"true\";\n const quietTicks = Math.ceil(getEnv().bedQuietMin * 60 / parseInt(readEnvWithDefault(\"HEARTBEAT_INTERVAL_SEC\", \"60\", \"hb\"), 10));\n const hbInterval = parseInt(readEnvWithDefault(\"HEARTBEAT_INTERVAL_SEC\", \"60\", \"heartbeat tick interval\"), 10);\n const hwSleepMin = Math.round(quietTicks * hbInterval / 60);\n\n const dreamReport = buildDreamReport();\n const sleepNote = hwEnabled ? ` Hardware sleep in ~${hwSleepMin} minutes if no activity.` : \"\";\n\n // #844: buffer silently \u2014 don't trigger model response\n const { bufferSystemEvent } = await import(\"../../components/system-event-buffer.js\");\n bufferSystemEvent(`${dreamReport}${sleepNote}`);\n\n if (hwEnabled) {\n _awaitingHwSleep = true;\n // Reset hw-check counters \u2014 prevents stale state from a prior cycle (crash, force-sleep\n // re-run) from poisoning this one, and avoids burning the first tick on a spurious\n // reset when the very first checkHwSleep() sees currentMsgTs > 0.\n postSleepQuietTicks = 0;\n lastMsgTsSeenByHwCheck = opts.getLastMsgTs?.() ?? 0;\n logInfo(\"sleep\", `\uD83D\uDCA4 Awaiting hardware sleep \u2014 ${quietTicks} quiet ticks (${hwSleepMin} min) required`);\n }\n })\n .catch((err: unknown) => {\n running = false;\n progress = null;\n writeSleepStatus(\"awake\");\n const msg = err instanceof Error ? err.message : String(err);\n if (attempts < MAX_RETRIES) {\n logWarn(\"sleep\", `\uD83D\uDE34 Sleep threw (attempt ${attempts}/${MAX_RETRIES}): ${msg} \u2014 retry in 5min`);\n setTimeout(spawnSleep, RETRY_MS);\n } else {\n logWarn(\"sleep\", `\uD83D\uDE34 Sleep threw \u2014 exhausted ${MAX_RETRIES} attempts: ${msg}`);\n }\n });\n }\n\n function checkHwSleep(): void {\n if (!_awaitingHwSleep) return;\n\n // Sleep-window cutoff \u2014 give up if we've crossed out of the window. Next night retries.\n // Mirrors spawnSleep()'s window logic for consistency.\n const WAKE_HOUR = parseInt(readEnvWithDefault(\"WAKE_TIME\", \"7\", \"wake hour\").split(\":\")[0] ?? \"7\", 10);\n const BED_HOUR = opts.sleepHour;\n const hour = new Date().getHours();\n const inSleepWindow = (BED_HOUR < WAKE_HOUR)\n ? (hour >= BED_HOUR && hour < WAKE_HOUR) // normal: BED=00:30, WAKE=07:00 \u2192 sleep 00-06\n : (hour >= BED_HOUR || hour < WAKE_HOUR); // overnight: BED=23:00, WAKE=07:00 \u2192 sleep 23-06\n if (!inSleepWindow) {\n logInfo(\"sleep\", `\u23F0 Past sleep window (now ${hour}:00, window ${BED_HOUR}:00-${WAKE_HOUR}:00) \u2014 abandoning hw-sleep attempt`);\n _awaitingHwSleep = false;\n postSleepQuietTicks = 0;\n return;\n }\n\n // User messaged since last check \u2014 postpone and reset\n const currentMsgTs = opts.getLastMsgTs?.() ?? 0;\n if (currentMsgTs > lastMsgTsSeenByHwCheck) {\n lastMsgTsSeenByHwCheck = currentMsgTs;\n postSleepQuietTicks = 0;\n logInfo(\"sleep\", \"\uD83D\uDCA4 Hardware sleep postponed \u2014 user messaged (will retry after quiet period)\");\n return;\n }\n\n // Quiet tick \u2014 increment\n const requiredTicks = Math.ceil(getEnv().bedQuietMin * 60 / parseInt(process.env[\"HEARTBEAT_INTERVAL_SEC\"] ?? \"60\", 10));\n postSleepQuietTicks++;\n if (postSleepQuietTicks < requiredTicks) return;\n\n // Threshold reached \u2014 sleep\n _awaitingHwSleep = false;\n postSleepQuietTicks = 0;\n // Kill any wake inhibitor from /wakeup before sleeping\n opts.killWakeInhibit?.();\n const sleepCmd = process.platform === \"darwin\" ? \"pmset sleepnow\" : \"systemctl suspend\";\n logInfo(\"sleep\", `\uD83D\uDCA4 Putting hardware to sleep (${sleepCmd})...`);\n writeSleepStatus(\"hw_sleep\");\n try { execSync(sleepCmd, { timeout: 5000 }); }\n catch (err) {\n writeSleepStatus(\"awake\"); // recover \u2014 don't leave \"hw_sleep\" if pmset failed\n logWarn(\"sleep\", `\uD83D\uDCA4 Hardware sleep failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n return {\n get isActive() { return running; },\n get progress() { return progress; },\n get awaitingHwSleep() { return _awaitingHwSleep; },\n spawn: spawnSleep,\n checkHwSleep,\n };\n}\n\n/** Capability registration \u2014 called by discoverCapabilities(). */\nexport function register(_api: CapabilityApi): void {\n // Sleep registration is a no-op here \u2014 the actual SleepHandle is created\n // in phase-sleep.ts because it needs ctx.sendSystemMessage + memory deps\n // that aren't available at capability discovery time.\n // This manifest exists so sleep appears in discoverCapabilities() and\n // can be disabled via DISABLED_CAPABILITIES=sleep.\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
|
|
4
|
+
// src/components/tasks/task-failure-buffer.ts
|
|
5
|
+
var buffer = [];
|
|
6
|
+
function addTaskFailure(entry) {
|
|
7
|
+
buffer.push(entry);
|
|
8
|
+
}
|
|
9
|
+
function drainTaskFailures() {
|
|
10
|
+
const entries = buffer.splice(0);
|
|
11
|
+
return entries;
|
|
12
|
+
}
|
|
13
|
+
function hasTaskFailures() {
|
|
14
|
+
return buffer.length > 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
addTaskFailure,
|
|
19
|
+
drainTaskFailures,
|
|
20
|
+
hasTaskFailures
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=chunk-ZAA7B5BN.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/components/tasks/task-failure-buffer.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * task-failure-buffer.ts \u2014 Buffers task failure notifications for injection (#646).\n * Drained before each prompt in the message pipeline.\n */\n\nexport interface TaskFailureEntry {\n taskName: string;\n exitCode: number;\n error?: string;\n timestamp: number;\n consecutiveFailures: number;\n}\n\nconst buffer: TaskFailureEntry[] = [];\n\nexport function addTaskFailure(entry: TaskFailureEntry): void {\n buffer.push(entry);\n}\n\n/** Drain all pending failures (consumed once on next prompt). */\nexport function drainTaskFailures(): TaskFailureEntry[] {\n const entries = buffer.splice(0);\n return entries;\n}\n\nexport function hasTaskFailures(): boolean {\n return buffer.length > 0;\n}\n"],
|
|
5
|
+
"mappings": ";;;;AAaA,IAAM,SAA6B,CAAC;AAE7B,SAAS,eAAe,OAA+B;AAC5D,SAAO,KAAK,KAAK;AACnB;AAGO,SAAS,oBAAwC;AACtD,QAAM,UAAU,OAAO,OAAO,CAAC;AAC/B,SAAO;AACT;AAEO,SAAS,kBAA2B;AACzC,SAAO,OAAO,SAAS;AACzB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -6,22 +6,23 @@ import {
|
|
|
6
6
|
registerCommand,
|
|
7
7
|
triggerNewSession,
|
|
8
8
|
triggerResetSession
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-OGZXYN6E.js";
|
|
10
10
|
import "./chunk-NIRYBWUW.js";
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-SA6YEFNG.js";
|
|
12
|
+
import "./chunk-MHK4UPM6.js";
|
|
13
|
+
import "./chunk-YWZPKBO6.js";
|
|
14
|
+
import "./chunk-L33WNMCP.js";
|
|
15
|
+
import "./chunk-HJQZP5CK.js";
|
|
16
16
|
import "./chunk-JAJ3DUQ2.js";
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-DO4INSXE.js";
|
|
18
|
+
import "./chunk-RTL7HO3N.js";
|
|
19
|
+
import "./chunk-SRFEIZQT.js";
|
|
20
|
+
import "./chunk-H7RX7UCR.js";
|
|
20
21
|
import "./chunk-MZWMYN4O.js";
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-3OXQWII3.js";
|
|
23
|
+
import "./chunk-CYSGXNBY.js";
|
|
24
|
+
import "./chunk-GUTRAMK3.js";
|
|
25
|
+
import "./chunk-WW5F2DCO.js";
|
|
25
26
|
import "./chunk-7K2YZTLD.js";
|
|
26
27
|
export {
|
|
27
28
|
handleCommand,
|
|
@@ -30,4 +31,4 @@ export {
|
|
|
30
31
|
triggerNewSession,
|
|
31
32
|
triggerResetSession
|
|
32
33
|
};
|
|
33
|
-
//# sourceMappingURL=commands-
|
|
34
|
+
//# sourceMappingURL=commands-AXW7L2MZ.js.map
|