@runeya/runeya 2.0.39 → 2.0.41
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/agent-manager-2I47P7CA.js +7 -0
- package/{chunk-PW6A3BLD.js → chunk-NJJMESIY.js} +400 -93
- package/chunk-NJJMESIY.js.map +1 -0
- package/index.js +1 -1
- package/package.json +1 -1
- package/{src-A3WSWXEY.js → src-BCBD4MPB.js} +1041 -336
- package/src-BCBD4MPB.js.map +1 -0
- package/web/assets/{AgentScalarChatInterface.vue-HiYdPZh0.js → AgentScalarChatInterface.vue-bk9hxmaQ.js} +1 -1
- package/web/assets/{AgentTerminalPage-BV1OTr-r.js → AgentTerminalPage-B04ZDAX6.js} +1 -1
- package/web/assets/AiChatPage-CRVc_0Nu.js +1 -0
- package/web/assets/{AppLayout-DW_-KBWL.css → AppLayout-BBifPBJu.css} +1 -1
- package/web/assets/AppLayout-DvrAr1Tw.js +1 -0
- package/web/assets/{AuditPage-Bc4NZud3.js → AuditPage-B64guLBx.js} +1 -1
- package/web/assets/CloudAccountPage-4nEDwbbP.js +1 -0
- package/web/assets/CloudAccountPage-C_OlcjXc.js +1 -0
- package/web/assets/CloudAccountPage-ChVg2wnJ.css +1 -0
- package/web/assets/{CloudMessagingPage-CWcahAog.js → CloudMessagingPage-ClNaEqU1.js} +1 -1
- package/web/assets/{DashboardPage-nhKxGmnu.js → DashboardPage-8z5zI4At.js} +1 -1
- package/web/assets/{EditorIcon-vSDu502Z.js → EditorIcon-QuM8Jw0F.js} +1 -1
- package/web/assets/{EnvironmentForm-8WEcxUYY.js → EnvironmentForm-CctbC-gb.js} +1 -1
- package/web/assets/{EnvironmentFormPage-CpwzzSeB.js → EnvironmentFormPage-BOLckpdf.js} +1 -1
- package/web/assets/{EnvironmentListPage-Dyq7x-l_.js → EnvironmentListPage-CWbCtHUP.js} +1 -1
- package/web/assets/{EnvironmentSelector-BXe42bF9.js → EnvironmentSelector-CSSr9Uoa.js} +1 -1
- package/web/assets/{KanbanBoardPage-DHAWtkkJ.js → KanbanBoardPage-wjk3mufd.js} +3 -3
- package/web/assets/{KanbanListPage-CjQfqoXf.js → KanbanListPage-CBa8MOZq.js} +1 -1
- package/web/assets/LaunchProjectPage-CnhTqUn6.js +1 -0
- package/web/assets/LaunchProjectPage-CxXC2U3O.css +1 -0
- package/web/assets/{LaunchServicesPage-DYLGFHSm.js → LaunchServicesPage-oHDlEgqh.js} +1 -1
- package/web/assets/{LogViewer-CEQDlzBl.js → LogViewer-CbXki1mv.js} +1 -1
- package/web/assets/{ProcessControls-RuqRu4r_.js → ProcessControls-E3Ka8erw.js} +1 -1
- package/web/assets/{ProcessDetailPage-CnK8kLHx.js → ProcessDetailPage-lofKmzDr.js} +1 -1
- package/web/assets/{ProcessMetrics-tNC5ggO0.js → ProcessMetrics-DNIFOkvO.js} +1 -1
- package/web/assets/ProjectDetailPage-B42imx75.css +1 -0
- package/web/assets/ProjectDetailPage-Dz2WCS0H.js +1 -0
- package/web/assets/{ProjectListPage-BGihYeDx.js → ProjectListPage-MH2MfkaC.js} +1 -1
- package/web/assets/{RandomJobTestPage-BgjN2Lqt.js → RandomJobTestPage-C1yrM6Zy.js} +1 -1
- package/web/assets/{ScenarioEditorPage-nU_bK6Wm.js → ScenarioEditorPage-Dy6iy9r8.js} +1 -1
- package/web/assets/{SendToChatDialog-DG6GidKi.js → SendToChatDialog-DCpOcZ4B.js} +1 -1
- package/web/assets/{ServiceControlsBar-lvV0380I.js → ServiceControlsBar-B3dt-TpS.js} +1 -1
- package/web/assets/{ServiceDetailPage-gG_F4CpK.js → ServiceDetailPage-Dt4DRm6q.js} +1 -1
- package/web/assets/{ServiceFormPage-5pLarqaj.js → ServiceFormPage-ks_mGrTT.js} +1 -1
- package/web/assets/{SettingsPage-DGtNwgNF.js → SettingsPage-Ca--x3I2.js} +4 -4
- package/web/assets/{SetupPage-zLbZ7HFD.js → SetupPage-DnbrJAZf.js} +1 -1
- package/web/assets/{UnlockPage-BNUgOO2j.js → UnlockPage-Brv5TJMY.js} +1 -1
- package/web/assets/{VariablesTable-Dh7ySbKc.js → VariablesTable-DWg01MKw.js} +1 -1
- package/web/assets/{VersionBadge-Bcr43sQb.js → VersionBadge-DzEXeyD9.js} +1 -1
- package/web/assets/WikiPage-GjwXa8Oq.js +1 -0
- package/web/assets/{WikiView-bePXeeW1.js → WikiView-CulrPak1.js} +1 -1
- package/web/assets/{add-scalar-classes-BZ33Hgh4.js → add-scalar-classes-CqTKiXd8.js} +3 -3
- package/web/assets/auth-errors-CUm_h-nn.js +1 -0
- package/web/assets/{autocomplete-Mxh2ZegH.js → autocomplete-DEB2Qu-k.js} +1 -1
- package/web/assets/{basic-shape-diamond.svg-C_plmghk.js → basic-shape-diamond.svg-KT7ENzRk.js} +1 -1
- package/web/assets/{basic-shape-hexagon.svg-A1qvevt_.js → basic-shape-hexagon.svg-BG-V5Q5m.js} +1 -1
- package/web/assets/{basic-shape-primary-circle-ellipse-round.svg-Df8UWBuG.js → basic-shape-primary-circle-ellipse-round.svg-DkS-BSnd.js} +1 -1
- package/web/assets/{basic-shape-primary-square-rectangle.svg-hAiISQ_N.js → basic-shape-primary-square-rectangle.svg-JAOlu5yc.js} +1 -1
- package/web/assets/{basic-shape-shield.svg-j04XHSeq.js → basic-shape-shield.svg-BhPI20FC.js} +1 -1
- package/web/assets/{browser-_K3D-Q-7.js → browser-D77gc3Rr.js} +1 -1
- package/web/assets/{browser-B4MIWpa7.js → browser-Dh2HVE1I.js} +1 -1
- package/web/assets/{card-DGaeJPst.js → card-DIJopohC.js} +1 -1
- package/web/assets/{checkbox-C5uNb3Rm.js → checkbox-gEptCzM4.js} +1 -1
- package/web/assets/{chip-DDjgi9qj.js → chip-Rl8eKYOz.js} +1 -1
- package/web/assets/{client-D9DmTFwP.js → client-CPmn2crt.js} +1 -1
- package/web/assets/{cloud-chat.store-BPUP_Hxk.js → cloud-chat.store-DoQXE_CW.js} +1 -1
- package/web/assets/{cloud-session-B1oqwDJc.js → cloud-session-GnprlXNn.js} +1 -1
- package/web/assets/{column-sUzyGFk3.js → column-CHn9iHRy.js} +1 -1
- package/web/assets/{computer-device-desktop-monitor.svg-BBuhFhn-.js → computer-device-desktop-monitor.svg-DRH73_n8.js} +1 -1
- package/web/assets/{computer-device-desktop.svg-LL5HezrB.js → computer-device-desktop.svg-DXLn48TE.js} +1 -1
- package/web/assets/{computer-device-laptop.svg-C4xmfwdM.js → computer-device-laptop.svg-Cx3qvopX.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-android-samsung-back.svg-B-uD42mr.js → computer-device-mobile-phone-android-samsung-back.svg-91VumZ5n.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-android-samsung.svg-qPPbtnL9.js → computer-device-mobile-phone-android-samsung.svg-B1rGCVDW.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-iphone-x-back.svg-B1Xa9B8p.js → computer-device-mobile-phone-iphone-x-back.svg-BpI2fov9.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-iphone-x.svg-B9zWUZbf.js → computer-device-mobile-phone-iphone-x.svg-CgXARUwD.js} +1 -1
- package/web/assets/{computer-device-mobile-tablet-touch.svg-CriHRQuM.js → computer-device-mobile-tablet-touch.svg-CCbrFsKS.js} +1 -1
- package/web/assets/{computer-device-mobile-tablet.svg-BOKVzupN.js → computer-device-mobile-tablet.svg-DjMvb6nR.js} +1 -1
- package/web/assets/{computer-device-network-ethernet-cat6.svg-D0L6yx6b.js → computer-device-network-ethernet-cat6.svg-Bqaea3Cl.js} +1 -1
- package/web/assets/{computer-device-network-lan-www.svg-n9m6VZVC.js → computer-device-network-lan-www.svg-CJxUMWWI.js} +1 -1
- package/web/assets/{computer-device-network-wifi-connection.svg-BqJzn-5W.js → computer-device-network-wifi-connection.svg-BUWGehfn.js} +1 -1
- package/web/assets/{computer-device-network-wifi-router.svg-DKcOeajJ.js → computer-device-network-wifi-router.svg-BC12dD1O.js} +1 -1
- package/web/assets/{cssMode-CLuhsa-I.js → cssMode-Df4SqVsZ.js} +1 -1
- package/web/assets/{divider-UPIM4dQl.js → divider-xI7dNZxb.js} +1 -1
- package/web/assets/{ecology-science-erlenmeyer-flask.svg-DyL2i1-k.js → ecology-science-erlenmeyer-flask.svg-DsEq5QkC.js} +1 -1
- package/web/assets/{fieldset-CIZfn4mb.js → fieldset-DHi1E3Rv.js} +1 -1
- package/web/assets/{freemarker2-BQV9kA1Y.js → freemarker2-DcSf8AuF.js} +1 -1
- package/web/assets/{handlebars-ib1US5Pw.js → handlebars-B866hvQq.js} +1 -1
- package/web/assets/{html-D-hYOiBO.js → html-Bqs2Jvnl.js} +1 -1
- package/web/assets/{htmlMode-WY_1KZ8Q.js → htmlMode-ZcQnxlbi.js} +1 -1
- package/web/assets/{image-flash-lightning.svg-wPJhlaEM.js → image-flash-lightning.svg-BnJa70PB.js} +1 -1
- package/web/assets/{image-picture-flower.svg-C15wjNsW.js → image-picture-flower.svg-CnHedFRr.js} +1 -1
- package/web/assets/{index-CcDpHMIW.js → index-DKBnMXVN.js} +259 -259
- package/web/assets/{interface-alert-exclamation-diamond.svg-C2MhzWE9.js → interface-alert-exclamation-diamond.svg-COmucSk_.js} +1 -1
- package/web/assets/{interface-alert-exclamation-triangle-warning.svg-D8heEy48.js → interface-alert-exclamation-triangle-warning.svg-M36BIAo6.js} +1 -1
- package/web/assets/{interface-alert-information-circle.svg-zrf3-9VP.js → interface-alert-information-circle.svg-1kMmqhO2.js} +1 -1
- package/web/assets/{interface-award-crown.svg-CT401HIW.js → interface-award-crown.svg-DptGWkkU.js} +1 -1
- package/web/assets/{interface-bookmark.svg-CqHV5l4k.js → interface-bookmark-tag.svg-D7TAAj3n.js} +1 -1
- package/web/assets/{interface-bookmark-tag.svg-h5CZEHt8.js → interface-bookmark.svg-ViiyYT_L.js} +1 -1
- package/web/assets/{interface-calendar-date-one.svg-DUdLsM_8.js → interface-calendar-date-one.svg-CWorrxsZ.js} +1 -1
- package/web/assets/{interface-content-book-open-pages.svg-DNR8SCd0.js → interface-content-book-open-pages.svg-Br_e_4Im.js} +1 -1
- package/web/assets/{interface-content-book-page.svg-Da9e-SX6.js → interface-content-book-page.svg-Du0uHoZ7.js} +1 -1
- package/web/assets/{interface-content-file.svg-BZM7jMWF.js → interface-content-file.svg-C972356w.js} +1 -1
- package/web/assets/{interface-content-folder.svg-BisjJGhi.js → interface-content-folder.svg-Erjx4HGU.js} +1 -1
- package/web/assets/interface-content-folder.svg-nZraYlQ1.js +1 -0
- package/web/assets/{interface-copy-clipboard.svg-AIcyJXPF.js → interface-copy-clipboard.svg-B9XvjK6U.js} +1 -1
- package/web/assets/{interface-edit-attachment.svg-XSvdzubS.js → interface-edit-attachment.svg-BWe41qK5.js} +1 -1
- package/web/assets/{interface-edit-binocular.svg-CCB9rIw_.js → interface-edit-binocular.svg-ChJsM_P7.js} +1 -1
- package/web/assets/{interface-edit-magic-wand.svg-Dd4afdpz.js → interface-edit-magic-wand.svg-BUs2NS7s.js} +1 -1
- package/web/assets/{interface-edit-tool-paint-roller.svg-DpO7rr7P.js → interface-edit-tool-paint-roller.svg-CdrYKzH6.js} +1 -1
- package/web/assets/{interface-edit-tool-pencil.svg-DbKruCrP.js → interface-edit-tool-pencil.svg-C8on9j4c.js} +1 -1
- package/web/assets/{interface-favorite-award.svg-DNIpxtuy.js → interface-favorite-award.svg-Bh_lIFBs.js} +1 -1
- package/web/assets/{interface-favorite-flag.svg-CgGWpm8Y.js → interface-favorite-flag.svg-BfecybVt.js} +1 -1
- package/web/assets/{interface-favorite-heart.svg-Bke1OXMv.js → interface-favorite-heart.svg-DDreuf_y.js} +1 -1
- package/web/assets/{interface-favorite-star.svg-DgwsiTjP.js → interface-favorite-star.svg-BJNTsPaT.js} +1 -1
- package/web/assets/{interface-favorite-stars-sparkles.svg-dKGlP2sr.js → interface-favorite-stars-sparkles.svg-CKOBWT4J.js} +1 -1
- package/web/assets/{interface-hierarchy-flowchart.svg-Bved245R.js → interface-hierarchy-flowchart.svg-7rufYb_n.js} +1 -1
- package/web/assets/{interface-home-house.svg-DJIEYhIa.js → interface-home-house.svg-CrKToh2q.js} +1 -1
- package/web/assets/{interface-hyperlink.svg-BBh6NFX7.js → interface-hyperlink.svg-BOjFniK_.js} +1 -1
- package/web/assets/{interface-lighting-brightness.svg-NqCt5nK8.js → interface-lighting-brightness.svg-B3-sdI-a.js} +1 -1
- package/web/assets/{interface-lock-closed.svg-CclDxo01.js → interface-lock-closed.svg-D3pw1rIY.js} +1 -1
- package/web/assets/{interface-lock-open-unlock.svg-CYPJVug8.js → interface-lock-open-unlock.svg-CJ_XAmbt.js} +1 -1
- package/web/assets/{interface-login-key.svg-DaW7pEY5.js → interface-login-key.svg-D--OEw7I.js} +1 -1
- package/web/assets/{interface-search.svg-j89Vz_N5.js → interface-search.svg-_5NliDrL.js} +1 -1
- package/web/assets/{interface-setting-cog.svg-CY2WkccU.js → interface-setting-cog.svg-uK8uMEZ2.js} +1 -1
- package/web/assets/{interface-share-megaphone-bullhorn.svg-C927tb6q.js → interface-share-megaphone-bullhorn.svg-CIdM6tKR.js} +1 -1
- package/web/assets/{interface-share-rocket.svg-B3sZvIoQ.js → interface-share-rocket.svg-CN-zhWTK.js} +1 -1
- package/web/assets/{interface-share-satellite.svg-CQ8A4dXG.js → interface-share-satellite.svg-CVTJ9m_O.js} +1 -1
- package/web/assets/{interface-share-space-ship.svg-BTGyj986.js → interface-share-space-ship.svg-jIDLHLi6.js} +1 -1
- package/web/assets/{interface-share.svg-BSQ8cEXV.js → interface-share.svg-33frw3Wv.js} +1 -1
- package/web/assets/{interface-signal-square.svg-1h2-Znr2.js → interface-signal-square.svg-Wg7BKl9x.js} +1 -1
- package/web/assets/{interface-time-clock-circle.svg-CgUcH4er.js → interface-time-clock-circle.svg-CZ6md3Ju.js} +1 -1
- package/web/assets/{interface-time-hour-glass.svg-Biz9ylcj.js → interface-time-hour-glass.svg-dRVhEG12.js} +1 -1
- package/web/assets/{interface-users-multiple.svg-B2SNNyd6.js → interface-users-multiple.svg-D7jrCQNN.js} +1 -1
- package/web/assets/{interface-weather-moon.svg-DFIwJsKU.js → interface-weather-moon.svg-BYWPWUQx.js} +1 -1
- package/web/assets/{javascript-w0UZtcmg.js → javascript-BATb-HYh.js} +1 -1
- package/web/assets/{jsonMode-CJUdXIyV.js → jsonMode-CP6RXg9k.js} +1 -1
- package/web/assets/{liquid-CjedKIbd.js → liquid-BCpH2Ett.js} +1 -1
- package/web/assets/{lspLanguageFeatures-DGvsogF_.js → lspLanguageFeatures-BWSdWSw7.js} +1 -1
- package/web/assets/{mail-chat-bubble-square.svg-D16l2agS.js → mail-chat-bubble-square.svg-BwFA9sJS.js} +1 -1
- package/web/assets/{mail-send-email-paper-airplane.svg-Bz-my4zw.js → mail-send-email-paper-airplane.svg-DWRvHccC.js} +1 -1
- package/web/assets/{mail-send-envelope.svg-Cgh2a1hO.js → mail-send-envelope.svg-6QBx4SLE.js} +1 -1
- package/web/assets/{mdx-Y5OqFrRV.js → mdx-JagJo-dt.js} +1 -1
- package/web/assets/{message-Bh-eAVAb.js → message-TwI_r5mZ.js} +1 -1
- package/web/assets/{minus-CxgjeEyu.js → minus-oYqzuR4a.js} +1 -1
- package/web/assets/modal-BEYg-JLN.js +1 -0
- package/web/assets/{modal-ciXJUOol.js → modal-CFM8h6A5.js} +1 -1
- package/web/assets/{money-cashier-receipt.svg-BP5bjawX.js → money-cashier-receipt.svg-Cl2LyS7q.js} +1 -1
- package/web/assets/{money-currency-dollar-pay.svg-vKtIhvs8.js → money-currency-dollar-pay.svg-DiytkCh0.js} +1 -1
- package/web/assets/{money-graph-arrow-increase.svg-CaeoOB93.js → money-graph-arrow-increase.svg-D4qMSRlp.js} +1 -1
- package/web/assets/{money-graph-bar-chart-increase.svg-CjRjHwbF.js → money-graph-bar-chart-increase.svg-CdCIWvvQ.js} +1 -1
- package/web/assets/{multiselect-CsE4Xly1.js → multiselect-CSyl93Ho.js} +1 -1
- package/web/assets/{nature-ecology-leaf.svg-umy4cUUw.js → nature-ecology-leaf.svg-GjBsj54D.js} +1 -1
- package/web/assets/{password-Brra1Twl.js → password-xomJK8iH.js} +1 -1
- package/web/assets/{phone-telephone.svg-DQ18gSw7.js → phone-telephone.svg-CBtGAjHv.js} +1 -1
- package/web/assets/{plus-e_D9UcW9.js → plus-C8MR9x_j.js} +1 -1
- package/web/assets/process.store-vy8KqH_z.js +1 -0
- package/web/assets/{programming-bug.svg-BL4Hus_Q.js → programming-bug.svg-BHCuUnau.js} +1 -1
- package/web/assets/{programming-cloud.svg-DrTlrDBe.js → programming-cloud.svg-DPdcvBlm.js} +1 -1
- package/web/assets/{programming-computer-database-server.svg-CnwbhD5W.js → programming-computer-database-server.svg-CaruocqU.js} +1 -1
- package/web/assets/{programming-computer-database.svg-GymDSTl9.js → programming-computer-database.svg-DFSRGAGE.js} +1 -1
- package/web/assets/{programming-module-four-layout.svg-DspyCTiu.js → programming-module-four-layout.svg-GUN-7Tqn.js} +1 -1
- package/web/assets/{programming-module-three.svg-BuYXTrWu.js → programming-module-three.svg-DYC-KU3a.js} +1 -1
- package/web/assets/{programming-module.svg-DIlRMVbW.js → programming-module.svg-NW_oL81i.js} +1 -1
- package/web/assets/{programming-script-code.svg-DPXJcL07.js → programming-script-code.svg-BPISkQtk.js} +1 -1
- package/web/assets/{python-3fAbpxqq.js → python-CXVm4gDt.js} +1 -1
- package/web/assets/{radiobutton-w7t3rGDJ.js → radiobutton-BLlyiAho.js} +1 -1
- package/web/assets/{razor-GDM0jSNH.js → razor-BcnFJswZ.js} +1 -1
- package/web/assets/router-Z6Tmw2JR.js +1 -0
- package/web/assets/{settings.store-D0eLKI4A.js → settings.store-CPAOxEyN.js} +1 -1
- package/web/assets/{shopping-cart.svg-B1y-4w0M.js → shopping-cart.svg-CA8D1Bj1.js} +1 -1
- package/web/assets/{shopping-gift-present.svg-DJ3mGWql.js → shopping-gift-present.svg-DA0s4ges.js} +1 -1
- package/web/assets/{shopping-shipping-box-parcel-package.svg-Bj3iHRT5.js → shopping-shipping-box-parcel-package.svg-BkLM7KC9.js} +1 -1
- package/web/assets/{src-wVYcxep_.js → src-DQG3PBVG.js} +1 -1
- package/web/assets/{src-BotO3dQ7.js → src-Dyv5MRfg.js} +1 -1
- package/web/assets/{tabpanel-DOZdp_HS.js → tabpanel-CNQhqmGV.js} +1 -1
- package/web/assets/{tag-new-circle.svg-Bb_ByVey.js → tag-new-circle.svg-BVZMrQWv.js} +1 -1
- package/web/assets/{travel-map-earth-globe.svg-Mso-K6XY.js → travel-map-earth-globe.svg-BZXWAlAZ.js} +1 -1
- package/web/assets/trpc-DVqzpQq9.js +1 -0
- package/web/assets/{tsMode-BUHQk9ZI.js → tsMode-BjuYVSR3.js} +1 -1
- package/web/assets/{typescript-Quc5d9qP.js → typescript-Bw5AHC7f.js} +1 -1
- package/web/assets/useAiChatDrawer-BCH3idQo.js +1 -0
- package/web/assets/useCloudOrg-A1wW_KrI.css +1 -0
- package/web/assets/useCloudOrg-BthYAZho.js +1 -0
- package/web/assets/{xml-CkYBw41O.js → xml-ESsLInqI.js} +1 -1
- package/web/assets/{yaml-CmSvkxzN.js → yaml-CEuOVTz-.js} +1 -1
- package/web/index.html +1 -1
- package/agent-manager-U3HLZ6QZ.js +0 -7
- package/chunk-PW6A3BLD.js.map +0 -1
- package/src-A3WSWXEY.js.map +0 -1
- package/web/assets/AiChatPage-Ct_f2ned.js +0 -1
- package/web/assets/AppLayout-BX_Buqtz.js +0 -1
- package/web/assets/CloudAccountPage-BqnCKZxn.js +0 -1
- package/web/assets/CloudAccountPage-CRN-tnI1.css +0 -1
- package/web/assets/CloudAccountPage-kTdYEt2S.js +0 -1
- package/web/assets/LaunchProjectPage-57kJRakH.css +0 -1
- package/web/assets/LaunchProjectPage-Bfs_AIgu.js +0 -1
- package/web/assets/ProjectDetailPage-BxLE6-54.css +0 -1
- package/web/assets/ProjectDetailPage-Cd3-8PAI.js +0 -1
- package/web/assets/WikiPage-DDx_jeaY.js +0 -1
- package/web/assets/auth-errors-BJV46AcQ.js +0 -1
- package/web/assets/interface-content-folder.svg-p32kmmD9.js +0 -1
- package/web/assets/modal-CIFHhhV7.js +0 -1
- package/web/assets/process.store-BhNwQ2dn.js +0 -1
- package/web/assets/router-C6yOFC1g.js +0 -1
- package/web/assets/trpc-BWtKBok1.js +0 -1
- package/web/assets/useAiChatDrawer-CRJCTTTO.js +0 -1
- package/web/assets/useCloudOrg-CBr3kqWH.js +0 -1
- package/web/assets/useCloudOrg-Gz6ek71z.css +0 -1
- /package/{agent-manager-U3HLZ6QZ.js.map → agent-manager-2I47P7CA.js.map} +0 -0
|
@@ -5,8 +5,13 @@ import { z as z21 } from "zod";
|
|
|
5
5
|
|
|
6
6
|
// ../server/src/services/agent-store.ts
|
|
7
7
|
import { randomUUID, randomBytes, createCipheriv, createDecipheriv } from "crypto";
|
|
8
|
-
import { readFile, writeFile, rename, mkdir, chmod } from "fs/promises";
|
|
9
|
-
import {
|
|
8
|
+
import { readFile, writeFile, rename, mkdir as mkdir2, chmod } from "fs/promises";
|
|
9
|
+
import { dirname } from "path";
|
|
10
|
+
|
|
11
|
+
// ../server/src/services/vault-resolver.ts
|
|
12
|
+
import { join, resolve } from "path";
|
|
13
|
+
import { homedir } from "os";
|
|
14
|
+
import { readdir, mkdir, access } from "fs/promises";
|
|
10
15
|
|
|
11
16
|
// ../server/src/config/env.ts
|
|
12
17
|
import { z } from "zod";
|
|
@@ -19,6 +24,10 @@ var EnvSchema = z.object({
|
|
|
19
24
|
RUNEYA_AGENT_HOST: z.string().default("127.0.0.1"),
|
|
20
25
|
RUNEYA_AGENT_BINARY_PATH: z.string().nullable().default(null),
|
|
21
26
|
RUNEYA_DATA_DIR: z.preprocess((v) => typeof v === "string" && v.length > 0 ? v : void 0, z.string().default(".runeya")),
|
|
27
|
+
// Home holding the cloud vaults (`<home>/.runeya/orgs/...`). Defaults to the
|
|
28
|
+
// user's home directory; overridden by tests so they never write to the real
|
|
29
|
+
// one, and usable to relocate the vaults on a shared machine.
|
|
30
|
+
RUNEYA_HOME: z.preprocess((v) => typeof v === "string" && v.length > 0 ? v : void 0, z.string().nullable().default(null)),
|
|
22
31
|
RUNEYA_CLOUD_URL: z.string().url().nullable().default(null),
|
|
23
32
|
// Cloud front-end (landing) URL — used by the web app for the registration /
|
|
24
33
|
// onboarding flow. Configured on the server at launch; the web fetches it.
|
|
@@ -40,6 +49,7 @@ var EnvSchema = z.object({
|
|
|
40
49
|
HOST: data.RUNEYA_HOST,
|
|
41
50
|
MODE: data.RUNEYA_MODE,
|
|
42
51
|
DATA_DIR: data.RUNEYA_DATA_DIR,
|
|
52
|
+
HOME_DIR: data.RUNEYA_HOME,
|
|
43
53
|
CLOUD_URL: data.RUNEYA_CLOUD_URL,
|
|
44
54
|
CLOUD_APP_URL: data.RUNEYA_CLOUD_APP_URL,
|
|
45
55
|
CORS_ORIGIN: data.RUNEYA_CORS_ORIGIN,
|
|
@@ -48,10 +58,93 @@ var EnvSchema = z.object({
|
|
|
48
58
|
}));
|
|
49
59
|
var env = EnvSchema.parse(process.env);
|
|
50
60
|
|
|
61
|
+
// ../server/src/services/vault-resolver.ts
|
|
62
|
+
var SAFE_ID = /^[A-Za-z0-9._-]{1,128}$/;
|
|
63
|
+
function assertSafeId(kind, id) {
|
|
64
|
+
if (!SAFE_ID.test(id) || id === "." || id === "..") {
|
|
65
|
+
throw new Error(`Invalid ${kind} id for a vault path: ${JSON.stringify(id)}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function machineRoot() {
|
|
69
|
+
const override = process.env["RUNEYA_HOME"];
|
|
70
|
+
return join(override && override.length > 0 ? override : homedir(), ".runeya");
|
|
71
|
+
}
|
|
72
|
+
function localVaultRoot() {
|
|
73
|
+
return resolve(env.DATA_DIR);
|
|
74
|
+
}
|
|
75
|
+
function orgVaultRoot(orgId) {
|
|
76
|
+
assertSafeId("organization", orgId);
|
|
77
|
+
return join(machineRoot(), "orgs", orgId);
|
|
78
|
+
}
|
|
79
|
+
function projectVaultRoot(orgId, projectId) {
|
|
80
|
+
assertSafeId("project", projectId);
|
|
81
|
+
return join(orgVaultRoot(orgId), "projects", projectId);
|
|
82
|
+
}
|
|
83
|
+
function vaultFor(target) {
|
|
84
|
+
if (!target.orgId) return { root: localVaultRoot() };
|
|
85
|
+
return { root: projectVaultRoot(target.orgId, target.id) };
|
|
86
|
+
}
|
|
87
|
+
async function listCloudVaults() {
|
|
88
|
+
const orgsDir = join(machineRoot(), "orgs");
|
|
89
|
+
const found = [];
|
|
90
|
+
let orgIds;
|
|
91
|
+
try {
|
|
92
|
+
orgIds = (await readdir(orgsDir, { withFileTypes: true })).filter((e) => e.isDirectory() && SAFE_ID.test(e.name)).map((e) => e.name);
|
|
93
|
+
} catch {
|
|
94
|
+
return found;
|
|
95
|
+
}
|
|
96
|
+
for (const orgId of orgIds) {
|
|
97
|
+
const projectsDir = join(orgsDir, orgId, "projects");
|
|
98
|
+
try {
|
|
99
|
+
for (const entry of await readdir(projectsDir, { withFileTypes: true })) {
|
|
100
|
+
if (!entry.isDirectory() || !SAFE_ID.test(entry.name)) continue;
|
|
101
|
+
found.push({ orgId, projectId: entry.name, root: join(projectsDir, entry.name) });
|
|
102
|
+
}
|
|
103
|
+
} catch {
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return found;
|
|
107
|
+
}
|
|
108
|
+
async function allVaultRoots() {
|
|
109
|
+
const cloud = await listCloudVaults();
|
|
110
|
+
return [localVaultRoot(), ...cloud.map((v) => v.root)];
|
|
111
|
+
}
|
|
112
|
+
function machineFilePath(filename) {
|
|
113
|
+
return join(machineRoot(), filename);
|
|
114
|
+
}
|
|
115
|
+
async function keyedFilePath(filename) {
|
|
116
|
+
return join(await keyRoot(), filename);
|
|
117
|
+
}
|
|
118
|
+
function legacyMachineFilePath(filename) {
|
|
119
|
+
return join(localVaultRoot(), filename);
|
|
120
|
+
}
|
|
121
|
+
async function ensureLocalVault() {
|
|
122
|
+
const root = localVaultRoot();
|
|
123
|
+
await mkdir(root, { recursive: true });
|
|
124
|
+
return root;
|
|
125
|
+
}
|
|
126
|
+
var KEY_FILES = [".encryption.key.enc", ".runeya-verify"];
|
|
127
|
+
var keyRootPromise = null;
|
|
128
|
+
function keyRoot() {
|
|
129
|
+
keyRootPromise ??= (async () => {
|
|
130
|
+
const local = localVaultRoot();
|
|
131
|
+
for (const filename of KEY_FILES) {
|
|
132
|
+
try {
|
|
133
|
+
await access(join(local, filename));
|
|
134
|
+
return local;
|
|
135
|
+
} catch {
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return machineRoot();
|
|
139
|
+
})();
|
|
140
|
+
return keyRootPromise;
|
|
141
|
+
}
|
|
142
|
+
|
|
51
143
|
// ../server/src/utils/encryption-key.ts
|
|
52
144
|
import { createHash } from "crypto";
|
|
53
145
|
var KEY_SIZE_BYTES = 32;
|
|
54
|
-
var
|
|
146
|
+
var DEFAULT_VAULT = "\0default";
|
|
147
|
+
var keyring = /* @__PURE__ */ new Map();
|
|
55
148
|
var _ciMode = false;
|
|
56
149
|
var _pendingLegacyKey = null;
|
|
57
150
|
function isCiMode() {
|
|
@@ -68,7 +161,7 @@ async function loadFromEnv() {
|
|
|
68
161
|
console.log(" Cette variable d'environnement est r\xE9serv\xE9e aux environnements CI/CD.");
|
|
69
162
|
console.log(" Ne la d\xE9finissez jamais sur une machine de d\xE9veloppement.");
|
|
70
163
|
console.log("");
|
|
71
|
-
|
|
164
|
+
setEncryptionKeyInMemory(Buffer.from(keyHex, "hex"));
|
|
72
165
|
_ciMode = true;
|
|
73
166
|
return true;
|
|
74
167
|
}
|
|
@@ -85,30 +178,31 @@ function clearPendingLegacyKey() {
|
|
|
85
178
|
function hasPendingLegacyKey() {
|
|
86
179
|
return _pendingLegacyKey !== null;
|
|
87
180
|
}
|
|
88
|
-
function setEncryptionKeyInMemory(key) {
|
|
181
|
+
function setEncryptionKeyInMemory(key, vault = DEFAULT_VAULT) {
|
|
89
182
|
if (key.length !== KEY_SIZE_BYTES) throw new Error("Taille de cl\xE9 invalide");
|
|
90
|
-
|
|
183
|
+
keyring.set(vault, key);
|
|
91
184
|
}
|
|
92
|
-
function clearEncryptionKey() {
|
|
93
|
-
|
|
185
|
+
function clearEncryptionKey(vault) {
|
|
186
|
+
if (vault === void 0) keyring.clear();
|
|
187
|
+
else keyring.delete(vault);
|
|
94
188
|
}
|
|
95
|
-
function hasEncryptionKey() {
|
|
96
|
-
return
|
|
189
|
+
function hasEncryptionKey(vault = DEFAULT_VAULT) {
|
|
190
|
+
return keyring.has(vault);
|
|
97
191
|
}
|
|
98
|
-
function getEncryptionKey() {
|
|
99
|
-
return
|
|
192
|
+
function getEncryptionKey(vault = DEFAULT_VAULT) {
|
|
193
|
+
return keyring.get(vault) ?? null;
|
|
100
194
|
}
|
|
101
|
-
function deriveStableSecret(purpose) {
|
|
102
|
-
const key = getEncryptionKey();
|
|
195
|
+
function deriveStableSecret(purpose, vault = DEFAULT_VAULT) {
|
|
196
|
+
const key = getEncryptionKey(vault);
|
|
103
197
|
if (!key) return null;
|
|
104
198
|
return createHash("sha256").update(key).update(purpose).digest("hex");
|
|
105
199
|
}
|
|
106
200
|
async function ensureEncryptionKey() {
|
|
107
|
-
return
|
|
201
|
+
return getEncryptionKey();
|
|
108
202
|
}
|
|
109
203
|
async function setEncryptionKey(keyHex) {
|
|
110
204
|
if (!/^[0-9a-f]{64}$/i.test(keyHex)) throw new Error("Invalid key format");
|
|
111
|
-
|
|
205
|
+
setEncryptionKeyInMemory(Buffer.from(keyHex, "hex"));
|
|
112
206
|
}
|
|
113
207
|
|
|
114
208
|
// ../server/src/services/agent-store.ts
|
|
@@ -148,16 +242,37 @@ var AgentStore = class {
|
|
|
148
242
|
passthroughEnv = {};
|
|
149
243
|
traefikConfigs = {};
|
|
150
244
|
loaded = false;
|
|
245
|
+
/**
|
|
246
|
+
* Encrypted, so it lives beside the key that opens it — usually the machine
|
|
247
|
+
* root, but a launch directory owning its own key keeps both together.
|
|
248
|
+
*/
|
|
151
249
|
getFilePath() {
|
|
152
|
-
return
|
|
250
|
+
return keyedFilePath(FILENAME);
|
|
251
|
+
}
|
|
252
|
+
/** Where older versions kept it — read only, so an older Runeya keeps working. */
|
|
253
|
+
getLegacyFilePath() {
|
|
254
|
+
return legacyMachineFilePath(FILENAME);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Read the machine file, falling back to the launch directory of old.
|
|
258
|
+
*
|
|
259
|
+
* The legacy file is left in place: the next save writes the new location,
|
|
260
|
+
* and a directory still opened by an older Runeya keeps working meanwhile.
|
|
261
|
+
*/
|
|
262
|
+
async readFromDisk() {
|
|
263
|
+
try {
|
|
264
|
+
return await readFile(await this.getFilePath(), "utf-8");
|
|
265
|
+
} catch {
|
|
266
|
+
return readFile(this.getLegacyFilePath(), "utf-8");
|
|
267
|
+
}
|
|
153
268
|
}
|
|
154
269
|
async ensureDir() {
|
|
155
|
-
await
|
|
270
|
+
await mkdir2(dirname(await this.getFilePath()), { recursive: true });
|
|
156
271
|
}
|
|
157
272
|
async load() {
|
|
158
273
|
if (this.loaded) return;
|
|
159
274
|
try {
|
|
160
|
-
const raw = await
|
|
275
|
+
const raw = await this.readFromDisk();
|
|
161
276
|
const data = JSON.parse(raw);
|
|
162
277
|
if (Array.isArray(data)) {
|
|
163
278
|
for (const a of data) this.agents.set(a.id, a);
|
|
@@ -174,7 +289,7 @@ var AgentStore = class {
|
|
|
174
289
|
}
|
|
175
290
|
async save() {
|
|
176
291
|
await this.ensureDir();
|
|
177
|
-
const filePath = this.getFilePath();
|
|
292
|
+
const filePath = await this.getFilePath();
|
|
178
293
|
const tmpPath = filePath + ".tmp";
|
|
179
294
|
const fileData = {
|
|
180
295
|
agents: Array.from(this.agents.values()),
|
|
@@ -282,12 +397,42 @@ var agentStore = new AgentStore();
|
|
|
282
397
|
|
|
283
398
|
// ../server/src/services/service-store.ts
|
|
284
399
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
285
|
-
import { readFile as readFile3, writeFile as writeFile3, rename as rename3, mkdir as
|
|
400
|
+
import { readFile as readFile3, writeFile as writeFile3, rename as rename3, mkdir as mkdir4, chmod as chmod3 } from "fs/promises";
|
|
286
401
|
import { join as join3 } from "path";
|
|
287
402
|
|
|
403
|
+
// ../server/src/services/vault-registry.ts
|
|
404
|
+
var loadProjects = null;
|
|
405
|
+
var projectRoots = /* @__PURE__ */ new Map();
|
|
406
|
+
var serviceOwners = /* @__PURE__ */ new Map();
|
|
407
|
+
function registerProjectLoader(load) {
|
|
408
|
+
loadProjects = load;
|
|
409
|
+
}
|
|
410
|
+
function setProjectVault(projectId, root) {
|
|
411
|
+
projectRoots.set(projectId, root);
|
|
412
|
+
}
|
|
413
|
+
function forgetProject(projectId) {
|
|
414
|
+
projectRoots.delete(projectId);
|
|
415
|
+
for (const [serviceId, owner] of serviceOwners) {
|
|
416
|
+
if (owner === projectId) serviceOwners.delete(serviceId);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
function setProjectServices(projectId, serviceIds) {
|
|
420
|
+
for (const [serviceId, owner] of serviceOwners) {
|
|
421
|
+
if (owner === projectId && !serviceIds.includes(serviceId)) serviceOwners.delete(serviceId);
|
|
422
|
+
}
|
|
423
|
+
for (const serviceId of serviceIds) serviceOwners.set(serviceId, projectId);
|
|
424
|
+
}
|
|
425
|
+
function rootOfProject(projectId) {
|
|
426
|
+
return projectRoots.get(projectId) ?? localVaultRoot();
|
|
427
|
+
}
|
|
428
|
+
function rootOfService(serviceId) {
|
|
429
|
+
const owner = serviceOwners.get(serviceId);
|
|
430
|
+
return owner ? rootOfProject(owner) : localVaultRoot();
|
|
431
|
+
}
|
|
432
|
+
|
|
288
433
|
// ../server/src/services/environment-store.ts
|
|
289
434
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
290
|
-
import { readFile as readFile2, writeFile as writeFile2, rename as rename2, mkdir as
|
|
435
|
+
import { readFile as readFile2, writeFile as writeFile2, rename as rename2, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
291
436
|
import { join as join2 } from "path";
|
|
292
437
|
|
|
293
438
|
// ../server/src/services/crypto-helpers.ts
|
|
@@ -1638,11 +1783,25 @@ var EnvironmentStore = class {
|
|
|
1638
1783
|
notify() {
|
|
1639
1784
|
for (const fn of this.listeners) fn();
|
|
1640
1785
|
}
|
|
1641
|
-
|
|
1642
|
-
|
|
1786
|
+
/**
|
|
1787
|
+
* Which vault each environment was read from, so a save puts it back where it
|
|
1788
|
+
* belongs even before its project has been loaded.
|
|
1789
|
+
*/
|
|
1790
|
+
roots = /* @__PURE__ */ new Map();
|
|
1791
|
+
getFilePath(root) {
|
|
1792
|
+
return join2(root, FILENAME2);
|
|
1643
1793
|
}
|
|
1644
|
-
|
|
1645
|
-
|
|
1794
|
+
/**
|
|
1795
|
+
* The vault an environment must be written to: its project's.
|
|
1796
|
+
*
|
|
1797
|
+
* Falls back to where it was last read, then to the local vault — an
|
|
1798
|
+
* environment whose project is unknown belongs to the launch directory, which
|
|
1799
|
+
* is where it lived before vaults existed.
|
|
1800
|
+
*/
|
|
1801
|
+
rootFor(environment) {
|
|
1802
|
+
const known = this.roots.get(environment.id);
|
|
1803
|
+
const projectRoot = environment.projectId ? rootOfProject(environment.projectId) : null;
|
|
1804
|
+
return projectRoot ?? known ?? localVaultRoot();
|
|
1646
1805
|
}
|
|
1647
1806
|
extractEncryptedCache(environment) {
|
|
1648
1807
|
const envSlots = extractEncryptedVariableSlots(
|
|
@@ -1671,35 +1830,106 @@ var EnvironmentStore = class {
|
|
|
1671
1830
|
}
|
|
1672
1831
|
return { ...environment, variables: decryptedVars };
|
|
1673
1832
|
}
|
|
1833
|
+
/**
|
|
1834
|
+
* Read every vault — the launch directory and each materialized cloud project.
|
|
1835
|
+
*
|
|
1836
|
+
* The roots come from the disk rather than from the project store, so loading
|
|
1837
|
+
* environments never has to wait on projects being loaded first (the project
|
|
1838
|
+
* store reads environments while absorbing a project, which would deadlock).
|
|
1839
|
+
*/
|
|
1674
1840
|
async load() {
|
|
1675
1841
|
if (this.loaded) return;
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
this.
|
|
1684
|
-
const
|
|
1685
|
-
|
|
1842
|
+
this.loaded = true;
|
|
1843
|
+
if (!getEncryptionKey()) {
|
|
1844
|
+
this.loaded = false;
|
|
1845
|
+
return;
|
|
1846
|
+
}
|
|
1847
|
+
for (const root of await allVaultRoots()) {
|
|
1848
|
+
try {
|
|
1849
|
+
const raw = await readFile2(this.getFilePath(root), "utf-8");
|
|
1850
|
+
const data = JSON.parse(raw);
|
|
1851
|
+
for (const e of data) {
|
|
1852
|
+
this.diskEncryptedSlots.set(e.id, this.extractEncryptedCache(e));
|
|
1853
|
+
const decrypted = this.decryptEnvironment(e);
|
|
1854
|
+
this.environments.set(e.id, decrypted);
|
|
1855
|
+
this.roots.set(e.id, root);
|
|
1856
|
+
}
|
|
1857
|
+
} catch {
|
|
1686
1858
|
}
|
|
1687
|
-
} catch {
|
|
1688
1859
|
}
|
|
1689
|
-
this.loaded = true;
|
|
1690
1860
|
}
|
|
1861
|
+
/**
|
|
1862
|
+
* Write each vault that holds — or held — an environment.
|
|
1863
|
+
*
|
|
1864
|
+
* Vaults emptied by this save are still written, as an empty list: an
|
|
1865
|
+
* environment that moved to another vault must not survive in the old one.
|
|
1866
|
+
*/
|
|
1691
1867
|
async save() {
|
|
1692
|
-
|
|
1693
|
-
const
|
|
1694
|
-
|
|
1695
|
-
const
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1868
|
+
const byRoot = /* @__PURE__ */ new Map();
|
|
1869
|
+
for (const root of this.roots.values()) byRoot.set(root, []);
|
|
1870
|
+
byRoot.set(localVaultRoot(), byRoot.get(localVaultRoot()) ?? []);
|
|
1871
|
+
for (const environment of this.environments.values()) {
|
|
1872
|
+
const root = this.rootFor(environment);
|
|
1873
|
+
const prepared = this.encryptEnvironment(environment);
|
|
1874
|
+
this.diskEncryptedSlots.set(prepared.id, this.extractEncryptedCache(prepared));
|
|
1875
|
+
this.roots.set(environment.id, root);
|
|
1876
|
+
const bucket = byRoot.get(root);
|
|
1877
|
+
if (bucket) bucket.push(prepared);
|
|
1878
|
+
else byRoot.set(root, [prepared]);
|
|
1879
|
+
}
|
|
1880
|
+
for (const [root, environments] of byRoot) {
|
|
1881
|
+
await mkdir3(root, { recursive: true });
|
|
1882
|
+
const filePath = this.getFilePath(root);
|
|
1883
|
+
const tmpPath = filePath + ".tmp";
|
|
1884
|
+
await writeFile2(tmpPath, JSON.stringify(environments, null, 2), "utf-8");
|
|
1885
|
+
await rename2(tmpPath, filePath);
|
|
1886
|
+
await chmod2(filePath, 384);
|
|
1887
|
+
}
|
|
1888
|
+
this.notify();
|
|
1889
|
+
}
|
|
1890
|
+
/**
|
|
1891
|
+
* Rewrite every vault, moving entities that now belong elsewhere.
|
|
1892
|
+
*
|
|
1893
|
+
* Called once the project store knows where projects live: entities read from
|
|
1894
|
+
* the launch directory whose project turns out to be a cloud one are written
|
|
1895
|
+
* into that project's vault, and disappear from the directory they came from.
|
|
1896
|
+
*/
|
|
1897
|
+
async relocateAll() {
|
|
1898
|
+
await this.load();
|
|
1899
|
+
await this.save();
|
|
1900
|
+
}
|
|
1901
|
+
/**
|
|
1902
|
+
* Which project a variable belongs to, by walking the environments that
|
|
1903
|
+
* define it.
|
|
1904
|
+
*
|
|
1905
|
+
* Overrides are keyed by variable id alone — nothing in an override says
|
|
1906
|
+
* which project it belongs to — so this is what lets them be stored with
|
|
1907
|
+
* their project rather than in one machine-wide pile.
|
|
1908
|
+
*/
|
|
1909
|
+
async projectIdOfVariable(variableId) {
|
|
1910
|
+
await this.load();
|
|
1911
|
+
for (const environment of this.environments.values()) {
|
|
1912
|
+
if (environment.variables && variableId in environment.variables) {
|
|
1913
|
+
return environment.projectId;
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
return null;
|
|
1917
|
+
}
|
|
1918
|
+
/**
|
|
1919
|
+
* Drop a project's environments from memory, without touching the disk.
|
|
1920
|
+
*
|
|
1921
|
+
* Used when a project stops being followed: its vault is removed as a whole,
|
|
1922
|
+
* and environments left in memory would be written back on the next save —
|
|
1923
|
+
* into the local vault, since their project is no longer known.
|
|
1924
|
+
*/
|
|
1925
|
+
async forgetByProject(projectId) {
|
|
1926
|
+
await this.load();
|
|
1927
|
+
for (const [id, environment] of this.environments) {
|
|
1928
|
+
if (environment.projectId !== projectId) continue;
|
|
1929
|
+
this.environments.delete(id);
|
|
1930
|
+
this.diskEncryptedSlots.delete(id);
|
|
1931
|
+
this.roots.delete(id);
|
|
1932
|
+
}
|
|
1703
1933
|
this.notify();
|
|
1704
1934
|
}
|
|
1705
1935
|
async list(projectId) {
|
|
@@ -1978,46 +2208,106 @@ var ServiceStore = class {
|
|
|
1978
2208
|
notify() {
|
|
1979
2209
|
for (const fn of this.listeners) fn();
|
|
1980
2210
|
}
|
|
1981
|
-
|
|
1982
|
-
|
|
2211
|
+
/** Which vault each service was read from, used until its project is known. */
|
|
2212
|
+
roots = /* @__PURE__ */ new Map();
|
|
2213
|
+
getFilePath(root) {
|
|
2214
|
+
return join3(root, FILENAME3);
|
|
1983
2215
|
}
|
|
1984
|
-
|
|
1985
|
-
|
|
2216
|
+
/**
|
|
2217
|
+
* The vault a service must be written to: the one of the project owning it.
|
|
2218
|
+
*
|
|
2219
|
+
* A service carries no project id — ownership lives in `project.serviceIds` —
|
|
2220
|
+
* so the registry answers, falling back to where the service was read and
|
|
2221
|
+
* finally to the local vault.
|
|
2222
|
+
*/
|
|
2223
|
+
rootFor(serviceId) {
|
|
2224
|
+
return rootOfService(serviceId) ?? this.roots.get(serviceId) ?? localVaultRoot();
|
|
1986
2225
|
}
|
|
2226
|
+
/**
|
|
2227
|
+
* Read every vault: the launch directory and each materialized cloud project.
|
|
2228
|
+
*
|
|
2229
|
+
* Roots come from the disk, not from the project store, so services load
|
|
2230
|
+
* without waiting on projects.
|
|
2231
|
+
*/
|
|
1987
2232
|
async load() {
|
|
1988
2233
|
if (this.loaded) return;
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
2234
|
+
if (!getEncryptionKey()) return;
|
|
2235
|
+
this.loaded = true;
|
|
2236
|
+
for (const root of await allVaultRoots()) {
|
|
2237
|
+
try {
|
|
2238
|
+
const raw = await readFile3(this.getFilePath(root), "utf-8");
|
|
2239
|
+
const data = JSON.parse(raw);
|
|
2240
|
+
for (const s of data) {
|
|
2241
|
+
if (s.commands) {
|
|
2242
|
+
for (const cmd of s.commands) {
|
|
2243
|
+
if (cmd.shell === void 0) cmd.shell = true;
|
|
2244
|
+
}
|
|
1999
2245
|
}
|
|
2246
|
+
this.diskForm.set(s.id, s);
|
|
2247
|
+
this.services.set(s.id, {
|
|
2248
|
+
...s,
|
|
2249
|
+
logSources: decryptLogSources(s.logSources ?? [])
|
|
2250
|
+
});
|
|
2251
|
+
this.roots.set(s.id, root);
|
|
2000
2252
|
}
|
|
2001
|
-
|
|
2002
|
-
this.services.set(s.id, {
|
|
2003
|
-
...s,
|
|
2004
|
-
logSources: decryptLogSources(s.logSources ?? [])
|
|
2005
|
-
});
|
|
2253
|
+
} catch {
|
|
2006
2254
|
}
|
|
2007
|
-
} catch {
|
|
2008
2255
|
}
|
|
2009
|
-
this.loaded = true;
|
|
2010
2256
|
}
|
|
2257
|
+
/**
|
|
2258
|
+
* Write each vault that holds — or held — a service.
|
|
2259
|
+
*
|
|
2260
|
+
* A vault emptied by this save is still written, as an empty list: a service
|
|
2261
|
+
* that moved to another vault must not survive in the one it left.
|
|
2262
|
+
*/
|
|
2011
2263
|
async save() {
|
|
2012
|
-
|
|
2013
|
-
const
|
|
2014
|
-
|
|
2015
|
-
const
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2264
|
+
const byRoot = /* @__PURE__ */ new Map();
|
|
2265
|
+
for (const root of this.roots.values()) byRoot.set(root, []);
|
|
2266
|
+
byRoot.set(localVaultRoot(), byRoot.get(localVaultRoot()) ?? []);
|
|
2267
|
+
for (const service of this.services.values()) {
|
|
2268
|
+
const root = this.rootFor(service.id);
|
|
2269
|
+
const prepared = prepareForDisk(service, this.diskForm.get(service.id));
|
|
2270
|
+
this.diskForm.set(prepared.id, prepared);
|
|
2271
|
+
this.roots.set(service.id, root);
|
|
2272
|
+
const bucket = byRoot.get(root);
|
|
2273
|
+
if (bucket) bucket.push(prepared);
|
|
2274
|
+
else byRoot.set(root, [prepared]);
|
|
2275
|
+
}
|
|
2276
|
+
for (const [root, services] of byRoot) {
|
|
2277
|
+
await mkdir4(root, { recursive: true });
|
|
2278
|
+
const filePath = this.getFilePath(root);
|
|
2279
|
+
const tmpPath = filePath + ".tmp";
|
|
2280
|
+
await writeFile3(tmpPath, JSON.stringify(services, null, 2), "utf-8");
|
|
2281
|
+
await rename3(tmpPath, filePath);
|
|
2282
|
+
await chmod3(filePath, 384);
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
/**
|
|
2286
|
+
* Drop services from memory, without touching the disk.
|
|
2287
|
+
*
|
|
2288
|
+
* Used when their project stops being followed: its vault goes away whole,
|
|
2289
|
+
* and services left in memory would be written back on the next save — into
|
|
2290
|
+
* the local vault, since their owner is no longer known.
|
|
2291
|
+
*/
|
|
2292
|
+
async forgetLocally(serviceIds) {
|
|
2293
|
+
await this.load();
|
|
2294
|
+
for (const id of serviceIds) {
|
|
2295
|
+
this.services.delete(id);
|
|
2296
|
+
this.diskForm.delete(id);
|
|
2297
|
+
this.roots.delete(id);
|
|
2298
|
+
}
|
|
2299
|
+
this.notify();
|
|
2300
|
+
}
|
|
2301
|
+
/**
|
|
2302
|
+
* Rewrite every vault, moving entities that now belong elsewhere.
|
|
2303
|
+
*
|
|
2304
|
+
* Called once the project store knows where projects live: entities read from
|
|
2305
|
+
* the launch directory whose project turns out to be a cloud one are written
|
|
2306
|
+
* into that project's vault, and disappear from the directory they came from.
|
|
2307
|
+
*/
|
|
2308
|
+
async relocateAll() {
|
|
2309
|
+
await this.load();
|
|
2310
|
+
await this.save();
|
|
2021
2311
|
}
|
|
2022
2312
|
async list() {
|
|
2023
2313
|
await this.load();
|
|
@@ -2177,7 +2467,7 @@ var serviceStore = new ServiceStore();
|
|
|
2177
2467
|
import { spawn } from "child_process";
|
|
2178
2468
|
import { createInterface } from "readline";
|
|
2179
2469
|
import { watch } from "fs";
|
|
2180
|
-
import { dirname, join as join4 } from "path";
|
|
2470
|
+
import { dirname as dirname2, join as join4 } from "path";
|
|
2181
2471
|
import { fileURLToPath } from "url";
|
|
2182
2472
|
function buildAgentEnv() {
|
|
2183
2473
|
const safeKeys = [
|
|
@@ -2235,7 +2525,7 @@ var AgentSpawner = class {
|
|
|
2235
2525
|
}
|
|
2236
2526
|
console.log(`[agent-spawner] Spawning local agent on ${agentUrl}...`);
|
|
2237
2527
|
const isDev = process.env.NODE_ENV === "development";
|
|
2238
|
-
this.agentDistPath = env.AGENT_BINARY_PATH || join4(
|
|
2528
|
+
this.agentDistPath = env.AGENT_BINARY_PATH || join4(dirname2(fileURLToPath(import.meta.url)), "..", "..", "agent", "dist", "index.js");
|
|
2239
2529
|
this.agentProcess = spawn("node", [this.agentDistPath], {
|
|
2240
2530
|
env: agentEnv,
|
|
2241
2531
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -2261,14 +2551,14 @@ var AgentSpawner = class {
|
|
|
2261
2551
|
console.log(`[agent-spawner] Local agent registered as ${LOCAL_AGENT_ID}`);
|
|
2262
2552
|
}
|
|
2263
2553
|
waitForPassphrase() {
|
|
2264
|
-
return new Promise((
|
|
2554
|
+
return new Promise((resolve2) => {
|
|
2265
2555
|
if (!this.agentProcess?.stdout) {
|
|
2266
|
-
|
|
2556
|
+
resolve2(null);
|
|
2267
2557
|
return;
|
|
2268
2558
|
}
|
|
2269
2559
|
const rl = createInterface({ input: this.agentProcess.stdout });
|
|
2270
2560
|
const timeout = setTimeout(() => {
|
|
2271
|
-
|
|
2561
|
+
resolve2(null);
|
|
2272
2562
|
}, PASSPHRASE_TIMEOUT);
|
|
2273
2563
|
let initialPassphraseFound = false;
|
|
2274
2564
|
rl.on("line", (line) => {
|
|
@@ -2278,7 +2568,7 @@ var AgentSpawner = class {
|
|
|
2278
2568
|
if (!initialPassphraseFound) {
|
|
2279
2569
|
initialPassphraseFound = true;
|
|
2280
2570
|
clearTimeout(timeout);
|
|
2281
|
-
|
|
2571
|
+
resolve2(newPassphrase);
|
|
2282
2572
|
} else {
|
|
2283
2573
|
console.log("[agent-spawner] \u{1F504} Agent reloaded, updating passphrase...");
|
|
2284
2574
|
this.updateAgentPassphrase(newPassphrase).catch((err) => {
|
|
@@ -2298,14 +2588,14 @@ var AgentSpawner = class {
|
|
|
2298
2588
|
this.agentProcess?.on("error", (err) => {
|
|
2299
2589
|
console.error("[agent-spawner] Failed to spawn agent:", err);
|
|
2300
2590
|
clearTimeout(timeout);
|
|
2301
|
-
if (!initialPassphraseFound)
|
|
2591
|
+
if (!initialPassphraseFound) resolve2(null);
|
|
2302
2592
|
});
|
|
2303
2593
|
this.agentProcess?.on("exit", (code) => {
|
|
2304
2594
|
if (code !== null && code !== 0) {
|
|
2305
2595
|
console.error(`[agent-spawner] Agent exited with code ${code}`);
|
|
2306
2596
|
}
|
|
2307
2597
|
clearTimeout(timeout);
|
|
2308
|
-
if (!initialPassphraseFound)
|
|
2598
|
+
if (!initialPassphraseFound) resolve2(null);
|
|
2309
2599
|
});
|
|
2310
2600
|
});
|
|
2311
2601
|
}
|
|
@@ -2317,9 +2607,9 @@ var AgentSpawner = class {
|
|
|
2317
2607
|
if (this.agentProcess) {
|
|
2318
2608
|
console.log("[agent-spawner] Stopping local agent...");
|
|
2319
2609
|
this.agentProcess.kill("SIGKILL");
|
|
2320
|
-
await new Promise((
|
|
2321
|
-
this.agentProcess?.on("exit", () =>
|
|
2322
|
-
setTimeout(
|
|
2610
|
+
await new Promise((resolve2) => {
|
|
2611
|
+
this.agentProcess?.on("exit", () => resolve2());
|
|
2612
|
+
setTimeout(resolve2, 2e3);
|
|
2323
2613
|
});
|
|
2324
2614
|
this.agentProcess = null;
|
|
2325
2615
|
}
|
|
@@ -2775,7 +3065,7 @@ var AgentManager = class extends EventEmitter2 {
|
|
|
2775
3065
|
if (isReRegistration) {
|
|
2776
3066
|
console.log(`[agent-manager] Re-registering agent ${config.name} (${config.id})`);
|
|
2777
3067
|
this.disconnectAgent(config.id);
|
|
2778
|
-
await new Promise((
|
|
3068
|
+
await new Promise((resolve2) => setTimeout(resolve2, 200));
|
|
2779
3069
|
}
|
|
2780
3070
|
this.connectAgent(config);
|
|
2781
3071
|
console.log(`[agent-manager] Agent ${config.name} (${config.id}) connection established`);
|
|
@@ -2792,7 +3082,7 @@ var AgentManager = class extends EventEmitter2 {
|
|
|
2792
3082
|
if (isReRegistration) {
|
|
2793
3083
|
console.log(`[agent-manager] Re-registering local agent ${config.name} (${config.id})`);
|
|
2794
3084
|
this.disconnectAgent(config.id);
|
|
2795
|
-
await new Promise((
|
|
3085
|
+
await new Promise((resolve2) => setTimeout(resolve2, 200));
|
|
2796
3086
|
}
|
|
2797
3087
|
const storedPassthrough = agentStore.getPassthroughEnv(config.id);
|
|
2798
3088
|
const configWithPassthrough = { ...config, passthroughEnv: storedPassthrough };
|
|
@@ -3114,6 +3404,18 @@ export {
|
|
|
3114
3404
|
getEncryptionKey,
|
|
3115
3405
|
ensureEncryptionKey,
|
|
3116
3406
|
setEncryptionKey,
|
|
3407
|
+
machineRoot,
|
|
3408
|
+
localVaultRoot,
|
|
3409
|
+
orgVaultRoot,
|
|
3410
|
+
projectVaultRoot,
|
|
3411
|
+
vaultFor,
|
|
3412
|
+
listCloudVaults,
|
|
3413
|
+
allVaultRoots,
|
|
3414
|
+
machineFilePath,
|
|
3415
|
+
keyedFilePath,
|
|
3416
|
+
legacyMachineFilePath,
|
|
3417
|
+
ensureLocalVault,
|
|
3418
|
+
keyRoot,
|
|
3117
3419
|
ProjectSchema,
|
|
3118
3420
|
ScenarioGroupSchema,
|
|
3119
3421
|
ScenarioNodeSchema,
|
|
@@ -3154,6 +3456,11 @@ export {
|
|
|
3154
3456
|
decryptVariableSlots,
|
|
3155
3457
|
extractEncryptedVariableSlots,
|
|
3156
3458
|
isEncryptedValue,
|
|
3459
|
+
registerProjectLoader,
|
|
3460
|
+
setProjectVault,
|
|
3461
|
+
forgetProject,
|
|
3462
|
+
setProjectServices,
|
|
3463
|
+
rootOfProject,
|
|
3157
3464
|
environmentStore,
|
|
3158
3465
|
serviceStore,
|
|
3159
3466
|
agentStore,
|
|
@@ -3161,4 +3468,4 @@ export {
|
|
|
3161
3468
|
traefikManager,
|
|
3162
3469
|
agentManager
|
|
3163
3470
|
};
|
|
3164
|
-
//# sourceMappingURL=chunk-
|
|
3471
|
+
//# sourceMappingURL=chunk-NJJMESIY.js.map
|