autohand-cli 0.7.14 → 0.8.0
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/assets/icon.png +0 -0
- package/dist/AgentRegistry-7LDL5HJH.js +10 -0
- package/dist/AgentRegistry-NQCLWABO.cjs +10 -0
- package/dist/{AutomodeManager-NGRAO2MH.js → AutomodeManager-MWLKGPZK.js} +2 -0
- package/dist/{AutomodeManager-ZKQMBM4T.cjs → AutomodeManager-NYIZNODK.cjs} +3 -1
- package/dist/CommunitySkillsCache-6QPRMTJO.js +8 -0
- package/dist/CommunitySkillsCache-GTQMOCCO.cjs +8 -0
- package/dist/{GitHubRegistryFetcher-US2JJID4.js → GitHubRegistryFetcher-6JQ5JEDZ.js} +1 -0
- package/dist/{GitHubRegistryFetcher-K744NNAJ.cjs → GitHubRegistryFetcher-S7QFUEKV.cjs} +1 -0
- package/dist/HookManager-Q2KYMCP4.cjs +7 -0
- package/dist/HookManager-TTP4Y6DC.js +7 -0
- package/dist/ImportWizard-IWVPRKFF.cjs +466 -0
- package/dist/ImportWizard-KASGQPUY.js +466 -0
- package/dist/McpClientManager-7RM6YT35.js +8 -0
- package/dist/McpClientManager-RKD7C6OY.cjs +8 -0
- package/dist/MemoryManager-GUNLRP5S.js +8 -0
- package/dist/MemoryManager-TNSGKDKX.cjs +8 -0
- package/dist/PermissionManager-2GO5PQ6M.cjs +11 -0
- package/dist/{PermissionManager-U5OMGR3L.js → PermissionManager-K7UWSNB6.js} +4 -3
- package/dist/ProjectProfiler-UMJJSOCE.js +194 -0
- package/dist/ProjectProfiler-ZDWR2ODG.cjs +194 -0
- package/dist/ProviderFactory-EFFQBRQ6.cjs +9 -0
- package/dist/ProviderFactory-S3LWTQQC.js +9 -0
- package/dist/SessionManager-FEUAU3ZJ.cjs +10 -0
- package/dist/SessionManager-IKWAK2PI.js +10 -0
- package/dist/SkillsRegistry-GDEGFP6O.cjs +9 -0
- package/dist/SkillsRegistry-SI5RUHQ4.js +9 -0
- package/dist/SubAgent-I75HELJG.js +11 -0
- package/dist/SubAgent-K3QP6WHC.cjs +11 -0
- package/dist/{SyncApiClient-AYXYSOJM.js → SyncApiClient-LVIO4C2S.js} +1 -0
- package/dist/{SyncApiClient-ID3KXEMA.cjs → SyncApiClient-ZNYMT36M.cjs} +1 -0
- package/dist/about-B2AGTV6N.js +12 -0
- package/dist/about-V2HWEZZO.cjs +12 -0
- package/dist/actionExecutor-6XCVL2SJ.js +19 -0
- package/dist/actionExecutor-YRUJNB5G.cjs +19 -0
- package/dist/add-dir-7FBQ5IFV.js +10 -0
- package/dist/add-dir-ALBSYRV3.cjs +10 -0
- package/dist/agents/builtin/code-cleaner.md +14 -0
- package/dist/agents/builtin/docs-writer.md +14 -0
- package/dist/agents/builtin/researcher.md +14 -0
- package/dist/agents/builtin/reviewer.md +15 -0
- package/dist/agents/builtin/tester.md +15 -0
- package/dist/agents/builtin/todo-resolver.md +15 -0
- package/dist/agents-FCGEWTA3.cjs +12 -0
- package/dist/agents-FENGUSJD.js +12 -0
- package/dist/agents-new-FU3O55CO.js +14 -0
- package/dist/agents-new-SAFTJ7TK.cjs +14 -0
- package/dist/assets/icon.png +0 -0
- package/dist/automode-CYLGXQ4A.cjs +10 -0
- package/dist/automode-O7G3DUYN.js +10 -0
- package/dist/{cc-UTTLESTY.js → cc-7LEIJ3KF.js} +1 -0
- package/dist/{cc-2W6M7J45.cjs → cc-Q5MM4AWC.cjs} +1 -0
- package/dist/{chunk-N4ZSG6JJ.cjs → chunk-22D2CNTP.cjs} +2 -2
- package/dist/chunk-24QIWILL.js +51 -0
- package/dist/{chunk-MYNHJHDZ.js → chunk-2AA5MFES.js} +1 -1
- package/dist/{chunk-KWRUQRXR.js → chunk-2ELK5DMH.js} +44 -10
- package/dist/chunk-2JYIR3EC.cjs +1176 -0
- package/dist/{chunk-CRQKDBLD.js → chunk-2RIAPTET.js} +90 -66
- package/dist/{chunk-TSY7JHIV.cjs → chunk-33A755XB.cjs} +2 -2
- package/dist/chunk-3OEDGIFW.js +42 -0
- package/dist/{chunk-P5VDZ6PV.js → chunk-3PDTTAKJ.js} +1 -1
- package/dist/{chunk-ULMPJUJW.cjs → chunk-3WCOFXQS.cjs} +23 -23
- package/dist/{chunk-PDKNHU5G.cjs → chunk-4HKTYHNL.cjs} +22 -16
- package/dist/{chunk-Z4J4W6YQ.cjs → chunk-4JNNTOGF.cjs} +2 -48
- package/dist/chunk-55B6SBHK.js +260 -0
- package/dist/chunk-5DDDUUBM.cjs +29 -0
- package/dist/{chunk-TQB222ZB.js → chunk-5EIEWVYX.js} +2 -2
- package/dist/{chunk-SMHY3Q7B.cjs → chunk-5GGX6WNY.cjs} +54 -22
- package/dist/{chunk-3S4DEIJP.cjs → chunk-5IXII4HX.cjs} +2 -2
- package/dist/{chunk-3KBBARKO.js → chunk-5OBNULPU.js} +85 -28
- package/dist/{chunk-VVBBEYTH.cjs → chunk-5YJG6H6P.cjs} +10 -10
- package/dist/{chunk-PKOAXQKW.cjs → chunk-63WXWFDI.cjs} +11 -11
- package/dist/{chunk-DSKVMFRM.cjs → chunk-643VRA5S.cjs} +12 -4
- package/dist/{chunk-L5ZFPWHY.js → chunk-6OYHF6MF.js} +12 -4
- package/dist/chunk-7GDVDSNI.js +1176 -0
- package/dist/chunk-7QEE6SW6.cjs +260 -0
- package/dist/chunk-7UOUW76C.js +603 -0
- package/dist/{chunk-SZP4ULM5.cjs → chunk-AFN7LH5N.cjs} +17 -17
- package/dist/chunk-AHD5JJ6F.cjs +78 -0
- package/dist/{chunk-WLTVF77A.js → chunk-ALYU6VTM.js} +1 -1
- package/dist/{chunk-BRXIEKJ3.cjs → chunk-AMT2UZBI.cjs} +5 -5
- package/dist/{chunk-SFNT5DYE.cjs → chunk-BT35E7NE.cjs} +4 -4
- package/dist/{chunk-NUHYCFHW.cjs → chunk-BVKXEQVG.cjs} +54 -65
- package/dist/chunk-CDMGQR4L.cjs +4470 -0
- package/dist/chunk-CNBKZEX5.cjs +109 -0
- package/dist/{chunk-GD4AFYJ3.js → chunk-CVVEYUFR.js} +1 -1
- package/dist/chunk-CWALFEGU.js +58 -0
- package/dist/{chunk-MTALRU7R.cjs → chunk-D3YCFT5O.cjs} +3 -3
- package/dist/{chunk-CH4SPVFD.cjs → chunk-D6VG7B5X.cjs} +9 -3
- package/dist/{chunk-TOTDRAWG.js → chunk-DH7DKCUL.js} +1 -1
- package/dist/{chunk-RFNCTE4V.cjs → chunk-DLG43ZJ7.cjs} +2 -2
- package/dist/chunk-DN573ME7.cjs +1675 -0
- package/dist/{chunk-63BXZQZW.js → chunk-E23CMMNJ.js} +20 -4
- package/dist/{chunk-4HA7IHLJ.cjs → chunk-EEGK5DYE.cjs} +32 -16
- package/dist/{chunk-DTFR3WD6.js → chunk-EF4LKUQY.js} +1 -1
- package/dist/{chunk-PWLLLJHU.js → chunk-EGFT4PGW.js} +3 -1
- package/dist/{chunk-S47TCZDL.js → chunk-EIU7K7CM.js} +7 -7
- package/dist/{chunk-BISFR6ZL.js → chunk-EPNYD4NV.js} +1 -1
- package/dist/chunk-EZMINVLU.js +123 -0
- package/dist/{chunk-LYMTYC67.js → chunk-F23EVNJU.js} +2 -2
- package/dist/chunk-FHK7UDOJ.cjs +42 -0
- package/dist/chunk-FMB3TSWP.cjs +218 -0
- package/dist/{chunk-XBUMKEFN.cjs → chunk-FPAE6ORV.cjs} +91 -34
- package/dist/{chunk-DEAEO7RI.js → chunk-FYZ67R4R.js} +1 -1
- package/dist/{chunk-6SHHB2VD.js → chunk-G7SZIOHF.js} +2 -2
- package/dist/{chunk-FB6JWNJS.js → chunk-GBHDROGL.js} +54 -65
- package/dist/chunk-GCHELXLO.js +131 -0
- package/dist/{chunk-XPOHYKR3.js → chunk-GHSBZ3YB.js} +2 -2
- package/dist/chunk-GLBAF54O.js +218 -0
- package/dist/chunk-GO3N7LRW.cjs +131 -0
- package/dist/{chunk-Y2ZSH3YF.cjs → chunk-H6ZGZEBG.cjs} +57 -23
- package/dist/{chunk-DSCQPWUB.cjs → chunk-HA7OAVOB.cjs} +15 -15
- package/dist/{chunk-NMWEDN4Z.js → chunk-HFMLWH7B.js} +108 -0
- package/dist/{chunk-D2XFTCRP.js → chunk-HQ7YZKXE.js} +1 -1
- package/dist/{chunk-L42HTMMR.cjs → chunk-HTLINWX6.cjs} +2 -2
- package/dist/chunk-IETRBBMP.cjs +603 -0
- package/dist/chunk-IQ5RXU6O.js +1675 -0
- package/dist/{chunk-GVZPIQWB.js → chunk-ITB3FS72.js} +11 -5
- package/dist/{chunk-B6EBHCK2.cjs → chunk-IUMJYXBX.cjs} +6 -6
- package/dist/{chunk-ZBIBLOZL.js → chunk-IVM5F2AE.js} +500 -317
- package/dist/{chunk-GRSVQ5YZ.js → chunk-IWVQ2EW3.js} +44 -12
- package/dist/chunk-JJWCQLOU.cjs +59 -0
- package/dist/{chunk-KXAAEROY.js → chunk-JMFDD7IZ.js} +2 -2
- package/dist/chunk-JSBRDJBE.js +30 -0
- package/dist/chunk-LJFUXC56.cjs +123 -0
- package/dist/chunk-LL3PQ2U6.js +4470 -0
- package/dist/chunk-LQ4LQQG6.cjs +27 -0
- package/dist/chunk-LQGVEP3E.js +109 -0
- package/dist/{chunk-425MT6Y5.cjs → chunk-LVE6Z5SL.cjs} +9 -9
- package/dist/{chunk-XL77XYI2.cjs → chunk-LXDOQTXQ.cjs} +4 -4
- package/dist/{chunk-BG4OQUKP.js → chunk-MBBY4ZIK.js} +1 -1
- package/dist/{chunk-ZXIQCYYV.cjs → chunk-MGMXR67S.cjs} +9 -9
- package/dist/{chunk-FHUNAB2K.cjs → chunk-MHLE6AVN.cjs} +33 -6
- package/dist/chunk-MHSDHPC4.cjs +58 -0
- package/dist/chunk-MUBW5UDH.cjs +55 -0
- package/dist/{chunk-MNSTWHK3.cjs → chunk-MVWOQBCC.cjs} +11 -11
- package/dist/chunk-N254NRHT.cjs +30 -0
- package/dist/{chunk-SRLY7K6J.js → chunk-OBLIITWJ.js} +2 -2
- package/dist/{chunk-SIGWDEPS.cjs → chunk-OI7OIGNB.cjs} +10 -10
- package/dist/{chunk-V7YTCNMN.cjs → chunk-OPR34VHL.cjs} +5 -5
- package/dist/chunk-OUHQZFN4.js +78 -0
- package/dist/{chunk-HMRDNRTH.js → chunk-PEC45WYS.js} +2 -2
- package/dist/{chunk-OSUWEUZE.js → chunk-PUOE5BCN.js} +1 -1
- package/dist/chunk-Q2VYSHWU.js +59 -0
- package/dist/chunk-Q3MJ6CYS.cjs +193 -0
- package/dist/{chunk-QRGPAUST.js → chunk-Q5RN7RXC.js} +2 -2
- package/dist/{chunk-43XS26AQ.cjs → chunk-Q5RX3XGB.cjs} +4 -4
- package/dist/chunk-QCLYBIMM.cjs +51 -0
- package/dist/chunk-QMAKTSZB.cjs +48 -0
- package/dist/chunk-QT2VZNFA.js +29 -0
- package/dist/{chunk-3XJD56Z4.js → chunk-QUFAULH7.js} +9 -3
- package/dist/{chunk-RJP3SZ7Q.cjs → chunk-RD5XAJR2.cjs} +492 -309
- package/dist/chunk-RGR6ME5J.cjs +844 -0
- package/dist/{chunk-EOGKE5GD.cjs → chunk-RKJTGGMU.cjs} +221 -126
- package/dist/{chunk-NMGF2KUN.js → chunk-RO46YAPI.js} +1 -1
- package/dist/{chunk-2U5HFVRO.cjs → chunk-RVUQKMXX.cjs} +108 -0
- package/dist/chunk-S52YW5ZQ.js +844 -0
- package/dist/{chunk-ZLOTP56B.cjs → chunk-S6BDWWUG.cjs} +5 -5
- package/dist/{chunk-6DWXHBAY.js → chunk-SAHBLB3E.js} +222 -127
- package/dist/chunk-SALLHB2I.js +27 -0
- package/dist/{chunk-GIZL57FE.cjs → chunk-SEKD5FH3.cjs} +3 -1
- package/dist/{chunk-DZHR34H6.cjs → chunk-SHFA46CS.cjs} +8 -8
- package/dist/{chunk-MILZEEUV.js → chunk-SIHRD34Z.js} +2 -2
- package/dist/{chunk-BPTBKO7D.js → chunk-SO3QQJAZ.js} +216 -36
- package/dist/{chunk-HSPWX4Z2.cjs → chunk-SRQW3B6J.cjs} +223 -43
- package/dist/{chunk-MY3TZER2.js → chunk-T63AMO6H.js} +1 -1
- package/dist/{chunk-X765A7J5.js → chunk-TERCG25S.js} +1 -1
- package/dist/{chunk-WOGJXDBU.cjs → chunk-TFSRRZWP.cjs} +3 -3
- package/dist/{chunk-RRZS5A53.js → chunk-TQHOVHRS.js} +1 -1
- package/dist/{chunk-JHOQABEF.js → chunk-TWEKBHUO.js} +5 -5
- package/dist/chunk-U3WDY42C.cjs +42 -0
- package/dist/{chunk-CKN2BLHK.cjs → chunk-UBS46QL3.cjs} +2 -2
- package/dist/{chunk-H3GBSPK5.js → chunk-UGTFKUW4.js} +14 -6
- package/dist/chunk-UJTCTTUF.cjs +271 -0
- package/dist/{chunk-RUZB43HU.cjs → chunk-UTI6ZQEY.cjs} +22 -14
- package/dist/{chunk-OLG7LZBD.js → chunk-VG34MG2U.js} +1 -1
- package/dist/{chunk-ZKZRFH37.cjs → chunk-VJYPP6PP.cjs} +6 -6
- package/dist/{chunk-YHGTBPEC.js → chunk-VNQ5GL34.js} +1 -1
- package/dist/{chunk-XDVG3NM4.js → chunk-W3X6PAC7.js} +2 -48
- package/dist/{chunk-FK2DVRPJ.js → chunk-WFUUXADU.js} +2 -2
- package/dist/{chunk-R5OO7MEB.cjs → chunk-WGTJOIB7.cjs} +22 -22
- package/dist/{chunk-VHBUKGRG.js → chunk-WJDPVW7T.js} +4 -4
- package/dist/chunk-WNUVPKBW.js +42 -0
- package/dist/{chunk-EV53SLSB.cjs → chunk-WPVWQSL7.cjs} +4 -4
- package/dist/chunk-WQ3VJXZB.js +118 -0
- package/dist/chunk-WTNBX2JO.js +271 -0
- package/dist/chunk-XAV24VYN.js +48 -0
- package/dist/chunk-XDLH4EDL.cjs +118 -0
- package/dist/{chunk-U7CZFKPL.cjs → chunk-XMNHZRUB.cjs} +2 -2
- package/dist/chunk-XUDSXGGV.cjs +1822 -0
- package/dist/{chunk-WQUQ5JMM.js → chunk-XWASJ2QL.js} +4 -4
- package/dist/chunk-Y2SXUCNJ.js +55 -0
- package/dist/{chunk-AIH6GUGB.cjs → chunk-YDCDGTK6.cjs} +5 -5
- package/dist/chunk-YFXTE422.cjs +92 -0
- package/dist/chunk-YKS55CMT.js +1822 -0
- package/dist/{chunk-KC5FPUOF.cjs → chunk-YRLYSQEQ.cjs} +2 -2
- package/dist/{chunk-JWPI6O5Z.js → chunk-YS34SVY5.js} +31 -4
- package/dist/{chunk-FEVHH525.cjs → chunk-YYB42DCU.cjs} +4 -4
- package/dist/chunk-ZK6HOR62.js +92 -0
- package/dist/{chunk-BHV7CBNT.js → chunk-ZSE42BRE.js} +1 -1
- package/dist/clear-ES5WCZRF.cjs +12 -0
- package/dist/clear-J7XS6T5W.js +12 -0
- package/dist/completion-XQTDTJLK.cjs +14 -0
- package/dist/completion-XR6ZONJQ.js +14 -0
- package/dist/config-2TB3A55J.js +18 -0
- package/dist/config-RDMVIV26.cjs +18 -0
- package/dist/constants-6CPCJ3DY.cjs +21 -0
- package/dist/{constants-V6J54N3X.js → constants-UFM5B232.js} +2 -1
- package/dist/{defaultHooks-WLMRQUXG.cjs → defaultHooks-RCXPHF4M.cjs} +3 -1
- package/dist/{defaultHooks-R56VYG7I.js → defaultHooks-RDRMER3Z.js} +2 -0
- package/dist/export-EWAYH353.cjs +12 -0
- package/dist/export-ZWA6XGVS.js +12 -0
- package/dist/extractSessionMemories-SDW2MVBQ.cjs +7 -0
- package/dist/extractSessionMemories-V7K42ZHW.js +7 -0
- package/dist/feedback-5RV6ODW4.js +15 -0
- package/dist/feedback-ZPITHFJR.cjs +15 -0
- package/dist/filesystem-3SGCW2BF.js +10 -0
- package/dist/filesystem-MCFXJQ6R.cjs +10 -0
- package/dist/formatters-6K7QVWQL.cjs +10 -0
- package/dist/formatters-DQHO5I36.js +10 -0
- package/dist/{help-LKKQU2TN.js → help-I5GRCA3S.js} +3 -2
- package/dist/help-X52PZM24.cjs +12 -0
- package/dist/history-4WIOZ4TW.cjs +14 -0
- package/dist/{history-AV4XBFRK.js → history-OCHJBJW7.js} +3 -2
- package/dist/hooks-IAVTXUAI.cjs +13 -0
- package/dist/hooks-YF6HL23E.js +13 -0
- package/dist/{i18n-BSAPXM56.js → i18n-KHBXUALK.js} +2 -1
- package/dist/i18n-MVQIAZWS.cjs +33 -0
- package/dist/ide-4R3BEBIS.js +12 -0
- package/dist/ide-C7WSPQTR.cjs +12 -0
- package/dist/import-2ICSKDL7.cjs +10 -0
- package/dist/import-EAAX5HJR.js +170 -0
- package/dist/import-KRVVYJCZ.js +10 -0
- package/dist/import-PQJPNXA4.cjs +170 -0
- package/dist/index.cjs +7503 -11251
- package/dist/index.js +8735 -12483
- package/dist/init-6K3NRDOM.js +10 -0
- package/dist/init-AOUGGITS.cjs +10 -0
- package/dist/language-Q7YFDVSR.cjs +18 -0
- package/dist/language-Y6ZC7LET.js +18 -0
- package/dist/{lint-44UQJ673.cjs → lint-D5UOJWIK.cjs} +1 -0
- package/dist/{lint-TA2ZHVLM.js → lint-NJPZWVN2.js} +1 -0
- package/dist/{localProjectPermissions-WQYMGI42.js → localProjectPermissions-N77HA3XK.js} +3 -2
- package/dist/localProjectPermissions-UFSMNTBJ.cjs +18 -0
- package/dist/login-6OAH2NEH.cjs +20 -0
- package/dist/login-DL3377MD.js +20 -0
- package/dist/logout-ELQBUMTU.cjs +18 -0
- package/dist/logout-TLYA5W45.js +18 -0
- package/dist/mcp-BHOIBYUB.js +18 -0
- package/dist/mcp-TNUEXR5T.cjs +18 -0
- package/dist/{mcp-install-2KVKRAMQ.cjs → mcp-install-GROTZHAW.cjs} +26 -14
- package/dist/{mcp-install-77UXRN6R.js → mcp-install-KSADVDBE.js} +21 -9
- package/dist/memory-6DRFA43C.js +10 -0
- package/dist/memory-IORZE6WF.cjs +10 -0
- package/dist/message-JUBOK2VU.js +9 -0
- package/dist/message-ZJ5AYAMT.cjs +9 -0
- package/dist/model-CJPSPGIC.cjs +10 -0
- package/dist/model-MQXC56ES.js +10 -0
- package/dist/new-7D2B7IWM.cjs +12 -0
- package/dist/new-7VYM36RC.js +12 -0
- package/dist/{patch-BAAQIYSW.js → patch-5F6VBIT3.js} +2 -0
- package/dist/{patch-J32X2QQP.cjs → patch-MOD7QC3D.cjs} +3 -1
- package/dist/permissions-MM77OSFO.js +13 -0
- package/dist/permissions-W2F62DJ6.cjs +13 -0
- package/dist/{plan-JFGNRL2S.js → plan-G5CEKJI4.js} +1 -0
- package/dist/{plan-B3CW5DXJ.cjs → plan-QKOHE3LH.cjs} +1 -0
- package/dist/quit-7D2RDGTD.cjs +10 -0
- package/dist/quit-PKBSEJOL.js +10 -0
- package/dist/registry-A5XLMQVC.cjs +1828 -0
- package/dist/registry-WQLWHOLY.js +1828 -0
- package/dist/resume-FBKXSDOA.js +13 -0
- package/dist/resume-KLPDYPWQ.cjs +13 -0
- package/dist/search-7RNYTCNO.js +17 -0
- package/dist/search-UESMQZC3.cjs +17 -0
- package/dist/{session-T3TAZ5ZU.cjs → session-BSU2L5UI.cjs} +1 -0
- package/dist/{session-H5QWKE5E.js → session-SZMRN5KG.js} +1 -0
- package/dist/sessions-TSSUFWIJ.cjs +10 -0
- package/dist/sessions-WAXBUQTU.js +10 -0
- package/dist/settings-D6JXX5RG.js +30 -0
- package/dist/settings-RKYGXKDG.cjs +30 -0
- package/dist/share-GLX4YHS4.cjs +14 -0
- package/dist/share-U2M2KBFJ.js +14 -0
- package/dist/skills-63QLZMUO.cjs +14 -0
- package/dist/{skills-LJZA6PVJ.js → skills-BAMMXP3Q.js} +3 -2
- package/dist/{skills-install-MQINL3EC.js → skills-install-QNQWC2MV.js} +99 -28
- package/dist/{skills-install-IKJZN4G2.cjs → skills-install-UMK5H3SO.cjs} +107 -36
- package/dist/skills-new-NYKNHJHV.cjs +15 -0
- package/dist/skills-new-NZFGFKML.js +15 -0
- package/dist/slashCommands-EJ23C3Z4.cjs +69 -0
- package/dist/slashCommands-JQIL4EWX.js +69 -0
- package/dist/status-BKC7GBNQ.js +11 -0
- package/dist/status-FU3CPJWQ.cjs +11 -0
- package/dist/sync-3IEIHXIP.cjs +18 -0
- package/dist/sync-7JMZVEQD.cjs +40 -0
- package/dist/{sync-EXYX7HXW.js → sync-KWX67OUN.js} +3 -2
- package/dist/sync-YVPFT7SL.js +18 -0
- package/dist/tasks-5FPBIFLC.js +9 -0
- package/dist/tasks-TXGKGNH6.cjs +9 -0
- package/dist/team-GVK5L73L.cjs +9 -0
- package/dist/team-RWIKCLTG.js +9 -0
- package/dist/teammate-3C4MLRGH.js +139 -0
- package/dist/teammate-7C3UDQSH.cjs +139 -0
- package/dist/theme-A2CEHI7W.js +18 -0
- package/dist/theme-LNOQOVR4.cjs +18 -0
- package/dist/ui/questionModal.cjs +7 -25
- package/dist/ui/questionModal.js +6 -24
- package/dist/undo-F2IZJQUV.js +10 -0
- package/dist/undo-QEV42XLU.cjs +10 -0
- package/dist/update-TVAJMMBC.js +82 -0
- package/dist/update-Z6BIIQDC.cjs +82 -0
- package/package.json +9 -3
- package/dist/CommunitySkillsCache-ILWHWE5P.js +0 -7
- package/dist/CommunitySkillsCache-KHC6RUJW.cjs +0 -7
- package/dist/HookManager-X47HCM5G.cjs +0 -6
- package/dist/HookManager-ZXKHCD7U.js +0 -6
- package/dist/MemoryManager-6ZT7IDO5.cjs +0 -7
- package/dist/MemoryManager-AJGS5AKB.js +0 -7
- package/dist/PermissionManager-HG6W2DGU.cjs +0 -10
- package/dist/SessionManager-BJ2G6VV4.cjs +0 -9
- package/dist/SessionManager-ENPGYK5J.js +0 -9
- package/dist/SkillsRegistry-6ZFOCT25.cjs +0 -8
- package/dist/SkillsRegistry-C2SHOZ5D.js +0 -8
- package/dist/about-3BJTNSLK.js +0 -11
- package/dist/about-EABQNJGV.cjs +0 -11
- package/dist/add-dir-7FD4DMDA.cjs +0 -9
- package/dist/add-dir-LOYJ4YB5.js +0 -9
- package/dist/agents-2Y6ASV7C.js +0 -10
- package/dist/agents-UOSPKLQL.cjs +0 -10
- package/dist/agents-new-23NSGAM5.js +0 -13
- package/dist/agents-new-WI2EL7IJ.cjs +0 -13
- package/dist/automode-LGWTY3UX.js +0 -9
- package/dist/automode-WLBQ7MN7.cjs +0 -9
- package/dist/chunk-5UBW2BGC.js +0 -33
- package/dist/chunk-I6DBWNLN.cjs +0 -169
- package/dist/chunk-IZBCMJHJ.cjs +0 -33
- package/dist/completion-7WGMHKOR.cjs +0 -13
- package/dist/completion-KH33NSGP.js +0 -13
- package/dist/constants-RBQTR32A.cjs +0 -20
- package/dist/export-3QN3IH7A.js +0 -11
- package/dist/export-BI54X3MP.cjs +0 -11
- package/dist/feedback-CI4OIPOS.cjs +0 -14
- package/dist/feedback-GFPL5STE.js +0 -14
- package/dist/formatters-N5IJKYZY.cjs +0 -8
- package/dist/formatters-UG6VZJJ5.js +0 -8
- package/dist/help-CWMUGD3V.cjs +0 -11
- package/dist/history-73VBEMSI.cjs +0 -13
- package/dist/hooks-62UDQBGH.cjs +0 -12
- package/dist/hooks-XORDJD5X.js +0 -12
- package/dist/i18n-X2IU2EZD.cjs +0 -32
- package/dist/ide-RPKZALQV.js +0 -11
- package/dist/ide-YMNXJB6A.cjs +0 -11
- package/dist/init-J5HR4R7U.js +0 -9
- package/dist/init-JCC7RVMC.cjs +0 -9
- package/dist/language-AZISJCEZ.js +0 -16
- package/dist/language-F65RA6FZ.cjs +0 -16
- package/dist/localProjectPermissions-2EATUDZM.cjs +0 -17
- package/dist/login-5HLPMECE.js +0 -18
- package/dist/login-ISWYYBXP.cjs +0 -18
- package/dist/logout-3EKZM5J3.cjs +0 -16
- package/dist/logout-GE7TSZ24.js +0 -16
- package/dist/mcp-EW64QRFA.cjs +0 -15
- package/dist/mcp-VHS7AMF2.js +0 -15
- package/dist/memory-2I473RU3.js +0 -9
- package/dist/memory-JZ6NPSP3.cjs +0 -9
- package/dist/model-GXZLARPT.js +0 -9
- package/dist/model-Y274DBDO.cjs +0 -9
- package/dist/new-BG5VIGZ7.cjs +0 -9
- package/dist/new-YXFDQOA7.js +0 -9
- package/dist/permissions-QILEAGBP.cjs +0 -12
- package/dist/permissions-WVEOVMWO.js +0 -12
- package/dist/quit-NC32OEJG.cjs +0 -9
- package/dist/quit-WRRIGU33.js +0 -9
- package/dist/resume-GJIKIDPR.cjs +0 -12
- package/dist/resume-RMJNCAOK.js +0 -12
- package/dist/search-UIWIXB73.js +0 -14
- package/dist/search-WQNXDA2E.cjs +0 -14
- package/dist/sessions-HPFX2GDD.js +0 -9
- package/dist/sessions-SAQU6MFA.cjs +0 -9
- package/dist/share-2WH5ZVOO.cjs +0 -13
- package/dist/share-PSSWWVV5.js +0 -13
- package/dist/skills-YTYGART7.cjs +0 -13
- package/dist/skills-new-3WCU3CWB.js +0 -14
- package/dist/skills-new-O5LFVFZU.cjs +0 -14
- package/dist/slashCommands-7IRDOXOQ.cjs +0 -55
- package/dist/slashCommands-C6CAQA25.js +0 -55
- package/dist/status-4EDV2LSY.cjs +0 -10
- package/dist/status-NU7TJDCE.js +0 -10
- package/dist/sync-3GFSEIAZ.js +0 -16
- package/dist/sync-6M3WRKMH.cjs +0 -39
- package/dist/sync-CQNQDNTJ.cjs +0 -16
- package/dist/theme-EMJGULMI.cjs +0 -16
- package/dist/theme-FGDSXNU3.js +0 -16
- package/dist/undo-CTXQYE7C.cjs +0 -9
- package/dist/undo-HX2ZMECP.js +0 -9
|
@@ -0,0 +1,1828 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
var _chunkSEKD5FH3cjs = require('./chunk-SEKD5FH3.cjs');
|
|
4
|
+
require('./chunk-N254NRHT.cjs');
|
|
5
|
+
|
|
6
|
+
// src/import/importers/ClaudeImporter.ts
|
|
7
|
+
var _path = require('path'); var _path2 = _interopRequireDefault(_path);
|
|
8
|
+
var _fsextra = require('fs-extra'); var _fsextra2 = _interopRequireDefault(_fsextra);
|
|
9
|
+
|
|
10
|
+
// src/import/importers/BaseImporter.ts
|
|
11
|
+
var _os = require('os'); var _os2 = _interopRequireDefault(_os);
|
|
12
|
+
|
|
13
|
+
var _crypto = require('crypto'); var _crypto2 = _interopRequireDefault(_crypto);
|
|
14
|
+
|
|
15
|
+
var BaseImporter = class {
|
|
16
|
+
// ---------------------------------------------------------------
|
|
17
|
+
// Resolved home path
|
|
18
|
+
// ---------------------------------------------------------------
|
|
19
|
+
/**
|
|
20
|
+
* Expands a `~/` prefix to the user's home directory.
|
|
21
|
+
* Returns absolute paths unchanged.
|
|
22
|
+
*/
|
|
23
|
+
get resolvedHomePath() {
|
|
24
|
+
if (this.homePath.startsWith("~/") || this.homePath === "~") {
|
|
25
|
+
return _path2.default.join(_os2.default.homedir(), this.homePath.slice(2));
|
|
26
|
+
}
|
|
27
|
+
return this.homePath;
|
|
28
|
+
}
|
|
29
|
+
// ---------------------------------------------------------------
|
|
30
|
+
// Detection
|
|
31
|
+
// ---------------------------------------------------------------
|
|
32
|
+
/**
|
|
33
|
+
* Checks whether this agent's data directory exists on disk.
|
|
34
|
+
*/
|
|
35
|
+
async detect() {
|
|
36
|
+
return _fsextra2.default.pathExists(this.resolvedHomePath);
|
|
37
|
+
}
|
|
38
|
+
// ---------------------------------------------------------------
|
|
39
|
+
// JSONL reader
|
|
40
|
+
// ---------------------------------------------------------------
|
|
41
|
+
/**
|
|
42
|
+
* Reads a JSONL file and returns an array of parsed records.
|
|
43
|
+
* Blank lines and malformed JSON lines are silently skipped.
|
|
44
|
+
*/
|
|
45
|
+
async readJsonlFile(filePath) {
|
|
46
|
+
const content = await _fsextra2.default.readFile(filePath, "utf-8");
|
|
47
|
+
const records = [];
|
|
48
|
+
for (const line of content.split("\n")) {
|
|
49
|
+
const trimmed = line.trim();
|
|
50
|
+
if (!trimmed) continue;
|
|
51
|
+
try {
|
|
52
|
+
records.push(JSON.parse(trimmed));
|
|
53
|
+
} catch (e2) {
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return records;
|
|
57
|
+
}
|
|
58
|
+
// ---------------------------------------------------------------
|
|
59
|
+
// Retry with exponential backoff
|
|
60
|
+
// ---------------------------------------------------------------
|
|
61
|
+
/**
|
|
62
|
+
* Retries `fn` up to `maxRetries` times with exponential backoff.
|
|
63
|
+
* Throws the last error if all retries are exhausted.
|
|
64
|
+
*/
|
|
65
|
+
async withRetry(fn, maxRetries = 3, baseDelay = 1e3) {
|
|
66
|
+
let lastError;
|
|
67
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
68
|
+
try {
|
|
69
|
+
return await fn();
|
|
70
|
+
} catch (err) {
|
|
71
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
72
|
+
if (attempt < maxRetries - 1) {
|
|
73
|
+
await this.delay(baseDelay * Math.pow(2, attempt));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
throw lastError;
|
|
78
|
+
}
|
|
79
|
+
// ---------------------------------------------------------------
|
|
80
|
+
// Session writing
|
|
81
|
+
// ---------------------------------------------------------------
|
|
82
|
+
/**
|
|
83
|
+
* Creates a new Autohand session directory with metadata and conversation data.
|
|
84
|
+
* Returns the generated session ID, or `null` if the session was already imported
|
|
85
|
+
* (deduplication by source + originalId).
|
|
86
|
+
*/
|
|
87
|
+
async writeAutohandSession(opts) {
|
|
88
|
+
if (await this.isAlreadyImported(opts.source, opts.originalId)) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const timestamp = Date.now();
|
|
92
|
+
const uuid = _crypto2.default.randomUUID();
|
|
93
|
+
const sessionId = `${uuid}-${timestamp}`;
|
|
94
|
+
const sessionDir = _path2.default.join(_chunkSEKD5FH3cjs.AUTOHAND_PATHS.sessions, sessionId);
|
|
95
|
+
await _fsextra2.default.ensureDir(sessionDir);
|
|
96
|
+
const metadata = {
|
|
97
|
+
sessionId,
|
|
98
|
+
createdAt: opts.createdAt,
|
|
99
|
+
lastActiveAt: _nullishCoalesce(opts.closedAt, () => ( opts.createdAt)),
|
|
100
|
+
closedAt: opts.closedAt,
|
|
101
|
+
projectPath: opts.projectPath,
|
|
102
|
+
projectName: opts.projectName,
|
|
103
|
+
model: opts.model,
|
|
104
|
+
messageCount: opts.messages.length,
|
|
105
|
+
summary: opts.summary,
|
|
106
|
+
status: _nullishCoalesce(opts.status, () => ( "completed")),
|
|
107
|
+
importedFrom: {
|
|
108
|
+
source: opts.source,
|
|
109
|
+
originalId: opts.originalId,
|
|
110
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
await _fsextra2.default.writeJson(_path2.default.join(sessionDir, "metadata.json"), metadata, { spaces: 2 });
|
|
114
|
+
const jsonl = opts.messages.map((msg) => JSON.stringify(msg)).join("\n") + "\n";
|
|
115
|
+
await _fsextra2.default.writeFile(_path2.default.join(sessionDir, "conversation.jsonl"), jsonl, "utf-8");
|
|
116
|
+
await this.updateSessionIndex(metadata);
|
|
117
|
+
return sessionId;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Checks whether a session from `source` with `originalId` was already imported.
|
|
121
|
+
* Uses the session index for O(n) lookup with `importedFrom` field.
|
|
122
|
+
*/
|
|
123
|
+
async isAlreadyImported(source, originalId) {
|
|
124
|
+
const indexPath = _path2.default.join(_chunkSEKD5FH3cjs.AUTOHAND_PATHS.sessions, "index.json");
|
|
125
|
+
if (!await _fsextra2.default.pathExists(indexPath)) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const loaded = await _fsextra2.default.readJson(indexPath);
|
|
130
|
+
if (!loaded || !Array.isArray(loaded.sessions)) return false;
|
|
131
|
+
return loaded.sessions.some(
|
|
132
|
+
(s) => _optionalChain([s, 'access', _ => _.importedFrom, 'optionalAccess', _2 => _2.source]) === source && _optionalChain([s, 'access', _3 => _3.importedFrom, 'optionalAccess', _4 => _4.originalId]) === originalId
|
|
133
|
+
);
|
|
134
|
+
} catch (e3) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// ---------------------------------------------------------------
|
|
139
|
+
// Session index management
|
|
140
|
+
// ---------------------------------------------------------------
|
|
141
|
+
/**
|
|
142
|
+
* Adds a session entry to `~/.autohand/sessions/index.json`.
|
|
143
|
+
* Creates the file if it does not exist.
|
|
144
|
+
*/
|
|
145
|
+
async updateSessionIndex(metadata) {
|
|
146
|
+
const indexPath = _path2.default.join(_chunkSEKD5FH3cjs.AUTOHAND_PATHS.sessions, "index.json");
|
|
147
|
+
let index = { sessions: [], byProject: {} };
|
|
148
|
+
if (await _fsextra2.default.pathExists(indexPath)) {
|
|
149
|
+
try {
|
|
150
|
+
const loaded = await _fsextra2.default.readJson(indexPath);
|
|
151
|
+
if (loaded && typeof loaded === "object" && Array.isArray(loaded.sessions) && loaded.byProject && typeof loaded.byProject === "object") {
|
|
152
|
+
index = loaded;
|
|
153
|
+
}
|
|
154
|
+
} catch (e4) {
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const entry = {
|
|
158
|
+
id: metadata.sessionId,
|
|
159
|
+
projectPath: metadata.projectPath,
|
|
160
|
+
createdAt: metadata.createdAt,
|
|
161
|
+
summary: metadata.summary
|
|
162
|
+
};
|
|
163
|
+
if (metadata.importedFrom) {
|
|
164
|
+
entry.importedFrom = {
|
|
165
|
+
source: metadata.importedFrom.source,
|
|
166
|
+
originalId: metadata.importedFrom.originalId
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
index.sessions.push(entry);
|
|
170
|
+
if (!index.byProject[metadata.projectPath]) {
|
|
171
|
+
index.byProject[metadata.projectPath] = [];
|
|
172
|
+
}
|
|
173
|
+
index.byProject[metadata.projectPath].push(metadata.sessionId);
|
|
174
|
+
await _fsextra2.default.ensureDir(_chunkSEKD5FH3cjs.AUTOHAND_PATHS.sessions);
|
|
175
|
+
await _fsextra2.default.writeJson(indexPath, index, { spaces: 2 });
|
|
176
|
+
}
|
|
177
|
+
// ---------------------------------------------------------------
|
|
178
|
+
// Utility
|
|
179
|
+
// ---------------------------------------------------------------
|
|
180
|
+
/**
|
|
181
|
+
* Safely read and parse a JSON file with pre-validation.
|
|
182
|
+
* Returns the parsed data, or throws with a descriptive error message.
|
|
183
|
+
* Handles empty files, corrupted JSON, and non-object content gracefully.
|
|
184
|
+
*/
|
|
185
|
+
async safeReadJson(filePath) {
|
|
186
|
+
const content = await _fsextra2.default.readFile(filePath, "utf-8");
|
|
187
|
+
if (!content.trim()) {
|
|
188
|
+
throw new Error(`File is empty: ${_path2.default.basename(filePath)}`);
|
|
189
|
+
}
|
|
190
|
+
try {
|
|
191
|
+
const parsed = JSON.parse(content);
|
|
192
|
+
return parsed;
|
|
193
|
+
} catch (err) {
|
|
194
|
+
throw new Error(
|
|
195
|
+
`Invalid JSON in ${_path2.default.basename(filePath)}: ${err instanceof Error ? err.message : String(err)}`
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Simple promise-based delay.
|
|
201
|
+
*/
|
|
202
|
+
delay(ms) {
|
|
203
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// src/import/importers/ClaudeImporter.ts
|
|
208
|
+
var ClaudeImporter = class extends BaseImporter {
|
|
209
|
+
constructor() {
|
|
210
|
+
super(...arguments);
|
|
211
|
+
this.name = "claude";
|
|
212
|
+
this.displayName = "Claude Code";
|
|
213
|
+
this.homePath = "~/.claude";
|
|
214
|
+
}
|
|
215
|
+
// ---------------------------------------------------------------
|
|
216
|
+
// scan()
|
|
217
|
+
// ---------------------------------------------------------------
|
|
218
|
+
async scan() {
|
|
219
|
+
const available = /* @__PURE__ */ new Map();
|
|
220
|
+
const home = this.resolvedHomePath;
|
|
221
|
+
if (!await _fsextra2.default.pathExists(home)) {
|
|
222
|
+
return { source: this.name, available };
|
|
223
|
+
}
|
|
224
|
+
const projectsDir = _path2.default.join(home, "projects");
|
|
225
|
+
let sessionCount = 0;
|
|
226
|
+
let memoryCount = 0;
|
|
227
|
+
if (await _fsextra2.default.pathExists(projectsDir)) {
|
|
228
|
+
const entries = await _fsextra2.default.readdir(projectsDir, { withFileTypes: true });
|
|
229
|
+
const projectDirs = entries.filter((e) => e.isDirectory());
|
|
230
|
+
for (const dir of projectDirs) {
|
|
231
|
+
const projectDir = _path2.default.join(projectsDir, dir.name);
|
|
232
|
+
const projectEntries = await _fsextra2.default.readdir(projectDir, { withFileTypes: true });
|
|
233
|
+
const jsonlFiles = projectEntries.filter((e) => e.isFile() && e.name.endsWith(".jsonl"));
|
|
234
|
+
sessionCount += jsonlFiles.length;
|
|
235
|
+
const hasMemoryDir = await _fsextra2.default.pathExists(_path2.default.join(projectDir, "memory"));
|
|
236
|
+
const hasClaudeMd = await _fsextra2.default.pathExists(_path2.default.join(projectDir, "CLAUDE.md"));
|
|
237
|
+
if (hasMemoryDir || hasClaudeMd) {
|
|
238
|
+
memoryCount++;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (sessionCount > 0) {
|
|
243
|
+
available.set("sessions", {
|
|
244
|
+
count: sessionCount,
|
|
245
|
+
description: `${sessionCount} session file${sessionCount !== 1 ? "s" : ""} across project directories`
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
const settingsPath = _path2.default.join(home, "settings.json");
|
|
249
|
+
if (await _fsextra2.default.pathExists(settingsPath)) {
|
|
250
|
+
available.set("settings", { count: 1, description: "Claude Code settings.json" });
|
|
251
|
+
}
|
|
252
|
+
const skillsDir = _path2.default.join(home, "skills");
|
|
253
|
+
if (await _fsextra2.default.pathExists(skillsDir)) {
|
|
254
|
+
const skillEntries = await _fsextra2.default.readdir(skillsDir, { withFileTypes: true });
|
|
255
|
+
const skillFiles = skillEntries.filter((e) => e.isFile());
|
|
256
|
+
if (skillFiles.length > 0) {
|
|
257
|
+
available.set("skills", {
|
|
258
|
+
count: skillFiles.length,
|
|
259
|
+
description: `${skillFiles.length} skill file${skillFiles.length !== 1 ? "s" : ""}`
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (memoryCount > 0) {
|
|
264
|
+
available.set("memory", {
|
|
265
|
+
count: memoryCount,
|
|
266
|
+
description: `${memoryCount} project${memoryCount !== 1 ? "s" : ""} with memory data`
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return { source: this.name, available };
|
|
270
|
+
}
|
|
271
|
+
// ---------------------------------------------------------------
|
|
272
|
+
// import()
|
|
273
|
+
// ---------------------------------------------------------------
|
|
274
|
+
async import(categories, onProgress) {
|
|
275
|
+
const start = Date.now();
|
|
276
|
+
const imported = /* @__PURE__ */ new Map();
|
|
277
|
+
const errors = [];
|
|
278
|
+
for (const category of categories) {
|
|
279
|
+
switch (category) {
|
|
280
|
+
case "sessions":
|
|
281
|
+
await this.importSessions(imported, errors, onProgress);
|
|
282
|
+
break;
|
|
283
|
+
case "settings":
|
|
284
|
+
await this.importSettings(imported, errors, onProgress);
|
|
285
|
+
break;
|
|
286
|
+
case "skills":
|
|
287
|
+
await this.importSkills(imported, errors, onProgress);
|
|
288
|
+
break;
|
|
289
|
+
case "memory":
|
|
290
|
+
await this.importMemory(imported, errors, onProgress);
|
|
291
|
+
break;
|
|
292
|
+
default:
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return {
|
|
297
|
+
source: this.name,
|
|
298
|
+
imported,
|
|
299
|
+
errors,
|
|
300
|
+
duration: Date.now() - start
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
// ---------------------------------------------------------------
|
|
304
|
+
// Sessions
|
|
305
|
+
// ---------------------------------------------------------------
|
|
306
|
+
async importSessions(imported, errors, onProgress) {
|
|
307
|
+
const home = this.resolvedHomePath;
|
|
308
|
+
const projectsDir = _path2.default.join(home, "projects");
|
|
309
|
+
let success = 0;
|
|
310
|
+
let failed = 0;
|
|
311
|
+
let skipped = 0;
|
|
312
|
+
const skipReasons = {};
|
|
313
|
+
const trackSkip = (reason) => {
|
|
314
|
+
skipped++;
|
|
315
|
+
skipReasons[reason] = (_nullishCoalesce(skipReasons[reason], () => ( 0))) + 1;
|
|
316
|
+
};
|
|
317
|
+
if (!await _fsextra2.default.pathExists(projectsDir)) {
|
|
318
|
+
imported.set("sessions", { success: 0, failed: 0, skipped: 0 });
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const projectEntries = await _fsextra2.default.readdir(projectsDir, { withFileTypes: true });
|
|
322
|
+
const projectDirs = projectEntries.filter((e) => e.isDirectory());
|
|
323
|
+
const allSessionFiles = [];
|
|
324
|
+
for (const dir of projectDirs) {
|
|
325
|
+
const projectDir = _path2.default.join(projectsDir, dir.name);
|
|
326
|
+
const entries = await _fsextra2.default.readdir(projectDir, { withFileTypes: true });
|
|
327
|
+
const jsonlFiles = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl"));
|
|
328
|
+
for (const f of jsonlFiles) {
|
|
329
|
+
allSessionFiles.push({
|
|
330
|
+
filePath: _path2.default.join(projectDir, f.name),
|
|
331
|
+
projectDirName: dir.name
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
const total = allSessionFiles.length;
|
|
336
|
+
for (let i = 0; i < allSessionFiles.length; i++) {
|
|
337
|
+
const { filePath, projectDirName } = allSessionFiles[i];
|
|
338
|
+
_optionalChain([onProgress, 'optionalCall', _5 => _5({
|
|
339
|
+
category: "sessions",
|
|
340
|
+
current: i + 1,
|
|
341
|
+
total,
|
|
342
|
+
item: _path2.default.basename(filePath),
|
|
343
|
+
status: "importing"
|
|
344
|
+
})]);
|
|
345
|
+
try {
|
|
346
|
+
const fileContent = await _fsextra2.default.readFile(filePath, "utf-8");
|
|
347
|
+
if (!fileContent.trim()) {
|
|
348
|
+
trackSkip("empty file");
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
const records = await this.readJsonlFile(filePath);
|
|
352
|
+
if (records.length === 0) {
|
|
353
|
+
trackSkip("no valid JSON records");
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
const events = records;
|
|
357
|
+
const relevantEvents = events.filter(
|
|
358
|
+
(e) => (e.type === "user" || e.type === "assistant") && !e.isMeta && e.message
|
|
359
|
+
);
|
|
360
|
+
if (relevantEvents.length === 0) {
|
|
361
|
+
trackSkip("no user/assistant messages");
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
const sessionGroups = /* @__PURE__ */ new Map();
|
|
365
|
+
for (const event of relevantEvents) {
|
|
366
|
+
const sid = _nullishCoalesce(event.sessionId, () => ( "unknown"));
|
|
367
|
+
if (!sessionGroups.has(sid)) {
|
|
368
|
+
sessionGroups.set(sid, []);
|
|
369
|
+
}
|
|
370
|
+
sessionGroups.get(sid).push(event);
|
|
371
|
+
}
|
|
372
|
+
for (const [sessionId, sessionEvents] of sessionGroups) {
|
|
373
|
+
const messages = sessionEvents.map((e) => ({
|
|
374
|
+
role: e.message.role,
|
|
375
|
+
content: this.extractContent(e.message.content),
|
|
376
|
+
timestamp: _nullishCoalesce(e.timestamp, () => ( (/* @__PURE__ */ new Date()).toISOString()))
|
|
377
|
+
}));
|
|
378
|
+
const firstEvent = sessionEvents[0];
|
|
379
|
+
const cwd = _nullishCoalesce(firstEvent.cwd, () => ( this.projectDirNameToPath(projectDirName)));
|
|
380
|
+
const model = _nullishCoalesce(this.extractModel(sessionEvents), () => ( "unknown"));
|
|
381
|
+
const projectName = _path2.default.basename(cwd);
|
|
382
|
+
const result = await this.writeAutohandSession({
|
|
383
|
+
projectPath: cwd,
|
|
384
|
+
projectName,
|
|
385
|
+
model,
|
|
386
|
+
messages,
|
|
387
|
+
source: this.name,
|
|
388
|
+
originalId: sessionId,
|
|
389
|
+
createdAt: messages[0].timestamp,
|
|
390
|
+
closedAt: messages[messages.length - 1].timestamp,
|
|
391
|
+
summary: this.buildSummary(messages),
|
|
392
|
+
status: "completed"
|
|
393
|
+
});
|
|
394
|
+
if (result === null) {
|
|
395
|
+
trackSkip("already imported");
|
|
396
|
+
} else {
|
|
397
|
+
success++;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
} catch (err) {
|
|
401
|
+
failed++;
|
|
402
|
+
errors.push({
|
|
403
|
+
category: "sessions",
|
|
404
|
+
item: _path2.default.basename(filePath),
|
|
405
|
+
error: err instanceof Error ? err.message : String(err),
|
|
406
|
+
retriable: true
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
imported.set("sessions", {
|
|
411
|
+
success,
|
|
412
|
+
failed,
|
|
413
|
+
skipped,
|
|
414
|
+
...Object.keys(skipReasons).length > 0 ? { skipReasons } : {}
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
// ---------------------------------------------------------------
|
|
418
|
+
// Settings
|
|
419
|
+
// ---------------------------------------------------------------
|
|
420
|
+
async importSettings(imported, errors, onProgress) {
|
|
421
|
+
const settingsPath = _path2.default.join(this.resolvedHomePath, "settings.json");
|
|
422
|
+
if (!await _fsextra2.default.pathExists(settingsPath)) {
|
|
423
|
+
imported.set("settings", { success: 0, failed: 0, skipped: 1 });
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
_optionalChain([onProgress, 'optionalCall', _6 => _6({
|
|
427
|
+
category: "settings",
|
|
428
|
+
current: 1,
|
|
429
|
+
total: 1,
|
|
430
|
+
item: "settings.json",
|
|
431
|
+
status: "importing"
|
|
432
|
+
})]);
|
|
433
|
+
try {
|
|
434
|
+
const settings = await this.safeReadJson(settingsPath);
|
|
435
|
+
const permissions = settings.permissions;
|
|
436
|
+
if (_optionalChain([permissions, 'optionalAccess', _7 => _7.allow])) {
|
|
437
|
+
const configDir = _chunkSEKD5FH3cjs.AUTOHAND_PATHS.config;
|
|
438
|
+
await _fsextra2.default.ensureDir(configDir);
|
|
439
|
+
const importedSettingsPath = _path2.default.join(configDir, "imported-claude-settings.json");
|
|
440
|
+
await _fsextra2.default.writeJson(importedSettingsPath, {
|
|
441
|
+
importedFrom: "claude",
|
|
442
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
443
|
+
permissions: permissions.allow,
|
|
444
|
+
raw: settings
|
|
445
|
+
}, { spaces: 2 });
|
|
446
|
+
}
|
|
447
|
+
imported.set("settings", { success: 1, failed: 0, skipped: 0 });
|
|
448
|
+
_optionalChain([onProgress, 'optionalCall', _8 => _8({
|
|
449
|
+
category: "settings",
|
|
450
|
+
current: 1,
|
|
451
|
+
total: 1,
|
|
452
|
+
item: "settings.json",
|
|
453
|
+
status: "done"
|
|
454
|
+
})]);
|
|
455
|
+
} catch (err) {
|
|
456
|
+
imported.set("settings", { success: 0, failed: 1, skipped: 0 });
|
|
457
|
+
errors.push({
|
|
458
|
+
category: "settings",
|
|
459
|
+
item: "settings.json",
|
|
460
|
+
error: err instanceof Error ? err.message : String(err),
|
|
461
|
+
retriable: false
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
// ---------------------------------------------------------------
|
|
466
|
+
// Skills
|
|
467
|
+
// ---------------------------------------------------------------
|
|
468
|
+
async importSkills(imported, errors, onProgress) {
|
|
469
|
+
const skillsDir = _path2.default.join(this.resolvedHomePath, "skills");
|
|
470
|
+
if (!await _fsextra2.default.pathExists(skillsDir)) {
|
|
471
|
+
imported.set("skills", { success: 0, failed: 0, skipped: 1 });
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
const entries = await _fsextra2.default.readdir(skillsDir, { withFileTypes: true });
|
|
475
|
+
const skillFiles = entries.filter((e) => e.isFile());
|
|
476
|
+
let success = 0;
|
|
477
|
+
let failed = 0;
|
|
478
|
+
const total = skillFiles.length;
|
|
479
|
+
const destDir = _path2.default.join(_chunkSEKD5FH3cjs.AUTOHAND_PATHS.skills, "imported-claude");
|
|
480
|
+
for (let i = 0; i < skillFiles.length; i++) {
|
|
481
|
+
const file = skillFiles[i];
|
|
482
|
+
const src = _path2.default.join(skillsDir, file.name);
|
|
483
|
+
const dest = _path2.default.join(destDir, file.name);
|
|
484
|
+
_optionalChain([onProgress, 'optionalCall', _9 => _9({
|
|
485
|
+
category: "skills",
|
|
486
|
+
current: i + 1,
|
|
487
|
+
total,
|
|
488
|
+
item: file.name,
|
|
489
|
+
status: "importing"
|
|
490
|
+
})]);
|
|
491
|
+
try {
|
|
492
|
+
await _fsextra2.default.ensureDir(destDir);
|
|
493
|
+
await _fsextra2.default.copy(src, dest);
|
|
494
|
+
success++;
|
|
495
|
+
} catch (err) {
|
|
496
|
+
failed++;
|
|
497
|
+
errors.push({
|
|
498
|
+
category: "skills",
|
|
499
|
+
item: file.name,
|
|
500
|
+
error: err instanceof Error ? err.message : String(err),
|
|
501
|
+
retriable: true
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
imported.set("skills", { success, failed, skipped: 0 });
|
|
506
|
+
}
|
|
507
|
+
// ---------------------------------------------------------------
|
|
508
|
+
// Memory
|
|
509
|
+
// ---------------------------------------------------------------
|
|
510
|
+
async importMemory(imported, errors, onProgress) {
|
|
511
|
+
const projectsDir = _path2.default.join(this.resolvedHomePath, "projects");
|
|
512
|
+
let success = 0;
|
|
513
|
+
let failed = 0;
|
|
514
|
+
if (!await _fsextra2.default.pathExists(projectsDir)) {
|
|
515
|
+
imported.set("memory", { success: 0, failed: 0, skipped: 0 });
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
const entries = await _fsextra2.default.readdir(projectsDir, { withFileTypes: true });
|
|
519
|
+
const projectDirs = entries.filter((e) => e.isDirectory());
|
|
520
|
+
const total = projectDirs.length;
|
|
521
|
+
for (let i = 0; i < projectDirs.length; i++) {
|
|
522
|
+
const dir = projectDirs[i];
|
|
523
|
+
const projectDir = _path2.default.join(projectsDir, dir.name);
|
|
524
|
+
const hasMemoryDir = await _fsextra2.default.pathExists(_path2.default.join(projectDir, "memory"));
|
|
525
|
+
const hasClaudeMd = await _fsextra2.default.pathExists(_path2.default.join(projectDir, "CLAUDE.md"));
|
|
526
|
+
if (!hasMemoryDir && !hasClaudeMd) {
|
|
527
|
+
continue;
|
|
528
|
+
}
|
|
529
|
+
_optionalChain([onProgress, 'optionalCall', _10 => _10({
|
|
530
|
+
category: "memory",
|
|
531
|
+
current: i + 1,
|
|
532
|
+
total,
|
|
533
|
+
item: dir.name,
|
|
534
|
+
status: "importing"
|
|
535
|
+
})]);
|
|
536
|
+
try {
|
|
537
|
+
const projectHash = dir.name.replace(/[^a-zA-Z0-9-]/g, "_");
|
|
538
|
+
const destDir = _path2.default.join(_chunkSEKD5FH3cjs.AUTOHAND_PATHS.projects, projectHash, "imported-claude");
|
|
539
|
+
await _fsextra2.default.ensureDir(destDir);
|
|
540
|
+
if (hasMemoryDir) {
|
|
541
|
+
await _fsextra2.default.copy(_path2.default.join(projectDir, "memory"), _path2.default.join(destDir, "memory"));
|
|
542
|
+
}
|
|
543
|
+
if (hasClaudeMd) {
|
|
544
|
+
await _fsextra2.default.copy(_path2.default.join(projectDir, "CLAUDE.md"), _path2.default.join(destDir, "CLAUDE.md"));
|
|
545
|
+
}
|
|
546
|
+
success++;
|
|
547
|
+
} catch (err) {
|
|
548
|
+
failed++;
|
|
549
|
+
errors.push({
|
|
550
|
+
category: "memory",
|
|
551
|
+
item: dir.name,
|
|
552
|
+
error: err instanceof Error ? err.message : String(err),
|
|
553
|
+
retriable: true
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
imported.set("memory", { success, failed, skipped: 0 });
|
|
558
|
+
}
|
|
559
|
+
// ---------------------------------------------------------------
|
|
560
|
+
// Helpers
|
|
561
|
+
// ---------------------------------------------------------------
|
|
562
|
+
/**
|
|
563
|
+
* Extract text content from a Claude message content field.
|
|
564
|
+
* Content can be a string or an array of content blocks.
|
|
565
|
+
*/
|
|
566
|
+
extractContent(content) {
|
|
567
|
+
if (typeof content === "string") {
|
|
568
|
+
return content;
|
|
569
|
+
}
|
|
570
|
+
if (Array.isArray(content)) {
|
|
571
|
+
return content.filter((block) => block.type === "text" && block.text).map((block) => block.text).join("");
|
|
572
|
+
}
|
|
573
|
+
return "";
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Extract the model name from session events. Takes the first found model.
|
|
577
|
+
*/
|
|
578
|
+
extractModel(events) {
|
|
579
|
+
for (const event of events) {
|
|
580
|
+
if (_optionalChain([event, 'access', _11 => _11.message, 'optionalAccess', _12 => _12.model])) {
|
|
581
|
+
return event.message.model;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
return void 0;
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Convert a project directory name (e.g. "-Users-me-project") to a path.
|
|
588
|
+
*/
|
|
589
|
+
projectDirNameToPath(dirName) {
|
|
590
|
+
return "/" + dirName.replace(/^-/, "").replace(/-/g, "/");
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Build a brief summary from the first real user message.
|
|
594
|
+
* Skips system-injected context (XML tags, CLAUDE.md, etc.)
|
|
595
|
+
*/
|
|
596
|
+
buildSummary(messages) {
|
|
597
|
+
for (const msg of messages) {
|
|
598
|
+
if (msg.role !== "user") continue;
|
|
599
|
+
const cleaned = this.stripSystemContent(msg.content);
|
|
600
|
+
if (cleaned.length > 0) {
|
|
601
|
+
const text = cleaned.slice(0, 100);
|
|
602
|
+
return text.length < cleaned.length ? `${text}...` : text;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return "Imported Claude session";
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Strip system-injected XML tags and their content from a message,
|
|
609
|
+
* returning only the actual user text.
|
|
610
|
+
*/
|
|
611
|
+
stripSystemContent(text) {
|
|
612
|
+
let cleaned = text;
|
|
613
|
+
const systemTags = [
|
|
614
|
+
"local-command-caveat",
|
|
615
|
+
"system-reminder",
|
|
616
|
+
"user_instructions",
|
|
617
|
+
"environment_context",
|
|
618
|
+
"context",
|
|
619
|
+
"automatic_reminders",
|
|
620
|
+
"user_request",
|
|
621
|
+
"bash-input",
|
|
622
|
+
"bash-stdout",
|
|
623
|
+
"bash-stderr"
|
|
624
|
+
];
|
|
625
|
+
for (const tag of systemTags) {
|
|
626
|
+
const pattern = new RegExp(`<${tag}>[\\s\\S]*?</${tag}>`, "g");
|
|
627
|
+
cleaned = cleaned.replace(pattern, "");
|
|
628
|
+
}
|
|
629
|
+
return cleaned.trim();
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
// src/import/importers/CodexImporter.ts
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
var CodexImporter = class extends BaseImporter {
|
|
637
|
+
constructor() {
|
|
638
|
+
super(...arguments);
|
|
639
|
+
this.name = "codex";
|
|
640
|
+
this.displayName = "OpenAI Codex";
|
|
641
|
+
this.homePath = "~/.codex";
|
|
642
|
+
}
|
|
643
|
+
// ---------------------------------------------------------------
|
|
644
|
+
// scan()
|
|
645
|
+
// ---------------------------------------------------------------
|
|
646
|
+
async scan() {
|
|
647
|
+
const available = /* @__PURE__ */ new Map();
|
|
648
|
+
const home = this.resolvedHomePath;
|
|
649
|
+
if (!await _fsextra2.default.pathExists(home)) {
|
|
650
|
+
return { source: this.name, available };
|
|
651
|
+
}
|
|
652
|
+
const sessionsDir = _path2.default.join(home, "sessions");
|
|
653
|
+
if (await _fsextra2.default.pathExists(sessionsDir)) {
|
|
654
|
+
const sessionFiles = await this.walkJsonlFiles(sessionsDir);
|
|
655
|
+
if (sessionFiles.length > 0) {
|
|
656
|
+
available.set("sessions", {
|
|
657
|
+
count: sessionFiles.length,
|
|
658
|
+
description: `${sessionFiles.length} session file${sessionFiles.length !== 1 ? "s" : ""}`
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
if (await _fsextra2.default.pathExists(_path2.default.join(home, "config.toml"))) {
|
|
663
|
+
available.set("settings", { count: 1, description: "Codex config.toml" });
|
|
664
|
+
}
|
|
665
|
+
const skillsDir = _path2.default.join(home, "skills");
|
|
666
|
+
if (await _fsextra2.default.pathExists(skillsDir)) {
|
|
667
|
+
const skillEntries = await _fsextra2.default.readdir(skillsDir, { withFileTypes: true });
|
|
668
|
+
const skillFiles = skillEntries.filter((e) => e.isFile());
|
|
669
|
+
if (skillFiles.length > 0) {
|
|
670
|
+
available.set("skills", {
|
|
671
|
+
count: skillFiles.length,
|
|
672
|
+
description: `${skillFiles.length} skill file${skillFiles.length !== 1 ? "s" : ""}`
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
const rulesDir = _path2.default.join(home, "rules");
|
|
677
|
+
if (await _fsextra2.default.pathExists(rulesDir)) {
|
|
678
|
+
const ruleEntries = await _fsextra2.default.readdir(rulesDir, { withFileTypes: true });
|
|
679
|
+
const ruleFiles = ruleEntries.filter((e) => e.isFile());
|
|
680
|
+
if (ruleFiles.length > 0) {
|
|
681
|
+
available.set("memory", {
|
|
682
|
+
count: ruleFiles.length,
|
|
683
|
+
description: `${ruleFiles.length} rule file${ruleFiles.length !== 1 ? "s" : ""}`
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
return { source: this.name, available };
|
|
688
|
+
}
|
|
689
|
+
// ---------------------------------------------------------------
|
|
690
|
+
// import()
|
|
691
|
+
// ---------------------------------------------------------------
|
|
692
|
+
async import(categories, onProgress) {
|
|
693
|
+
const start = Date.now();
|
|
694
|
+
const imported = /* @__PURE__ */ new Map();
|
|
695
|
+
const errors = [];
|
|
696
|
+
for (const category of categories) {
|
|
697
|
+
switch (category) {
|
|
698
|
+
case "sessions":
|
|
699
|
+
await this.importSessions(imported, errors, onProgress);
|
|
700
|
+
break;
|
|
701
|
+
case "settings":
|
|
702
|
+
await this.importSettings(imported, errors, onProgress);
|
|
703
|
+
break;
|
|
704
|
+
case "skills":
|
|
705
|
+
await this.importSkills(imported, errors, onProgress);
|
|
706
|
+
break;
|
|
707
|
+
default:
|
|
708
|
+
break;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
return {
|
|
712
|
+
source: this.name,
|
|
713
|
+
imported,
|
|
714
|
+
errors,
|
|
715
|
+
duration: Date.now() - start
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
// ---------------------------------------------------------------
|
|
719
|
+
// Sessions
|
|
720
|
+
// ---------------------------------------------------------------
|
|
721
|
+
async importSessions(imported, errors, onProgress) {
|
|
722
|
+
const sessionsDir = _path2.default.join(this.resolvedHomePath, "sessions");
|
|
723
|
+
let success = 0;
|
|
724
|
+
let failed = 0;
|
|
725
|
+
let skipped = 0;
|
|
726
|
+
const skipReasons = {};
|
|
727
|
+
const trackSkip = (reason) => {
|
|
728
|
+
skipped++;
|
|
729
|
+
skipReasons[reason] = (_nullishCoalesce(skipReasons[reason], () => ( 0))) + 1;
|
|
730
|
+
};
|
|
731
|
+
if (!await _fsextra2.default.pathExists(sessionsDir)) {
|
|
732
|
+
imported.set("sessions", { success: 0, failed: 0, skipped: 0 });
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
const sessionFiles = await this.walkJsonlFiles(sessionsDir);
|
|
736
|
+
const total = sessionFiles.length;
|
|
737
|
+
for (let i = 0; i < sessionFiles.length; i++) {
|
|
738
|
+
const filePath = sessionFiles[i];
|
|
739
|
+
_optionalChain([onProgress, 'optionalCall', _13 => _13({
|
|
740
|
+
category: "sessions",
|
|
741
|
+
current: i + 1,
|
|
742
|
+
total,
|
|
743
|
+
item: _path2.default.basename(filePath),
|
|
744
|
+
status: "importing"
|
|
745
|
+
})]);
|
|
746
|
+
try {
|
|
747
|
+
const fileContent = await _fsextra2.default.readFile(filePath, "utf-8");
|
|
748
|
+
if (!fileContent.trim()) {
|
|
749
|
+
trackSkip("empty file");
|
|
750
|
+
continue;
|
|
751
|
+
}
|
|
752
|
+
const records = await this.readJsonlFile(filePath);
|
|
753
|
+
if (records.length === 0) {
|
|
754
|
+
trackSkip("no valid JSON records");
|
|
755
|
+
continue;
|
|
756
|
+
}
|
|
757
|
+
const events = records;
|
|
758
|
+
const metaEvent = events.find((e) => e.type === "session_meta");
|
|
759
|
+
const sessionId = _nullishCoalesce(_optionalChain([metaEvent, 'optionalAccess', _14 => _14.payload, 'optionalAccess', _15 => _15.id]), () => ( _path2.default.basename(filePath, ".jsonl")));
|
|
760
|
+
const cwd = _nullishCoalesce(_optionalChain([metaEvent, 'optionalAccess', _16 => _16.payload, 'optionalAccess', _17 => _17.cwd]), () => ( "/unknown"));
|
|
761
|
+
const messages = [];
|
|
762
|
+
for (const event of events) {
|
|
763
|
+
if (event.type === "response_item") {
|
|
764
|
+
const payload = event.payload;
|
|
765
|
+
if (payload.type === "message" && payload.role && payload.content) {
|
|
766
|
+
const text = payload.content.filter((c) => (c.type === "input_text" || c.type === "output_text") && c.text).map((c) => c.text).join("");
|
|
767
|
+
if (text && !this.isSystemMessage(text)) {
|
|
768
|
+
messages.push({
|
|
769
|
+
role: payload.role,
|
|
770
|
+
content: text,
|
|
771
|
+
timestamp: event.timestamp
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
} else if (event.type === "event_msg") {
|
|
776
|
+
const payload = event.payload;
|
|
777
|
+
if (payload.type === "agent_message" && payload.message) {
|
|
778
|
+
messages.push({
|
|
779
|
+
role: "assistant",
|
|
780
|
+
content: payload.message,
|
|
781
|
+
timestamp: event.timestamp
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
if (messages.length === 0) {
|
|
787
|
+
trackSkip("no user messages (only system content)");
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
790
|
+
const projectName = _path2.default.basename(cwd);
|
|
791
|
+
const result = await this.writeAutohandSession({
|
|
792
|
+
projectPath: cwd,
|
|
793
|
+
projectName,
|
|
794
|
+
model: "codex",
|
|
795
|
+
messages,
|
|
796
|
+
source: this.name,
|
|
797
|
+
originalId: sessionId,
|
|
798
|
+
createdAt: messages[0].timestamp,
|
|
799
|
+
closedAt: messages[messages.length - 1].timestamp,
|
|
800
|
+
summary: this.buildSummary(messages),
|
|
801
|
+
status: "completed"
|
|
802
|
+
});
|
|
803
|
+
if (result === null) {
|
|
804
|
+
trackSkip("already imported");
|
|
805
|
+
} else {
|
|
806
|
+
success++;
|
|
807
|
+
}
|
|
808
|
+
} catch (err) {
|
|
809
|
+
failed++;
|
|
810
|
+
errors.push({
|
|
811
|
+
category: "sessions",
|
|
812
|
+
item: _path2.default.basename(filePath),
|
|
813
|
+
error: err instanceof Error ? err.message : String(err),
|
|
814
|
+
retriable: true
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
imported.set("sessions", {
|
|
819
|
+
success,
|
|
820
|
+
failed,
|
|
821
|
+
skipped,
|
|
822
|
+
...Object.keys(skipReasons).length > 0 ? { skipReasons } : {}
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
// ---------------------------------------------------------------
|
|
826
|
+
// Settings (TOML)
|
|
827
|
+
// ---------------------------------------------------------------
|
|
828
|
+
async importSettings(imported, errors, onProgress) {
|
|
829
|
+
const configPath = _path2.default.join(this.resolvedHomePath, "config.toml");
|
|
830
|
+
if (!await _fsextra2.default.pathExists(configPath)) {
|
|
831
|
+
imported.set("settings", { success: 0, failed: 0, skipped: 1 });
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
_optionalChain([onProgress, 'optionalCall', _18 => _18({
|
|
835
|
+
category: "settings",
|
|
836
|
+
current: 1,
|
|
837
|
+
total: 1,
|
|
838
|
+
item: "config.toml",
|
|
839
|
+
status: "importing"
|
|
840
|
+
})]);
|
|
841
|
+
try {
|
|
842
|
+
const tomlContent = await _fsextra2.default.readFile(configPath, "utf-8");
|
|
843
|
+
const parsed = this.parseToml(tomlContent);
|
|
844
|
+
const configDir = _chunkSEKD5FH3cjs.AUTOHAND_PATHS.config;
|
|
845
|
+
await _fsextra2.default.ensureDir(configDir);
|
|
846
|
+
await _fsextra2.default.writeJson(
|
|
847
|
+
_path2.default.join(configDir, "imported-codex-settings.json"),
|
|
848
|
+
{
|
|
849
|
+
importedFrom: "codex",
|
|
850
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
851
|
+
parsed,
|
|
852
|
+
raw: tomlContent
|
|
853
|
+
},
|
|
854
|
+
{ spaces: 2 }
|
|
855
|
+
);
|
|
856
|
+
imported.set("settings", { success: 1, failed: 0, skipped: 0 });
|
|
857
|
+
_optionalChain([onProgress, 'optionalCall', _19 => _19({
|
|
858
|
+
category: "settings",
|
|
859
|
+
current: 1,
|
|
860
|
+
total: 1,
|
|
861
|
+
item: "config.toml",
|
|
862
|
+
status: "done"
|
|
863
|
+
})]);
|
|
864
|
+
} catch (err) {
|
|
865
|
+
imported.set("settings", { success: 0, failed: 1, skipped: 0 });
|
|
866
|
+
errors.push({
|
|
867
|
+
category: "settings",
|
|
868
|
+
item: "config.toml",
|
|
869
|
+
error: err instanceof Error ? err.message : String(err),
|
|
870
|
+
retriable: false
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
// ---------------------------------------------------------------
|
|
875
|
+
// Skills
|
|
876
|
+
// ---------------------------------------------------------------
|
|
877
|
+
async importSkills(imported, errors, onProgress) {
|
|
878
|
+
const skillsDir = _path2.default.join(this.resolvedHomePath, "skills");
|
|
879
|
+
if (!await _fsextra2.default.pathExists(skillsDir)) {
|
|
880
|
+
imported.set("skills", { success: 0, failed: 0, skipped: 1 });
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
const entries = await _fsextra2.default.readdir(skillsDir, { withFileTypes: true });
|
|
884
|
+
const skillFiles = entries.filter((e) => e.isFile());
|
|
885
|
+
let success = 0;
|
|
886
|
+
let failed = 0;
|
|
887
|
+
const total = skillFiles.length;
|
|
888
|
+
const destDir = _path2.default.join(_chunkSEKD5FH3cjs.AUTOHAND_PATHS.skills, "imported-codex");
|
|
889
|
+
for (let i = 0; i < skillFiles.length; i++) {
|
|
890
|
+
const file = skillFiles[i];
|
|
891
|
+
const src = _path2.default.join(skillsDir, file.name);
|
|
892
|
+
const dest = _path2.default.join(destDir, file.name);
|
|
893
|
+
_optionalChain([onProgress, 'optionalCall', _20 => _20({
|
|
894
|
+
category: "skills",
|
|
895
|
+
current: i + 1,
|
|
896
|
+
total,
|
|
897
|
+
item: file.name,
|
|
898
|
+
status: "importing"
|
|
899
|
+
})]);
|
|
900
|
+
try {
|
|
901
|
+
await _fsextra2.default.ensureDir(destDir);
|
|
902
|
+
await _fsextra2.default.copy(src, dest);
|
|
903
|
+
success++;
|
|
904
|
+
} catch (err) {
|
|
905
|
+
failed++;
|
|
906
|
+
errors.push({
|
|
907
|
+
category: "skills",
|
|
908
|
+
item: file.name,
|
|
909
|
+
error: err instanceof Error ? err.message : String(err),
|
|
910
|
+
retriable: true
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
imported.set("skills", { success, failed, skipped: 0 });
|
|
915
|
+
}
|
|
916
|
+
// ---------------------------------------------------------------
|
|
917
|
+
// Helpers
|
|
918
|
+
// ---------------------------------------------------------------
|
|
919
|
+
/**
|
|
920
|
+
* Recursively walk a directory tree and collect all .jsonl file paths.
|
|
921
|
+
*/
|
|
922
|
+
async walkJsonlFiles(dir) {
|
|
923
|
+
const results = [];
|
|
924
|
+
const entries = await _fsextra2.default.readdir(dir, { withFileTypes: true });
|
|
925
|
+
for (const entry of entries) {
|
|
926
|
+
const fullPath = _path2.default.join(dir, entry.name);
|
|
927
|
+
if (entry.isDirectory()) {
|
|
928
|
+
const nested = await this.walkJsonlFiles(fullPath);
|
|
929
|
+
results.push(...nested);
|
|
930
|
+
} else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
931
|
+
results.push(fullPath);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
return results;
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Simple TOML parser. Handles:
|
|
938
|
+
* - `key = "value"` (quoted strings)
|
|
939
|
+
* - `key = value` (unquoted – numbers, booleans, bare strings)
|
|
940
|
+
* - `[section]` and `[section.subsection]` headers
|
|
941
|
+
* - `# comments`
|
|
942
|
+
* - blank lines
|
|
943
|
+
*
|
|
944
|
+
* Returns a flat object with dotted keys for sections
|
|
945
|
+
* (e.g. `{ "section.key": "value" }`).
|
|
946
|
+
*/
|
|
947
|
+
parseToml(content) {
|
|
948
|
+
const result = {};
|
|
949
|
+
let currentSection = "";
|
|
950
|
+
for (const rawLine of content.split("\n")) {
|
|
951
|
+
const line = rawLine.trim();
|
|
952
|
+
if (!line || line.startsWith("#")) continue;
|
|
953
|
+
const sectionMatch = line.match(/^\[([^\]]+)\]$/);
|
|
954
|
+
if (sectionMatch) {
|
|
955
|
+
currentSection = sectionMatch[1];
|
|
956
|
+
continue;
|
|
957
|
+
}
|
|
958
|
+
const kvMatch = line.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)\s*=\s*(.+)$/);
|
|
959
|
+
if (!kvMatch) continue;
|
|
960
|
+
const key = currentSection ? `${currentSection}.${kvMatch[1]}` : kvMatch[1];
|
|
961
|
+
let value = kvMatch[2].trim();
|
|
962
|
+
const inlineComment = value.indexOf(" #");
|
|
963
|
+
if (inlineComment > 0) {
|
|
964
|
+
value = value.slice(0, inlineComment).trim();
|
|
965
|
+
}
|
|
966
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
967
|
+
result[key] = value.slice(1, -1);
|
|
968
|
+
} else if (value === "true") {
|
|
969
|
+
result[key] = true;
|
|
970
|
+
} else if (value === "false") {
|
|
971
|
+
result[key] = false;
|
|
972
|
+
} else if (/^-?\d+(\.\d+)?$/.test(value)) {
|
|
973
|
+
result[key] = Number(value);
|
|
974
|
+
} else {
|
|
975
|
+
result[key] = value;
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
return result;
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
981
|
+
* Detect system-injected context messages that should not be imported.
|
|
982
|
+
* These are Codex CLI-generated system prompts, environment info, etc.
|
|
983
|
+
*/
|
|
984
|
+
isSystemMessage(text) {
|
|
985
|
+
const trimmed = text.trimStart();
|
|
986
|
+
return trimmed.startsWith("<user_instructions>") || trimmed.startsWith("<environment_context>") || trimmed.startsWith("<user_request>") || trimmed.startsWith("<automatic_reminders>") || trimmed.startsWith("<system-reminder>") || trimmed.startsWith("<context>") || trimmed.startsWith("# Agents Guidance\n");
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Build a brief summary from the first real user message.
|
|
990
|
+
*/
|
|
991
|
+
buildSummary(messages) {
|
|
992
|
+
const firstUser = messages.find((m) => m.role === "user");
|
|
993
|
+
if (!firstUser) return "Imported Codex session";
|
|
994
|
+
const text = firstUser.content.trim().slice(0, 100);
|
|
995
|
+
return text.length < firstUser.content.trim().length ? `${text}...` : text;
|
|
996
|
+
}
|
|
997
|
+
};
|
|
998
|
+
|
|
999
|
+
// src/import/importers/GeminiImporter.ts
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
var GeminiImporter = class extends BaseImporter {
|
|
1003
|
+
constructor() {
|
|
1004
|
+
super(...arguments);
|
|
1005
|
+
this.name = "gemini";
|
|
1006
|
+
this.displayName = "Google Gemini";
|
|
1007
|
+
this.homePath = "~/.gemini";
|
|
1008
|
+
}
|
|
1009
|
+
// ---------------------------------------------------------------
|
|
1010
|
+
// scan()
|
|
1011
|
+
// ---------------------------------------------------------------
|
|
1012
|
+
async scan() {
|
|
1013
|
+
const available = /* @__PURE__ */ new Map();
|
|
1014
|
+
const home = this.resolvedHomePath;
|
|
1015
|
+
if (!await _fsextra2.default.pathExists(home)) {
|
|
1016
|
+
return { source: this.name, available };
|
|
1017
|
+
}
|
|
1018
|
+
const settingsPath = _path2.default.join(home, "settings.json");
|
|
1019
|
+
const hasSettings = await _fsextra2.default.pathExists(settingsPath);
|
|
1020
|
+
if (hasSettings) {
|
|
1021
|
+
available.set("settings", { count: 1, description: "Gemini settings.json" });
|
|
1022
|
+
try {
|
|
1023
|
+
const settings = await this.safeReadJson(settingsPath);
|
|
1024
|
+
const hooks = settings.hooks;
|
|
1025
|
+
if (hooks) {
|
|
1026
|
+
const hookSections = Object.keys(hooks).filter(
|
|
1027
|
+
(k) => Array.isArray(hooks[k]) && hooks[k].length > 0
|
|
1028
|
+
);
|
|
1029
|
+
if (hookSections.length > 0) {
|
|
1030
|
+
available.set("hooks", {
|
|
1031
|
+
count: hookSections.length,
|
|
1032
|
+
description: `${hookSections.length} hook section${hookSections.length !== 1 ? "s" : ""} (${hookSections.join(", ")})`
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
} catch (e5) {
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
const geminiMdPath = _path2.default.join(home, "GEMINI.md");
|
|
1040
|
+
if (await _fsextra2.default.pathExists(geminiMdPath)) {
|
|
1041
|
+
available.set("memory", { count: 1, description: "GEMINI.md project memory" });
|
|
1042
|
+
}
|
|
1043
|
+
return { source: this.name, available };
|
|
1044
|
+
}
|
|
1045
|
+
// ---------------------------------------------------------------
|
|
1046
|
+
// import()
|
|
1047
|
+
// ---------------------------------------------------------------
|
|
1048
|
+
async import(categories, onProgress) {
|
|
1049
|
+
const start = Date.now();
|
|
1050
|
+
const imported = /* @__PURE__ */ new Map();
|
|
1051
|
+
const errors = [];
|
|
1052
|
+
for (const category of categories) {
|
|
1053
|
+
switch (category) {
|
|
1054
|
+
case "settings":
|
|
1055
|
+
await this.importSettings(imported, errors, onProgress);
|
|
1056
|
+
break;
|
|
1057
|
+
case "hooks":
|
|
1058
|
+
await this.importHooks(imported, errors, onProgress);
|
|
1059
|
+
break;
|
|
1060
|
+
case "memory":
|
|
1061
|
+
await this.importMemory(imported, errors, onProgress);
|
|
1062
|
+
break;
|
|
1063
|
+
default:
|
|
1064
|
+
break;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
return {
|
|
1068
|
+
source: this.name,
|
|
1069
|
+
imported,
|
|
1070
|
+
errors,
|
|
1071
|
+
duration: Date.now() - start
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
// ---------------------------------------------------------------
|
|
1075
|
+
// Settings
|
|
1076
|
+
// ---------------------------------------------------------------
|
|
1077
|
+
async importSettings(imported, errors, onProgress) {
|
|
1078
|
+
const settingsPath = _path2.default.join(this.resolvedHomePath, "settings.json");
|
|
1079
|
+
if (!await _fsextra2.default.pathExists(settingsPath)) {
|
|
1080
|
+
imported.set("settings", { success: 0, failed: 0, skipped: 1 });
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1083
|
+
_optionalChain([onProgress, 'optionalCall', _21 => _21({
|
|
1084
|
+
category: "settings",
|
|
1085
|
+
current: 1,
|
|
1086
|
+
total: 1,
|
|
1087
|
+
item: "settings.json",
|
|
1088
|
+
status: "importing"
|
|
1089
|
+
})]);
|
|
1090
|
+
try {
|
|
1091
|
+
const settings = await this.safeReadJson(settingsPath);
|
|
1092
|
+
const configDir = _chunkSEKD5FH3cjs.AUTOHAND_PATHS.config;
|
|
1093
|
+
await _fsextra2.default.ensureDir(configDir);
|
|
1094
|
+
await _fsextra2.default.writeJson(
|
|
1095
|
+
_path2.default.join(configDir, "imported-gemini-settings.json"),
|
|
1096
|
+
{
|
|
1097
|
+
importedFrom: "gemini",
|
|
1098
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1099
|
+
raw: settings
|
|
1100
|
+
},
|
|
1101
|
+
{ spaces: 2 }
|
|
1102
|
+
);
|
|
1103
|
+
imported.set("settings", { success: 1, failed: 0, skipped: 0 });
|
|
1104
|
+
_optionalChain([onProgress, 'optionalCall', _22 => _22({
|
|
1105
|
+
category: "settings",
|
|
1106
|
+
current: 1,
|
|
1107
|
+
total: 1,
|
|
1108
|
+
item: "settings.json",
|
|
1109
|
+
status: "done"
|
|
1110
|
+
})]);
|
|
1111
|
+
} catch (err) {
|
|
1112
|
+
imported.set("settings", { success: 0, failed: 1, skipped: 0 });
|
|
1113
|
+
errors.push({
|
|
1114
|
+
category: "settings",
|
|
1115
|
+
item: "settings.json",
|
|
1116
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1117
|
+
retriable: false
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
// ---------------------------------------------------------------
|
|
1122
|
+
// Hooks
|
|
1123
|
+
// ---------------------------------------------------------------
|
|
1124
|
+
async importHooks(imported, errors, onProgress) {
|
|
1125
|
+
const settingsPath = _path2.default.join(this.resolvedHomePath, "settings.json");
|
|
1126
|
+
if (!await _fsextra2.default.pathExists(settingsPath)) {
|
|
1127
|
+
imported.set("hooks", { success: 0, failed: 0, skipped: 1 });
|
|
1128
|
+
return;
|
|
1129
|
+
}
|
|
1130
|
+
_optionalChain([onProgress, 'optionalCall', _23 => _23({
|
|
1131
|
+
category: "hooks",
|
|
1132
|
+
current: 1,
|
|
1133
|
+
total: 1,
|
|
1134
|
+
item: "hooks from settings.json",
|
|
1135
|
+
status: "importing"
|
|
1136
|
+
})]);
|
|
1137
|
+
try {
|
|
1138
|
+
const settings = await this.safeReadJson(settingsPath);
|
|
1139
|
+
const hooks = settings.hooks;
|
|
1140
|
+
if (!hooks || Object.keys(hooks).length === 0) {
|
|
1141
|
+
imported.set("hooks", { success: 0, failed: 0, skipped: 1 });
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
const configDir = _chunkSEKD5FH3cjs.AUTOHAND_PATHS.config;
|
|
1145
|
+
await _fsextra2.default.ensureDir(configDir);
|
|
1146
|
+
await _fsextra2.default.writeJson(
|
|
1147
|
+
_path2.default.join(configDir, "imported-gemini-hooks.json"),
|
|
1148
|
+
{
|
|
1149
|
+
importedFrom: "gemini",
|
|
1150
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1151
|
+
hooks
|
|
1152
|
+
},
|
|
1153
|
+
{ spaces: 2 }
|
|
1154
|
+
);
|
|
1155
|
+
imported.set("hooks", { success: 1, failed: 0, skipped: 0 });
|
|
1156
|
+
_optionalChain([onProgress, 'optionalCall', _24 => _24({
|
|
1157
|
+
category: "hooks",
|
|
1158
|
+
current: 1,
|
|
1159
|
+
total: 1,
|
|
1160
|
+
item: "hooks from settings.json",
|
|
1161
|
+
status: "done"
|
|
1162
|
+
})]);
|
|
1163
|
+
} catch (err) {
|
|
1164
|
+
imported.set("hooks", { success: 0, failed: 1, skipped: 0 });
|
|
1165
|
+
errors.push({
|
|
1166
|
+
category: "hooks",
|
|
1167
|
+
item: "hooks from settings.json",
|
|
1168
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1169
|
+
retriable: false
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
// ---------------------------------------------------------------
|
|
1174
|
+
// Memory
|
|
1175
|
+
// ---------------------------------------------------------------
|
|
1176
|
+
async importMemory(imported, errors, onProgress) {
|
|
1177
|
+
const geminiMdPath = _path2.default.join(this.resolvedHomePath, "GEMINI.md");
|
|
1178
|
+
if (!await _fsextra2.default.pathExists(geminiMdPath)) {
|
|
1179
|
+
imported.set("memory", { success: 0, failed: 0, skipped: 1 });
|
|
1180
|
+
return;
|
|
1181
|
+
}
|
|
1182
|
+
_optionalChain([onProgress, 'optionalCall', _25 => _25({
|
|
1183
|
+
category: "memory",
|
|
1184
|
+
current: 1,
|
|
1185
|
+
total: 1,
|
|
1186
|
+
item: "GEMINI.md",
|
|
1187
|
+
status: "importing"
|
|
1188
|
+
})]);
|
|
1189
|
+
try {
|
|
1190
|
+
const destDir = _path2.default.join(_chunkSEKD5FH3cjs.AUTOHAND_PATHS.memory, "imported-gemini");
|
|
1191
|
+
await _fsextra2.default.ensureDir(destDir);
|
|
1192
|
+
await _fsextra2.default.copy(geminiMdPath, _path2.default.join(destDir, "GEMINI.md"));
|
|
1193
|
+
imported.set("memory", { success: 1, failed: 0, skipped: 0 });
|
|
1194
|
+
_optionalChain([onProgress, 'optionalCall', _26 => _26({
|
|
1195
|
+
category: "memory",
|
|
1196
|
+
current: 1,
|
|
1197
|
+
total: 1,
|
|
1198
|
+
item: "GEMINI.md",
|
|
1199
|
+
status: "done"
|
|
1200
|
+
})]);
|
|
1201
|
+
} catch (err) {
|
|
1202
|
+
imported.set("memory", { success: 0, failed: 1, skipped: 0 });
|
|
1203
|
+
errors.push({
|
|
1204
|
+
category: "memory",
|
|
1205
|
+
item: "GEMINI.md",
|
|
1206
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1207
|
+
retriable: true
|
|
1208
|
+
});
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
|
|
1213
|
+
// src/import/importers/CursorImporter.ts
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
var CursorImporter = class extends BaseImporter {
|
|
1217
|
+
constructor() {
|
|
1218
|
+
super(...arguments);
|
|
1219
|
+
this.name = "cursor";
|
|
1220
|
+
this.displayName = "Cursor";
|
|
1221
|
+
this.homePath = "~/.cursor";
|
|
1222
|
+
}
|
|
1223
|
+
// ---------------------------------------------------------------
|
|
1224
|
+
// scan()
|
|
1225
|
+
// ---------------------------------------------------------------
|
|
1226
|
+
async scan() {
|
|
1227
|
+
const available = /* @__PURE__ */ new Map();
|
|
1228
|
+
const home = this.resolvedHomePath;
|
|
1229
|
+
if (!await _fsextra2.default.pathExists(home)) {
|
|
1230
|
+
return { source: this.name, available };
|
|
1231
|
+
}
|
|
1232
|
+
const hooksPath = _path2.default.join(home, "hooks.json");
|
|
1233
|
+
if (await _fsextra2.default.pathExists(hooksPath)) {
|
|
1234
|
+
available.set("settings", { count: 1, description: "Cursor hooks.json preferences" });
|
|
1235
|
+
available.set("hooks", { count: 1, description: "Cursor hook configurations" });
|
|
1236
|
+
}
|
|
1237
|
+
const mcpPath = _path2.default.join(home, "mcp.json");
|
|
1238
|
+
if (await _fsextra2.default.pathExists(mcpPath)) {
|
|
1239
|
+
available.set("mcp", { count: 1, description: "Cursor MCP server configurations" });
|
|
1240
|
+
}
|
|
1241
|
+
return { source: this.name, available };
|
|
1242
|
+
}
|
|
1243
|
+
// ---------------------------------------------------------------
|
|
1244
|
+
// import()
|
|
1245
|
+
// ---------------------------------------------------------------
|
|
1246
|
+
async import(categories, onProgress) {
|
|
1247
|
+
const start = Date.now();
|
|
1248
|
+
const imported = /* @__PURE__ */ new Map();
|
|
1249
|
+
const errors = [];
|
|
1250
|
+
for (const category of categories) {
|
|
1251
|
+
switch (category) {
|
|
1252
|
+
case "settings":
|
|
1253
|
+
await this.importSettings(imported, errors, onProgress);
|
|
1254
|
+
break;
|
|
1255
|
+
case "hooks":
|
|
1256
|
+
await this.importHooks(imported, errors, onProgress);
|
|
1257
|
+
break;
|
|
1258
|
+
case "mcp":
|
|
1259
|
+
await this.importMcp(imported, errors, onProgress);
|
|
1260
|
+
break;
|
|
1261
|
+
default:
|
|
1262
|
+
break;
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
return {
|
|
1266
|
+
source: this.name,
|
|
1267
|
+
imported,
|
|
1268
|
+
errors,
|
|
1269
|
+
duration: Date.now() - start
|
|
1270
|
+
};
|
|
1271
|
+
}
|
|
1272
|
+
// ---------------------------------------------------------------
|
|
1273
|
+
// Settings
|
|
1274
|
+
// ---------------------------------------------------------------
|
|
1275
|
+
async importSettings(imported, errors, onProgress) {
|
|
1276
|
+
const hooksPath = _path2.default.join(this.resolvedHomePath, "hooks.json");
|
|
1277
|
+
if (!await _fsextra2.default.pathExists(hooksPath)) {
|
|
1278
|
+
imported.set("settings", { success: 0, failed: 0, skipped: 1 });
|
|
1279
|
+
return;
|
|
1280
|
+
}
|
|
1281
|
+
_optionalChain([onProgress, 'optionalCall', _27 => _27({
|
|
1282
|
+
category: "settings",
|
|
1283
|
+
current: 1,
|
|
1284
|
+
total: 1,
|
|
1285
|
+
item: "hooks.json",
|
|
1286
|
+
status: "importing"
|
|
1287
|
+
})]);
|
|
1288
|
+
try {
|
|
1289
|
+
const hooksData = await this.safeReadJson(hooksPath);
|
|
1290
|
+
const configDir = _chunkSEKD5FH3cjs.AUTOHAND_PATHS.config;
|
|
1291
|
+
await _fsextra2.default.ensureDir(configDir);
|
|
1292
|
+
await _fsextra2.default.writeJson(
|
|
1293
|
+
_path2.default.join(configDir, "imported-cursor-settings.json"),
|
|
1294
|
+
{
|
|
1295
|
+
importedFrom: "cursor",
|
|
1296
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1297
|
+
raw: hooksData
|
|
1298
|
+
},
|
|
1299
|
+
{ spaces: 2 }
|
|
1300
|
+
);
|
|
1301
|
+
imported.set("settings", { success: 1, failed: 0, skipped: 0 });
|
|
1302
|
+
_optionalChain([onProgress, 'optionalCall', _28 => _28({
|
|
1303
|
+
category: "settings",
|
|
1304
|
+
current: 1,
|
|
1305
|
+
total: 1,
|
|
1306
|
+
item: "hooks.json",
|
|
1307
|
+
status: "done"
|
|
1308
|
+
})]);
|
|
1309
|
+
} catch (err) {
|
|
1310
|
+
imported.set("settings", { success: 0, failed: 1, skipped: 0 });
|
|
1311
|
+
errors.push({
|
|
1312
|
+
category: "settings",
|
|
1313
|
+
item: "hooks.json",
|
|
1314
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1315
|
+
retriable: false
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
// ---------------------------------------------------------------
|
|
1320
|
+
// Hooks
|
|
1321
|
+
// ---------------------------------------------------------------
|
|
1322
|
+
async importHooks(imported, errors, onProgress) {
|
|
1323
|
+
const hooksPath = _path2.default.join(this.resolvedHomePath, "hooks.json");
|
|
1324
|
+
if (!await _fsextra2.default.pathExists(hooksPath)) {
|
|
1325
|
+
imported.set("hooks", { success: 0, failed: 0, skipped: 1 });
|
|
1326
|
+
return;
|
|
1327
|
+
}
|
|
1328
|
+
_optionalChain([onProgress, 'optionalCall', _29 => _29({
|
|
1329
|
+
category: "hooks",
|
|
1330
|
+
current: 1,
|
|
1331
|
+
total: 1,
|
|
1332
|
+
item: "hooks.json",
|
|
1333
|
+
status: "importing"
|
|
1334
|
+
})]);
|
|
1335
|
+
try {
|
|
1336
|
+
const hooksData = await this.safeReadJson(hooksPath);
|
|
1337
|
+
const configDir = _chunkSEKD5FH3cjs.AUTOHAND_PATHS.config;
|
|
1338
|
+
await _fsextra2.default.ensureDir(configDir);
|
|
1339
|
+
await _fsextra2.default.writeJson(
|
|
1340
|
+
_path2.default.join(configDir, "imported-cursor-hooks.json"),
|
|
1341
|
+
{
|
|
1342
|
+
importedFrom: "cursor",
|
|
1343
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1344
|
+
hooks: _nullishCoalesce(hooksData.hooks, () => ( hooksData))
|
|
1345
|
+
},
|
|
1346
|
+
{ spaces: 2 }
|
|
1347
|
+
);
|
|
1348
|
+
imported.set("hooks", { success: 1, failed: 0, skipped: 0 });
|
|
1349
|
+
_optionalChain([onProgress, 'optionalCall', _30 => _30({
|
|
1350
|
+
category: "hooks",
|
|
1351
|
+
current: 1,
|
|
1352
|
+
total: 1,
|
|
1353
|
+
item: "hooks.json",
|
|
1354
|
+
status: "done"
|
|
1355
|
+
})]);
|
|
1356
|
+
} catch (err) {
|
|
1357
|
+
imported.set("hooks", { success: 0, failed: 1, skipped: 0 });
|
|
1358
|
+
errors.push({
|
|
1359
|
+
category: "hooks",
|
|
1360
|
+
item: "hooks.json",
|
|
1361
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1362
|
+
retriable: false
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
// ---------------------------------------------------------------
|
|
1367
|
+
// MCP
|
|
1368
|
+
// ---------------------------------------------------------------
|
|
1369
|
+
async importMcp(imported, errors, onProgress) {
|
|
1370
|
+
const mcpPath = _path2.default.join(this.resolvedHomePath, "mcp.json");
|
|
1371
|
+
if (!await _fsextra2.default.pathExists(mcpPath)) {
|
|
1372
|
+
imported.set("mcp", { success: 0, failed: 0, skipped: 1 });
|
|
1373
|
+
return;
|
|
1374
|
+
}
|
|
1375
|
+
_optionalChain([onProgress, 'optionalCall', _31 => _31({
|
|
1376
|
+
category: "mcp",
|
|
1377
|
+
current: 1,
|
|
1378
|
+
total: 1,
|
|
1379
|
+
item: "mcp.json",
|
|
1380
|
+
status: "importing"
|
|
1381
|
+
})]);
|
|
1382
|
+
try {
|
|
1383
|
+
const mcpData = await this.safeReadJson(mcpPath);
|
|
1384
|
+
const configDir = _chunkSEKD5FH3cjs.AUTOHAND_PATHS.config;
|
|
1385
|
+
await _fsextra2.default.ensureDir(configDir);
|
|
1386
|
+
await _fsextra2.default.writeJson(
|
|
1387
|
+
_path2.default.join(configDir, "imported-cursor-mcp.json"),
|
|
1388
|
+
{
|
|
1389
|
+
importedFrom: "cursor",
|
|
1390
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1391
|
+
mcpServers: _nullishCoalesce(mcpData.mcpServers, () => ( mcpData))
|
|
1392
|
+
},
|
|
1393
|
+
{ spaces: 2 }
|
|
1394
|
+
);
|
|
1395
|
+
imported.set("mcp", { success: 1, failed: 0, skipped: 0 });
|
|
1396
|
+
_optionalChain([onProgress, 'optionalCall', _32 => _32({
|
|
1397
|
+
category: "mcp",
|
|
1398
|
+
current: 1,
|
|
1399
|
+
total: 1,
|
|
1400
|
+
item: "mcp.json",
|
|
1401
|
+
status: "done"
|
|
1402
|
+
})]);
|
|
1403
|
+
} catch (err) {
|
|
1404
|
+
imported.set("mcp", { success: 0, failed: 1, skipped: 0 });
|
|
1405
|
+
errors.push({
|
|
1406
|
+
category: "mcp",
|
|
1407
|
+
item: "mcp.json",
|
|
1408
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1409
|
+
retriable: false
|
|
1410
|
+
});
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
};
|
|
1414
|
+
|
|
1415
|
+
// src/import/importers/ClineImporter.ts
|
|
1416
|
+
|
|
1417
|
+
|
|
1418
|
+
var ClineImporter = class extends BaseImporter {
|
|
1419
|
+
constructor() {
|
|
1420
|
+
super(...arguments);
|
|
1421
|
+
this.name = "cline";
|
|
1422
|
+
this.displayName = "Cline";
|
|
1423
|
+
this.homePath = "~/.cline";
|
|
1424
|
+
}
|
|
1425
|
+
// ---------------------------------------------------------------
|
|
1426
|
+
// scan()
|
|
1427
|
+
// ---------------------------------------------------------------
|
|
1428
|
+
async scan() {
|
|
1429
|
+
const available = /* @__PURE__ */ new Map();
|
|
1430
|
+
const home = this.resolvedHomePath;
|
|
1431
|
+
if (!await _fsextra2.default.pathExists(home)) {
|
|
1432
|
+
return { source: this.name, available };
|
|
1433
|
+
}
|
|
1434
|
+
const globalStatePath = _path2.default.join(home, "data", "globalState.json");
|
|
1435
|
+
if (await _fsextra2.default.pathExists(globalStatePath)) {
|
|
1436
|
+
available.set("settings", {
|
|
1437
|
+
count: 1,
|
|
1438
|
+
description: "Cline global state (model preferences, auto-approval, browser settings)"
|
|
1439
|
+
});
|
|
1440
|
+
}
|
|
1441
|
+
return { source: this.name, available };
|
|
1442
|
+
}
|
|
1443
|
+
// ---------------------------------------------------------------
|
|
1444
|
+
// import()
|
|
1445
|
+
// ---------------------------------------------------------------
|
|
1446
|
+
async import(categories, onProgress) {
|
|
1447
|
+
const start = Date.now();
|
|
1448
|
+
const imported = /* @__PURE__ */ new Map();
|
|
1449
|
+
const errors = [];
|
|
1450
|
+
for (const category of categories) {
|
|
1451
|
+
switch (category) {
|
|
1452
|
+
case "settings":
|
|
1453
|
+
await this.importSettings(imported, errors, onProgress);
|
|
1454
|
+
break;
|
|
1455
|
+
default:
|
|
1456
|
+
break;
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
return {
|
|
1460
|
+
source: this.name,
|
|
1461
|
+
imported,
|
|
1462
|
+
errors,
|
|
1463
|
+
duration: Date.now() - start
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1466
|
+
// ---------------------------------------------------------------
|
|
1467
|
+
// Settings
|
|
1468
|
+
// ---------------------------------------------------------------
|
|
1469
|
+
async importSettings(imported, errors, onProgress) {
|
|
1470
|
+
const globalStatePath = _path2.default.join(this.resolvedHomePath, "data", "globalState.json");
|
|
1471
|
+
if (!await _fsextra2.default.pathExists(globalStatePath)) {
|
|
1472
|
+
imported.set("settings", { success: 0, failed: 0, skipped: 1 });
|
|
1473
|
+
return;
|
|
1474
|
+
}
|
|
1475
|
+
_optionalChain([onProgress, 'optionalCall', _33 => _33({
|
|
1476
|
+
category: "settings",
|
|
1477
|
+
current: 1,
|
|
1478
|
+
total: 1,
|
|
1479
|
+
item: "globalState.json",
|
|
1480
|
+
status: "importing"
|
|
1481
|
+
})]);
|
|
1482
|
+
try {
|
|
1483
|
+
const state = await this.safeReadJson(globalStatePath);
|
|
1484
|
+
const extracted = {};
|
|
1485
|
+
if (state.apiModelId) extracted.model = state.apiModelId;
|
|
1486
|
+
if (state.autoApprovalSettings) extracted.autoApproval = state.autoApprovalSettings;
|
|
1487
|
+
if (state.browserSettings) extracted.browser = state.browserSettings;
|
|
1488
|
+
if (state.workspaceRoots) extracted.workspaceRoots = state.workspaceRoots;
|
|
1489
|
+
const configDir = _chunkSEKD5FH3cjs.AUTOHAND_PATHS.config;
|
|
1490
|
+
await _fsextra2.default.ensureDir(configDir);
|
|
1491
|
+
await _fsextra2.default.writeJson(
|
|
1492
|
+
_path2.default.join(configDir, "imported-cline-settings.json"),
|
|
1493
|
+
{
|
|
1494
|
+
importedFrom: "cline",
|
|
1495
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1496
|
+
...extracted,
|
|
1497
|
+
raw: state
|
|
1498
|
+
},
|
|
1499
|
+
{ spaces: 2 }
|
|
1500
|
+
);
|
|
1501
|
+
imported.set("settings", { success: 1, failed: 0, skipped: 0 });
|
|
1502
|
+
_optionalChain([onProgress, 'optionalCall', _34 => _34({
|
|
1503
|
+
category: "settings",
|
|
1504
|
+
current: 1,
|
|
1505
|
+
total: 1,
|
|
1506
|
+
item: "globalState.json",
|
|
1507
|
+
status: "done"
|
|
1508
|
+
})]);
|
|
1509
|
+
} catch (err) {
|
|
1510
|
+
imported.set("settings", { success: 0, failed: 1, skipped: 0 });
|
|
1511
|
+
errors.push({
|
|
1512
|
+
category: "settings",
|
|
1513
|
+
item: "globalState.json",
|
|
1514
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1515
|
+
retriable: false
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
};
|
|
1520
|
+
|
|
1521
|
+
// src/import/importers/ContinueImporter.ts
|
|
1522
|
+
|
|
1523
|
+
|
|
1524
|
+
var ContinueImporter = class extends BaseImporter {
|
|
1525
|
+
constructor() {
|
|
1526
|
+
super(...arguments);
|
|
1527
|
+
this.name = "continue";
|
|
1528
|
+
this.displayName = "Continue.dev";
|
|
1529
|
+
this.homePath = "~/.continue";
|
|
1530
|
+
}
|
|
1531
|
+
// ---------------------------------------------------------------
|
|
1532
|
+
// scan()
|
|
1533
|
+
// ---------------------------------------------------------------
|
|
1534
|
+
async scan() {
|
|
1535
|
+
const available = /* @__PURE__ */ new Map();
|
|
1536
|
+
const home = this.resolvedHomePath;
|
|
1537
|
+
if (!await _fsextra2.default.pathExists(home)) {
|
|
1538
|
+
return { source: this.name, available };
|
|
1539
|
+
}
|
|
1540
|
+
const configPath = _path2.default.join(home, "config.json");
|
|
1541
|
+
if (await _fsextra2.default.pathExists(configPath)) {
|
|
1542
|
+
available.set("settings", {
|
|
1543
|
+
count: 1,
|
|
1544
|
+
description: "Continue.dev config (models, context providers, slash commands, embeddings)"
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
return { source: this.name, available };
|
|
1548
|
+
}
|
|
1549
|
+
// ---------------------------------------------------------------
|
|
1550
|
+
// import()
|
|
1551
|
+
// ---------------------------------------------------------------
|
|
1552
|
+
async import(categories, onProgress) {
|
|
1553
|
+
const start = Date.now();
|
|
1554
|
+
const imported = /* @__PURE__ */ new Map();
|
|
1555
|
+
const errors = [];
|
|
1556
|
+
for (const category of categories) {
|
|
1557
|
+
switch (category) {
|
|
1558
|
+
case "settings":
|
|
1559
|
+
await this.importSettings(imported, errors, onProgress);
|
|
1560
|
+
break;
|
|
1561
|
+
default:
|
|
1562
|
+
break;
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
return {
|
|
1566
|
+
source: this.name,
|
|
1567
|
+
imported,
|
|
1568
|
+
errors,
|
|
1569
|
+
duration: Date.now() - start
|
|
1570
|
+
};
|
|
1571
|
+
}
|
|
1572
|
+
// ---------------------------------------------------------------
|
|
1573
|
+
// Settings
|
|
1574
|
+
// ---------------------------------------------------------------
|
|
1575
|
+
async importSettings(imported, errors, onProgress) {
|
|
1576
|
+
const configPath = _path2.default.join(this.resolvedHomePath, "config.json");
|
|
1577
|
+
if (!await _fsextra2.default.pathExists(configPath)) {
|
|
1578
|
+
imported.set("settings", { success: 0, failed: 0, skipped: 1 });
|
|
1579
|
+
return;
|
|
1580
|
+
}
|
|
1581
|
+
_optionalChain([onProgress, 'optionalCall', _35 => _35({
|
|
1582
|
+
category: "settings",
|
|
1583
|
+
current: 1,
|
|
1584
|
+
total: 1,
|
|
1585
|
+
item: "config.json",
|
|
1586
|
+
status: "importing"
|
|
1587
|
+
})]);
|
|
1588
|
+
try {
|
|
1589
|
+
const config = await this.safeReadJson(configPath);
|
|
1590
|
+
const extracted = {
|
|
1591
|
+
importedFrom: "continue",
|
|
1592
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1593
|
+
};
|
|
1594
|
+
if (config.models) extracted.models = config.models;
|
|
1595
|
+
if (config.contextProviders) extracted.contextProviders = config.contextProviders;
|
|
1596
|
+
if (config.slashCommands) extracted.slashCommands = config.slashCommands;
|
|
1597
|
+
if (config.embeddingsProvider) extracted.embeddingsProvider = config.embeddingsProvider;
|
|
1598
|
+
const configDir = _chunkSEKD5FH3cjs.AUTOHAND_PATHS.config;
|
|
1599
|
+
await _fsextra2.default.ensureDir(configDir);
|
|
1600
|
+
await _fsextra2.default.writeJson(
|
|
1601
|
+
_path2.default.join(configDir, "imported-continue-settings.json"),
|
|
1602
|
+
extracted,
|
|
1603
|
+
{ spaces: 2 }
|
|
1604
|
+
);
|
|
1605
|
+
imported.set("settings", { success: 1, failed: 0, skipped: 0 });
|
|
1606
|
+
_optionalChain([onProgress, 'optionalCall', _36 => _36({
|
|
1607
|
+
category: "settings",
|
|
1608
|
+
current: 1,
|
|
1609
|
+
total: 1,
|
|
1610
|
+
item: "config.json",
|
|
1611
|
+
status: "done"
|
|
1612
|
+
})]);
|
|
1613
|
+
} catch (err) {
|
|
1614
|
+
imported.set("settings", { success: 0, failed: 1, skipped: 0 });
|
|
1615
|
+
errors.push({
|
|
1616
|
+
category: "settings",
|
|
1617
|
+
item: "config.json",
|
|
1618
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1619
|
+
retriable: false
|
|
1620
|
+
});
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
};
|
|
1624
|
+
|
|
1625
|
+
// src/import/importers/AugmentImporter.ts
|
|
1626
|
+
|
|
1627
|
+
|
|
1628
|
+
var AugmentImporter = class extends BaseImporter {
|
|
1629
|
+
constructor() {
|
|
1630
|
+
super(...arguments);
|
|
1631
|
+
this.name = "augment";
|
|
1632
|
+
this.displayName = "Augment";
|
|
1633
|
+
this.homePath = "~/.augment";
|
|
1634
|
+
}
|
|
1635
|
+
// ---------------------------------------------------------------
|
|
1636
|
+
// scan()
|
|
1637
|
+
// ---------------------------------------------------------------
|
|
1638
|
+
async scan() {
|
|
1639
|
+
const available = /* @__PURE__ */ new Map();
|
|
1640
|
+
const home = this.resolvedHomePath;
|
|
1641
|
+
if (!await _fsextra2.default.pathExists(home)) {
|
|
1642
|
+
return { source: this.name, available };
|
|
1643
|
+
}
|
|
1644
|
+
const mcpPath = _path2.default.join(home, "mcp.json");
|
|
1645
|
+
if (await _fsextra2.default.pathExists(mcpPath)) {
|
|
1646
|
+
available.set("mcp", { count: 1, description: "Augment MCP server configurations" });
|
|
1647
|
+
}
|
|
1648
|
+
const settingsPath = _path2.default.join(home, "settings.json");
|
|
1649
|
+
if (await _fsextra2.default.pathExists(settingsPath)) {
|
|
1650
|
+
available.set("settings", { count: 1, description: "Augment settings" });
|
|
1651
|
+
}
|
|
1652
|
+
return { source: this.name, available };
|
|
1653
|
+
}
|
|
1654
|
+
// ---------------------------------------------------------------
|
|
1655
|
+
// import()
|
|
1656
|
+
// ---------------------------------------------------------------
|
|
1657
|
+
async import(categories, onProgress) {
|
|
1658
|
+
const start = Date.now();
|
|
1659
|
+
const imported = /* @__PURE__ */ new Map();
|
|
1660
|
+
const errors = [];
|
|
1661
|
+
for (const category of categories) {
|
|
1662
|
+
switch (category) {
|
|
1663
|
+
case "mcp":
|
|
1664
|
+
await this.importMcp(imported, errors, onProgress);
|
|
1665
|
+
break;
|
|
1666
|
+
case "settings":
|
|
1667
|
+
await this.importSettings(imported, errors, onProgress);
|
|
1668
|
+
break;
|
|
1669
|
+
default:
|
|
1670
|
+
break;
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
return {
|
|
1674
|
+
source: this.name,
|
|
1675
|
+
imported,
|
|
1676
|
+
errors,
|
|
1677
|
+
duration: Date.now() - start
|
|
1678
|
+
};
|
|
1679
|
+
}
|
|
1680
|
+
// ---------------------------------------------------------------
|
|
1681
|
+
// MCP
|
|
1682
|
+
// ---------------------------------------------------------------
|
|
1683
|
+
async importMcp(imported, errors, onProgress) {
|
|
1684
|
+
const mcpPath = _path2.default.join(this.resolvedHomePath, "mcp.json");
|
|
1685
|
+
if (!await _fsextra2.default.pathExists(mcpPath)) {
|
|
1686
|
+
imported.set("mcp", { success: 0, failed: 0, skipped: 1 });
|
|
1687
|
+
return;
|
|
1688
|
+
}
|
|
1689
|
+
_optionalChain([onProgress, 'optionalCall', _37 => _37({
|
|
1690
|
+
category: "mcp",
|
|
1691
|
+
current: 1,
|
|
1692
|
+
total: 1,
|
|
1693
|
+
item: "mcp.json",
|
|
1694
|
+
status: "importing"
|
|
1695
|
+
})]);
|
|
1696
|
+
try {
|
|
1697
|
+
const mcpData = await this.safeReadJson(mcpPath);
|
|
1698
|
+
const configDir = _chunkSEKD5FH3cjs.AUTOHAND_PATHS.config;
|
|
1699
|
+
await _fsextra2.default.ensureDir(configDir);
|
|
1700
|
+
await _fsextra2.default.writeJson(
|
|
1701
|
+
_path2.default.join(configDir, "imported-augment-mcp.json"),
|
|
1702
|
+
{
|
|
1703
|
+
importedFrom: "augment",
|
|
1704
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1705
|
+
mcpServers: _nullishCoalesce(mcpData.mcpServers, () => ( mcpData))
|
|
1706
|
+
},
|
|
1707
|
+
{ spaces: 2 }
|
|
1708
|
+
);
|
|
1709
|
+
imported.set("mcp", { success: 1, failed: 0, skipped: 0 });
|
|
1710
|
+
_optionalChain([onProgress, 'optionalCall', _38 => _38({
|
|
1711
|
+
category: "mcp",
|
|
1712
|
+
current: 1,
|
|
1713
|
+
total: 1,
|
|
1714
|
+
item: "mcp.json",
|
|
1715
|
+
status: "done"
|
|
1716
|
+
})]);
|
|
1717
|
+
} catch (err) {
|
|
1718
|
+
imported.set("mcp", { success: 0, failed: 1, skipped: 0 });
|
|
1719
|
+
errors.push({
|
|
1720
|
+
category: "mcp",
|
|
1721
|
+
item: "mcp.json",
|
|
1722
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1723
|
+
retriable: false
|
|
1724
|
+
});
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
// ---------------------------------------------------------------
|
|
1728
|
+
// Settings
|
|
1729
|
+
// ---------------------------------------------------------------
|
|
1730
|
+
async importSettings(imported, errors, onProgress) {
|
|
1731
|
+
const settingsPath = _path2.default.join(this.resolvedHomePath, "settings.json");
|
|
1732
|
+
if (!await _fsextra2.default.pathExists(settingsPath)) {
|
|
1733
|
+
imported.set("settings", { success: 0, failed: 0, skipped: 1 });
|
|
1734
|
+
return;
|
|
1735
|
+
}
|
|
1736
|
+
_optionalChain([onProgress, 'optionalCall', _39 => _39({
|
|
1737
|
+
category: "settings",
|
|
1738
|
+
current: 1,
|
|
1739
|
+
total: 1,
|
|
1740
|
+
item: "settings.json",
|
|
1741
|
+
status: "importing"
|
|
1742
|
+
})]);
|
|
1743
|
+
try {
|
|
1744
|
+
const settings = await this.safeReadJson(settingsPath);
|
|
1745
|
+
const configDir = _chunkSEKD5FH3cjs.AUTOHAND_PATHS.config;
|
|
1746
|
+
await _fsextra2.default.ensureDir(configDir);
|
|
1747
|
+
await _fsextra2.default.writeJson(
|
|
1748
|
+
_path2.default.join(configDir, "imported-augment-settings.json"),
|
|
1749
|
+
{
|
|
1750
|
+
importedFrom: "augment",
|
|
1751
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1752
|
+
raw: settings
|
|
1753
|
+
},
|
|
1754
|
+
{ spaces: 2 }
|
|
1755
|
+
);
|
|
1756
|
+
imported.set("settings", { success: 1, failed: 0, skipped: 0 });
|
|
1757
|
+
_optionalChain([onProgress, 'optionalCall', _40 => _40({
|
|
1758
|
+
category: "settings",
|
|
1759
|
+
current: 1,
|
|
1760
|
+
total: 1,
|
|
1761
|
+
item: "settings.json",
|
|
1762
|
+
status: "done"
|
|
1763
|
+
})]);
|
|
1764
|
+
} catch (err) {
|
|
1765
|
+
imported.set("settings", { success: 0, failed: 1, skipped: 0 });
|
|
1766
|
+
errors.push({
|
|
1767
|
+
category: "settings",
|
|
1768
|
+
item: "settings.json",
|
|
1769
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1770
|
+
retriable: false
|
|
1771
|
+
});
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
};
|
|
1775
|
+
|
|
1776
|
+
// src/import/registry.ts
|
|
1777
|
+
var ImporterRegistry = class {
|
|
1778
|
+
constructor() {
|
|
1779
|
+
this.importers = /* @__PURE__ */ new Map();
|
|
1780
|
+
this.register(new ClaudeImporter());
|
|
1781
|
+
this.register(new CodexImporter());
|
|
1782
|
+
this.register(new GeminiImporter());
|
|
1783
|
+
this.register(new CursorImporter());
|
|
1784
|
+
this.register(new ClineImporter());
|
|
1785
|
+
this.register(new ContinueImporter());
|
|
1786
|
+
this.register(new AugmentImporter());
|
|
1787
|
+
}
|
|
1788
|
+
/**
|
|
1789
|
+
* Register an importer instance by its source name.
|
|
1790
|
+
*/
|
|
1791
|
+
register(importer) {
|
|
1792
|
+
this.importers.set(importer.name, importer);
|
|
1793
|
+
}
|
|
1794
|
+
/**
|
|
1795
|
+
* Get an importer by its source name.
|
|
1796
|
+
* Returns undefined if the source is not registered.
|
|
1797
|
+
*/
|
|
1798
|
+
get(name) {
|
|
1799
|
+
return this.importers.get(name);
|
|
1800
|
+
}
|
|
1801
|
+
/**
|
|
1802
|
+
* Get all registered importers.
|
|
1803
|
+
*/
|
|
1804
|
+
getAll() {
|
|
1805
|
+
return Array.from(this.importers.values());
|
|
1806
|
+
}
|
|
1807
|
+
/**
|
|
1808
|
+
* Detect which agent data directories exist on disk.
|
|
1809
|
+
* Runs all detect() calls in parallel for speed.
|
|
1810
|
+
*/
|
|
1811
|
+
async detectAvailable() {
|
|
1812
|
+
const results = await Promise.all(
|
|
1813
|
+
this.getAll().map(async (importer) => ({
|
|
1814
|
+
importer,
|
|
1815
|
+
exists: await importer.detect()
|
|
1816
|
+
}))
|
|
1817
|
+
);
|
|
1818
|
+
return results.filter((r) => r.exists).map((r) => r.importer);
|
|
1819
|
+
}
|
|
1820
|
+
};
|
|
1821
|
+
|
|
1822
|
+
|
|
1823
|
+
exports.ImporterRegistry = ImporterRegistry;
|
|
1824
|
+
/**
|
|
1825
|
+
* @license
|
|
1826
|
+
* Copyright 2025 Autohand AI LLC
|
|
1827
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
1828
|
+
*/
|