autohand-cli 0.8.2 → 0.9.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/README.md +173 -74
- package/dist/AgentRegistry-EGBDIUAK.cjs +10 -0
- package/dist/{AgentRegistry-7LDL5HJH.js → AgentRegistry-XPWSVO3Q.js} +3 -3
- package/dist/{AutomodeManager-MWLKGPZK.js → AutomodeManager-APLLPEYJ.js} +32 -18
- package/dist/{AutomodeManager-NYIZNODK.cjs → AutomodeManager-MPSXT2RH.cjs} +38 -24
- package/dist/CommunitySkillsCache-2OIUV227.cjs +8 -0
- package/dist/CommunitySkillsCache-ZEQWP6YM.js +8 -0
- package/dist/GitHubRegistryFetcher-CYJLF2XL.cjs +7 -0
- package/dist/{GitHubRegistryFetcher-6JQ5JEDZ.js → GitHubRegistryFetcher-J2BWPXJF.js} +2 -2
- package/dist/HookManager-CWLTFKWO.js +7 -0
- package/dist/HookManager-TMAJQU4S.cjs +7 -0
- package/dist/{ImportWizard-35YBJ4AM.cjs → ImportWizard-MQXEED2U.cjs} +41 -17
- package/dist/{ImportWizard-XH7CINCH.js → ImportWizard-QBKQEXDW.js} +35 -11
- package/dist/LearnAdvisor-46FG2XIP.js +9 -0
- package/dist/LearnAdvisor-XBRDNAGH.cjs +9 -0
- package/dist/McpClientManager-BNSKLHIN.cjs +8 -0
- package/dist/{McpClientManager-7RM6YT35.js → McpClientManager-SL35BR24.js} +2 -2
- package/dist/MemoryManager-34L4YOKA.cjs +8 -0
- package/dist/MemoryManager-WJMLPWGU.js +8 -0
- package/dist/NVIDIAProvider-2HR737UE.js +14 -0
- package/dist/NVIDIAProvider-MVTL62PR.cjs +14 -0
- package/dist/PermissionManager-5OOJ7FAT.cjs +11 -0
- package/dist/{PermissionManager-ATUV34LQ.js → PermissionManager-KMYILJ4Z.js} +4 -4
- package/dist/{ProjectProfiler-ZDWR2ODG.cjs → ProjectProfiler-CDAE7ECW.cjs} +2 -1
- package/dist/{ProjectProfiler-UMJJSOCE.js → ProjectProfiler-NZTJDRHD.js} +2 -1
- package/dist/ProviderFactory-C3YPXTDD.cjs +11 -0
- package/dist/ProviderFactory-HFPRVQ25.js +11 -0
- package/dist/SessionManager-PNBTJJTQ.js +10 -0
- package/dist/SessionManager-WAPTFMDO.cjs +10 -0
- package/dist/SkillsRegistry-4RRD5GMX.js +9 -0
- package/dist/SkillsRegistry-7AJP74GJ.cjs +9 -0
- package/dist/SubAgent-FDIH3DXB.js +11 -0
- package/dist/SubAgent-HVL2ICVZ.cjs +11 -0
- package/dist/{SyncApiClient-LVIO4C2S.js → SyncApiClient-LRPFNCKJ.js} +2 -2
- package/dist/SyncApiClient-VMBOLQ6H.cjs +11 -0
- package/dist/about-BW3PDZUU.js +14 -0
- package/dist/about-FCAX37YC.cjs +14 -0
- package/dist/acp-EOETGAHC.cjs +1517 -0
- package/dist/acp-VHEL7BOW.js +1517 -0
- package/dist/actionExecutor-33I47NZS.js +24 -0
- package/dist/actionExecutor-4YBMR3YH.cjs +24 -0
- package/dist/add-dir-7SS6KSH5.cjs +11 -0
- package/dist/add-dir-VFX7QT4E.js +11 -0
- package/dist/agent-DMRUFU4M.cjs +116 -0
- package/dist/agent-WCJEYQJT.js +116 -0
- package/dist/agents/builtin/code-cleaner.md +1 -1
- package/dist/agents/builtin/docs-writer.md +1 -1
- package/dist/agents/builtin/researcher.md +2 -2
- package/dist/agents/builtin/reviewer.md +1 -1
- package/dist/agents/builtin/tester.md +1 -1
- package/dist/agents/builtin/todo-resolver.md +1 -1
- package/dist/agents-CHROO3VU.cjs +17 -0
- package/dist/agents-UVDUL65K.js +17 -0
- package/dist/agents-new-AUBWSOXP.js +17 -0
- package/dist/agents-new-Y562WC47.cjs +17 -0
- package/dist/{autoSkill-6TGBTEQD.js → autoSkill-EFMK6WU6.js} +3 -3
- package/dist/autoSkill-YOLLFTP2.cjs +20 -0
- package/dist/automode-BMYSRM34.js +10 -0
- package/dist/automode-DBLKTTKD.cjs +10 -0
- package/dist/browserToolBridge-BXRQB4B4.cjs +58 -0
- package/dist/browserToolBridge-F5N66PE7.js +58 -0
- package/dist/{cc-7LEIJ3KF.js → cc-AYEP2CA3.js} +1 -1
- package/dist/{cc-Q5MM4AWC.cjs → cc-S2QLQFBR.cjs} +1 -1
- package/dist/chrome-ATC4OO5I.cjs +20 -0
- package/dist/chrome-NHJ44WUN.js +50 -0
- package/dist/chrome-O62WXV7F.js +20 -0
- package/dist/chrome-XHJLCO4M.cjs +50 -0
- package/dist/chromeSkill-53TH55PM.js +105 -0
- package/dist/chromeSkill-THW7N4IY.cjs +105 -0
- package/dist/{chunk-HOAHWIQ5.cjs → chunk-2CGE7ZV3.cjs} +26 -26
- package/dist/chunk-2H5O745H.js +63 -0
- package/dist/chunk-2HOLOHVK.js +2219 -0
- package/dist/{chunk-3PDTTAKJ.js → chunk-2QL6MNXG.js} +15 -8
- package/dist/{chunk-PGRH5Q77.cjs → chunk-2VHB43IX.cjs} +35 -6
- package/dist/{chunk-VG34MG2U.js → chunk-37M5UM6I.js} +9 -6
- package/dist/{chunk-6HYLHBQG.cjs → chunk-3DDL2E55.cjs} +20 -16
- package/dist/chunk-3EDDDZS2.cjs +5 -0
- package/dist/{chunk-6OYHF6MF.js → chunk-3GUEUCZK.js} +28 -4
- package/dist/{chunk-N254NRHT.cjs → chunk-3HT76LNN.cjs} +9 -2
- package/dist/{chunk-DVUHHH3B.cjs → chunk-3KLSNNRW.cjs} +4 -4
- package/dist/chunk-3LJJG5YY.cjs +387 -0
- package/dist/chunk-3OF56EMA.cjs +197 -0
- package/dist/chunk-3PXKRVCW.js +108 -0
- package/dist/{chunk-IKGWDOGU.cjs → chunk-3S563FNF.cjs} +160 -79
- package/dist/chunk-3UT7R3XV.js +663 -0
- package/dist/chunk-4256YRCO.cjs +80 -0
- package/dist/chunk-46C73ZKK.cjs +663 -0
- package/dist/chunk-46MTALKD.js +44 -0
- package/dist/{chunk-AEJH23FO.cjs → chunk-47PHDKNW.cjs} +6 -6
- package/dist/chunk-4LMUDS2K.js +124 -0
- package/dist/{chunk-HLHTG5ZU.cjs → chunk-5CMYEM3R.cjs} +14 -12
- package/dist/{chunk-MBBY4ZIK.js → chunk-5F6ZKSHO.js} +4 -1
- package/dist/chunk-5JFTY3VU.js +74 -0
- package/dist/chunk-5JTTM5SC.js +59 -0
- package/dist/{chunk-IETRBBMP.cjs → chunk-5K3CDSWZ.cjs} +108 -31
- package/dist/{chunk-GJH7XMSK.js → chunk-5VHP6HDQ.js} +8 -6
- package/dist/{chunk-6ZCULLCA.js → chunk-62RTC3XX.js} +1 -1
- package/dist/{chunk-MSED7RH2.cjs → chunk-6GUODJKM.cjs} +112 -41
- package/dist/{chunk-47CKWKEX.cjs → chunk-6HH236FV.cjs} +9 -4
- package/dist/{chunk-WHE2SWHU.js → chunk-6NVAK6CK.js} +2 -2
- package/dist/chunk-6R25D2H5.js +121 -0
- package/dist/{chunk-3PCTTUNW.cjs → chunk-6XVVIY54.cjs} +55 -25
- package/dist/{chunk-3L53OA4E.cjs → chunk-75EDROHL.cjs} +10 -10
- package/dist/{chunk-G4CAKI3V.js → chunk-7HPWMALN.js} +7 -2
- package/dist/chunk-7JLT2VNW.cjs +18963 -0
- package/dist/chunk-7LWQCE4Y.cjs +987 -0
- package/dist/{chunk-OLSBBZW6.cjs → chunk-7MU7LWF3.cjs} +5 -5
- package/dist/{chunk-HLQV64Y5.js → chunk-7RFJB75Y.js} +140 -59
- package/dist/{chunk-X2MSVKDV.js → chunk-A7HHCIDQ.js} +2 -2
- package/dist/{chunk-SKYG33B2.cjs → chunk-AC7DZ6SK.cjs} +3 -3
- package/dist/{chunk-XX2ZO7DS.js → chunk-ACDQGA4Z.js} +90 -16
- package/dist/{chunk-CZXGCVTR.cjs → chunk-AOKCI722.cjs} +2 -2
- package/dist/chunk-ARBEHFCG.js +715 -0
- package/dist/{chunk-OOKY3HPZ.js → chunk-AT7OWLY5.js} +50 -9
- package/dist/chunk-AU6JAGZJ.cjs +231 -0
- package/dist/chunk-AUFNACED.js +18963 -0
- package/dist/{chunk-CDBPBM2K.cjs → chunk-AUYSIEVV.cjs} +3 -3
- package/dist/chunk-B4HSNOIH.cjs +354 -0
- package/dist/{chunk-EGMZDTSL.js → chunk-B5CGDNMR.js} +10 -2
- package/dist/{chunk-34M3HWLR.js → chunk-BFQDQRDE.js} +2 -2
- package/dist/{chunk-2AA5MFES.js → chunk-BL2UC7HC.js} +8 -5
- package/dist/{chunk-LNMYK2F5.cjs → chunk-BQ22N3TX.cjs} +56 -41
- package/dist/chunk-BQU3HAE7.js +21 -0
- package/dist/chunk-BWF4VDYE.js +3897 -0
- package/dist/chunk-BYE7RQFZ.cjs +121 -0
- package/dist/{chunk-APIXPPMT.js → chunk-CBFH2J3O.js} +855 -33
- package/dist/chunk-CCVMREXI.js +420 -0
- package/dist/chunk-CFAWTLSC.js +13 -0
- package/dist/{chunk-G27PQQFD.js → chunk-CFFE4VA3.js} +1 -1
- package/dist/{chunk-ZYQMLKOK.cjs → chunk-CH2J4PVE.cjs} +212 -70
- package/dist/{chunk-7BTSG4ME.cjs → chunk-CHI52KFR.cjs} +855 -33
- package/dist/{chunk-DJDE4DTT.cjs → chunk-CWINVFRI.cjs} +25 -19
- package/dist/{chunk-HXGBSJL5.cjs → chunk-D2OSPLYC.cjs} +2 -2
- package/dist/{chunk-GBHDROGL.js → chunk-D6GZBSOX.js} +16 -4
- package/dist/{chunk-CNBKZEX5.cjs → chunk-DA7NBAJK.cjs} +49 -17
- package/dist/chunk-DEQVRSV5.cjs +866 -0
- package/dist/{chunk-RGR6ME5J.cjs → chunk-DI57A4BX.cjs} +25 -28
- package/dist/{chunk-WM5PAOTQ.cjs → chunk-DIZTWFVR.cjs} +1649 -484
- package/dist/{chunk-YZXUDM5X.js → chunk-DLP436GI.js} +204 -62
- package/dist/{chunk-OHUZKDGX.js → chunk-DMRXF5DU.js} +3 -3
- package/dist/{chunk-U46VYPLR.cjs → chunk-DPSIGY6L.cjs} +9 -9
- package/dist/{chunk-DN573ME7.cjs → chunk-DRWDEHE5.cjs} +4 -4
- package/dist/{chunk-SEKD5FH3.cjs → chunk-E26KKI46.cjs} +5 -2
- package/dist/{chunk-J4Q7XR3G.js → chunk-E46DJH5S.js} +3 -3
- package/dist/{chunk-Q7XSCYND.cjs → chunk-E6GFD7VR.cjs} +49 -26
- package/dist/chunk-ES2HJQ4N.js +37 -0
- package/dist/chunk-EZJHLOWP.js +80 -0
- package/dist/chunk-FFBDRUO5.cjs +59 -0
- package/dist/{chunk-AYSFIUFW.js → chunk-FGT6KK6T.js} +38 -15
- package/dist/{chunk-SAHBLB3E.js → chunk-FP46B4X3.js} +208 -3
- package/dist/{chunk-DSPQEHDT.js → chunk-FQAVGSPW.js} +2 -2
- package/dist/chunk-FQVG6ZHF.js +197 -0
- package/dist/chunk-GBMDFWJX.cjs +152 -0
- package/dist/{chunk-DRE2RXBZ.js → chunk-GGLKUENP.js} +1605 -440
- package/dist/{chunk-S52YW5ZQ.js → chunk-GNBBIAMD.js} +16 -19
- package/dist/{chunk-MYISNQH4.js → chunk-GWO66KBI.js} +1 -1
- package/dist/chunk-GWY26SUD.cjs +63 -0
- package/dist/{chunk-YGN4CQIP.js → chunk-GZ6DV2UG.js} +1 -1
- package/dist/{chunk-EZMINVLU.js → chunk-H4D2Q2AL.js} +5 -2
- package/dist/chunk-HDK2EHVH.cjs +570 -0
- package/dist/chunk-HJIXWGQZ.js +139 -0
- package/dist/{chunk-6RF7UKUS.js → chunk-HKYZSUQ5.js} +48 -47
- package/dist/{chunk-LQGVEP3E.js → chunk-HQUSEWT4.js} +45 -13
- package/dist/{chunk-HTLINWX6.cjs → chunk-HQWQZML5.cjs} +16 -13
- package/dist/{chunk-DVZOENQ7.cjs → chunk-HS4USDND.cjs} +9 -4
- package/dist/chunk-HSCUPEA4.cjs +3897 -0
- package/dist/{chunk-JCLYQ2JC.js → chunk-HXJEGMGB.js} +12 -6
- package/dist/{chunk-LJFUXC56.cjs → chunk-HXQREVTA.cjs} +9 -6
- package/dist/{chunk-SCXX4LW5.js → chunk-I24CWKKK.js} +15 -8
- package/dist/chunk-IAGCRVJ3.js +355 -0
- package/dist/chunk-IEXKKKOF.cjs +92 -0
- package/dist/{chunk-5IXII4HX.cjs → chunk-IGMPWJ2I.cjs} +19 -12
- package/dist/chunk-IKUMVBCW.cjs +33 -0
- package/dist/{chunk-XTB6VJVQ.cjs → chunk-J2K57QM7.cjs} +6 -6
- package/dist/{chunk-O4IF4NJT.cjs → chunk-J5ADZN6V.cjs} +57 -56
- package/dist/chunk-J5HE6CUM.cjs +124 -0
- package/dist/{chunk-JS7IPR7P.js → chunk-JAQO6XDB.js} +31 -2
- package/dist/chunk-JIMSII7R.js +987 -0
- package/dist/chunk-JJ4KA7HK.cjs +2219 -0
- package/dist/chunk-JMN3GZU6.js +570 -0
- package/dist/{chunk-X5VSP65C.cjs → chunk-JP3YHTQ2.cjs} +4 -4
- package/dist/{chunk-SKV2F3NM.js → chunk-JYKPWK5O.js} +1 -1
- package/dist/{chunk-NNPAM4HC.cjs → chunk-KNTUI4TZ.cjs} +12 -6
- package/dist/{chunk-HIVRCQS2.js → chunk-L4F7SUYL.js} +56 -25
- package/dist/{chunk-C5IJIM2V.cjs → chunk-LDJQ5QHG.cjs} +68 -37
- package/dist/{chunk-ULQ6MDSJ.cjs → chunk-LFDPTJYF.cjs} +43 -35
- package/dist/chunk-LJD7KR3L.cjs +44 -0
- package/dist/chunk-LN7D3EJZ.js +387 -0
- package/dist/{chunk-643VRA5S.cjs → chunk-LQBONA55.cjs} +32 -8
- package/dist/{chunk-NCC6ETZS.js → chunk-LUMV3DB2.js} +41 -33
- package/dist/chunk-M4KNC5BQ.js +78 -0
- package/dist/chunk-MO4KP6XS.cjs +229 -0
- package/dist/{chunk-BVKXEQVG.cjs → chunk-MOJ7ADW4.cjs} +22 -10
- package/dist/chunk-MPULXVC4.cjs +715 -0
- package/dist/{chunk-X5YJ34FZ.cjs → chunk-MQESBFBZ.cjs} +46 -23
- package/dist/chunk-MUNUUFU7.cjs +21 -0
- package/dist/{chunk-X3WS5LDG.js → chunk-MX75JYIY.js} +7 -5
- package/dist/chunk-MXVIDIC6.cjs +139 -0
- package/dist/{chunk-3K2ESU53.cjs → chunk-N6O3XUZ2.cjs} +2 -2
- package/dist/{chunk-IVM5F2AE.js → chunk-NBGOIFKP.js} +265 -18
- package/dist/{chunk-SLQAYV3W.js → chunk-NMQ47RCG.js} +8 -2
- package/dist/{chunk-JYTDYJVW.js → chunk-O64I2GYI.js} +1 -1
- package/dist/{chunk-IFFXSTOM.cjs → chunk-O6TQP7U7.cjs} +3 -3
- package/dist/{chunk-AYS2ASM7.js → chunk-OHWMWKJQ.js} +1 -1
- package/dist/{chunk-N23UAW4I.js → chunk-OM24WXEE.js} +7 -2
- package/dist/{chunk-MAKMSQMQ.cjs → chunk-OPNI6O7F.cjs} +8 -6
- package/dist/chunk-OR67YXQK.cjs +13 -0
- package/dist/{chunk-QOXPOR5D.js → chunk-OV3PVUYN.js} +115 -44
- package/dist/{chunk-TNZRZQ7Q.js → chunk-PB7W7R72.js} +3 -78
- package/dist/chunk-PCM3N3CL.cjs +37 -0
- package/dist/{chunk-A4IJHHV7.cjs → chunk-PDHT7LQS.cjs} +52 -11
- package/dist/{chunk-LA7H35XM.cjs → chunk-PHJO5YAL.cjs} +9 -9
- package/dist/{chunk-KPELYZ6L.js → chunk-PQLKJCIE.js} +2 -2
- package/dist/chunk-PUD76XQT.cjs +78 -0
- package/dist/chunk-Q2IL4DDI.cjs +355 -0
- package/dist/{chunk-WPVWQSL7.cjs → chunk-Q6AC3PHY.cjs} +16 -13
- package/dist/{chunk-XRZEUWKF.js → chunk-QCHIDZBA.js} +1 -1
- package/dist/{chunk-IQ5RXU6O.js → chunk-QEGOB6QV.js} +1 -1
- package/dist/{chunk-JSBRDJBE.js → chunk-QGM4M3NI.js} +8 -1
- package/dist/chunk-QKP772OZ.js +4291 -0
- package/dist/chunk-QQ7PANOP.js +59 -0
- package/dist/{chunk-YHD6TUIR.cjs → chunk-QW2RW2GY.cjs} +2 -0
- package/dist/chunk-RAKO7UN7.js +114 -0
- package/dist/chunk-RBHANOYY.js +33 -0
- package/dist/chunk-RBZ7AFX7.cjs +29 -0
- package/dist/{chunk-TXSDBGKX.cjs → chunk-REMGR23V.cjs} +46 -49
- package/dist/chunk-ROLA6EFO.cjs +85 -0
- package/dist/{chunk-TBEGGJNC.cjs → chunk-SOLBYSLY.cjs} +33 -16
- package/dist/{chunk-FKSDEWDH.js → chunk-SWCQM52V.js} +68 -25
- package/dist/{chunk-H5SWOLG6.js → chunk-TBOLJDUG.js} +39 -24
- package/dist/chunk-TH26BQJG.js +101 -0
- package/dist/{chunk-245KJE5Y.cjs → chunk-TJNBASFD.cjs} +14 -6
- package/dist/chunk-TKKN34TV.js +229 -0
- package/dist/chunk-TQ33WBY5.cjs +74 -0
- package/dist/{chunk-EGFT4PGW.js → chunk-TWQDAUZU.js} +5 -2
- package/dist/{chunk-OGV4WJ5L.cjs → chunk-TXPSTCG7.cjs} +74 -59
- package/dist/{chunk-CAMZTXV6.js → chunk-U4C3HW6P.js} +67 -52
- package/dist/{chunk-5P2NXKP3.js → chunk-UEIXJG45.js} +104 -76
- package/dist/{chunk-22D2CNTP.cjs → chunk-UGFVM77J.cjs} +5 -2
- package/dist/chunk-UOQECODR.js +34 -0
- package/dist/chunk-UR27UDTB.js +354 -0
- package/dist/chunk-UWFG2R2I.cjs +420 -0
- package/dist/{chunk-Y72HH2TF.cjs → chunk-UXLW45ZE.cjs} +102 -28
- package/dist/{chunk-FPHU2ES6.cjs → chunk-VBOFPU5M.cjs} +6 -0
- package/dist/{chunk-JX3DFKBI.js → chunk-VDWJMWDF.js} +54 -24
- package/dist/{chunk-LENHP55G.cjs → chunk-VGEV44V2.cjs} +1076 -158
- package/dist/{chunk-33RSHBDH.js → chunk-VKBIE6I6.js} +38 -7
- package/dist/{chunk-CWMZKFTT.js → chunk-VRMZO6TB.js} +31 -8
- package/dist/chunk-VUGOOGHB.js +400 -0
- package/dist/chunk-WBU4Q4GS.cjs +400 -0
- package/dist/chunk-WGLBC5AY.cjs +59 -0
- package/dist/{chunk-KWXVKLQ5.cjs → chunk-WGNMOVMT.cjs} +7 -82
- package/dist/{chunk-RKJTGGMU.cjs → chunk-WKRDBCP2.cjs} +221 -16
- package/dist/chunk-WRTXCQ3V.cjs +4291 -0
- package/dist/chunk-WTB7AFL6.cjs +101 -0
- package/dist/{chunk-NDMIPTV4.js → chunk-WZV6UVPY.js} +8 -3
- package/dist/chunk-XF2WIKHR.cjs +34 -0
- package/dist/{chunk-L3WAH3EM.cjs → chunk-XGMI6IYB.cjs} +46 -15
- package/dist/{chunk-FW774QXH.js → chunk-XIVFAD2L.js} +1048 -130
- package/dist/chunk-XV2HXRHX.js +85 -0
- package/dist/{chunk-72FKPBT5.js → chunk-Y3M2DABP.js} +16 -12
- package/dist/{chunk-QNGEW5TC.js → chunk-YV63VW4K.js} +1 -1
- package/dist/{chunk-UJ2JSM6H.js → chunk-YVQI26H4.js} +2 -0
- package/dist/{chunk-RD5XAJR2.cjs → chunk-YWTIXHU6.cjs} +266 -19
- package/dist/chunk-YZWE7XSM.js +5 -0
- package/dist/{chunk-I5IW3T2Y.js → chunk-Z3XSSF7B.js} +32 -15
- package/dist/{chunk-6UJMCWRY.js → chunk-Z4LIPMPM.js} +6 -0
- package/dist/chunk-ZASDSY7P.cjs +114 -0
- package/dist/{chunk-R33VKSH5.cjs → chunk-ZHJ7JGME.cjs} +11 -11
- package/dist/chunk-ZPD2AO3U.js +866 -0
- package/dist/{chunk-7UOUW76C.js → chunk-ZQAT5VT5.js} +101 -24
- package/dist/chunk-ZR46OJNZ.js +152 -0
- package/dist/{chunk-G3V4SFET.cjs → chunk-ZZ63NW7A.cjs} +78 -35
- package/dist/clear-33TWQ2ES.cjs +12 -0
- package/dist/clear-OFLFQ3MR.js +12 -0
- package/dist/{communityInstaller-6KCFN7YZ.js → communityInstaller-COB2KTOW.js} +9 -6
- package/dist/communityInstaller-TWMGPSYM.cjs +22 -0
- package/dist/completion-IIZMHXYP.cjs +17 -0
- package/dist/completion-PT4VM2H2.js +17 -0
- package/dist/config-KL6WU7R2.cjs +20 -0
- package/dist/{config-ZN66VXPS.js → config-R4O7GBTY.js} +7 -5
- package/dist/{constants-UFM5B232.js → constants-HVCHVQAF.js} +2 -2
- package/dist/constants-RLMJ5D5P.cjs +21 -0
- package/dist/{defaultHooks-RCXPHF4M.cjs → defaultHooks-2V2CQL63.cjs} +26 -11
- package/dist/{defaultHooks-RDRMER3Z.js → defaultHooks-TMHDU3FS.js} +26 -11
- package/dist/export-3PK3VFCE.js +15 -0
- package/dist/export-WLGNWEMJ.cjs +15 -0
- package/dist/{extractSessionMemories-V7K42ZHW.js → extractSessionMemories-A2JX5WJ2.js} +1 -1
- package/dist/{extractSessionMemories-SDW2MVBQ.cjs → extractSessionMemories-XL3MS37F.cjs} +1 -1
- package/dist/feedback-G635NCLJ.js +18 -0
- package/dist/feedback-LLMK3TZH.cjs +18 -0
- package/dist/fffSearchProvider-2YCNKOYD.js +412 -0
- package/dist/fffSearchProvider-W6627E2V.cjs +412 -0
- package/dist/filesystem-L6DQKGWK.js +11 -0
- package/dist/filesystem-PGUPCMVK.cjs +11 -0
- package/dist/{formatters-6K7QVWQL.cjs → formatters-53XTCNGQ.cjs} +1 -1
- package/dist/{formatters-DQHO5I36.js → formatters-T6KV4BPP.js} +1 -1
- package/dist/help-BAXLP2M2.cjs +12 -0
- package/dist/{help-2BLR7L43.js → help-X3OAZ3CY.js} +3 -3
- package/dist/history-6HOJSEMT.cjs +14 -0
- package/dist/{history-5FZ3M2AK.js → history-YKFPHBJN.js} +3 -3
- package/dist/hooks-7TA4PIIB.js +18 -0
- package/dist/hooks-XVFU67T2.cjs +18 -0
- package/dist/{i18n-K7QOWIBH.js → i18n-2KBUU7XL.js} +2 -2
- package/dist/i18n-MUJMKTFM.cjs +33 -0
- package/dist/ide-CCQ33PGC.cjs +15 -0
- package/dist/ide-VLVFBZ5F.js +15 -0
- package/dist/immediateCommandRouter-MTEHZXQX.js +15 -0
- package/dist/immediateCommandRouter-ROXU3MWT.cjs +15 -0
- package/dist/{import-UXM3VK7B.js → import-4CHYLS4K.js} +4 -4
- package/dist/{import-QEME3E4T.cjs → import-I7T4ZHYL.cjs} +4 -4
- package/dist/import-J46F54JY.cjs +10 -0
- package/dist/import-JWPYKXCZ.js +10 -0
- package/dist/index.cjs +747 -22356
- package/dist/index.d.cts +93 -0
- package/dist/index.d.ts +93 -0
- package/dist/index.js +786 -22395
- package/dist/init-262MWZV4.js +10 -0
- package/dist/init-EE5Y7RBL.cjs +10 -0
- package/dist/inkMode-VUE6ZDLD.cjs +7 -0
- package/dist/inkMode-WBNFOSAT.js +7 -0
- package/dist/inputPrompt-IIFKCX5Q.cjs +90 -0
- package/dist/inputPrompt-YGBHDUEP.js +90 -0
- package/dist/language-CVLPB7OV.js +21 -0
- package/dist/language-ZTWFHUSV.cjs +21 -0
- package/dist/learn-PON7I5QS.js +23 -0
- package/dist/learn-XLRSVNA3.cjs +23 -0
- package/dist/{lint-D5UOJWIK.cjs → lint-4NDGCSCL.cjs} +1 -1
- package/dist/{lint-NJPZWVN2.js → lint-FZ7ZJUB3.js} +1 -1
- package/dist/login-223QTGBG.cjs +26 -0
- package/dist/login-6IKTBUBY.js +26 -0
- package/dist/logout-RN2AG6SI.js +23 -0
- package/dist/logout-U3M4FFX7.cjs +23 -0
- package/dist/mcp-5O6PUL4G.js +20 -0
- package/dist/mcp-NUQ76QQB.cjs +20 -0
- package/dist/{mcp-install-VESN42PI.js → mcp-install-6XWXLFVY.js} +18 -11
- package/dist/{mcp-install-G27HSS3Z.cjs → mcp-install-P6DHES7V.cjs} +22 -15
- package/dist/memory-CYMDQ2YC.cjs +10 -0
- package/dist/memory-Q54CESNM.js +10 -0
- package/dist/{message-ZJ5AYAMT.cjs → message-4OKO775J.cjs} +1 -1
- package/dist/{message-JUBOK2VU.js → message-X3LOAAM7.js} +1 -1
- package/dist/model-6AJ77PJG.js +10 -0
- package/dist/model-IDRCKDML.cjs +10 -0
- package/dist/new-7LEWOUF2.cjs +12 -0
- package/dist/new-ZXHEWC2S.js +12 -0
- package/dist/onboarding-FXX7YHSJ.cjs +35 -0
- package/dist/onboarding-JYNMK6NI.js +35 -0
- package/dist/{patch-MOD7QC3D.cjs → patch-DJ2GPFST.cjs} +1 -1
- package/dist/{patch-5F6VBIT3.js → patch-NIJWIRHS.js} +1 -1
- package/dist/permissions-YBNSANIA.cjs +10 -0
- package/dist/permissions-YHJMVA6L.js +10 -0
- package/dist/plan-XEJMOT55.cjs +13 -0
- package/dist/plan-YYUAXPTL.js +13 -0
- package/dist/pr-review-CW6J7P62.cjs +9 -0
- package/dist/pr-review-YZSBQVT2.js +9 -0
- package/dist/quit-B43SJ6E4.cjs +10 -0
- package/dist/quit-GWTNHQSP.js +10 -0
- package/dist/rawMode-6W5AXAKI.cjs +7 -0
- package/dist/rawMode-GFNLXQPU.js +7 -0
- package/dist/{registry-KWZGYJC2.js → registry-34GL6BNJ.js} +30 -45
- package/dist/{registry-YN4FQPOO.cjs → registry-V24W7YK6.cjs} +66 -81
- package/dist/repeat-P4FAPE3Y.cjs +17 -0
- package/dist/repeat-RALE6AUO.js +17 -0
- package/dist/resume-DYVOQN5L.cjs +16 -0
- package/dist/resume-M25UQKOX.js +16 -0
- package/dist/review-QHP2KP4Q.js +9 -0
- package/dist/review-UWHWQHCB.cjs +9 -0
- package/dist/ripgrep-67SCU2BA.cjs +9 -0
- package/dist/ripgrep-VHJQQ55W.js +9 -0
- package/dist/rpc-NPS3PU4O.cjs +3730 -0
- package/dist/rpc-S3DGW6KV.js +3730 -0
- package/dist/search-CPX4PWHP.js +20 -0
- package/dist/search-VUF3M4N3.cjs +20 -0
- package/dist/{session-BSU2L5UI.cjs → session-LXKC4X5Q.cjs} +1 -1
- package/dist/{session-SZMRN5KG.js → session-NMMO4QOL.js} +1 -1
- package/dist/sessions-IYAXMK23.js +10 -0
- package/dist/sessions-JODKER5D.cjs +10 -0
- package/dist/settings-55BNW6BF.js +33 -0
- package/dist/settings-BKTS7OMC.cjs +33 -0
- package/dist/setup-IRC5HQG2.js +29 -0
- package/dist/setup-MMQ7TWOP.cjs +29 -0
- package/dist/share-6JRQECAH.cjs +17 -0
- package/dist/share-YM5MJKMO.js +17 -0
- package/dist/{skills-FYY6F2WV.cjs → skills-GGMZOVIE.cjs} +14 -11
- package/dist/skills-LWSOKOSH.cjs +29 -0
- package/dist/{skills-6OL4OSGA.js → skills-MVIZNHT4.js} +13 -10
- package/dist/skills-VWOMV3CR.js +29 -0
- package/dist/{skills-install-6CSWC24P.js → skills-install-QBA5RCV6.js} +22 -71
- package/dist/{skills-install-O3LZ2ETC.cjs → skills-install-VTAMCNNY.cjs} +35 -84
- package/dist/skills-new-GPL46YV2.js +18 -0
- package/dist/skills-new-L5BEZN5V.cjs +18 -0
- package/dist/slashCommands-FBPCIWM5.cjs +95 -0
- package/dist/slashCommands-FCWY5DXW.js +95 -0
- package/dist/status-3B5SDZPL.js +17 -0
- package/dist/status-TTGRF6NC.cjs +17 -0
- package/dist/summarizer-DGPHE5IQ.js +17 -0
- package/dist/summarizer-JNXLUAQG.cjs +17 -0
- package/dist/sync-77CXVVTK.cjs +21 -0
- package/dist/{sync-KWX67OUN.js → sync-7BILIQHP.js} +4 -4
- package/dist/sync-7OKF6636.js +21 -0
- package/dist/sync-EH4K5U3N.cjs +40 -0
- package/dist/{tasks-5FPBIFLC.js → tasks-R5MBGAQ6.js} +1 -1
- package/dist/{tasks-TXGKGNH6.cjs → tasks-V4WB3MFR.cjs} +1 -1
- package/dist/{team-5YXP3JGR.js → team-JESCHGWB.js} +1 -1
- package/dist/{team-IIWEZKNR.cjs → team-VQQKWGZB.cjs} +1 -1
- package/dist/{teammate-L6EZQ3I2.js → teammate-GZQSCIMS.js} +29 -8
- package/dist/{teammate-2KMKJXAM.cjs → teammate-J6PHGL23.cjs} +30 -9
- package/dist/theme-64BYGJ57.cjs +21 -0
- package/dist/theme-YJE6HEON.js +21 -0
- package/dist/tools-3PPTTKFV.js +9 -0
- package/dist/tools-THIQA7WC.cjs +9 -0
- package/dist/ui/questionModal.cjs +9 -6
- package/dist/ui/questionModal.js +8 -5
- package/dist/undo-PRTEGL2J.cjs +10 -0
- package/dist/undo-SZEHLX7X.js +10 -0
- package/dist/{update-TVAJMMBC.js → update-53WMKYVS.js} +1 -1
- package/dist/{update-Z6BIIQDC.cjs → update-NV6QRYY7.cjs} +1 -1
- package/dist/web-3BA2WV37.cjs +37 -0
- package/dist/web-6FYGBX5K.js +37 -0
- package/dist/workspaceSafety-MDJGHK6D.cjs +9 -0
- package/dist/workspaceSafety-XOUMUBVB.js +9 -0
- package/dist/yolo-GF2YD7ZI.js +9 -0
- package/dist/yolo-OGDA7HNC.cjs +9 -0
- package/dist/yoloMode-3DJDA75U.cjs +17 -0
- package/dist/yoloMode-4JOOSU26.js +17 -0
- package/package.json +46 -49
- package/dist/AgentRegistry-NQCLWABO.cjs +0 -10
- package/dist/CommunitySkillsCache-6QPRMTJO.js +0 -8
- package/dist/CommunitySkillsCache-GTQMOCCO.cjs +0 -8
- package/dist/GitHubRegistryFetcher-S7QFUEKV.cjs +0 -7
- package/dist/HookManager-Q2KYMCP4.cjs +0 -7
- package/dist/HookManager-TTP4Y6DC.js +0 -7
- package/dist/LearnAdvisor-A4Q5PPBI.js +0 -9
- package/dist/LearnAdvisor-GASQD7HT.cjs +0 -9
- package/dist/McpClientManager-RKD7C6OY.cjs +0 -8
- package/dist/MemoryManager-GUNLRP5S.js +0 -8
- package/dist/MemoryManager-TNSGKDKX.cjs +0 -8
- package/dist/PermissionManager-KMN53FJP.cjs +0 -11
- package/dist/ProviderFactory-MR5B23QJ.js +0 -9
- package/dist/ProviderFactory-VFGCJJX6.cjs +0 -9
- package/dist/SessionManager-FEUAU3ZJ.cjs +0 -10
- package/dist/SessionManager-IKWAK2PI.js +0 -10
- package/dist/SkillsRegistry-KPQFTRIT.cjs +0 -9
- package/dist/SkillsRegistry-XJSKPDF2.js +0 -9
- package/dist/SubAgent-NYH6GWQ3.js +0 -11
- package/dist/SubAgent-PZKBDUBA.cjs +0 -11
- package/dist/SyncApiClient-ZNYMT36M.cjs +0 -11
- package/dist/about-HHTF2YFL.js +0 -12
- package/dist/about-JGRVNNQC.cjs +0 -12
- package/dist/actionExecutor-U6IBN2TU.cjs +0 -19
- package/dist/actionExecutor-XT5FW3W6.js +0 -19
- package/dist/add-dir-247K3XRY.js +0 -10
- package/dist/add-dir-GS4DXKKH.cjs +0 -10
- package/dist/agents-R6ZEFTVR.cjs +0 -12
- package/dist/agents-WJPQWQF2.js +0 -12
- package/dist/agents-new-HKVEIBDJ.js +0 -14
- package/dist/agents-new-X6GTHIO6.cjs +0 -14
- package/dist/autoSkill-H4T6VVDA.cjs +0 -20
- package/dist/automode-BC6NVECO.js +0 -10
- package/dist/automode-WN2RSOGW.cjs +0 -10
- package/dist/chunk-33A755XB.cjs +0 -168
- package/dist/chunk-3OTU3RS3.cjs +0 -1607
- package/dist/chunk-4PKF7WPD.js +0 -100
- package/dist/chunk-ALYU6VTM.js +0 -105
- package/dist/chunk-AS6RTLN7.cjs +0 -203
- package/dist/chunk-BWN2CLLM.cjs +0 -298
- package/dist/chunk-HQ7YZKXE.js +0 -168
- package/dist/chunk-HVKOZ2VP.cjs +0 -115
- package/dist/chunk-J6QET7EF.cjs +0 -454
- package/dist/chunk-LWUJFGOZ.js +0 -115
- package/dist/chunk-P47WPOXN.js +0 -298
- package/dist/chunk-PRRCJFU3.cjs +0 -85
- package/dist/chunk-RO6WYEWH.js +0 -454
- package/dist/chunk-SYVYLZZF.cjs +0 -24
- package/dist/chunk-T73IDKDF.js +0 -111
- package/dist/chunk-YRLYSQEQ.cjs +0 -105
- package/dist/chunk-ZQE72E6W.cjs +0 -100
- package/dist/chunk-ZVY2XD6T.js +0 -1607
- package/dist/clear-UO4MNWZW.cjs +0 -12
- package/dist/clear-ZJ5NYP6E.js +0 -12
- package/dist/communityInstaller-PVSOFDZD.cjs +0 -19
- package/dist/completion-MMF2PN2H.js +0 -14
- package/dist/completion-UI5WKHXI.cjs +0 -14
- package/dist/config-E7RINK4R.cjs +0 -18
- package/dist/constants-6CPCJ3DY.cjs +0 -21
- package/dist/export-N4XIVDSL.cjs +0 -12
- package/dist/export-W22L4D5C.js +0 -12
- package/dist/feedback-DR6ADSNE.cjs +0 -15
- package/dist/feedback-FEEAP4QW.js +0 -15
- package/dist/filesystem-3SGCW2BF.js +0 -10
- package/dist/filesystem-MCFXJQ6R.cjs +0 -10
- package/dist/help-AQHGTS7P.cjs +0 -12
- package/dist/history-NIUDRMKA.cjs +0 -14
- package/dist/hooks-2EY4IPKV.js +0 -13
- package/dist/hooks-LJVORRIG.cjs +0 -13
- package/dist/i18n-ARDG2SMC.cjs +0 -33
- package/dist/ide-GFW6IJHD.js +0 -12
- package/dist/ide-N2ZNSSB3.cjs +0 -12
- package/dist/import-DFVN3KNZ.js +0 -10
- package/dist/import-ZS6DPGU5.cjs +0 -10
- package/dist/init-PY75HA3S.cjs +0 -10
- package/dist/init-QNMWLAVY.js +0 -10
- package/dist/language-5UE4G2BT.cjs +0 -18
- package/dist/language-UXMHEZUJ.js +0 -18
- package/dist/learn-HJ3FLNZC.cjs +0 -20
- package/dist/learn-MVYS3RU5.js +0 -20
- package/dist/localProjectPermissions-N77HA3XK.js +0 -18
- package/dist/localProjectPermissions-UFSMNTBJ.cjs +0 -18
- package/dist/login-DSE7H63A.js +0 -20
- package/dist/login-V3MEWPKN.cjs +0 -20
- package/dist/logout-BMVCLKKW.js +0 -18
- package/dist/logout-XEG7FHOZ.cjs +0 -18
- package/dist/mcp-PYUR4PHO.js +0 -18
- package/dist/mcp-SG6JFLGC.cjs +0 -18
- package/dist/memory-4ZMMEZ2Z.js +0 -10
- package/dist/memory-QSGMVVGH.cjs +0 -10
- package/dist/model-NANLBZ4Z.cjs +0 -10
- package/dist/model-ZXNV4AF7.js +0 -10
- package/dist/new-5QJY5JP2.js +0 -12
- package/dist/new-PMMG55UX.cjs +0 -12
- package/dist/permissions-LECTCJ4H.cjs +0 -13
- package/dist/permissions-VP5VGIBL.js +0 -13
- package/dist/plan-G5CEKJI4.js +0 -11
- package/dist/plan-QKOHE3LH.cjs +0 -11
- package/dist/quit-BKOOPHU5.cjs +0 -10
- package/dist/quit-FVFNYACP.js +0 -10
- package/dist/resume-EXFQSQPH.js +0 -13
- package/dist/resume-PP2IQM5S.cjs +0 -13
- package/dist/search-C56FBN67.cjs +0 -17
- package/dist/search-XGZDYBF4.js +0 -17
- package/dist/sessions-54KI3F2Q.js +0 -10
- package/dist/sessions-DDTSPNVW.cjs +0 -10
- package/dist/settings-BDO37TTO.cjs +0 -30
- package/dist/settings-FHRDFPLK.js +0 -30
- package/dist/share-IERCTBGN.cjs +0 -14
- package/dist/share-TGROUE6R.js +0 -14
- package/dist/skills-OM4IGBAA.cjs +0 -26
- package/dist/skills-S3GRN323.js +0 -26
- package/dist/skills-new-ALD2PTHN.js +0 -15
- package/dist/skills-new-PWLKK7GW.cjs +0 -15
- package/dist/slashCommands-L4ZD33LJ.js +0 -75
- package/dist/slashCommands-YY2VUUDF.cjs +0 -75
- package/dist/status-3PC5XWSS.cjs +0 -11
- package/dist/status-KCLVOYPD.js +0 -11
- package/dist/sync-6SDWG5RK.js +0 -18
- package/dist/sync-7JMZVEQD.cjs +0 -40
- package/dist/sync-WHURZL3U.cjs +0 -18
- package/dist/theme-BE5A4FPN.cjs +0 -18
- package/dist/theme-YMFCQP7J.js +0 -18
- package/dist/undo-KZHUUZTD.cjs +0 -10
- package/dist/undo-NEIEHQVX.js +0 -10
|
@@ -0,0 +1,987 @@
|
|
|
1
|
+
import {
|
|
2
|
+
package_default
|
|
3
|
+
} from "./chunk-3PXKRVCW.js";
|
|
4
|
+
import {
|
|
5
|
+
ApiError
|
|
6
|
+
} from "./chunk-FQVG6ZHF.js";
|
|
7
|
+
import {
|
|
8
|
+
themedFg
|
|
9
|
+
} from "./chunk-JAQO6XDB.js";
|
|
10
|
+
import {
|
|
11
|
+
AUTOHAND_FILES,
|
|
12
|
+
AUTOHAND_PATHS
|
|
13
|
+
} from "./chunk-TWQDAUZU.js";
|
|
14
|
+
|
|
15
|
+
// src/utils/sessionWorktree.ts
|
|
16
|
+
import { spawnSync } from "child_process";
|
|
17
|
+
import { existsSync } from "fs";
|
|
18
|
+
import path from "path";
|
|
19
|
+
import crypto from "crypto";
|
|
20
|
+
function runGit(cwd, args) {
|
|
21
|
+
const result = spawnSync("git", args, {
|
|
22
|
+
cwd,
|
|
23
|
+
encoding: "utf8"
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
stdout: result.stdout ?? "",
|
|
27
|
+
stderr: result.stderr ?? "",
|
|
28
|
+
status: result.status
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function ensureGitRepo(cwd) {
|
|
32
|
+
const result = runGit(cwd, ["rev-parse", "--show-toplevel"]);
|
|
33
|
+
if (result.status !== 0) {
|
|
34
|
+
const details = result.stderr.trim() || result.stdout.trim() || "unknown error";
|
|
35
|
+
throw new Error(`--worktree requires a git repository (git rev-parse failed: ${details})`);
|
|
36
|
+
}
|
|
37
|
+
return result.stdout.trim();
|
|
38
|
+
}
|
|
39
|
+
function sanitizeName(input) {
|
|
40
|
+
const trimmed = input.trim();
|
|
41
|
+
const normalized = trimmed.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+/, "").replace(/-+$/, "");
|
|
42
|
+
return normalized || "autohand-worktree";
|
|
43
|
+
}
|
|
44
|
+
function buildAutoBranchName(mode) {
|
|
45
|
+
const ts = Date.now().toString(36);
|
|
46
|
+
const rand = crypto.randomBytes(3).toString("hex");
|
|
47
|
+
return sanitizeName(`autohand-${mode ?? "cli"}-${ts}-${rand}`);
|
|
48
|
+
}
|
|
49
|
+
function branchExists(repoRoot, branchName) {
|
|
50
|
+
const result = runGit(repoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${branchName}`]);
|
|
51
|
+
return result.status === 0;
|
|
52
|
+
}
|
|
53
|
+
function findAvailablePath(basePath) {
|
|
54
|
+
if (!existsSync(basePath)) {
|
|
55
|
+
return basePath;
|
|
56
|
+
}
|
|
57
|
+
for (let i = 2; i < 1e3; i++) {
|
|
58
|
+
const candidate = `${basePath}-${i}`;
|
|
59
|
+
if (!existsSync(candidate)) {
|
|
60
|
+
return candidate;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
throw new Error(`Unable to find available worktree path near ${basePath}`);
|
|
64
|
+
}
|
|
65
|
+
function isSessionWorktreeEnabled(worktree) {
|
|
66
|
+
return worktree !== void 0 && worktree !== false;
|
|
67
|
+
}
|
|
68
|
+
function prepareSessionWorktree(input) {
|
|
69
|
+
const repoRoot = ensureGitRepo(input.cwd);
|
|
70
|
+
const branchName = typeof input.worktree === "string" ? sanitizeName(input.worktree) : buildAutoBranchName(input.mode);
|
|
71
|
+
const repoName = path.basename(repoRoot);
|
|
72
|
+
const parentDir = path.dirname(repoRoot);
|
|
73
|
+
const basePath = path.join(parentDir, `${repoName}-${branchName}`);
|
|
74
|
+
const worktreePath = findAvailablePath(basePath);
|
|
75
|
+
const existingBranch = branchExists(repoRoot, branchName);
|
|
76
|
+
const args = existingBranch ? ["worktree", "add", worktreePath, branchName] : ["worktree", "add", "-b", branchName, worktreePath];
|
|
77
|
+
const result = runGit(repoRoot, args);
|
|
78
|
+
if (result.status !== 0) {
|
|
79
|
+
const details = result.stderr.trim() || result.stdout.trim() || "unknown error";
|
|
80
|
+
throw new Error(`Failed to create git worktree: ${details}`);
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
repoRoot,
|
|
84
|
+
worktreePath,
|
|
85
|
+
branchName,
|
|
86
|
+
createdBranch: !existingBranch
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// src/ui/theme/startup.ts
|
|
91
|
+
import chalk from "chalk";
|
|
92
|
+
function formatStartupBanner(logo) {
|
|
93
|
+
return logo.split("\n").map((line, index) => themedFg(index % 2 === 0 ? "accent" : "borderAccent", line, chalk.cyan)).join("\n");
|
|
94
|
+
}
|
|
95
|
+
function formatWelcomeVersionPrefix(version) {
|
|
96
|
+
return `${themedFg("accent", "> Autohand", chalk.bold)} ${themedFg("muted", `v${version}`, chalk.gray)}`;
|
|
97
|
+
}
|
|
98
|
+
function formatUpdateAvailable(version) {
|
|
99
|
+
return themedFg("warning", ` \u2B06 Update available: v${version}`, chalk.yellow);
|
|
100
|
+
}
|
|
101
|
+
function formatUpdateReady() {
|
|
102
|
+
return themedFg("success", " \u2713 Up to date", chalk.green);
|
|
103
|
+
}
|
|
104
|
+
function formatInstallHint(hint) {
|
|
105
|
+
return `${themedFg("muted", " \u21B3 Run: ", chalk.gray)}${themedFg("accent", hint, chalk.cyan)}`;
|
|
106
|
+
}
|
|
107
|
+
function formatWelcomeGreeting(nameOrEmail) {
|
|
108
|
+
return themedFg("success", `Welcome back, ${nameOrEmail}!`, chalk.green);
|
|
109
|
+
}
|
|
110
|
+
function formatWelcomeStatusLine(model, ccEnabled, dir) {
|
|
111
|
+
const ccStatus = ccEnabled ? themedFg("success", "[CC: ON]", chalk.green) : themedFg("warning", "[CC: OFF]", chalk.yellow);
|
|
112
|
+
return [
|
|
113
|
+
themedFg("muted", "model:", chalk.gray),
|
|
114
|
+
themedFg("accent", model, chalk.cyan),
|
|
115
|
+
ccStatus,
|
|
116
|
+
themedFg("muted", "| directory:", chalk.gray),
|
|
117
|
+
themedFg("accent", dir, chalk.cyan)
|
|
118
|
+
].join(" ");
|
|
119
|
+
}
|
|
120
|
+
function formatWelcomeTitle() {
|
|
121
|
+
return themedFg("muted", "To get started, describe a task or try one of these commands:", chalk.gray);
|
|
122
|
+
}
|
|
123
|
+
function formatWelcomeSuggestion(command, description) {
|
|
124
|
+
return themedFg("accent", `${command} `, chalk.cyan) + themedFg("muted", description, chalk.gray);
|
|
125
|
+
}
|
|
126
|
+
function formatSessionEnding() {
|
|
127
|
+
return themedFg("muted", "Ending Autohand session.", chalk.gray);
|
|
128
|
+
}
|
|
129
|
+
function formatSessionSaved(sessionId) {
|
|
130
|
+
return themedFg("accent", `\u{1F4BE} Session saved: ${sessionId}`, chalk.cyan);
|
|
131
|
+
}
|
|
132
|
+
function formatResumeHint(sessionId) {
|
|
133
|
+
return themedFg("muted", ` Resume with: autohand resume ${sessionId}`, chalk.gray);
|
|
134
|
+
}
|
|
135
|
+
function formatExitCleanup() {
|
|
136
|
+
return themedFg("muted", "\nExiting - clearing queues and stopping...", chalk.gray);
|
|
137
|
+
}
|
|
138
|
+
function formatForceExit() {
|
|
139
|
+
return themedFg("muted", "\nForce exiting...", chalk.gray);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/utils/debugLog.ts
|
|
143
|
+
function isAutohandDebugEnabled(env = process.env) {
|
|
144
|
+
const value = env.AUTOHAND_DEBUG?.trim().toLowerCase();
|
|
145
|
+
return value === "1" || value === "true";
|
|
146
|
+
}
|
|
147
|
+
function writeAutohandDebugLine(message, writer) {
|
|
148
|
+
if (!isAutohandDebugEnabled()) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (writer) {
|
|
152
|
+
writer(message);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const line = message.endsWith("\n") ? message : `${message}
|
|
156
|
+
`;
|
|
157
|
+
process.stderr.write(line);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// src/reporting/AutoReportManager.ts
|
|
161
|
+
import crypto3 from "crypto";
|
|
162
|
+
|
|
163
|
+
// src/reporting/AutoReportClient.ts
|
|
164
|
+
import crypto2 from "crypto";
|
|
165
|
+
import fs from "fs-extra";
|
|
166
|
+
import os from "os";
|
|
167
|
+
var DEVICE_ID_FILE = AUTOHAND_FILES.deviceId;
|
|
168
|
+
var AutoReportClient = class {
|
|
169
|
+
apiBaseUrl;
|
|
170
|
+
constructor(apiBaseUrl = "https://api.autohand.ai") {
|
|
171
|
+
this.apiBaseUrl = apiBaseUrl;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Read device ID from ~/.autohand/device-id (shared with telemetry)
|
|
175
|
+
*/
|
|
176
|
+
getDeviceId() {
|
|
177
|
+
try {
|
|
178
|
+
if (fs.existsSync(DEVICE_ID_FILE)) {
|
|
179
|
+
return fs.readFileSync(DEVICE_ID_FILE, "utf8").trim();
|
|
180
|
+
}
|
|
181
|
+
} catch {
|
|
182
|
+
}
|
|
183
|
+
return `anon-${crypto2.randomUUID().slice(0, 8)}`;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Sanitize a string by replacing absolute paths with safe equivalents.
|
|
187
|
+
* Removes user home directories and any user-identifying paths.
|
|
188
|
+
*/
|
|
189
|
+
sanitizePaths(text) {
|
|
190
|
+
const home = os.homedir();
|
|
191
|
+
let sanitized = text;
|
|
192
|
+
sanitized = sanitized.replaceAll(home, "~");
|
|
193
|
+
sanitized = sanitized.replace(/\/Users\/[^/\s:]+/g, "~/...");
|
|
194
|
+
sanitized = sanitized.replace(/\/home\/[^/\s:]+/g, "~/...");
|
|
195
|
+
sanitized = sanitized.replace(/[A-Z]:\\Users\\[^\\\s:]+/gi, "~\\...");
|
|
196
|
+
sanitized = sanitized.replace(/\\\\[^\\]+\\[^\\]+\\[^\\\s:]+/g, "~\\...");
|
|
197
|
+
return sanitized;
|
|
198
|
+
}
|
|
199
|
+
/** @deprecated Use sanitizePaths() instead */
|
|
200
|
+
sanitizeStack(stack) {
|
|
201
|
+
return this.sanitizePaths(stack);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Send an error report to the API
|
|
205
|
+
* NEVER throws - always returns a ReportResponse
|
|
206
|
+
*/
|
|
207
|
+
async report(data) {
|
|
208
|
+
try {
|
|
209
|
+
const payload = {
|
|
210
|
+
...data,
|
|
211
|
+
deviceId: this.getDeviceId(),
|
|
212
|
+
cliVersion: package_default.version,
|
|
213
|
+
platform: process.platform,
|
|
214
|
+
osVersion: os.release(),
|
|
215
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
216
|
+
};
|
|
217
|
+
const controller = new AbortController();
|
|
218
|
+
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
219
|
+
try {
|
|
220
|
+
const response = await fetch(`${this.apiBaseUrl}/v1/reports`, {
|
|
221
|
+
method: "POST",
|
|
222
|
+
headers: {
|
|
223
|
+
"Content-Type": "application/json",
|
|
224
|
+
"X-CLI-Version": package_default.version,
|
|
225
|
+
"X-Device-ID": payload.deviceId
|
|
226
|
+
},
|
|
227
|
+
body: JSON.stringify(payload),
|
|
228
|
+
signal: controller.signal
|
|
229
|
+
});
|
|
230
|
+
clearTimeout(timeoutId);
|
|
231
|
+
if (!response.ok) {
|
|
232
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
233
|
+
return { success: false, error: `HTTP ${response.status}: ${errorText}` };
|
|
234
|
+
}
|
|
235
|
+
const result = await response.json();
|
|
236
|
+
return result;
|
|
237
|
+
} catch (err) {
|
|
238
|
+
clearTimeout(timeoutId);
|
|
239
|
+
if (err.name === "AbortError") {
|
|
240
|
+
return { success: false, error: "Request timeout" };
|
|
241
|
+
}
|
|
242
|
+
return { success: false, error: err.message };
|
|
243
|
+
}
|
|
244
|
+
} catch (err) {
|
|
245
|
+
return { success: false, error: err.message };
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
// src/reporting/AutoReportManager.ts
|
|
251
|
+
var isDebug = () => isAutohandDebugEnabled();
|
|
252
|
+
var AutoReportManager = class _AutoReportManager {
|
|
253
|
+
client;
|
|
254
|
+
reportedHashes = /* @__PURE__ */ new Set();
|
|
255
|
+
enabled;
|
|
256
|
+
constructor(config, _cliVersion) {
|
|
257
|
+
const apiBaseUrl = config.api?.baseUrl || "https://api.autohand.ai";
|
|
258
|
+
this.client = new AutoReportClient(apiBaseUrl);
|
|
259
|
+
this.enabled = config.autoReport?.enabled !== false;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Check if auto-reporting is enabled
|
|
263
|
+
*/
|
|
264
|
+
isEnabled() {
|
|
265
|
+
return this.enabled;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* API error codes that represent expected operational conditions, NOT bugs.
|
|
269
|
+
* These should never be auto-reported as GitHub issues.
|
|
270
|
+
*/
|
|
271
|
+
static OPERATIONAL_API_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
272
|
+
"rate_limited",
|
|
273
|
+
// User hit rate limits — expected, handled by retry
|
|
274
|
+
"cancelled",
|
|
275
|
+
// User cancelled the request
|
|
276
|
+
"timeout",
|
|
277
|
+
// Provider too slow — expected for local inference
|
|
278
|
+
"network_error",
|
|
279
|
+
// Can't reach provider — user's network
|
|
280
|
+
"server_error",
|
|
281
|
+
// Provider is down — not our bug
|
|
282
|
+
"auth_failed",
|
|
283
|
+
// Bad API key — user config issue
|
|
284
|
+
"payment_required",
|
|
285
|
+
// Account billing issue
|
|
286
|
+
"access_denied",
|
|
287
|
+
// API key lacks permissions
|
|
288
|
+
"model_not_found"
|
|
289
|
+
// Wrong model name — user config issue
|
|
290
|
+
]);
|
|
291
|
+
/**
|
|
292
|
+
* Check if an error represents an expected operational condition
|
|
293
|
+
* that should NOT be auto-reported as a bug.
|
|
294
|
+
*/
|
|
295
|
+
isOperationalError(error) {
|
|
296
|
+
if (error instanceof ApiError) {
|
|
297
|
+
return _AutoReportManager.OPERATIONAL_API_ERROR_CODES.has(error.code);
|
|
298
|
+
}
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Compute a simple hash from error name + message for in-session deduplication
|
|
303
|
+
*/
|
|
304
|
+
computeHash(error) {
|
|
305
|
+
const key = `${error.name}:${error.message.slice(0, 200)}`;
|
|
306
|
+
return crypto3.createHash("sha256").update(key).digest("hex").slice(0, 16);
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Report an error to the API
|
|
310
|
+
* NEVER throws - silently handles all failures
|
|
311
|
+
*/
|
|
312
|
+
async reportError(error, context) {
|
|
313
|
+
try {
|
|
314
|
+
if (!this.enabled) return;
|
|
315
|
+
if (this.isOperationalError(error)) {
|
|
316
|
+
if (isDebug()) {
|
|
317
|
+
process.stderr.write(`[autohand:report] Skipping operational error: ${error.code}
|
|
318
|
+
`);
|
|
319
|
+
}
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const hash = this.computeHash(error);
|
|
323
|
+
if (this.reportedHashes.has(hash)) {
|
|
324
|
+
if (isDebug()) {
|
|
325
|
+
process.stderr.write(`[autohand:report] Skipping duplicate error: ${hash}
|
|
326
|
+
`);
|
|
327
|
+
}
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
this.reportedHashes.add(hash);
|
|
331
|
+
const report = {
|
|
332
|
+
errorType: context?.errorType || error.name,
|
|
333
|
+
errorMessage: this.client.sanitizePaths(error.message.slice(0, 500)),
|
|
334
|
+
sanitizedStack: error.stack ? this.client.sanitizePaths(error.stack) : void 0,
|
|
335
|
+
...context
|
|
336
|
+
};
|
|
337
|
+
const result = await this.client.report(report);
|
|
338
|
+
if (result.success) {
|
|
339
|
+
if (isDebug()) {
|
|
340
|
+
process.stderr.write(`[autohand:report] Reported: issue=${result.issueNumber ?? "n/a"} dedup=${result.deduplicated ?? false}
|
|
341
|
+
`);
|
|
342
|
+
}
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
if (isDebug()) {
|
|
346
|
+
process.stderr.write(`[autohand:report] First attempt failed: ${result.error}, retrying...
|
|
347
|
+
`);
|
|
348
|
+
}
|
|
349
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
350
|
+
const retryResult = await this.client.report(report);
|
|
351
|
+
if (isDebug()) {
|
|
352
|
+
if (retryResult.success) {
|
|
353
|
+
process.stderr.write(`[autohand:report] Retry succeeded: issue=${retryResult.issueNumber ?? "n/a"}
|
|
354
|
+
`);
|
|
355
|
+
} else {
|
|
356
|
+
process.stderr.write(`[autohand:report] Retry failed: ${retryResult.error}, giving up
|
|
357
|
+
`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
} catch {
|
|
361
|
+
if (isDebug()) {
|
|
362
|
+
process.stderr.write(`[autohand:report] Unexpected error in reportError, giving up
|
|
363
|
+
`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
// src/telemetry/TelemetryClient.ts
|
|
370
|
+
import fs2 from "fs-extra";
|
|
371
|
+
import path2 from "path";
|
|
372
|
+
import crypto4 from "crypto";
|
|
373
|
+
var TELEMETRY_DIR = AUTOHAND_PATHS.telemetry;
|
|
374
|
+
var QUEUE_FILE = AUTOHAND_FILES.telemetryQueue;
|
|
375
|
+
var DEVICE_ID_FILE2 = AUTOHAND_FILES.deviceId;
|
|
376
|
+
var TelemetryClient = class {
|
|
377
|
+
config;
|
|
378
|
+
queue = [];
|
|
379
|
+
deviceId;
|
|
380
|
+
flushTimer = null;
|
|
381
|
+
isFlushing = false;
|
|
382
|
+
constructor(config = {}) {
|
|
383
|
+
this.config = {
|
|
384
|
+
enabled: false,
|
|
385
|
+
apiBaseUrl: "https://api.autohand.ai",
|
|
386
|
+
batchSize: 20,
|
|
387
|
+
flushIntervalMs: 6e4,
|
|
388
|
+
// 1 minute
|
|
389
|
+
maxQueueSize: 500,
|
|
390
|
+
maxRetries: 3,
|
|
391
|
+
enableSessionSync: false,
|
|
392
|
+
companySecret: "",
|
|
393
|
+
clientType: "cli",
|
|
394
|
+
clientVersion: void 0,
|
|
395
|
+
...config
|
|
396
|
+
};
|
|
397
|
+
this.deviceId = this.getOrCreateDeviceId();
|
|
398
|
+
this.loadQueue();
|
|
399
|
+
this.startFlushTimer();
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Get or create a persistent device ID
|
|
403
|
+
*/
|
|
404
|
+
getOrCreateDeviceId() {
|
|
405
|
+
try {
|
|
406
|
+
fs2.ensureDirSync(path2.dirname(DEVICE_ID_FILE2));
|
|
407
|
+
if (fs2.existsSync(DEVICE_ID_FILE2)) {
|
|
408
|
+
return fs2.readFileSync(DEVICE_ID_FILE2, "utf8").trim();
|
|
409
|
+
}
|
|
410
|
+
const id = crypto4.randomUUID();
|
|
411
|
+
fs2.writeFileSync(DEVICE_ID_FILE2, id);
|
|
412
|
+
return id;
|
|
413
|
+
} catch {
|
|
414
|
+
return crypto4.randomUUID();
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Load queued events from disk (for offline support)
|
|
419
|
+
*/
|
|
420
|
+
loadQueue() {
|
|
421
|
+
try {
|
|
422
|
+
fs2.ensureDirSync(TELEMETRY_DIR);
|
|
423
|
+
if (fs2.existsSync(QUEUE_FILE)) {
|
|
424
|
+
const data = fs2.readFileSync(QUEUE_FILE, "utf8");
|
|
425
|
+
this.queue = JSON.parse(data);
|
|
426
|
+
}
|
|
427
|
+
} catch {
|
|
428
|
+
this.queue = [];
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Persist queue to disk for offline support
|
|
433
|
+
*/
|
|
434
|
+
saveQueue() {
|
|
435
|
+
try {
|
|
436
|
+
fs2.ensureDirSync(TELEMETRY_DIR);
|
|
437
|
+
fs2.writeFileSync(QUEUE_FILE, JSON.stringify(this.queue, null, 2));
|
|
438
|
+
} catch {
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Start periodic flush timer
|
|
443
|
+
*/
|
|
444
|
+
startFlushTimer() {
|
|
445
|
+
if (this.flushTimer) {
|
|
446
|
+
clearInterval(this.flushTimer);
|
|
447
|
+
}
|
|
448
|
+
this.flushTimer = setInterval(() => {
|
|
449
|
+
this.flush().catch(() => {
|
|
450
|
+
});
|
|
451
|
+
}, this.config.flushIntervalMs);
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Stop flush timer
|
|
455
|
+
*/
|
|
456
|
+
stopFlushTimer() {
|
|
457
|
+
if (this.flushTimer) {
|
|
458
|
+
clearInterval(this.flushTimer);
|
|
459
|
+
this.flushTimer = null;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Get device ID
|
|
464
|
+
*/
|
|
465
|
+
getDeviceId() {
|
|
466
|
+
return this.deviceId;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Check if online
|
|
470
|
+
*/
|
|
471
|
+
async isOnline() {
|
|
472
|
+
try {
|
|
473
|
+
const controller = new AbortController();
|
|
474
|
+
const timeout = setTimeout(() => controller.abort(), 3e3);
|
|
475
|
+
const response = await fetch(`${this.config.apiBaseUrl}/health`, {
|
|
476
|
+
method: "GET",
|
|
477
|
+
signal: controller.signal
|
|
478
|
+
});
|
|
479
|
+
clearTimeout(timeout);
|
|
480
|
+
return response.ok;
|
|
481
|
+
} catch {
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Queue an event for sending
|
|
487
|
+
*/
|
|
488
|
+
async track(event) {
|
|
489
|
+
if (!this.config.enabled) return;
|
|
490
|
+
const fullEvent = {
|
|
491
|
+
...event,
|
|
492
|
+
id: crypto4.randomUUID(),
|
|
493
|
+
deviceId: this.deviceId,
|
|
494
|
+
clientType: this.config.clientType,
|
|
495
|
+
clientVersion: this.config.clientVersion,
|
|
496
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
497
|
+
};
|
|
498
|
+
this.queue.push(fullEvent);
|
|
499
|
+
if (this.queue.length > this.config.maxQueueSize) {
|
|
500
|
+
this.queue = this.queue.slice(-this.config.maxQueueSize);
|
|
501
|
+
}
|
|
502
|
+
this.saveQueue();
|
|
503
|
+
if (this.queue.length >= this.config.batchSize) {
|
|
504
|
+
await this.flush();
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Flush queued events to the server
|
|
509
|
+
*/
|
|
510
|
+
async flush() {
|
|
511
|
+
if (!this.config.enabled || this.isFlushing || this.queue.length === 0) {
|
|
512
|
+
return { sent: 0, failed: 0, queued: this.queue.length };
|
|
513
|
+
}
|
|
514
|
+
const online = await this.isOnline();
|
|
515
|
+
if (!online) {
|
|
516
|
+
return { sent: 0, failed: 0, queued: this.queue.length };
|
|
517
|
+
}
|
|
518
|
+
this.isFlushing = true;
|
|
519
|
+
try {
|
|
520
|
+
const eventsToSend = this.queue.slice(0, this.config.batchSize);
|
|
521
|
+
let sent = 0;
|
|
522
|
+
let failed = 0;
|
|
523
|
+
for (let attempt = 0; attempt < this.config.maxRetries; attempt++) {
|
|
524
|
+
try {
|
|
525
|
+
const authToken = `${this.deviceId}.${this.config.companySecret}`;
|
|
526
|
+
const response = await fetch(`${this.config.apiBaseUrl}/v1/telemetry`, {
|
|
527
|
+
method: "POST",
|
|
528
|
+
headers: {
|
|
529
|
+
"Content-Type": "application/json",
|
|
530
|
+
"Authorization": `Bearer ${authToken}`,
|
|
531
|
+
"X-CLI-Version": eventsToSend[0]?.cliVersion || "unknown"
|
|
532
|
+
},
|
|
533
|
+
body: JSON.stringify({ events: eventsToSend })
|
|
534
|
+
});
|
|
535
|
+
if (response.ok) {
|
|
536
|
+
this.queue = this.queue.slice(eventsToSend.length);
|
|
537
|
+
sent = eventsToSend.length;
|
|
538
|
+
this.saveQueue();
|
|
539
|
+
break;
|
|
540
|
+
} else {
|
|
541
|
+
failed = eventsToSend.length;
|
|
542
|
+
}
|
|
543
|
+
} catch {
|
|
544
|
+
failed = eventsToSend.length;
|
|
545
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3 * (attempt + 1)));
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
return { sent, failed, queued: this.queue.length };
|
|
549
|
+
} finally {
|
|
550
|
+
this.isFlushing = false;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Force sync all queued events (called on graceful shutdown)
|
|
555
|
+
*/
|
|
556
|
+
async syncAll() {
|
|
557
|
+
if (!this.config.enabled || this.queue.length === 0) {
|
|
558
|
+
return { sent: 0, failed: 0 };
|
|
559
|
+
}
|
|
560
|
+
const online = await this.isOnline();
|
|
561
|
+
if (!online) {
|
|
562
|
+
this.saveQueue();
|
|
563
|
+
return { sent: 0, failed: this.queue.length };
|
|
564
|
+
}
|
|
565
|
+
let totalSent = 0;
|
|
566
|
+
let totalFailed = 0;
|
|
567
|
+
while (this.queue.length > 0) {
|
|
568
|
+
const result = await this.flush();
|
|
569
|
+
totalSent += result.sent;
|
|
570
|
+
if (result.sent === 0) {
|
|
571
|
+
totalFailed += result.queued;
|
|
572
|
+
break;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
return { sent: totalSent, failed: totalFailed };
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Upload session data for cloud sync
|
|
579
|
+
*/
|
|
580
|
+
async uploadSession(sessionData) {
|
|
581
|
+
if (!this.config.enabled || !this.config.enableSessionSync) {
|
|
582
|
+
return { success: false, error: "Session sync disabled" };
|
|
583
|
+
}
|
|
584
|
+
const online = await this.isOnline();
|
|
585
|
+
if (!online) {
|
|
586
|
+
try {
|
|
587
|
+
const syncQueueFile = path2.join(TELEMETRY_DIR, "session-sync-queue.json");
|
|
588
|
+
let syncQueue = [];
|
|
589
|
+
if (fs2.existsSync(syncQueueFile)) {
|
|
590
|
+
syncQueue = JSON.parse(fs2.readFileSync(syncQueueFile, "utf8"));
|
|
591
|
+
}
|
|
592
|
+
syncQueue.push(sessionData);
|
|
593
|
+
if (syncQueue.length > 10) {
|
|
594
|
+
syncQueue = syncQueue.slice(-10);
|
|
595
|
+
}
|
|
596
|
+
fs2.writeFileSync(syncQueueFile, JSON.stringify(syncQueue, null, 2));
|
|
597
|
+
return { success: false, error: "Offline - queued for sync" };
|
|
598
|
+
} catch {
|
|
599
|
+
return { success: false, error: "Failed to queue session" };
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
try {
|
|
603
|
+
const authToken = `${this.deviceId}.${this.config.companySecret}`;
|
|
604
|
+
const response = await fetch(`${this.config.apiBaseUrl}/v1/history`, {
|
|
605
|
+
method: "POST",
|
|
606
|
+
headers: {
|
|
607
|
+
"Content-Type": "application/json",
|
|
608
|
+
"Authorization": `Bearer ${authToken}`
|
|
609
|
+
},
|
|
610
|
+
body: JSON.stringify({
|
|
611
|
+
deviceId: this.deviceId,
|
|
612
|
+
sessionId: sessionData.sessionId,
|
|
613
|
+
messages: sessionData.messages,
|
|
614
|
+
metadata: sessionData.metadata
|
|
615
|
+
})
|
|
616
|
+
});
|
|
617
|
+
if (response.ok) {
|
|
618
|
+
const data = await response.json();
|
|
619
|
+
return { success: true, id: data.id };
|
|
620
|
+
} else {
|
|
621
|
+
return { success: false, error: `HTTP ${response.status}` };
|
|
622
|
+
}
|
|
623
|
+
} catch (err) {
|
|
624
|
+
return { success: false, error: String(err) };
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Sync queued sessions (call when back online)
|
|
629
|
+
*/
|
|
630
|
+
async syncQueuedSessions() {
|
|
631
|
+
const syncQueueFile = path2.join(TELEMETRY_DIR, "session-sync-queue.json");
|
|
632
|
+
if (!fs2.existsSync(syncQueueFile)) {
|
|
633
|
+
return { synced: 0, failed: 0 };
|
|
634
|
+
}
|
|
635
|
+
try {
|
|
636
|
+
const syncQueue = JSON.parse(fs2.readFileSync(syncQueueFile, "utf8"));
|
|
637
|
+
let synced = 0;
|
|
638
|
+
let failed = 0;
|
|
639
|
+
const remaining = [];
|
|
640
|
+
for (const session of syncQueue) {
|
|
641
|
+
const result = await this.uploadSession(session);
|
|
642
|
+
if (result.success) {
|
|
643
|
+
synced++;
|
|
644
|
+
} else if (result.error !== "Offline - queued for sync") {
|
|
645
|
+
failed++;
|
|
646
|
+
} else {
|
|
647
|
+
remaining.push(session);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
if (remaining.length > 0) {
|
|
651
|
+
fs2.writeFileSync(syncQueueFile, JSON.stringify(remaining, null, 2));
|
|
652
|
+
} else {
|
|
653
|
+
fs2.removeSync(syncQueueFile);
|
|
654
|
+
}
|
|
655
|
+
return { synced, failed };
|
|
656
|
+
} catch {
|
|
657
|
+
return { synced: 0, failed: 0 };
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Get queue stats
|
|
662
|
+
*/
|
|
663
|
+
getStats() {
|
|
664
|
+
return {
|
|
665
|
+
queued: this.queue.length,
|
|
666
|
+
deviceId: this.deviceId
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Disable telemetry
|
|
671
|
+
*/
|
|
672
|
+
disable() {
|
|
673
|
+
this.config.enabled = false;
|
|
674
|
+
this.stopFlushTimer();
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Enable telemetry
|
|
678
|
+
*/
|
|
679
|
+
enable() {
|
|
680
|
+
this.config.enabled = true;
|
|
681
|
+
this.startFlushTimer();
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
// src/telemetry/TelemetryManager.ts
|
|
686
|
+
import os2 from "os";
|
|
687
|
+
var TelemetryManager = class {
|
|
688
|
+
client;
|
|
689
|
+
sessionId = null;
|
|
690
|
+
sessionStartTime = null;
|
|
691
|
+
interactionCount = 0;
|
|
692
|
+
toolsUsed = /* @__PURE__ */ new Set();
|
|
693
|
+
errorsCount = 0;
|
|
694
|
+
currentModel = null;
|
|
695
|
+
currentProvider = null;
|
|
696
|
+
constructor(config = {}) {
|
|
697
|
+
this.client = new TelemetryClient(config);
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Get system info for events
|
|
701
|
+
*/
|
|
702
|
+
getSystemInfo() {
|
|
703
|
+
return {
|
|
704
|
+
cliVersion: package_default.version,
|
|
705
|
+
platform: process.platform,
|
|
706
|
+
osVersion: os2.release(),
|
|
707
|
+
nodeVersion: process.version,
|
|
708
|
+
cpuArch: process.arch,
|
|
709
|
+
cpuCores: os2.cpus().length,
|
|
710
|
+
memoryTotal: Math.round(os2.totalmem() / 1024 / 1024),
|
|
711
|
+
// MB
|
|
712
|
+
memoryFree: Math.round(os2.freemem() / 1024 / 1024)
|
|
713
|
+
// MB
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Track a generic event
|
|
718
|
+
*/
|
|
719
|
+
async trackEvent(eventType, eventData) {
|
|
720
|
+
await this.client.track({
|
|
721
|
+
eventType,
|
|
722
|
+
eventData,
|
|
723
|
+
sessionId: this.sessionId || "unknown",
|
|
724
|
+
...this.getSystemInfo(),
|
|
725
|
+
interactionCount: this.interactionCount,
|
|
726
|
+
toolsUsed: Array.from(this.toolsUsed),
|
|
727
|
+
errorsCount: this.errorsCount
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Start a new session
|
|
732
|
+
*/
|
|
733
|
+
async startSession(sessionId, model, provider) {
|
|
734
|
+
this.sessionId = sessionId;
|
|
735
|
+
this.sessionStartTime = /* @__PURE__ */ new Date();
|
|
736
|
+
this.interactionCount = 0;
|
|
737
|
+
this.toolsUsed.clear();
|
|
738
|
+
this.errorsCount = 0;
|
|
739
|
+
this.currentModel = model || null;
|
|
740
|
+
this.currentProvider = provider || null;
|
|
741
|
+
await this.trackEvent("session_start", {
|
|
742
|
+
model,
|
|
743
|
+
provider
|
|
744
|
+
});
|
|
745
|
+
await this.client.syncQueuedSessions();
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* End current session
|
|
749
|
+
*/
|
|
750
|
+
async endSession(status = "completed") {
|
|
751
|
+
const duration = this.sessionStartTime ? Math.round((Date.now() - this.sessionStartTime.getTime()) / 1e3) : 0;
|
|
752
|
+
await this.trackEvent("session_end", {
|
|
753
|
+
status,
|
|
754
|
+
duration,
|
|
755
|
+
model: this.currentModel,
|
|
756
|
+
provider: this.currentProvider
|
|
757
|
+
});
|
|
758
|
+
await this.client.syncAll();
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* Track tool usage
|
|
762
|
+
*/
|
|
763
|
+
async trackToolUse(data) {
|
|
764
|
+
this.toolsUsed.add(data.tool);
|
|
765
|
+
if (!data.success) {
|
|
766
|
+
this.errorsCount++;
|
|
767
|
+
}
|
|
768
|
+
await this.trackEvent("tool_use", {
|
|
769
|
+
tool: data.tool,
|
|
770
|
+
success: data.success,
|
|
771
|
+
duration: data.duration,
|
|
772
|
+
error: data.error
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Track an error
|
|
777
|
+
*/
|
|
778
|
+
async trackError(data) {
|
|
779
|
+
this.errorsCount++;
|
|
780
|
+
const sanitizedStack = data.stack?.replace(/\/Users\/[^/]+/g, "/Users/***").replace(/\/home\/[^/]+/g, "/home/***").replace(/C:\\Users\\[^\\]+/g, "C:\\Users\\***");
|
|
781
|
+
await this.trackEvent("error", {
|
|
782
|
+
type: data.type,
|
|
783
|
+
message: data.message,
|
|
784
|
+
stack: sanitizedStack,
|
|
785
|
+
context: data.context
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* Track a session failure as a bug report with detailed context.
|
|
790
|
+
* Prefixes the error type with "BUG:" for easy identification.
|
|
791
|
+
*/
|
|
792
|
+
async trackSessionFailureBug(data) {
|
|
793
|
+
this.errorsCount++;
|
|
794
|
+
const sanitizedStack = data.error.stack?.replace(/\/Users\/[^/]+/g, "/Users/***").replace(/\/home\/[^/]+/g, "/home/***").replace(/C:\\Users\\[^\\]+/g, "C:\\Users\\***");
|
|
795
|
+
const bugData = {
|
|
796
|
+
type: "BUG:session_failure",
|
|
797
|
+
errorMessage: data.error.message,
|
|
798
|
+
errorName: data.error.name,
|
|
799
|
+
stack: sanitizedStack,
|
|
800
|
+
retryAttempt: data.retryAttempt,
|
|
801
|
+
maxRetries: data.maxRetries,
|
|
802
|
+
conversationLength: data.conversationLength,
|
|
803
|
+
lastToolCalls: data.lastToolCalls,
|
|
804
|
+
iterationCount: data.iterationCount,
|
|
805
|
+
contextUsage: data.contextUsage,
|
|
806
|
+
model: data.model || this.currentModel || void 0,
|
|
807
|
+
provider: data.provider || this.currentProvider || void 0,
|
|
808
|
+
isRetrying: data.retryAttempt < data.maxRetries
|
|
809
|
+
};
|
|
810
|
+
await this.trackEvent("session_failure_bug", bugData);
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Track slash command usage
|
|
814
|
+
*/
|
|
815
|
+
async trackCommand(data) {
|
|
816
|
+
this.interactionCount++;
|
|
817
|
+
await this.trackEvent("command_use", {
|
|
818
|
+
command: data.command,
|
|
819
|
+
args: data.args
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Track skill activation/usage
|
|
824
|
+
*/
|
|
825
|
+
async trackSkillUse(data) {
|
|
826
|
+
await this.trackEvent("skill_use", {
|
|
827
|
+
skillName: data.skillName,
|
|
828
|
+
source: data.source,
|
|
829
|
+
activationType: data.activationType,
|
|
830
|
+
action: data.action
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Track model switch
|
|
835
|
+
*/
|
|
836
|
+
async trackModelSwitch(data) {
|
|
837
|
+
const previousModel = this.currentModel;
|
|
838
|
+
this.currentModel = data.toModel;
|
|
839
|
+
this.currentProvider = data.provider;
|
|
840
|
+
await this.trackEvent("model_switch", {
|
|
841
|
+
fromModel: previousModel || data.fromModel,
|
|
842
|
+
toModel: data.toModel,
|
|
843
|
+
provider: data.provider
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Track heartbeat (periodic check-in)
|
|
848
|
+
*/
|
|
849
|
+
async trackHeartbeat() {
|
|
850
|
+
await this.trackEvent("heartbeat", {
|
|
851
|
+
uptime: this.sessionStartTime ? Math.round((Date.now() - this.sessionStartTime.getTime()) / 1e3) : 0
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Record an interaction (user message)
|
|
856
|
+
*/
|
|
857
|
+
recordInteraction() {
|
|
858
|
+
this.interactionCount++;
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Upload session for cloud sync
|
|
862
|
+
*/
|
|
863
|
+
async syncSession(data) {
|
|
864
|
+
if (!this.sessionId) {
|
|
865
|
+
return { success: false, error: "No active session" };
|
|
866
|
+
}
|
|
867
|
+
return this.client.uploadSession({
|
|
868
|
+
sessionId: this.sessionId,
|
|
869
|
+
messages: data.messages,
|
|
870
|
+
metadata: {
|
|
871
|
+
model: this.currentModel || void 0,
|
|
872
|
+
provider: this.currentProvider || void 0,
|
|
873
|
+
totalTokens: data.metadata?.totalTokens,
|
|
874
|
+
startTime: this.sessionStartTime?.toISOString(),
|
|
875
|
+
endTime: (/* @__PURE__ */ new Date()).toISOString(),
|
|
876
|
+
workspaceRoot: data.metadata?.workspaceRoot
|
|
877
|
+
}
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* Get current session ID
|
|
882
|
+
*/
|
|
883
|
+
getSessionId() {
|
|
884
|
+
return this.sessionId;
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* Get device ID
|
|
888
|
+
*/
|
|
889
|
+
getDeviceId() {
|
|
890
|
+
return this.client.getDeviceId();
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* Get stats
|
|
894
|
+
*/
|
|
895
|
+
getStats() {
|
|
896
|
+
return {
|
|
897
|
+
...this.client.getStats(),
|
|
898
|
+
sessionId: this.sessionId,
|
|
899
|
+
interactionCount: this.interactionCount,
|
|
900
|
+
toolsUsed: Array.from(this.toolsUsed),
|
|
901
|
+
errorsCount: this.errorsCount,
|
|
902
|
+
sessionDuration: this.sessionStartTime ? Math.round((Date.now() - this.sessionStartTime.getTime()) / 1e3) : 0
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
/**
|
|
906
|
+
* Flush pending events
|
|
907
|
+
*/
|
|
908
|
+
async flush() {
|
|
909
|
+
return this.client.flush();
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Disable telemetry
|
|
913
|
+
*/
|
|
914
|
+
disable() {
|
|
915
|
+
this.client.disable();
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* Enable telemetry
|
|
919
|
+
*/
|
|
920
|
+
enable() {
|
|
921
|
+
this.client.enable();
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Stop and cleanup
|
|
925
|
+
*/
|
|
926
|
+
async shutdown() {
|
|
927
|
+
this.client.stopFlushTimer();
|
|
928
|
+
await this.client.syncAll();
|
|
929
|
+
}
|
|
930
|
+
};
|
|
931
|
+
|
|
932
|
+
export {
|
|
933
|
+
isAutohandDebugEnabled,
|
|
934
|
+
writeAutohandDebugLine,
|
|
935
|
+
AutoReportManager,
|
|
936
|
+
TelemetryManager,
|
|
937
|
+
isSessionWorktreeEnabled,
|
|
938
|
+
prepareSessionWorktree,
|
|
939
|
+
formatStartupBanner,
|
|
940
|
+
formatWelcomeVersionPrefix,
|
|
941
|
+
formatUpdateAvailable,
|
|
942
|
+
formatUpdateReady,
|
|
943
|
+
formatInstallHint,
|
|
944
|
+
formatWelcomeGreeting,
|
|
945
|
+
formatWelcomeStatusLine,
|
|
946
|
+
formatWelcomeTitle,
|
|
947
|
+
formatWelcomeSuggestion,
|
|
948
|
+
formatSessionEnding,
|
|
949
|
+
formatSessionSaved,
|
|
950
|
+
formatResumeHint,
|
|
951
|
+
formatExitCleanup,
|
|
952
|
+
formatForceExit
|
|
953
|
+
};
|
|
954
|
+
/**
|
|
955
|
+
* @license
|
|
956
|
+
* Copyright 2025 Autohand AI LLC
|
|
957
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
958
|
+
*/
|
|
959
|
+
/**
|
|
960
|
+
* @license
|
|
961
|
+
* Copyright 2026 Autohand AI LLC
|
|
962
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
963
|
+
*/
|
|
964
|
+
/**
|
|
965
|
+
* @license
|
|
966
|
+
* Copyright 2025 Autohand AI LLC
|
|
967
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
968
|
+
*
|
|
969
|
+
* AutoReportClient - Low-level HTTP client for error reporting
|
|
970
|
+
* Sends sanitized error reports to the Autohand API for automatic GitHub issue creation
|
|
971
|
+
*/
|
|
972
|
+
/**
|
|
973
|
+
* @license
|
|
974
|
+
* Copyright 2025 Autohand AI LLC
|
|
975
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
976
|
+
*
|
|
977
|
+
* AutoReportManager - High-level manager for automatic error reporting
|
|
978
|
+
* Handles deduplication, retries, and config-based enable/disable
|
|
979
|
+
*/
|
|
980
|
+
/**
|
|
981
|
+
* TelemetryClient - Low-level API client with offline batching
|
|
982
|
+
* @license Apache-2.0
|
|
983
|
+
*/
|
|
984
|
+
/**
|
|
985
|
+
* TelemetryManager - High-level telemetry tracking
|
|
986
|
+
* @license Apache-2.0
|
|
987
|
+
*/
|