nolo-cli 0.149.0-alpha.1 → 0.151.0-alpha.3
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/{_executeModel-OW3H7ICR.js → _executeModel-T7ANHTUW.js} +134 -91
- package/accountResolver-7RYB4D2P.js +300 -0
- package/action-SXJD5N5R.js +23 -0
- package/{addContentAction-B2DRF7P6.js → addContentAction-ZV774PHH.js} +20 -14
- package/{addDialogAgentAction-2P2FLTLD.js → addDialogAgentAction-A6SMKAGH.js} +26 -22
- package/{agentDeleteCommand-7IDWF6E3.js → agentDeleteCommand-4L5KCKFY.js} +181 -93
- package/{agentEmailCommands-A6XBQZBN.js → agentEmailCommands-2IMMIRO2.js} +132 -112
- package/{agentGrantCommands-M3XFO6EN.js → agentGrantCommands-HOJ3JBBQ.js} +3 -3
- package/agentListCommands-TWFLUYIZ.js +802 -0
- package/{agentMachineCommands-DQPUIMAC.js → agentMachineCommands-KIWXWT6L.js} +58 -62
- package/{agentProviderCommands-YK2BIIXZ.js → agentProviderCommands-HL6MBLCL.js} +149 -2
- package/{agentPullCommand-HF4A42D4.js → agentPullCommand-FA43RBRU.js} +7 -7
- package/agentRecordCommands-727NPCRW.js +154 -0
- package/agentRunCommand-JASIG3FZ.js +183 -0
- package/{agentRunControl-2SKCR4SB.js → agentRunControl-IFM7IGMG.js} +10 -2
- package/{agentRuntimeLocal-AK2QVJHY.js → agentRuntimeLocal-KKSQJMTE.js} +47 -50
- package/{agentSlice-O4RUQUMT.js → agentSlice-SLV57QGU.js} +23 -16
- package/{appDeleteCommands-N3XEVVYC.js → appDeleteCommands-4PL4KYRN.js} +58 -59
- package/{appDeployCommands-AWFIXYVW.js → appDeployCommands-EEEXCEB6.js} +67 -63
- package/{appDeployStatusCommands-CZRON2FO.js → appDeployStatusCommands-35ZX7T66.js} +56 -56
- package/{appGetCommands-XQIUY4TD.js → appGetCommands-WFCHXJWF.js} +56 -56
- package/{appListCommands-NNG4H36Y.js → appListCommands-XY2U6DPF.js} +57 -59
- package/{authCommand-UBJ4EWYZ.js → authCommand-QYN47CQD.js} +371 -68
- package/{authCommands-H6WKKCRW.js → authCommands-77CHYBGF.js} +12 -9
- package/{builtinSkillRegistry-ZMF6YGNO.js → builtinSkillRegistry-TDQ6JB2E.js} +13 -11
- package/{chromeCommands-2N6MEWRU.js → chromeCommands-OBBNJCLS.js} +314 -13
- package/chromeOpsCommands-3Z34RKSE.js +472 -0
- package/{chunk-ALXHV7NK.js → chunk-2GGXHQIW.js} +43 -4
- package/{localRuntimeAuthority-5W6IJRAD.js → chunk-2IXDJNZI.js} +154 -75
- package/{chunk-IVZJWTDI.js → chunk-36OMEXXR.js} +89 -21
- package/{chunk-H6A6X4EK.js → chunk-3MZAGMYY.js} +16 -0
- package/chunk-3PVYUPXK.js +40 -0
- package/chunk-3SZA4U64.js +1192 -0
- package/{chunk-ID7LNBWR.js → chunk-3T4ZG6AC.js} +1920 -644
- package/{chunk-GNMAFAIS.js → chunk-44WXLHFI.js} +1 -1
- package/{chunk-AGGIDPCZ.js → chunk-4JH2UMJR.js} +6 -0
- package/chunk-4LCOCOR5.js +50 -0
- package/chunk-4YRTZIVN.js +871 -0
- package/{chunk-N7J63Q6C.js → chunk-56GBUMO5.js} +10 -1
- package/{chunk-W7XHHYWM.js → chunk-5BHQICF2.js} +5 -1
- package/{chunk-XUWRURDF.js → chunk-5EBLANFT.js} +1 -1
- package/{chunk-3AH7LNUB.js → chunk-5EMSBTQ6.js} +33 -14
- package/{chunk-YRRASA5Q.js → chunk-5MM7NNO6.js} +113 -52
- package/chunk-5MMAK75Q.js +15 -0
- package/{chunk-TXH4IWJL.js → chunk-626KHJNX.js} +20 -11
- package/{chunk-M5PVFLD4.js → chunk-64K7WX26.js} +90 -21
- package/{chunk-AKG5W4LG.js → chunk-6CCFTVBP.js} +76 -221
- package/chunk-6MJNEXUU.js +614 -0
- package/{chunk-62IL3KQV.js → chunk-6MXDOUMH.js} +15 -3
- package/{chunk-QOKAKDPE.js → chunk-6Q7UTJKR.js} +6 -94
- package/chunk-6QDYSCPW.js +223 -0
- package/{chunk-HYZIYH2H.js → chunk-74RAWNQN.js} +56 -63
- package/chunk-7DPNBQSV.js +9 -0
- package/{chunk-IAESIMK7.js → chunk-A4MW3YZL.js} +10 -14
- package/{chunk-OMRJYNCI.js → chunk-AG7MCDLR.js} +26 -31
- package/chunk-AGIM7IMJ.js +147 -0
- package/{chunk-7CHC4W22.js → chunk-AIZE5TDM.js} +3 -3
- package/chunk-AJ3G7X2K.js +7012 -0
- package/{chunk-5GVBDNTO.js → chunk-AU7AXHUL.js} +1 -1
- package/{chunk-4H22P2JV.js → chunk-AUIJZACN.js} +2073 -1275
- package/{chunk-CIF4X6ZM.js → chunk-AWVFQMOV.js} +25 -3
- package/{chunk-YAQJJDC2.js → chunk-BJEZC5RA.js} +214 -51
- package/{chunk-RYZINGPM.js → chunk-BPMPOFWP.js} +347 -235
- package/{chunk-YUNJN43V.js → chunk-BU2YQBV4.js} +215 -28
- package/{chunk-XPRWFQQK.js → chunk-CBHGZRCE.js} +38 -12
- package/{chunk-Y3PMXGLH.js → chunk-CHCS6XPJ.js} +365 -144
- package/chunk-CHOZJMJS.js +78 -0
- package/chunk-CYJWI3NH.js +119 -0
- package/{chunk-GBRG75BQ.js → chunk-D2MDMY2M.js} +1 -0
- package/{chunk-3SV7RM24.js → chunk-D2QN6CTI.js} +117 -72
- package/{chunk-TZZ2WRBL.js → chunk-DFDXM2Y4.js} +20 -16
- package/{chunk-5TEEECZM.js → chunk-E2AKSW7L.js} +10 -7
- package/{chunk-RSEEDUMS.js → chunk-EDX5XSJM.js} +2 -2
- package/{chunk-QDSINZM3.js → chunk-EUGTFFO6.js} +2 -23
- package/{chunk-UNYJU5L6.js → chunk-EYLGAEB4.js} +5 -1
- package/{chunk-CU3QB4HW.js → chunk-EYWJT7A2.js} +12 -12
- package/{chunk-BNGW5ASC.js → chunk-EZVK3N5L.js} +66 -18
- package/{chunk-6FGTMQCL.js → chunk-F32Z66T4.js} +6 -10
- package/{chunk-ZOVKKMF6.js → chunk-FY4SDK2E.js} +1 -1
- package/chunk-G6OOUQWJ.js +417 -0
- package/{chunk-PQWU42UQ.js → chunk-GCKHQECX.js} +6 -6
- package/chunk-GKXCHNTE.js +15 -0
- package/{chunk-P6GMCCAT.js → chunk-GQV5KHJU.js} +78 -12
- package/{chunk-B2XUQXQX.js → chunk-HIQ4GF53.js} +191 -68
- package/{chunk-GMZLP5DV.js → chunk-HNUWUO75.js} +30 -19
- package/{chunk-UASIEDKM.js → chunk-I2XLRXVX.js} +36 -31
- package/{chunk-5UTFL4QJ.js → chunk-I2ZMGXXF.js} +10 -5
- package/chunk-I42VC5KR.js +15 -0
- package/{chunk-3BXNTXYI.js → chunk-I4SN4NUQ.js} +1199 -56
- package/chunk-IA7TRNNR.js +11 -0
- package/{chunk-WIWM4FE3.js → chunk-IJERIUXS.js} +55 -748
- package/{chunk-BIDGLJQ3.js → chunk-IK2TSJQA.js} +45 -8
- package/{chunk-CPUFH46E.js → chunk-ILU2NPWY.js} +10 -10
- package/{chunk-SLLGJZDT.js → chunk-ISQL4V7C.js} +4 -4
- package/chunk-IT3ZZRJE.js +12 -0
- package/{chunk-DY7ANLKG.js → chunk-JKMLSTZK.js} +43 -12
- package/{chunk-6TPOEJMQ.js → chunk-JZX2XLKC.js} +64 -23
- package/{chunk-27ONFIEY.js → chunk-K2AER7RX.js} +19 -12
- package/{chunk-O2OWEFII.js → chunk-KFHQQ3NO.js} +1 -1
- package/{chunk-QXGPFY6J.js → chunk-LGN377P3.js} +27 -17
- package/{chunk-L36OWPP3.js → chunk-LIQJTQRN.js} +118 -139
- package/{chunk-BFU6C242.js → chunk-NMFV26UG.js} +1 -1
- package/{chunk-5J3PYNUP.js → chunk-NYYFIKHI.js} +17 -3
- package/{chunk-6O4IK4V2.js → chunk-OFFL4DCR.js} +1 -1
- package/{chunk-B6SAMB33.js → chunk-OWYYDMGJ.js} +209 -9
- package/{chunk-KQHGZWSV.js → chunk-OXME3PEE.js} +1 -1
- package/{chunk-CTUQJVQM.js → chunk-P5QACQDK.js} +1 -1
- package/{chunk-TB3MIBRC.js → chunk-PIDUNDFS.js} +572 -430
- package/{chunk-4JMDLJAD.js → chunk-PJNFNEJE.js} +114 -37
- package/chunk-PKZKOVA5.js +11507 -0
- package/{chunk-Z4CSIXYP.js → chunk-PLSVXHSA.js} +3 -3
- package/chunk-PWTNI4N7.js +47 -0
- package/chunk-QFEW2ULV.js +42 -0
- package/{chunk-RGNEEJ3Y.js → chunk-QLQ573SU.js} +35 -9
- package/chunk-QQ56R7KS.js +88 -0
- package/chunk-QYPE3TS3.js +43 -0
- package/{chunk-HTVYCXBP.js → chunk-RN2GPWN6.js} +354 -120
- package/{chunk-ATLTFRYJ.js → chunk-ROCUB2H2.js} +280 -98
- package/{chunk-4DPP773Q.js → chunk-RSHPU4PD.js} +59 -11
- package/chunk-RVWMAFIT.js +134 -0
- package/{chunk-ESHYE7WU.js → chunk-S73EPYNC.js} +10 -7
- package/{chunk-UQNS32WZ.js → chunk-SCMHQUMK.js} +1 -1
- package/chunk-SW4S4XYB.js +1794 -0
- package/{chunk-ZUEK6A6C.js → chunk-TTH4HOJD.js} +1973 -754
- package/chunk-TY3TIUJK.js +89 -0
- package/{chunk-X2QRZXZH.js → chunk-TYJ5XFEA.js} +4 -4
- package/{chunk-ALFH24P3.js → chunk-TYYRSFBG.js} +197 -155
- package/{chunk-MST6R3E4.js → chunk-U5GPBQDG.js} +34 -22
- package/chunk-U5ICMAFV.js +14110 -0
- package/{chunk-7KVZ5LDQ.js → chunk-UBUH2TCC.js} +18 -4
- package/chunk-UEILX4EV.js +15 -0
- package/chunk-UHTDNB5Y.js +140 -0
- package/{chunk-YYLHWIW6.js → chunk-UKZX3NHN.js} +1 -1
- package/{chunk-OHOVNO7I.js → chunk-UOKFKFPO.js} +6 -3
- package/{chunk-XISEYOGH.js → chunk-USHQX6VT.js} +5 -5
- package/chunk-UUPR3TD7.js +53 -0
- package/{chunk-3DAVPNFT.js → chunk-V4EE3D54.js} +122 -107
- package/{chunk-HDLLCBRF.js → chunk-VEA7H5FG.js} +2 -2
- package/chunk-VHGD6FHV.js +116 -0
- package/chunk-VIWDGTDA.js +8 -0
- package/{chunk-GOH6RW6F.js → chunk-VJXHL6MH.js} +34 -11
- package/{chunk-4XEYAFLY.js → chunk-VL5KOY2C.js} +623 -94
- package/{chunk-EADNWBAZ.js → chunk-VP3BINY7.js} +13 -0
- package/{chunk-DXHL7G2L.js → chunk-VWW6O2TL.js} +274 -93
- package/{chunk-EOARMOVD.js → chunk-W4S6OTSC.js} +6 -3
- package/chunk-WD4XYDYC.js +567 -0
- package/chunk-WJZOQR2J.js +151 -0
- package/{chunk-AUDNYVRC.js → chunk-XETG4RIX.js} +5 -5
- package/{chunk-MX574M24.js → chunk-XI7DGLUK.js} +4 -4
- package/{chunk-3L2WKC3W.js → chunk-XPWGOTBQ.js} +8 -1
- package/chunk-XRUSXPCQ.js +514 -0
- package/{chunk-I4OPU5TK.js → chunk-XS47QOFV.js} +273 -11
- package/{chunk-S5XGT6GB.js → chunk-XZNCX52W.js} +30 -9
- package/{chunk-5OA5HMTL.js → chunk-YLMMECCH.js} +1 -1
- package/{chunk-CFT5HBGW.js → chunk-YVLQXTUB.js} +448 -12
- package/chunk-YVPQATSC.js +709 -0
- package/chunk-ZEZC7IIM.js +126 -0
- package/{chunk-ALGORS6Y.js → chunk-ZF6526IQ.js} +43 -8
- package/chunk-ZIWPQEFU.js +165 -0
- package/chunk-ZRAU6T47.js +56 -0
- package/{cliExecutor-AWYR3T33.js → cliExecutor-BWBF2MTI.js} +4 -3
- package/{clipboardy-BX4NMYHE.js → clipboardy-GCO3GT3I.js} +3 -8
- package/{commandRegistry-2KBOXZQC.js → commandRegistry-NBLZEMCW.js} +183 -107
- package/contentThunks-6AIWNSGO.js +84 -0
- package/{cooldownCommands-ZLEPIB4A.js → cooldownCommands-JFKTYS2D.js} +2 -2
- package/{createAgentAutomationAction-5UGTB26P.js → createAgentAutomationAction-4BUS65DZ.js} +53 -44
- package/createDialogAction-QAIKSCG4.js +76 -0
- package/{createPageAction-CDLDKPRM.js → createPageAction-DXCZ334C.js} +65 -54
- package/cursorProvider-YGGNMVWX.js +6123 -0
- package/{db-VQSAOWAO.js → db-2QOTXYGH.js} +11 -5
- package/{dbSlice-DQ32LYTJ.js → dbSlice-J37OGIXH.js} +19 -13
- package/{deleteFile-NX6QHCWZ.js → deleteFile-6JWDDRVP.js} +10 -6
- package/dialogCommands-YZLSJB6X.js +113 -0
- package/{dialogSlice-N3YB65G5.js → dialogSlice-PVUSMKFW.js} +53 -39
- package/{docCreateCommands-ZSLGVBZT.js → docCreateCommands-JB2RRMRJ.js} +54 -57
- package/{docDeleteCommands-5N4GVZBG.js → docDeleteCommands-AQENULNM.js} +56 -58
- package/{docReadCommands-YJSAA7AV.js → docReadCommands-DYD25YLQ.js} +53 -56
- package/{docStore-E3CEOV5Q.js → docStore-CSEBEMKP.js} +25 -16
- package/{docUpdateCommands-WEMLSW6W.js → docUpdateCommands-3GVS23QL.js} +54 -57
- package/{fetchMessages-67MEFPZR.js → fetchMessages-IIJWQ3HR.js} +5 -4
- package/{getPricing-NMMFT3YI.js → getPricing-FKK3F5EJ.js} +11 -9
- package/{handleSendMessageAction-DQAD5ERJ.js → handleSendMessageAction-G2TLYGC4.js} +422 -118
- package/index.js +11 -7
- package/{lib-FRRS27KN.js → lib-4YTWAGY7.js} +581 -248
- package/{localDialogRead-EBRS242U.js → localDialogRead-FSOMOPDZ.js} +2 -2
- package/localRuntimeAdapter-B4TAYYA7.js +244 -0
- package/localRuntimeAuthority-JDAD7CB6.js +16 -0
- package/{localRuntimeDb-3LRMNLCM.js → localRuntimeDb-CVC62PM5.js} +1 -1
- package/{machineCommands-HAP75VSG.js → machineCommands-6OBFD3XF.js} +503 -161
- package/{machineInfo-66ZFUMLE.js → machineInfo-UKPTZO5Y.js} +2 -2
- package/machineWsRunDispatch-OO7N3O3Y.js +169 -0
- package/{memberThunks-5ZXPR63F.js → memberThunks-66DH6ABQ.js} +25 -18
- package/{models-ZPU5EDF4.js → models-LAS4B2B5.js} +2 -2
- package/package.json +1 -1
- package/{providerPresetApply-DD6NGWW6.js → providerPresetApply-MY66I6NT.js} +10 -10
- package/{providerRegistry-XDRLMYGJ.js → providerRegistry-QOE2FT57.js} +13 -9
- package/{read-EPTJRAEF.js → read-DC4NUGN6.js} +12 -8
- package/{readDocTool-W4NDXNEX.js → readDocTool-NCJ5NT25.js} +1 -1
- package/{readlineWorkspace-7BC66QSX.js → readlineWorkspace-UIQN7JUR.js} +5017 -915
- package/{removeDialogAgentAction-OSYNZRX7.js → removeDialogAgentAction-E2H3OZU6.js} +29 -28
- package/{runAgentClientLoop-6E6UC3CE.js → runAgentClientLoop-GS3SGG37.js} +154 -97
- package/{runtimeDoctorCommands-ID23PNNZ.js → runtimeDoctorCommands-GIOGC5SC.js} +17 -17
- package/secretCommands-ZXZRLR3R.js +700 -0
- package/setDialogExtraReferencesAction-SITRPMYU.js +37 -0
- package/{setPrimaryDialogAgentAction-WZ7KI3YA.js → setPrimaryDialogAgentAction-U7N45TGC.js} +30 -29
- package/{chunk-SONWNI3L.js → settingThunks-Y7SVJOMZ.js} +223 -928
- package/{skillDiscovery-ZBU76COE.js → skillDiscovery-QC35EQY4.js} +2 -2
- package/{slateUtils-RIZES3PV.js → slateUtils-NGV2NMKM.js} +1 -1
- package/{spaceCommands-UJOVU4XI.js → spaceCommands-ZR5BR3GX.js} +59 -59
- package/{streamAgentChatTurn-3UXPYFNX.js → streamAgentChatTurn-4XYC33KE.js} +309 -165
- package/{switchDialogAgentAction-GMR7WN3P.js → switchDialogAgentAction-OMGBD3N2.js} +26 -22
- package/{tableCommands-G7RV3RU3.js → tableCommands-U3QDY4L6.js} +19 -17
- package/{toolApiClient-CVGWM4PN.js → toolApiClient-7WSJJJBV.js} +6 -5
- package/tools-P77EE7Q4.js +124 -0
- package/tuiSummaryLlmCaller-BM3VSTBU.js +130 -0
- package/{updateCommands-4EHDLF5J.js → updateCommands-NQXAGFM7.js} +3 -3
- package/{updateDialogTitleAction-UPFV7TDT.js → updateDialogTitleAction-CIANVPZC.js} +102 -57
- package/workloadLifecycle-36DXRZKU.js +320 -0
- package/action-GI44T4DR.js +0 -31
- package/agentListCommands-IW3GQVUP.js +0 -427
- package/agentRecordCommands-VCA76W6B.js +0 -134
- package/agentRunCommand-YNLDKVR7.js +0 -161
- package/browser-image-compression-MFDTD7K6.js +0 -1763
- package/chatQueueReduxAdapter-TJRMXMYA.js +0 -186
- package/chromeOpsCommands-IXRLN57H.js +0 -289
- package/chunk-36KZDDO5.js +0 -2415
- package/chunk-ACQD6YI2.js +0 -25363
- package/chunk-CQ3WA2NE.js +0 -299
- package/chunk-CYSYR67N.js +0 -93
- package/chunk-JBTJAPUF.js +0 -35
- package/chunk-K2CSUCHJ.js +0 -620
- package/chunk-LTRXGFMS.js +0 -83
- package/chunk-M76ECQRD.js +0 -13658
- package/chunk-MEYIRKDN.js +0 -8967
- package/chunk-OCZKATRC.js +0 -129
- package/chunk-OTGFTBLI.js +0 -13
- package/chunk-PUOC4YRO.js +0 -394
- package/chunk-PZZTFEKK.js +0 -34
- package/chunk-URMS4XY2.js +0 -10
- package/chunk-UV6VISQJ.js +0 -20
- package/chunk-VJVNU77E.js +0 -83
- package/chunk-XYJSY4KG.js +0 -13807
- package/chunk-Y5GCAMGP.js +0 -9
- package/chunk-YPREESF4.js +0 -225
- package/contentThunks-BDIQRZR6.js +0 -73
- package/createDialogAction-B7VGVEVU.js +0 -66
- package/dialogCommands-G7YBVAMC.js +0 -102
- package/levelLazyShim-GZBKODGI.js +0 -7
- package/machineWsRunDispatch-L32G7C4P.js +0 -149
- package/serverStoreFactory-YMXDF4NI.js +0 -20
- package/setDialogExtraReferencesAction-M32UYNCG.js +0 -30
- package/settingSlice-Q6EKL7EQ.js +0 -204
- package/syncMapping-N6RGXGBW.js +0 -437
- package/tools-MKYDMWA4.js +0 -111
- package/tuiSummaryLlmCaller-3YFNHCTW.js +0 -128
- package/{chunk-SV5IJK6K.js → chunk-NBTY7YJF.js} +3 -3
- package/{chunk-2SYTUTLI.js → chunk-YBNHPX4S.js} +3 -3
- package/{offlineMarxistsAgentCommand-HGXZV4XJ.js → offlineMarxistsAgentCommand-2QTHJCHV.js} +4 -4
|
@@ -0,0 +1,700 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createFileCredentialBroker
|
|
3
|
+
} from "./chunk-UHTDNB5Y.js";
|
|
4
|
+
import "./chunk-3EUW3WEO.js";
|
|
5
|
+
import "./chunk-ZWQUWF6W.js";
|
|
6
|
+
import "./chunk-4VNS5WPM.js";
|
|
7
|
+
|
|
8
|
+
// packages/core/secretsStore.ts
|
|
9
|
+
import {
|
|
10
|
+
existsSync,
|
|
11
|
+
mkdirSync,
|
|
12
|
+
readFileSync,
|
|
13
|
+
renameSync,
|
|
14
|
+
chmodSync,
|
|
15
|
+
writeFileSync,
|
|
16
|
+
openSync,
|
|
17
|
+
closeSync,
|
|
18
|
+
unlinkSync
|
|
19
|
+
} from "fs";
|
|
20
|
+
import { dirname, join, resolve } from "path";
|
|
21
|
+
import { homedir } from "os";
|
|
22
|
+
function resolveCredentialsDir(env = process.env) {
|
|
23
|
+
const noloHome = env.NOLO_HOME?.trim();
|
|
24
|
+
const base = noloHome ? resolve(noloHome) : join(homedir(), ".nolo");
|
|
25
|
+
return join(base, "credentials");
|
|
26
|
+
}
|
|
27
|
+
function getSecretsFilePath() {
|
|
28
|
+
const override = process.env.NOLO_SECRETS_FILE;
|
|
29
|
+
if (override && override.trim()) return override;
|
|
30
|
+
return join(resolveCredentialsDir(), "secrets.json");
|
|
31
|
+
}
|
|
32
|
+
var SecretsFileCorruptedError = class extends Error {
|
|
33
|
+
constructor(filePath, cause) {
|
|
34
|
+
super(
|
|
35
|
+
`secrets file is not valid JSON and was left untouched: ${filePath}. Refusing to overwrite it \u2014 repair or move the file aside first.`
|
|
36
|
+
);
|
|
37
|
+
this.name = "SecretsFileCorruptedError";
|
|
38
|
+
this.cause = cause;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
var SecretHasNoEnvMappingError = class extends Error {
|
|
42
|
+
constructor(name) {
|
|
43
|
+
super(
|
|
44
|
+
`secret "${name}" produced no environment variables; it was stored as a scalar that cannot be injected (expected a string or an object of scalars).`
|
|
45
|
+
);
|
|
46
|
+
this.name = "SecretHasNoEnvMappingError";
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
function ensureDirectorySecured(dirPath) {
|
|
50
|
+
if (existsSync(dirPath)) return;
|
|
51
|
+
mkdirSync(dirPath, { recursive: true, mode: 448 });
|
|
52
|
+
try {
|
|
53
|
+
chmodSync(dirPath, 448);
|
|
54
|
+
} catch {
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function readSecretsData() {
|
|
58
|
+
const filePath = getSecretsFilePath();
|
|
59
|
+
if (!existsSync(filePath)) return {};
|
|
60
|
+
let raw;
|
|
61
|
+
try {
|
|
62
|
+
raw = readFileSync(filePath, "utf8");
|
|
63
|
+
} catch (error) {
|
|
64
|
+
throw new SecretsFileCorruptedError(filePath, error);
|
|
65
|
+
}
|
|
66
|
+
if (!raw.trim()) return {};
|
|
67
|
+
let parsed;
|
|
68
|
+
try {
|
|
69
|
+
parsed = JSON.parse(raw);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
throw new SecretsFileCorruptedError(filePath, error);
|
|
72
|
+
}
|
|
73
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
74
|
+
throw new SecretsFileCorruptedError(filePath);
|
|
75
|
+
}
|
|
76
|
+
return parsed;
|
|
77
|
+
}
|
|
78
|
+
function readSecretsForRead() {
|
|
79
|
+
try {
|
|
80
|
+
return { data: readSecretsData(), corrupted: false };
|
|
81
|
+
} catch (error) {
|
|
82
|
+
return { data: {}, corrupted: true, error };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function writeSecretsData(data) {
|
|
86
|
+
const filePath = getSecretsFilePath();
|
|
87
|
+
const dir = dirname(filePath);
|
|
88
|
+
ensureDirectorySecured(dir);
|
|
89
|
+
const tempPath = join(dir, `.secrets-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
|
|
90
|
+
writeFileSync(tempPath, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
|
|
91
|
+
try {
|
|
92
|
+
chmodSync(tempPath, 384);
|
|
93
|
+
} catch {
|
|
94
|
+
}
|
|
95
|
+
renameSync(tempPath, filePath);
|
|
96
|
+
}
|
|
97
|
+
function sleepSync(ms) {
|
|
98
|
+
try {
|
|
99
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
100
|
+
} catch {
|
|
101
|
+
const end = Date.now() + ms;
|
|
102
|
+
while (Date.now() < end) {
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function withSecretsLock(fn) {
|
|
107
|
+
const lockPath = `${getSecretsFilePath()}.lock`;
|
|
108
|
+
ensureDirectorySecured(dirname(lockPath));
|
|
109
|
+
const deadline = Date.now() + 1e3;
|
|
110
|
+
let fd = null;
|
|
111
|
+
for (; ; ) {
|
|
112
|
+
try {
|
|
113
|
+
fd = openSync(lockPath, "wx", 384);
|
|
114
|
+
break;
|
|
115
|
+
} catch (error) {
|
|
116
|
+
if (error.code !== "EEXIST") throw error;
|
|
117
|
+
if (Date.now() > deadline) {
|
|
118
|
+
throw new Error(`timed out waiting for the secrets lock: ${lockPath}`);
|
|
119
|
+
}
|
|
120
|
+
sleepSync(20);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
return fn();
|
|
125
|
+
} finally {
|
|
126
|
+
if (fd !== null) {
|
|
127
|
+
closeSync(fd);
|
|
128
|
+
try {
|
|
129
|
+
unlinkSync(lockPath);
|
|
130
|
+
} catch {
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function getSecret(name) {
|
|
136
|
+
if (!name || typeof name !== "string") return void 0;
|
|
137
|
+
return readSecretsForRead().data[name];
|
|
138
|
+
}
|
|
139
|
+
function setSecret(name, value) {
|
|
140
|
+
if (!name || typeof name !== "string") {
|
|
141
|
+
throw new Error("Secret name must be a non-empty string");
|
|
142
|
+
}
|
|
143
|
+
if (typeof value !== "string" && (typeof value !== "object" || value === null)) {
|
|
144
|
+
throw new Error("Secret value must be a string or a plain object");
|
|
145
|
+
}
|
|
146
|
+
withSecretsLock(() => {
|
|
147
|
+
const data = readSecretsData();
|
|
148
|
+
data[name] = value;
|
|
149
|
+
writeSecretsData(data);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function deleteSecret(name) {
|
|
153
|
+
if (!name || typeof name !== "string") return false;
|
|
154
|
+
return withSecretsLock(() => {
|
|
155
|
+
const data = readSecretsData();
|
|
156
|
+
if (!(name in data)) return false;
|
|
157
|
+
delete data[name];
|
|
158
|
+
writeSecretsData(data);
|
|
159
|
+
return true;
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
function resolveSecretEnvVars(name) {
|
|
163
|
+
const val = getSecret(name);
|
|
164
|
+
if (val === void 0) return {};
|
|
165
|
+
const envs = {};
|
|
166
|
+
if (name.toLowerCase() === "amo") {
|
|
167
|
+
if (typeof val === "object" && val !== null) {
|
|
168
|
+
const obj = val;
|
|
169
|
+
const issuer = obj.issuer ?? obj.apiKey ?? obj.key ?? obj.WEB_EXT_API_KEY;
|
|
170
|
+
const secret = obj.secret ?? obj.apiSecret ?? obj.WEB_EXT_API_SECRET;
|
|
171
|
+
if (typeof issuer === "string" && issuer) {
|
|
172
|
+
envs["WEB_EXT_API_KEY"] = issuer;
|
|
173
|
+
envs["AMO_JWT_ISSUER"] = issuer;
|
|
174
|
+
}
|
|
175
|
+
if (typeof secret === "string" && secret) {
|
|
176
|
+
envs["WEB_EXT_API_SECRET"] = secret;
|
|
177
|
+
envs["AMO_JWT_SECRET"] = secret;
|
|
178
|
+
}
|
|
179
|
+
} else if (typeof val === "string" && val) {
|
|
180
|
+
envs["AMO_JWT_SECRET"] = val;
|
|
181
|
+
}
|
|
182
|
+
} else if (typeof val === "string") {
|
|
183
|
+
if (val) envs[name.toUpperCase().replace(/[^A-Z0-9_]/g, "_")] = val;
|
|
184
|
+
} else if (typeof val === "object" && val !== null) {
|
|
185
|
+
for (const [k, v] of Object.entries(val)) {
|
|
186
|
+
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
|
|
187
|
+
const envKey = `${name.toUpperCase()}_${k.toUpperCase()}`.replace(/[^A-Z0-9_]/g, "_");
|
|
188
|
+
envs[envKey] = String(v);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (Object.keys(envs).length === 0) throw new SecretHasNoEnvMappingError(name);
|
|
193
|
+
return envs;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// packages/core/secretBindings.ts
|
|
197
|
+
import {
|
|
198
|
+
existsSync as existsSync2,
|
|
199
|
+
mkdirSync as mkdirSync2,
|
|
200
|
+
readFileSync as readFileSync2,
|
|
201
|
+
renameSync as renameSync2,
|
|
202
|
+
chmodSync as chmodSync2,
|
|
203
|
+
writeFileSync as writeFileSync2,
|
|
204
|
+
openSync as openSync2,
|
|
205
|
+
closeSync as closeSync2,
|
|
206
|
+
unlinkSync as unlinkSync2
|
|
207
|
+
} from "fs";
|
|
208
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
209
|
+
var SecretBindingsFileCorruptedError = class extends SecretsFileCorruptedError {
|
|
210
|
+
constructor(filePath, cause) {
|
|
211
|
+
super(filePath, cause);
|
|
212
|
+
this.name = "SecretBindingsFileCorruptedError";
|
|
213
|
+
this.message = `secret bindings file is not valid JSON or corrupted and was left untouched: ${filePath}. Refusing to overwrite it \u2014 repair or move the file aside first.`;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
function getSecretBindingsFilePath() {
|
|
217
|
+
const override = process.env.NOLO_SECRET_BINDINGS_FILE;
|
|
218
|
+
if (override && override.trim()) return override.trim();
|
|
219
|
+
return join2(resolveCredentialsDir(), "secret_bindings.json");
|
|
220
|
+
}
|
|
221
|
+
function ensureDirectorySecured2(dirPath) {
|
|
222
|
+
if (!existsSync2(dirPath)) {
|
|
223
|
+
mkdirSync2(dirPath, { recursive: true, mode: 448 });
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
chmodSync2(dirPath, 448);
|
|
227
|
+
} catch {
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function sleepSync2(ms) {
|
|
231
|
+
try {
|
|
232
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
233
|
+
} catch {
|
|
234
|
+
const end = Date.now() + ms;
|
|
235
|
+
while (Date.now() < end) {
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
var lockDepth = 0;
|
|
240
|
+
function withSecretsLock2(fn) {
|
|
241
|
+
if (lockDepth > 0) {
|
|
242
|
+
lockDepth++;
|
|
243
|
+
try {
|
|
244
|
+
return fn();
|
|
245
|
+
} finally {
|
|
246
|
+
lockDepth--;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const lockPath = `${getSecretBindingsFilePath()}.lock`;
|
|
250
|
+
ensureDirectorySecured2(dirname2(lockPath));
|
|
251
|
+
const deadline = Date.now() + 2e3;
|
|
252
|
+
let fd = null;
|
|
253
|
+
for (; ; ) {
|
|
254
|
+
try {
|
|
255
|
+
fd = openSync2(lockPath, "wx", 384);
|
|
256
|
+
break;
|
|
257
|
+
} catch (error) {
|
|
258
|
+
if (error.code !== "EEXIST") throw error;
|
|
259
|
+
if (Date.now() > deadline) {
|
|
260
|
+
throw new Error(`timed out waiting for the secret bindings lock: ${lockPath}`);
|
|
261
|
+
}
|
|
262
|
+
sleepSync2(20);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
lockDepth = 1;
|
|
266
|
+
try {
|
|
267
|
+
return fn();
|
|
268
|
+
} finally {
|
|
269
|
+
lockDepth = 0;
|
|
270
|
+
if (fd !== null) {
|
|
271
|
+
closeSync2(fd);
|
|
272
|
+
try {
|
|
273
|
+
unlinkSync2(lockPath);
|
|
274
|
+
} catch {
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
function validateAlias(alias) {
|
|
280
|
+
if (typeof alias !== "string" || !alias || !/^[a-z0-9_]+$/.test(alias)) {
|
|
281
|
+
throw new Error(
|
|
282
|
+
`Invalid alias: ${JSON.stringify(alias)}. Alias must be a non-empty string consisting only of lowercase letters, digits, and underscores.`
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function validateBrokerRef(brokerRef) {
|
|
287
|
+
if (typeof brokerRef !== "string" || !brokerRef) {
|
|
288
|
+
throw new Error(`Invalid brokerRef: brokerRef must be a non-empty string.`);
|
|
289
|
+
}
|
|
290
|
+
if (brokerRef.includes("$nolo_cred:")) {
|
|
291
|
+
throw new Error(
|
|
292
|
+
`Invalid brokerRef: "${brokerRef}". Must not contain "$nolo_cred:" prefix.`
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
if (brokerRef.includes("/") || brokerRef.includes("\\") || brokerRef.includes("..")) {
|
|
296
|
+
throw new Error(
|
|
297
|
+
`Invalid brokerRef: "${brokerRef}". Path traversal characters ("/", "\\", "..") are strictly forbidden.`
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
if (!brokerRef.startsWith("vault-cred-") || brokerRef === "vault-cred-") {
|
|
301
|
+
throw new Error(
|
|
302
|
+
`Invalid brokerRef: "${brokerRef}". Must start with "vault-cred-".`
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
if (!/^vault-cred-[a-zA-Z0-9_.-]+$/.test(brokerRef)) {
|
|
306
|
+
throw new Error(
|
|
307
|
+
`Invalid brokerRef: "${brokerRef}". Contains invalid characters.`
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
function validateEnvName(envName) {
|
|
312
|
+
if (typeof envName !== "string" || !envName || !/^[A-Z_][A-Z0-9_]*$/.test(envName)) {
|
|
313
|
+
throw new Error(
|
|
314
|
+
`Invalid envName: ${JSON.stringify(envName)}. Must be a non-empty string matching standard environment variable naming (uppercase letters, digits, and underscores, not beginning with a digit).`
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function isValidSecretBinding(entry, expectedAlias) {
|
|
319
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return false;
|
|
320
|
+
const b = entry;
|
|
321
|
+
if (b.version !== 1) return false;
|
|
322
|
+
if (typeof b.alias !== "string" || !/^[a-z0-9_]+$/.test(b.alias)) return false;
|
|
323
|
+
if (expectedAlias !== void 0 && b.alias !== expectedAlias) return false;
|
|
324
|
+
if (typeof b.brokerRef !== "string" || !b.brokerRef.startsWith("vault-cred-") || b.brokerRef === "vault-cred-" || b.brokerRef.includes("..") || b.brokerRef.includes("/") || b.brokerRef.includes("\\") || b.brokerRef.includes("$nolo_cred:") || !/^vault-cred-[a-zA-Z0-9_.-]+$/.test(b.brokerRef)) {
|
|
325
|
+
return false;
|
|
326
|
+
}
|
|
327
|
+
if (typeof b.envName !== "string" || !/^[A-Z_][A-Z0-9_]*$/.test(b.envName)) return false;
|
|
328
|
+
if (typeof b.createdAt !== "number" || !Number.isFinite(b.createdAt)) return false;
|
|
329
|
+
if (typeof b.updatedAt !== "number" || !Number.isFinite(b.updatedAt)) return false;
|
|
330
|
+
if (b.ownerUserId !== void 0 && typeof b.ownerUserId !== "string") return false;
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
function readSecretBindingsData() {
|
|
334
|
+
const filePath = getSecretBindingsFilePath();
|
|
335
|
+
if (!existsSync2(filePath)) return {};
|
|
336
|
+
let raw;
|
|
337
|
+
try {
|
|
338
|
+
raw = readFileSync2(filePath, "utf8");
|
|
339
|
+
} catch (error) {
|
|
340
|
+
throw new SecretBindingsFileCorruptedError(filePath, error);
|
|
341
|
+
}
|
|
342
|
+
if (!raw.trim()) return {};
|
|
343
|
+
let parsed;
|
|
344
|
+
try {
|
|
345
|
+
parsed = JSON.parse(raw);
|
|
346
|
+
} catch (error) {
|
|
347
|
+
throw new SecretBindingsFileCorruptedError(filePath, error);
|
|
348
|
+
}
|
|
349
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
350
|
+
throw new SecretBindingsFileCorruptedError(filePath);
|
|
351
|
+
}
|
|
352
|
+
const result = {};
|
|
353
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
354
|
+
if (!isValidSecretBinding(value, key)) {
|
|
355
|
+
throw new SecretBindingsFileCorruptedError(filePath);
|
|
356
|
+
}
|
|
357
|
+
result[key] = value;
|
|
358
|
+
}
|
|
359
|
+
return result;
|
|
360
|
+
}
|
|
361
|
+
function writeSecretBindingsData(data) {
|
|
362
|
+
const filePath = getSecretBindingsFilePath();
|
|
363
|
+
const dir = dirname2(filePath);
|
|
364
|
+
ensureDirectorySecured2(dir);
|
|
365
|
+
const tempPath = join2(
|
|
366
|
+
dir,
|
|
367
|
+
`.secret_bindings-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`
|
|
368
|
+
);
|
|
369
|
+
writeFileSync2(tempPath, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
|
|
370
|
+
try {
|
|
371
|
+
chmodSync2(tempPath, 384);
|
|
372
|
+
} catch {
|
|
373
|
+
}
|
|
374
|
+
renameSync2(tempPath, filePath);
|
|
375
|
+
try {
|
|
376
|
+
chmodSync2(filePath, 384);
|
|
377
|
+
} catch {
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
function readSecretBindingsForRead() {
|
|
381
|
+
try {
|
|
382
|
+
const data = readSecretBindingsData();
|
|
383
|
+
const bindings = Object.values(data).sort((a, b) => a.alias.localeCompare(b.alias));
|
|
384
|
+
return { data, bindings, corrupted: false };
|
|
385
|
+
} catch (error) {
|
|
386
|
+
return { data: {}, bindings: [], corrupted: true, error };
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
function getSecretBinding(alias) {
|
|
390
|
+
if (!alias || typeof alias !== "string") return void 0;
|
|
391
|
+
const data = readSecretBindingsData();
|
|
392
|
+
return data[alias];
|
|
393
|
+
}
|
|
394
|
+
function setSecretBinding(binding) {
|
|
395
|
+
if (!binding || typeof binding !== "object") {
|
|
396
|
+
throw new Error("binding must be an object");
|
|
397
|
+
}
|
|
398
|
+
validateAlias(binding.alias);
|
|
399
|
+
validateBrokerRef(binding.brokerRef);
|
|
400
|
+
validateEnvName(binding.envName);
|
|
401
|
+
withSecretsLock2(() => {
|
|
402
|
+
const data = readSecretBindingsData();
|
|
403
|
+
const existing = data[binding.alias];
|
|
404
|
+
const now = Date.now();
|
|
405
|
+
const newRecord = {
|
|
406
|
+
version: 1,
|
|
407
|
+
alias: binding.alias,
|
|
408
|
+
brokerRef: binding.brokerRef,
|
|
409
|
+
envName: binding.envName,
|
|
410
|
+
createdAt: existing ? existing.createdAt : now,
|
|
411
|
+
updatedAt: now
|
|
412
|
+
};
|
|
413
|
+
if (binding.ownerUserId !== void 0) {
|
|
414
|
+
newRecord.ownerUserId = binding.ownerUserId;
|
|
415
|
+
} else if (existing?.ownerUserId !== void 0) {
|
|
416
|
+
newRecord.ownerUserId = existing.ownerUserId;
|
|
417
|
+
}
|
|
418
|
+
data[binding.alias] = newRecord;
|
|
419
|
+
writeSecretBindingsData(data);
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
function deleteSecretBinding(alias) {
|
|
423
|
+
if (!alias || typeof alias !== "string") return false;
|
|
424
|
+
return withSecretsLock2(() => {
|
|
425
|
+
const data = readSecretBindingsData();
|
|
426
|
+
if (!(alias in data)) return false;
|
|
427
|
+
delete data[alias];
|
|
428
|
+
writeSecretBindingsData(data);
|
|
429
|
+
return true;
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// packages/cli/secretCommands.ts
|
|
434
|
+
import { spawn } from "child_process";
|
|
435
|
+
function parseSecretValue(raw) {
|
|
436
|
+
const trimmed = raw.trim();
|
|
437
|
+
const looksLikeJson = trimmed.startsWith("{") || trimmed.startsWith("[");
|
|
438
|
+
if (!looksLikeJson) return raw;
|
|
439
|
+
let parsed;
|
|
440
|
+
try {
|
|
441
|
+
parsed = JSON.parse(trimmed);
|
|
442
|
+
} catch {
|
|
443
|
+
throw new Error("value starts with { or [ but is not valid JSON");
|
|
444
|
+
}
|
|
445
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
446
|
+
throw new Error("JSON values must be an object or an array, not a scalar");
|
|
447
|
+
}
|
|
448
|
+
return parsed;
|
|
449
|
+
}
|
|
450
|
+
async function runSecretCommand(args, options = {}) {
|
|
451
|
+
const [subcommand, ...rest] = args;
|
|
452
|
+
if (!subcommand || subcommand === "--help" || subcommand === "-h") {
|
|
453
|
+
console.log(`\u7528\u6CD5:
|
|
454
|
+
nolo secret list \u5217\u51FA\u5DF2\u4FDD\u5B58\u7684 secret \u540D\u79F0\uFF08\u4E0D\u663E\u793A\u503C\uFF09
|
|
455
|
+
nolo secret get <name> \u6253\u5370\u6307\u5B9A secret \u7684\u503C\uFF08\u4F9B\u8C03\u8BD5\uFF1BAgent \u4E0D\u5F97\u8BFB\u53D6\uFF09
|
|
456
|
+
nolo secret set <name> <value|json> \u8BBE\u7F6E secret\uFF08\u5B57\u7B26\u4E32\uFF0C\u6216\u4EE5 { / [ \u5F00\u5934\u7684 JSON\uFF09
|
|
457
|
+
nolo secret delete <name> \u5220\u9664\u6307\u5B9A\u7684 secret
|
|
458
|
+
nolo secret run --with <names> -- <cmd> \u5B89\u5168\u6CE8\u5165 secret \u73AF\u5883\u53D8\u91CF\u5E76\u6267\u884C\u5B50\u547D\u4EE4
|
|
459
|
+
nolo secret bind <alias> <ref> [--env <ENV_NAME>] \u5C06\u53D7\u63A7\u51ED\u636E\u5F15\u7528\u7ED1\u5B9A\u5230\u522B\u540D
|
|
460
|
+
nolo secret list-bindings \u5217\u51FA\u5DF2\u914D\u7F6E\u7684 secret \u522B\u540D\u7ED1\u5B9A
|
|
461
|
+
nolo secret unbind <alias> \u89E3\u9664\u6307\u5B9A\u7684 secret \u522B\u540D\u7ED1\u5B9A
|
|
462
|
+
`);
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
try {
|
|
466
|
+
switch (subcommand) {
|
|
467
|
+
case "list": {
|
|
468
|
+
const read = readSecretsForRead();
|
|
469
|
+
if (read.corrupted) {
|
|
470
|
+
console.error(`\u9519\u8BEF: ${read.error.message}`);
|
|
471
|
+
process.exitCode = 1;
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
const names = Object.keys(read.data).sort();
|
|
475
|
+
if (names.length === 0) {
|
|
476
|
+
console.log("\uFF08\u5F53\u524D\u672A\u4FDD\u5B58\u4EFB\u4F55 secret\uFF09");
|
|
477
|
+
} else {
|
|
478
|
+
console.log("\u5DF2\u914D\u7F6E\u7684 secret \u5217\u8868:");
|
|
479
|
+
for (const name of names) console.log(` - ${name}`);
|
|
480
|
+
}
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
case "get": {
|
|
484
|
+
const [name] = rest;
|
|
485
|
+
if (!name) {
|
|
486
|
+
console.error("\u9519\u8BEF: \u8BF7\u63D0\u4F9B secret \u540D\u79F0\u3002\u4F8B\u5982: nolo secret get amo");
|
|
487
|
+
process.exitCode = 1;
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
const read = readSecretsForRead();
|
|
491
|
+
if (read.corrupted) {
|
|
492
|
+
console.error(`\u9519\u8BEF: ${read.error.message}`);
|
|
493
|
+
process.exitCode = 1;
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
const val = read.data[name];
|
|
497
|
+
if (val === void 0) {
|
|
498
|
+
console.error(`\u9519\u8BEF: \u672A\u627E\u5230\u540D\u4E3A "${name}" \u7684 secret`);
|
|
499
|
+
process.exitCode = 1;
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
console.log(typeof val === "object" ? JSON.stringify(val, null, 2) : String(val));
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
case "set": {
|
|
506
|
+
const [name, ...valParts] = rest;
|
|
507
|
+
if (!name) {
|
|
508
|
+
console.error("\u9519\u8BEF: \u8BF7\u63D0\u4F9B secret \u540D\u79F0\u4E0E\u503C");
|
|
509
|
+
process.exitCode = 1;
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
const rawVal = valParts.join(" ").trim();
|
|
513
|
+
if (!rawVal) {
|
|
514
|
+
console.error("\u9519\u8BEF: \u8BF7\u63D0\u4F9B secret \u503C");
|
|
515
|
+
process.exitCode = 1;
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
setSecret(name, parseSecretValue(rawVal));
|
|
519
|
+
console.log(`\u2705 \u6210\u529F\u4FDD\u5B58 secret: "${name}"\uFF08\u6743\u9650 0600\uFF09`);
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
case "delete":
|
|
523
|
+
case "del":
|
|
524
|
+
case "rm": {
|
|
525
|
+
const [name] = rest;
|
|
526
|
+
if (!name) {
|
|
527
|
+
console.error("\u9519\u8BEF: \u8BF7\u63D0\u4F9B\u8981\u5220\u9664\u7684 secret \u540D\u79F0");
|
|
528
|
+
process.exitCode = 1;
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
console.log(
|
|
532
|
+
deleteSecret(name) ? `\u2705 \u6210\u529F\u5220\u9664 secret: "${name}"` : `\u672A\u627E\u5230\u540D\u4E3A "${name}" \u7684 secret\uFF0C\u65E0\u9700\u5220\u9664`
|
|
533
|
+
);
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
case "run":
|
|
537
|
+
case "exec": {
|
|
538
|
+
const doubleDashIdx = rest.indexOf("--");
|
|
539
|
+
const beforeDash = doubleDashIdx >= 0 ? rest.slice(0, doubleDashIdx) : [];
|
|
540
|
+
const cmdParts = doubleDashIdx >= 0 ? rest.slice(doubleDashIdx + 1) : rest;
|
|
541
|
+
let withNames = [];
|
|
542
|
+
for (let i = 0; i < beforeDash.length; i++) {
|
|
543
|
+
if (beforeDash[i] === "--with" && beforeDash[i + 1]) {
|
|
544
|
+
withNames = beforeDash[i + 1].split(",").map((s) => s.trim()).filter(Boolean);
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
if (cmdParts.length === 0) {
|
|
549
|
+
console.error("\u9519\u8BEF: \u8BF7\u63D0\u4F9B\u8981\u6267\u884C\u7684\u547D\u4EE4\u3002\u4F8B\u5982: nolo secret run --with amo -- bunx web-ext sign");
|
|
550
|
+
process.exitCode = 1;
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
const injectedEnvs = {};
|
|
554
|
+
const missing = [];
|
|
555
|
+
for (const name of withNames) {
|
|
556
|
+
if (getSecret(name) !== void 0) {
|
|
557
|
+
Object.assign(injectedEnvs, resolveSecretEnvVars(name));
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
560
|
+
const binding = getSecretBinding(name);
|
|
561
|
+
if (binding) {
|
|
562
|
+
const broker = options.broker ?? createFileCredentialBroker();
|
|
563
|
+
const secretValue = await broker.get(binding.brokerRef);
|
|
564
|
+
if (!secretValue) {
|
|
565
|
+
console.error(
|
|
566
|
+
`\u9519\u8BEF: \u51ED\u8BC1\u5F15\u7528 ${binding.brokerRef} \u5728\u672C\u5730\u4FDD\u7BA1\u5E93\u4E2D\u4E0D\u5B58\u5728\u6216\u672A\u6388\u6743\u3002`
|
|
567
|
+
);
|
|
568
|
+
process.exitCode = 1;
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
injectedEnvs[binding.envName] = secretValue;
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
missing.push(name);
|
|
575
|
+
}
|
|
576
|
+
if (missing.length > 0) {
|
|
577
|
+
console.error(
|
|
578
|
+
`\u9519\u8BEF: \u672A\u627E\u5230 secret: ${missing.join(", ")}\u3002\u7528 nolo secret list \u6838\u5BF9\u5DF2\u4FDD\u5B58\u7684\u540D\u79F0\u3002`
|
|
579
|
+
);
|
|
580
|
+
process.exitCode = 1;
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
if (withNames.length > 0 && Object.keys(injectedEnvs).length === 0) {
|
|
584
|
+
console.error(
|
|
585
|
+
`\u9519\u8BEF: --with ${withNames.join(",")} \u6CA1\u6709\u89E3\u6790\u51FA\u4EFB\u4F55\u73AF\u5883\u53D8\u91CF\uFF08\u51ED\u636E\u65E0\u6CD5\u6620\u5C04\u6210\u53D8\u91CF\uFF09\u3002`
|
|
586
|
+
);
|
|
587
|
+
process.exitCode = 1;
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
await new Promise((resolvePromise) => {
|
|
591
|
+
let settled = false;
|
|
592
|
+
const finish = (code) => {
|
|
593
|
+
if (settled) return;
|
|
594
|
+
settled = true;
|
|
595
|
+
process.exitCode = code;
|
|
596
|
+
resolvePromise();
|
|
597
|
+
};
|
|
598
|
+
const child = spawn(cmdParts[0], cmdParts.slice(1), {
|
|
599
|
+
stdio: "inherit",
|
|
600
|
+
env: { ...process.env, ...injectedEnvs }
|
|
601
|
+
});
|
|
602
|
+
child.on(
|
|
603
|
+
"close",
|
|
604
|
+
(code, signal) => finish(signal ? 1 : code ?? 1)
|
|
605
|
+
);
|
|
606
|
+
child.on("error", (err) => {
|
|
607
|
+
console.error(`\u6267\u884C\u547D\u4EE4\u5931\u8D25: ${err.message}`);
|
|
608
|
+
finish(1);
|
|
609
|
+
});
|
|
610
|
+
});
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
case "bind": {
|
|
614
|
+
let envOption;
|
|
615
|
+
const positional = [];
|
|
616
|
+
for (let i = 0; i < rest.length; i++) {
|
|
617
|
+
const arg = rest[i];
|
|
618
|
+
if (arg === "--env") {
|
|
619
|
+
if (i + 1 < rest.length) {
|
|
620
|
+
envOption = rest[i + 1];
|
|
621
|
+
i++;
|
|
622
|
+
} else {
|
|
623
|
+
console.error("\u9519\u8BEF: --env \u9700\u8981\u6307\u5B9A\u73AF\u5883\u53D8\u91CF\u540D\u3002\u4F8B\u5982: --env DEEPINFRA_API_KEY");
|
|
624
|
+
process.exitCode = 1;
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
} else if (arg.startsWith("--env=")) {
|
|
628
|
+
envOption = arg.slice("--env=".length);
|
|
629
|
+
} else {
|
|
630
|
+
positional.push(arg);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
const [alias, rawRef] = positional;
|
|
634
|
+
if (!alias || !rawRef) {
|
|
635
|
+
console.error(
|
|
636
|
+
"\u9519\u8BEF: \u8BF7\u63D0\u4F9B alias \u4E0E\u51ED\u636E\u5F15\u7528 (ref)\u3002\u4F8B\u5982: nolo secret bind deepinfra_api_key vault-cred-xxx [--env DEEPINFRA_API_KEY]"
|
|
637
|
+
);
|
|
638
|
+
process.exitCode = 1;
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
let brokerRef = rawRef;
|
|
642
|
+
if (brokerRef.startsWith("$nolo_cred:")) {
|
|
643
|
+
brokerRef = brokerRef.slice("$nolo_cred:".length);
|
|
644
|
+
}
|
|
645
|
+
const envName = envOption !== void 0 ? envOption : alias.toUpperCase().replace(/[^A-Z0-9_]/g, "_");
|
|
646
|
+
setSecretBinding({
|
|
647
|
+
alias,
|
|
648
|
+
brokerRef,
|
|
649
|
+
envName
|
|
650
|
+
});
|
|
651
|
+
console.log(`\u2705 \u6210\u529F\u7ED1\u5B9A secret: "${alias}" -> ${brokerRef} (env: ${envName})`);
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
case "list-bindings":
|
|
655
|
+
case "bindings": {
|
|
656
|
+
const read = readSecretBindingsForRead();
|
|
657
|
+
if (read.corrupted) {
|
|
658
|
+
console.error(`\u9519\u8BEF: ${read.error.message}`);
|
|
659
|
+
process.exitCode = 1;
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
const bindings = read.bindings;
|
|
663
|
+
if (bindings.length === 0) {
|
|
664
|
+
console.log("\uFF08\u5F53\u524D\u672A\u914D\u7F6E\u4EFB\u4F55 secret \u522B\u540D\u7ED1\u5B9A\uFF09");
|
|
665
|
+
} else {
|
|
666
|
+
console.log("\u5DF2\u914D\u7F6E\u7684 secret \u522B\u540D\u7ED1\u5B9A\u5217\u8868:");
|
|
667
|
+
for (const b of bindings) {
|
|
668
|
+
console.log(` - ${b.alias} -> ${b.brokerRef} (env: ${b.envName})`);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
case "unbind": {
|
|
674
|
+
const [alias] = rest;
|
|
675
|
+
if (!alias) {
|
|
676
|
+
console.error("\u9519\u8BEF: \u8BF7\u63D0\u4F9B\u8981\u89E3\u9664\u7ED1\u5B9A\u7684\u522B\u540D (alias)\u3002\u4F8B\u5982: nolo secret unbind deepinfra_api_key");
|
|
677
|
+
process.exitCode = 1;
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
console.log(
|
|
681
|
+
deleteSecretBinding(alias) ? `\u2705 \u6210\u529F\u89E3\u9664 secret \u7ED1\u5B9A: "${alias}"` : `\u672A\u627E\u5230\u540D\u4E3A "${alias}" \u7684 secret \u7ED1\u5B9A\uFF0C\u65E0\u9700\u89E3\u9664`
|
|
682
|
+
);
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
default:
|
|
686
|
+
console.error(`\u672A\u77E5\u5B50\u547D\u4EE4: ${subcommand}\u3002\u8FD0\u884C nolo secret --help \u67E5\u770B\u7528\u6CD5`);
|
|
687
|
+
process.exitCode = 1;
|
|
688
|
+
}
|
|
689
|
+
} catch (error) {
|
|
690
|
+
if (error instanceof SecretsFileCorruptedError) {
|
|
691
|
+
console.error(`\u9519\u8BEF: ${error.message}`);
|
|
692
|
+
} else {
|
|
693
|
+
console.error(`\u9519\u8BEF: ${error.message}`);
|
|
694
|
+
}
|
|
695
|
+
process.exitCode = 1;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
export {
|
|
699
|
+
runSecretCommand
|
|
700
|
+
};
|