@runeya/runeya 2.0.47 → 2.0.49
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/index.js +11 -1
- package/agent/index.js.map +1 -1
- package/agent-manager-JNA5ZALK.js +7 -0
- package/{chunk-5PRQBES2.js → chunk-4AGTVGSH.js} +59 -6
- package/chunk-4AGTVGSH.js.map +1 -0
- package/index.js +1 -1
- package/package.json +1 -1
- package/{src-IFPDFIDZ.js → src-WVK4WUI3.js} +65 -8
- package/src-WVK4WUI3.js.map +1 -0
- package/web/assets/{AgentScalarChatInterface.vue-Z3BLbola.js → AgentScalarChatInterface.vue-D53JSFzC.js} +1 -1
- package/web/assets/{AgentTerminalPage-Dg4kOMbK.js → AgentTerminalPage-zuXFRGB0.js} +1 -1
- package/web/assets/AiChatPage-BjC9iQnH.js +1 -0
- package/web/assets/{AppLayout-BQpUnN2N.js → AppLayout-fVYVDGr-.js} +1 -1
- package/web/assets/{AuditPage-zfim5OLa.js → AuditPage-DvhG8fxh.js} +1 -1
- package/web/assets/{CloudAccountPage-BD-L27Wl.js → CloudAccountPage-CE3b0q5v.js} +1 -1
- package/web/assets/CloudAccountPage-YkGuA0nb.js +1 -0
- package/web/assets/{CloudMessagingPage-BnaGxzNK.js → CloudMessagingPage-okqqdltV.js} +1 -1
- package/web/assets/{DashboardPage-ByzcpJV7.js → DashboardPage-CmZITjvU.js} +1 -1
- package/web/assets/{EditorIcon-jk0Nz8Mr.js → EditorIcon-dUXSIPv3.js} +1 -1
- package/web/assets/{EnvironmentForm-BH4EMxM6.js → EnvironmentForm-_y5JoRHH.js} +1 -1
- package/web/assets/{EnvironmentFormPage-Bwjr8SsV.js → EnvironmentFormPage-DYhDZdPj.js} +1 -1
- package/web/assets/{EnvironmentListPage-BgqHe-4p.js → EnvironmentListPage-soh5FJDb.js} +1 -1
- package/web/assets/{EnvironmentSelector-CBh21uuY.js → EnvironmentSelector-CQNLsssr.js} +1 -1
- package/web/assets/{KanbanBoardPage-Dg0Od24D.js → KanbanBoardPage-C3cG7v4z.js} +3 -3
- package/web/assets/KanbanListPage-xyv-oiyq.js +1 -0
- package/web/assets/KanbanListPage-yeTYeAas.css +1 -0
- package/web/assets/{LaunchProjectPage-BZe2kaRt.js → LaunchProjectPage-DKqMjh-V.js} +1 -1
- package/web/assets/{LaunchServicesPage-B4xd4APa.js → LaunchServicesPage-IhWdB_Gw.js} +1 -1
- package/web/assets/{LogViewer-BhaSYgvw.js → LogViewer-ChElXmMu.js} +1 -1
- package/web/assets/{ProcessControls-lDF1qNIM.js → ProcessControls-t9skQ_zd.js} +1 -1
- package/web/assets/{ProcessDetailPage-DwaApuHs.js → ProcessDetailPage-DFv0ESg1.js} +1 -1
- package/web/assets/{ProcessMetrics-rGmADRtS.js → ProcessMetrics-DL00NyoX.js} +1 -1
- package/web/assets/{ProjectDetailPage-BoIcnBMH.js → ProjectDetailPage-DEXvg1pg.js} +1 -1
- package/web/assets/{ProjectListPage-C3JtBL-6.js → ProjectListPage-h0AQ_RCw.js} +1 -1
- package/web/assets/{RandomJobTestPage-CndKGKYR.js → RandomJobTestPage-Dp7A7Qgx.js} +1 -1
- package/web/assets/{ScenarioEditorPage-DU7tb4M-.js → ScenarioEditorPage-D0_VpZUT.js} +1 -1
- package/web/assets/{SendToChatDialog-CCRCitBB.js → SendToChatDialog-BpJetpLA.js} +1 -1
- package/web/assets/{ServiceControlsBar-BjyMYoiN.js → ServiceControlsBar-qiCaxnab.js} +1 -1
- package/web/assets/{ServiceDetailPage-JqpmujmY.js → ServiceDetailPage-BD8D0CuN.js} +1 -1
- package/web/assets/{ServiceFormPage-DgNwiYzM.js → ServiceFormPage-Dax40DkX.js} +1 -1
- package/web/assets/{SettingsPage-BZM3WWqc.js → SettingsPage-zriZbuPv.js} +4 -4
- package/web/assets/{UnlockPage-BcZ2vL57.js → UnlockPage-BYtu3w_t.js} +1 -1
- package/web/assets/{VariablesTable-0Gz2ffiL.js → VariablesTable-IvhXwdsn.js} +1 -1
- package/web/assets/{VaultMigrationPage-BxTBDL19.js → VaultMigrationPage-6Id4Fmeo.js} +1 -1
- package/web/assets/{VersionBadge-DvsaGqvh.js → VersionBadge-B-PtNx51.js} +1 -1
- package/web/assets/WikiPage-DqqlIbM6.js +1 -0
- package/web/assets/{WikiView-e81ejcA8.js → WikiView-BZvgaTQp.js} +1 -1
- package/web/assets/{add-scalar-classes-Bh8ghfnQ.js → add-scalar-classes-CEf8wgbL.js} +3 -3
- package/web/assets/auth-errors-B510-08J.js +1 -0
- package/web/assets/{autocomplete-CDWkaHAi.js → autocomplete-DpSrZtZQ.js} +1 -1
- package/web/assets/{basic-shape-diamond.svg-7zqPzGW0.js → basic-shape-diamond.svg-BxBPwaOm.js} +1 -1
- package/web/assets/{basic-shape-hexagon.svg-DQwxqMd2.js → basic-shape-hexagon.svg-Du908vLS.js} +1 -1
- package/web/assets/{basic-shape-primary-circle-ellipse-round.svg-Bqm796vK.js → basic-shape-primary-circle-ellipse-round.svg-CfFm5Pl7.js} +1 -1
- package/web/assets/{basic-shape-primary-square-rectangle.svg-D7eyO04i.js → basic-shape-primary-square-rectangle.svg-CP0kG7Ut.js} +1 -1
- package/web/assets/{basic-shape-shield.svg-Bnc_pFVA.js → basic-shape-shield.svg-DxTsLdrS.js} +1 -1
- package/web/assets/{browser-LxxhMX-Z.js → browser-BvCyKum4.js} +1 -1
- package/web/assets/{browser-DeXg6zUY.js → browser-DV9-oWjy.js} +1 -1
- package/web/assets/{card-RaXQSIfv.js → card-TJ-av0Pi.js} +1 -1
- package/web/assets/{checkbox-DnpUXs7B.js → checkbox-D5bej0ao.js} +1 -1
- package/web/assets/{chip-0f0r_-zR.js → chip-D8vO8NID.js} +1 -1
- package/web/assets/{client-CTzGkOjO.js → client-D5eMRPpD.js} +1 -1
- package/web/assets/{cloud-chat.store-D2oJ_DFn.js → cloud-chat.store-DzSz0QMb.js} +1 -1
- package/web/assets/{cloud-session-BLn7b3ke.js → cloud-session-tALRHewK.js} +1 -1
- package/web/assets/{column-DqAehgUU.js → column-BAToyYIb.js} +1 -1
- package/web/assets/{computer-device-desktop-monitor.svg-k2x9Oiiu.js → computer-device-desktop-monitor.svg-82Glaw7U.js} +1 -1
- package/web/assets/{computer-device-desktop.svg-CyFljvrh.js → computer-device-desktop.svg-BZb-XFcK.js} +1 -1
- package/web/assets/{computer-device-laptop.svg-ZKpV0gtW.js → computer-device-laptop.svg-BnptbmCn.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-android-samsung-back.svg-BkRkRpCh.js → computer-device-mobile-phone-android-samsung-back.svg-g23ZYYHm.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-android-samsung.svg-gpUXFo9R.js → computer-device-mobile-phone-android-samsung.svg-B5fBZlIN.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-iphone-x-back.svg-CJwr0WJ3.js → computer-device-mobile-phone-iphone-x-back.svg-BsKZAUH_.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-iphone-x.svg-BsPF_njN.js → computer-device-mobile-phone-iphone-x.svg-GVv-OoXC.js} +1 -1
- package/web/assets/{computer-device-mobile-tablet-touch.svg-DON7qRSP.js → computer-device-mobile-tablet-touch.svg-CpyRybCz.js} +1 -1
- package/web/assets/{computer-device-mobile-tablet.svg-BPnT3MvS.js → computer-device-mobile-tablet.svg-C_6zzbHC.js} +1 -1
- package/web/assets/{computer-device-network-ethernet-cat6.svg-Bpjv_2ub.js → computer-device-network-ethernet-cat6.svg-s_MRa0bJ.js} +1 -1
- package/web/assets/{computer-device-network-lan-www.svg-BhXBIyrf.js → computer-device-network-lan-www.svg-31TS3sqT.js} +1 -1
- package/web/assets/{computer-device-network-wifi-connection.svg-DUaA1GcU.js → computer-device-network-wifi-connection.svg-BfBnT-iK.js} +1 -1
- package/web/assets/{computer-device-network-wifi-router.svg-k_DqQho1.js → computer-device-network-wifi-router.svg-BNQJ_FEI.js} +1 -1
- package/web/assets/{cssMode-CfVTS8OM.js → cssMode-IplHgA8x.js} +1 -1
- package/web/assets/{divider-C1huit3M.js → divider-D-QC8_57.js} +1 -1
- package/web/assets/{ecology-science-erlenmeyer-flask.svg-D7pbgLTT.js → ecology-science-erlenmeyer-flask.svg-CKCEQFIq.js} +1 -1
- package/web/assets/{fieldset-BVRjgmg4.js → fieldset-DpQHSMKf.js} +1 -1
- package/web/assets/{freemarker2-DsY_gjrP.js → freemarker2-DHUVsWtT.js} +1 -1
- package/web/assets/{handlebars-mh1HrGq7.js → handlebars-pE00Hjr_.js} +1 -1
- package/web/assets/{html-BsaAhzOa.js → html-DMtmtVNV.js} +1 -1
- package/web/assets/{htmlMode-pIhI3cAi.js → htmlMode-DFeVLqUM.js} +1 -1
- package/web/assets/{image-flash-lightning.svg-DDbhd-eu.js → image-flash-lightning.svg-NAFI_e2J.js} +1 -1
- package/web/assets/{image-picture-flower.svg-Bbx1pu02.js → image-picture-flower.svg-B6ZUCTNS.js} +1 -1
- package/web/assets/{index-Do0zA8cN.js → index-a1iwaPG1.js} +6 -6
- package/web/assets/{interface-alert-exclamation-diamond.svg-DUJeN1hs.js → interface-alert-exclamation-diamond.svg-CwHTxp3a.js} +1 -1
- package/web/assets/{interface-alert-exclamation-triangle-warning.svg-5y99yZSY.js → interface-alert-exclamation-triangle-warning.svg-Bi-1vcWG.js} +1 -1
- package/web/assets/{interface-alert-information-circle.svg-DPGP01ZU.js → interface-alert-information-circle.svg-CQnbLMfS.js} +1 -1
- package/web/assets/{interface-award-crown.svg-GDQ8ZRUh.js → interface-award-crown.svg-CFtMz4dE.js} +1 -1
- package/web/assets/{interface-bookmark.svg-CTZlXD4R.js → interface-bookmark-tag.svg-DumdjnW1.js} +1 -1
- package/web/assets/{interface-bookmark-tag.svg-D1NUMLB5.js → interface-bookmark.svg-7SV2pxyN.js} +1 -1
- package/web/assets/{interface-calendar-date-one.svg-DXo4raY8.js → interface-calendar-date-one.svg-e7-h1b3y.js} +1 -1
- package/web/assets/{interface-content-book-open-pages.svg-DTsCVw_D.js → interface-content-book-open-pages.svg-DwLQV4lf.js} +1 -1
- package/web/assets/{interface-content-book-page.svg-w9azHLUe.js → interface-content-book-page.svg-CAKDQ2x-.js} +1 -1
- package/web/assets/{interface-content-file.svg-69CCnbNb.js → interface-content-file.svg-DZEwGNLB.js} +1 -1
- package/web/assets/interface-content-folder.svg-BF9F5qf2.js +1 -0
- package/web/assets/{interface-content-folder.svg-85PnJNaK.js → interface-content-folder.svg-BnFYmNMO.js} +1 -1
- package/web/assets/{interface-copy-clipboard.svg-B0AfVljN.js → interface-copy-clipboard.svg-9UwhLON-.js} +1 -1
- package/web/assets/{interface-edit-attachment.svg-mFLLqqcw.js → interface-edit-attachment.svg-C1_u9TNx.js} +1 -1
- package/web/assets/{interface-edit-binocular.svg-CHzgny3z.js → interface-edit-binocular.svg-DoQnsqHf.js} +1 -1
- package/web/assets/{interface-edit-magic-wand.svg-BbJg9LMT.js → interface-edit-magic-wand.svg-C7wTd6JH.js} +1 -1
- package/web/assets/{interface-edit-tool-paint-roller.svg-YKE28Xpc.js → interface-edit-tool-paint-roller.svg-BZ4hqe-1.js} +1 -1
- package/web/assets/{interface-edit-tool-pencil.svg-Cy12MfEi.js → interface-edit-tool-pencil.svg-D1bysygW.js} +1 -1
- package/web/assets/{interface-favorite-award.svg-COiLJu4w.js → interface-favorite-award.svg-0Thu2k9M.js} +1 -1
- package/web/assets/{interface-favorite-flag.svg-C0NtaPD_.js → interface-favorite-flag.svg-DI4_vrUQ.js} +1 -1
- package/web/assets/{interface-favorite-heart.svg-CcKJOjOh.js → interface-favorite-heart.svg-DpwKtPuU.js} +1 -1
- package/web/assets/{interface-favorite-star.svg-C3vRaRtM.js → interface-favorite-star.svg-D-udxHVN.js} +1 -1
- package/web/assets/{interface-favorite-stars-sparkles.svg-DN9WOkFs.js → interface-favorite-stars-sparkles.svg-Dc4Z9Mjg.js} +1 -1
- package/web/assets/{interface-hierarchy-flowchart.svg-CffgUWNS.js → interface-hierarchy-flowchart.svg-vfERX-oc.js} +1 -1
- package/web/assets/{interface-home-house.svg-B9c4N9Fi.js → interface-home-house.svg-BY98XY-a.js} +1 -1
- package/web/assets/{interface-hyperlink.svg-B8dXB276.js → interface-hyperlink.svg-8D6WX1Q9.js} +1 -1
- package/web/assets/{interface-lighting-brightness.svg-BjFVAOW3.js → interface-lighting-brightness.svg-DUoPpiwx.js} +1 -1
- package/web/assets/{interface-lock-closed.svg-DwNcKmwu.js → interface-lock-closed.svg-CzFKU_Z4.js} +1 -1
- package/web/assets/{interface-lock-open-unlock.svg-BXZeKlHt.js → interface-lock-open-unlock.svg-BnrVx0lo.js} +1 -1
- package/web/assets/{interface-login-key.svg-CQnZGVMJ.js → interface-login-key.svg-DAfv-MMA.js} +1 -1
- package/web/assets/{interface-search.svg-CXre9Ja4.js → interface-search.svg-Q2hCozQb.js} +1 -1
- package/web/assets/{interface-setting-cog.svg-CGK2QxqV.js → interface-setting-cog.svg-Bvq0dvZR.js} +1 -1
- package/web/assets/{interface-share-megaphone-bullhorn.svg-BcdTvuin.js → interface-share-megaphone-bullhorn.svg-fUmta8NQ.js} +1 -1
- package/web/assets/{interface-share-rocket.svg-DIvKBIQX.js → interface-share-rocket.svg-BKSZkx2r.js} +1 -1
- package/web/assets/{interface-share-satellite.svg-DNbqAorz.js → interface-share-satellite.svg-CB_uwNHS.js} +1 -1
- package/web/assets/{interface-share-space-ship.svg-Biobo33q.js → interface-share-space-ship.svg-CcUB1z0B.js} +1 -1
- package/web/assets/{interface-share.svg-DWjt5rBb.js → interface-share.svg-Bug50vV0.js} +1 -1
- package/web/assets/{interface-signal-square.svg--hmv5CmE.js → interface-signal-square.svg-zg41vf79.js} +1 -1
- package/web/assets/{interface-time-clock-circle.svg-C1GnMIQD.js → interface-time-clock-circle.svg-a4omIVlV.js} +1 -1
- package/web/assets/{interface-time-hour-glass.svg-BCRsHIbm.js → interface-time-hour-glass.svg-3zmzbQg_.js} +1 -1
- package/web/assets/{interface-users-multiple.svg-CUpeUldF.js → interface-users-multiple.svg-BdPX2m6Y.js} +1 -1
- package/web/assets/{interface-weather-moon.svg-QXMY6B27.js → interface-weather-moon.svg-D9_m-QTi.js} +1 -1
- package/web/assets/{javascript-DKeyayKI.js → javascript-BJlgvmgy.js} +1 -1
- package/web/assets/{jsonMode-I9zemAn2.js → jsonMode-D0zJGMKu.js} +1 -1
- package/web/assets/{liquid-xEdzGxP1.js → liquid-B0fONmvZ.js} +1 -1
- package/web/assets/{lspLanguageFeatures-DOVjCuiu.js → lspLanguageFeatures-CrwGD4mx.js} +1 -1
- package/web/assets/{mail-chat-bubble-square.svg-CR8byO78.js → mail-chat-bubble-square.svg-DZaD3FQ3.js} +1 -1
- package/web/assets/{mail-send-email-paper-airplane.svg-B0cIMUKH.js → mail-send-email-paper-airplane.svg-DkbRfjXY.js} +1 -1
- package/web/assets/{mail-send-envelope.svg-El4e7bXy.js → mail-send-envelope.svg-5c8j8mB_.js} +1 -1
- package/web/assets/{mdx-AWoH37r-.js → mdx-CKW2c2uF.js} +1 -1
- package/web/assets/{message-CATQqbP_.js → message-DZ0RuJXv.js} +1 -1
- package/web/assets/{minus-Sd1wO9DO.js → minus-C_n6M3oC.js} +1 -1
- package/web/assets/modal-C5SccGq4.js +1 -0
- package/web/assets/{modal-ZXFHQ6vP.js → modal-CvqNyAvh.js} +1 -1
- package/web/assets/{money-cashier-receipt.svg-BIEGQvlX.js → money-cashier-receipt.svg-nNTup6TP.js} +1 -1
- package/web/assets/{money-currency-dollar-pay.svg-BgCHAYq5.js → money-currency-dollar-pay.svg-D6ct80fW.js} +1 -1
- package/web/assets/{money-graph-arrow-increase.svg-q6aDu3og.js → money-graph-arrow-increase.svg-DrQ3RzKG.js} +1 -1
- package/web/assets/{money-graph-bar-chart-increase.svg-mRvG_dWg.js → money-graph-bar-chart-increase.svg-CgI8xnRe.js} +1 -1
- package/web/assets/{multiselect-BK7hJt7W.js → multiselect-CSd05WUd.js} +1 -1
- package/web/assets/{nature-ecology-leaf.svg-DdhvC8mq.js → nature-ecology-leaf.svg-SIUCD6fX.js} +1 -1
- package/web/assets/{password-Dnf9oU5a.js → password-1NqZx53t.js} +1 -1
- package/web/assets/{phone-telephone.svg-CjbyxKZA.js → phone-telephone.svg-DuLAx6_w.js} +1 -1
- package/web/assets/{plus-jYeRYaw9.js → plus-CP-dlA9U.js} +1 -1
- package/web/assets/process.store-B_vfVoW1.js +1 -0
- package/web/assets/{programming-bug.svg-DvDCWw4P.js → programming-bug.svg-DzOMyrsK.js} +1 -1
- package/web/assets/{programming-cloud.svg-2prWAqB7.js → programming-cloud.svg-CB7hznLf.js} +1 -1
- package/web/assets/{programming-computer-database-server.svg-CT7k5d_p.js → programming-computer-database-server.svg-Vdd0DgKt.js} +1 -1
- package/web/assets/{programming-computer-database.svg-Dm7fpvII.js → programming-computer-database.svg-CEqheAaf.js} +1 -1
- package/web/assets/{programming-module-four-layout.svg-DBv6QvEO.js → programming-module-four-layout.svg-BdPzuTtB.js} +1 -1
- package/web/assets/{programming-module-three.svg-BnP96bPJ.js → programming-module-three.svg-PwBqCXu4.js} +1 -1
- package/web/assets/{programming-module.svg-Bdr4ZdZO.js → programming-module.svg-DsBi6ejo.js} +1 -1
- package/web/assets/{programming-script-code.svg-DIcr6sF-.js → programming-script-code.svg-Broms4WV.js} +1 -1
- package/web/assets/{python-C554d-pk.js → python-DfCB9qU4.js} +1 -1
- package/web/assets/{razor-BvOiTjBp.js → razor-BBh-Aao5.js} +1 -1
- package/web/assets/router-CEOd6ZAd.js +1 -0
- package/web/assets/{settings.store-DISlY-48.js → settings.store-BfNYjk_y.js} +1 -1
- package/web/assets/{shopping-cart.svg-DoCVSOin.js → shopping-cart.svg-CKdnb6hR.js} +1 -1
- package/web/assets/{shopping-gift-present.svg-CgNqOSQr.js → shopping-gift-present.svg-DIxbK0pG.js} +1 -1
- package/web/assets/{shopping-shipping-box-parcel-package.svg-YkVPEp7J.js → shopping-shipping-box-parcel-package.svg-C-9ntsF7.js} +1 -1
- package/web/assets/{src-DKVQlKvZ.js → src-C77fweBS.js} +1 -1
- package/web/assets/{src-Cvt5pswj.js → src-CXyRAwtR.js} +1 -1
- package/web/assets/{tabpanel-DFoLVdFR.js → tabpanel-C0aUv4Tp.js} +1 -1
- package/web/assets/{tag-new-circle.svg-BeUe12X2.js → tag-new-circle.svg-D9mnL-uB.js} +1 -1
- package/web/assets/{travel-map-earth-globe.svg-B1I1Ed-v.js → travel-map-earth-globe.svg-B1pf_UKK.js} +1 -1
- package/web/assets/trpc-BNJN8Syq.js +1 -0
- package/web/assets/{tsMode-BPD-0Vep.js → tsMode-CBiaVW1A.js} +1 -1
- package/web/assets/{typescript-Q2uKnndS.js → typescript-DSa5kNRs.js} +1 -1
- package/web/assets/useAiChatDrawer-DJh6hREC.js +1 -0
- package/web/assets/useCloudOrg-DYG5BAW1.js +1 -0
- package/web/assets/useCloudOrg-DinvbrpR.css +1 -0
- package/web/assets/{useProjectCatalog-Kh_sHbSD.js → useProjectCatalog-Dyg12Vcr.js} +1 -1
- package/web/assets/{xml-B0CfAsFk.js → xml-BYwyGk9G.js} +1 -1
- package/web/assets/{yaml-B3zRI6AS.js → yaml-Dl2OSYTO.js} +1 -1
- package/web/index.html +1 -1
- package/agent-manager-JJYZDLNB.js +0 -7
- package/chunk-5PRQBES2.js.map +0 -1
- package/src-IFPDFIDZ.js.map +0 -1
- package/web/assets/AiChatPage-0igbt0Ie.js +0 -1
- package/web/assets/CloudAccountPage-CHZG-vv-.js +0 -1
- package/web/assets/KanbanListPage-BXWsI5ji.css +0 -1
- package/web/assets/KanbanListPage-C6bsD-gJ.js +0 -1
- package/web/assets/WikiPage-DkEQXkzp.js +0 -1
- package/web/assets/auth-errors-C1B7h06f.js +0 -1
- package/web/assets/interface-content-folder.svg-Db3hJMdF.js +0 -1
- package/web/assets/modal-BbDElcmR.js +0 -1
- package/web/assets/process.store-C5LXrPXo.js +0 -1
- package/web/assets/router-CCEIu6U5.js +0 -1
- package/web/assets/trpc-CVPkysoa.js +0 -1
- package/web/assets/useAiChatDrawer-B70XYuU8.js +0 -1
- package/web/assets/useCloudOrg-A1wW_KrI.css +0 -1
- package/web/assets/useCloudOrg-CZ68epfW.js +0 -1
- /package/{agent-manager-JJYZDLNB.js.map → agent-manager-JNA5ZALK.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../server/src/services/agent-manager.ts","../../server/src/services/agent-store.ts","../../server/src/services/vault-resolver.ts","../../server/src/config/env.ts","../../server/src/utils/encryption-key.ts","../../server/src/services/service-store.ts","../../server/src/services/project-key.ts","../../server/src/services/vault-registry.ts","../../server/src/services/vault-conflicts.ts","../../server/src/services/environment-store.ts","../../server/src/services/crypto-helpers.ts","../../../packages/shared/src/schemas/user.schema.ts","../../../packages/shared/src/schemas/org.schema.ts","../../../packages/shared/src/schemas/project.schema.ts","../../../packages/shared/src/schemas/service.schema.ts","../../../packages/shared/src/schemas/settings.schema.ts","../../../packages/shared/src/schemas/scenario.schema.ts","../../../packages/shared/src/schemas/log-source.schema.ts","../../../packages/shared/src/schemas/process.schema.ts","../../../packages/shared/src/schemas/log.schema.ts","../../../packages/shared/src/schemas/agent.schema.ts","../../../packages/shared/src/schemas/permission.schema.ts","../../../packages/shared/src/schemas/sync.schema.ts","../../../packages/shared/src/schemas/audit.schema.ts","../../../packages/shared/src/schemas/metrics.schema.ts","../../../packages/shared/src/schemas/environment.schema.ts","../../../packages/shared/src/schemas/environment-overrides.schema.ts","../../../packages/shared/src/schemas/api-key.schema.ts","../../../packages/shared/src/schemas/image.schema.ts","../../../packages/shared/src/schemas/kanban.schema.ts","../../../packages/shared/src/utils/crypto.ts","../../../packages/shared/src/native-parsers.ts","../../../packages/shared/src/js-log-parser.ts","../../../packages/shared/src/constants/intervals.ts","../../../packages/shared/src/constants/buffers.ts","../../../packages/shared/src/constants/timeouts.ts","../../../packages/shared/src/constants/editors.ts","../../../packages/shared/src/sync/json-crdt.ts","../../server/src/services/agent-spawner.ts","../../server/src/services/traefik-manager.ts","../../server/src/services/agent-ws-bridge.ts"],"sourcesContent":["import { EventEmitter } from 'node:events';\nimport WebSocket from 'ws';\nimport { z } from 'zod';\nimport { agentStore } from './agent-store.js';\nimport { serviceStore } from './service-store.js';\nimport { agentSpawner } from './agent-spawner.js';\nimport { traefikManager } from './traefik-manager.js';\nimport { AgentWSBridge } from './agent-ws-bridge.js';\nimport {\n WS_RECONNECT_MIN,\n WS_RECONNECT_MAX,\n AGENT_HEALTH_POLL_INTERVAL,\n AGENT_FETCH_TIMEOUT,\n TraefikConfigSchema,\n} from '@runeya/packages-shared';\nimport type { AgentConfig, AgentStatus } from '@runeya/packages-shared';\n\nconst HealthMessageSchema = z.object({\n status: z.string(),\n uptime: z.number(),\n runnersAvailable: z.array(z.enum(['native', 'docker'])),\n processCount: z.number(),\n runningCount: z.number(),\n lanIp: z.string().optional(),\n});\n\ninterface AgentConnection {\n config: AgentConfig;\n status: AgentStatus;\n healthWs?: WebSocket;\n bridge?: AgentWSBridge;\n reconnectTimer?: ReturnType<typeof setTimeout>;\n reconnectDelay: number;\n aliveTimer?: ReturnType<typeof setTimeout>;\n}\n\nconst MIN_RECONNECT_DELAY = WS_RECONNECT_MIN;\nconst MAX_RECONNECT_DELAY = WS_RECONNECT_MAX;\nconst ALIVE_TIMEOUT = AGENT_HEALTH_POLL_INTERVAL;\n\nfunction resolvePassthroughValues(names: string[]): Record<string, string> {\n const values: Record<string, string> = {};\n for (const name of names) {\n if (process.env[name] !== undefined) {\n values[name] = process.env[name]!;\n }\n }\n return values;\n}\n\nclass AgentManager extends EventEmitter {\n private connections: Map<string, AgentConnection> = new Map();\n\n /**\n * In-flight GET calls, keyed by agent + path + input.\n *\n * Several callers legitimately ask the same agent the same question at the\n * same moment — the sidebar and the git panel both read `git.status` for the\n * open service, the chat store, the chat page and the kanban board all read\n * `ai.findPtyBySession` for the same conversation. Sharing the pending\n * promise collapses those into a single round-trip: same response, same\n * instant, one less request queued on the agent. GET only — every tRPC query\n * is a read, whereas replaying a mutation must always hit the agent.\n */\n private inFlightGets: Map<string, Promise<unknown>> = new Map();\n\n constructor() {\n super();\n // Each WS client subscribes to up to 4 process event types + 1 agent status,\n // plus 1 bridge fan-out per agent. Two browser tabs = 10+ listeners easily.\n this.setMaxListeners(50);\n }\n\n // Make an authenticated fetch call to an agent's tRPC endpoint.\n // GET calls that are already in flight with identical input are shared rather\n // than re-issued (see `inFlightGets`).\n private async agentCall<T>(agent: AgentConfig, path: string, input?: unknown, method: 'GET' | 'POST' = 'GET', timeout = AGENT_FETCH_TIMEOUT): Promise<T> {\n if (method !== 'GET') return this.performAgentCall<T>(agent, path, input, method, timeout);\n\n let serialisedInput: string;\n try {\n serialisedInput = input === undefined ? '' : JSON.stringify(input);\n } catch {\n // Non-serialisable input — can't key it, so just issue the call.\n return this.performAgentCall<T>(agent, path, input, method, timeout);\n }\n // The timeout is part of the key: a caller must never inherit a shorter\n // deadline than it asked for by piggybacking on someone else's call.\n const key = `${agent.id}\\u0000${path}\\u0000${timeout}\\u0000${serialisedInput}`;\n\n const pending = this.inFlightGets.get(key);\n if (pending) return pending as Promise<T>;\n\n const call = this.performAgentCall<T>(agent, path, input, method, timeout)\n .finally(() => { this.inFlightGets.delete(key); });\n this.inFlightGets.set(key, call);\n return call;\n }\n\n private async performAgentCall<T>(agent: AgentConfig, path: string, input?: unknown, method: 'GET' | 'POST' = 'GET', timeout = AGENT_FETCH_TIMEOUT): Promise<T> {\n const url = new URL(`/api/trpc/${path}`, agent.url);\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${agent.passphrase}`,\n 'Content-Type': 'application/json',\n };\n\n // console.log(`[agent-manager] Calling agent ${agent.id} → ${method} ${path}`);\n\n let response: Response;\n try {\n if (method === 'GET') {\n if (input !== undefined) {\n url.searchParams.set('input', JSON.stringify(input));\n }\n response = await fetch(url.toString(), { headers, signal: AbortSignal.timeout(timeout) });\n } else {\n response = await fetch(url.toString(), {\n method: 'POST',\n headers,\n body: JSON.stringify(input !== undefined ? input : {}),\n signal: AbortSignal.timeout(timeout),\n });\n }\n } catch (err: unknown) {\n console.error('[agent-manager] Agent call failed (' + method + ' ' + path + '):', err instanceof Error ? err.message : String(err)); // nosemgrep: unsafe-formatstring\n throw err;\n }\n\n if (!response.ok) {\n let agentMessage = '';\n try {\n const errBody = await response.json() as { error?: { message?: string }; message?: string };\n agentMessage = errBody?.error?.message ?? errBody?.message ?? '';\n } catch { /* ignore parse errors */ }\n const detail = agentMessage ? `: ${agentMessage}` : '';\n console.error('[agent-manager] Agent call failed: HTTP', response.status, 'for', method, path, detail);\n throw new Error(`Agent call failed: HTTP ${response.status}${detail}`);\n }\n\n const json = await response.json() as { error?: { message?: string }; result?: { data?: T } };\n if (json.error) {\n console.error('[agent-manager] Agent error on', path + ':', json.error);\n throw new Error(`Agent error on ${path}: ${json.error.message ?? 'unknown'}`);\n }\n return json.result?.data as T;\n }\n\n // Query wrapper\n async agentQuery<T>(agentId: string, path: string, input?: unknown): Promise<T> {\n const agent = this.getAgent(agentId);\n if (!agent) throw new Error(`Agent ${agentId} not found`);\n return this.agentCall<T>(agent.config, path, input, 'GET');\n }\n\n // Mutation wrapper\n async agentMutation<T>(agentId: string, path: string, input?: unknown, timeout?: number): Promise<T> {\n const agent = this.getAgent(agentId);\n if (!agent) throw new Error(`Agent ${agentId} not found`);\n return this.agentCall<T>(agent.config, path, input, 'POST', timeout);\n }\n\n /**\n * Open a dynamic tRPC subscription on the agent's WS bridge.\n * Returns an unsubscribe function.\n * Used for per-session streaming (e.g. terminal.onData).\n */\n agentSubscribe(\n agentId: string,\n path: string,\n input: unknown,\n onData: (data: unknown) => void,\n onStop?: () => void,\n ): () => void {\n const conn = this.connections.get(agentId);\n if (!conn?.bridge) throw new Error(`Agent ${agentId} not connected via WebSocket`);\n return conn.bridge.subscribeWithInput(path, input, onData, onStop);\n }\n\n async init(): Promise<void> {\n const agents = await agentStore.list();\n for (const agent of agents) {\n this.connectAgent(agent);\n }\n }\n\n async register(name: string, url: string, passphrase: string): Promise<AgentConfig> {\n const config = await agentStore.register(name, url, passphrase);\n const isReRegistration = this.connections.has(config.id);\n\n // If already connected (e.g. loaded by init() then re-registered by spawner),\n // close the stale WS before opening a fresh one with the new passphrase.\n if (isReRegistration) {\n console.log(`[agent-manager] Re-registering agent ${config.name} (${config.id})`);\n this.disconnectAgent(config.id);\n // Small delay to ensure WS are fully closed before reconnecting\n await new Promise(resolve => setTimeout(resolve, 200));\n }\n\n this.connectAgent(config);\n console.log(`[agent-manager] Agent ${config.name} (${config.id}) connection established`);\n return config;\n }\n\n /**\n * Register a local agent in-memory only (no persistence to agentStore).\n * The local agent is always auto-spawned with deterministic config,\n * so it doesn't need disk persistence.\n * Also reassigns orphaned services (from old UUID-based agent IDs) to this agent.\n */\n async registerLocal(config: AgentConfig): Promise<void> {\n const isReRegistration = this.connections.has(config.id);\n\n if (isReRegistration) {\n console.log(`[agent-manager] Re-registering local agent ${config.name} (${config.id})`);\n this.disconnectAgent(config.id);\n await new Promise(resolve => setTimeout(resolve, 200));\n }\n\n // Load persisted passthrough env for the local agent\n const storedPassthrough = agentStore.getPassthroughEnv(config.id);\n const configWithPassthrough = { ...config, passthroughEnv: storedPassthrough };\n\n // Reassign orphaned services: any service whose agentId doesn't match\n // a known agent gets reassigned to this local agent (migration from UUID → stable ID).\n await this.reassignOrphanedServices(config.id);\n\n this.connectAgent(configWithPassthrough);\n console.log(`[agent-manager] Local agent ${config.name} (${config.id}) connected (in-memory only)`);\n }\n\n /**\n * Find services assigned to unknown agent IDs and reassign them to the given agent.\n * This handles the migration from random UUID-based agent IDs to the stable 'local-agent' ID.\n */\n private async reassignOrphanedServices(localAgentId: string): Promise<void> {\n const allServices = await serviceStore.list();\n const persistedAgents = await agentStore.list();\n const knownIds = new Set([localAgentId, ...persistedAgents.map(a => a.id)]);\n\n for (const service of allServices) {\n if (service.agentId && !knownIds.has(service.agentId)) {\n console.log(`[agent-manager] Reassigning orphaned service ${service.name} (${service.id}) from ${service.agentId} → ${localAgentId}`);\n await serviceStore.update({ id: service.id, agentId: localAgentId });\n }\n }\n }\n\n async update(agentId: string, fields: { name?: string; url?: string; passphrase?: string; passthroughEnv?: string[] }): Promise<AgentConfig> {\n const isLocal = agentSpawner.getLocalAgentId() === agentId;\n\n // Local agent: only passthroughEnv is allowed\n if (isLocal) {\n const hasOtherFields = fields.name !== undefined || fields.url !== undefined || fields.passphrase !== undefined;\n if (hasOtherFields) {\n throw new Error('Cannot modify the local agent');\n }\n }\n\n // Handle passthroughEnv separately (persisted in agentStore, pushed to agent)\n if (fields.passthroughEnv !== undefined) {\n await agentStore.savePassthroughEnv(agentId, fields.passthroughEnv);\n\n const conn = this.connections.get(agentId);\n if (conn) {\n conn.config = { ...conn.config, passthroughEnv: fields.passthroughEnv };\n // Push to the agent\n try {\n await this.agentMutation(agentId, 'config.setPassthroughEnv', {\n names: fields.passthroughEnv,\n values: resolvePassthroughValues(fields.passthroughEnv),\n });\n } catch (err) {\n console.error('[agent-manager] Failed to push passthroughEnv to agent', agentId + ':', err instanceof Error ? err.message : String(err));\n }\n }\n }\n\n // For local agent with only passthroughEnv, return config from connection\n if (isLocal) {\n const conn = this.connections.get(agentId);\n if (!conn) throw new Error(`Agent ${agentId} not found`);\n return conn.config;\n }\n\n // Remote agent: update name/url/passphrase in the store\n const { passthroughEnv: _pt, ...storeFields } = fields;\n const hasStoreFields = storeFields.name !== undefined || storeFields.url !== undefined || storeFields.passphrase !== undefined;\n\n if (hasStoreFields) {\n const updated = await agentStore.update(agentId, storeFields);\n if (!updated) {\n throw new Error(`Agent ${agentId} not found`);\n }\n const conn = this.connections.get(agentId);\n if (conn) {\n conn.config = updated;\n if (storeFields.url !== undefined || storeFields.passphrase !== undefined) {\n this.disconnectAgent(agentId);\n this.connectAgent(updated);\n }\n }\n return updated;\n }\n\n // passthroughEnv-only update for remote agent\n const conn = this.connections.get(agentId);\n if (!conn) throw new Error(`Agent ${agentId} not found`);\n return conn.config;\n }\n\n async remove(agentId: string): Promise<boolean> {\n // Prevent removal of the local spawned agent\n if (agentSpawner.getLocalAgentId() === agentId) {\n throw new Error('Cannot remove the local agent');\n }\n this.disconnectAgent(agentId);\n return agentStore.remove(agentId);\n }\n\n private connectAgent(config: AgentConfig): void {\n const connection: AgentConnection = {\n config,\n status: {\n connected: false,\n lastSeen: null,\n uptime: 0,\n runnersAvailable: [],\n },\n reconnectDelay: MIN_RECONNECT_DELAY,\n };\n\n this.connections.set(config.id, connection);\n this.openHealthWs(config.id);\n this.openBridge(config.id);\n }\n\n private openBridge(agentId: string): void {\n const conn = this.connections.get(agentId);\n if (!conn) return;\n\n console.log(`[agent-manager] Opening tRPC bridge for agent ${conn.config.name} (${agentId})`);\n\n const bridge = new AgentWSBridge(agentId, conn.config.url, conn.config.passphrase);\n conn.bridge = bridge;\n\n // Fan-out bridge events to the AgentManager\n const eventTypes = ['process:status', 'process:log', 'process:health', 'process:metrics'] as const;\n for (const eventType of eventTypes) {\n bridge.on(eventType, (data: unknown) => {\n this.emit(eventType, data);\n });\n }\n\n bridge.connect();\n }\n\n private disconnectAgent(agentId: string): void {\n const conn = this.connections.get(agentId);\n if (!conn) return;\n\n console.log(`[agent-manager] Disconnecting agent ${conn.config.name} (${agentId})`);\n\n if (conn.healthWs) {\n conn.healthWs.removeAllListeners();\n conn.healthWs.close();\n conn.healthWs = undefined;\n }\n if (conn.bridge) {\n conn.bridge.disconnect();\n conn.bridge = undefined;\n }\n if (conn.reconnectTimer) {\n clearTimeout(conn.reconnectTimer);\n conn.reconnectTimer = undefined;\n }\n if (conn.aliveTimer) {\n clearTimeout(conn.aliveTimer);\n conn.aliveTimer = undefined;\n }\n\n this.connections.delete(agentId);\n this.emit('status', { agentId, status: { connected: false, lastSeen: null, uptime: 0, runnersAvailable: [] } satisfies AgentStatus });\n }\n\n private openHealthWs(agentId: string): void {\n const conn = this.connections.get(agentId);\n if (!conn) return;\n\n // Build WS URL from agent HTTP URL\n const httpUrl = new URL(conn.config.url);\n const wsProtocol = httpUrl.protocol === 'https:' ? 'wss:' : 'ws:';\n const wsUrl = `${wsProtocol}//${httpUrl.host}/ws/health`;\n\n const ws = new WebSocket(wsUrl, {\n headers: { 'Authorization': `Bearer ${conn.config.passphrase}` },\n });\n conn.healthWs = ws;\n\n const resetAliveTimer = () => {\n if (conn.aliveTimer) clearTimeout(conn.aliveTimer);\n conn.aliveTimer = setTimeout(() => {\n console.debug(`[agent-manager] Agent ${conn.config.name} (${agentId}) alive timeout — closing WS`);\n ws.close();\n }, ALIVE_TIMEOUT);\n };\n\n ws.on('open', () => {\n console.debug(`[agent-manager] WS open to agent ${conn.config.name} (${agentId})`);\n resetAliveTimer();\n });\n\n ws.on('message', (raw: Buffer | string) => {\n try {\n const health = HealthMessageSchema.parse(\n JSON.parse(typeof raw === 'string' ? raw : raw.toString()),\n );\n\n // Only reset alive timer after successful validation\n resetAliveTimer();\n\n const wasConnected = conn.status.connected;\n conn.status = {\n connected: true,\n lastSeen: new Date().toISOString(),\n uptime: health.uptime,\n runnersAvailable: health.runnersAvailable,\n lanIp: health.lanIp,\n };\n\n // Reset reconnect delay on successful message\n conn.reconnectDelay = MIN_RECONNECT_DELAY;\n\n this.emit('status', { agentId, status: { ...conn.status } satisfies AgentStatus });\n\n if (!wasConnected) {\n console.debug(`[agent-manager] Agent ${conn.config.name} (${agentId}) connected`);\n void this.pushPassthroughEnv(agentId);\n void this.reconcileAiSpawns(agentId);\n const rawTraefikConfig = agentStore.getTraefikConfig(agentId);\n if (rawTraefikConfig) {\n const parsed = TraefikConfigSchema.safeParse(rawTraefikConfig);\n if (parsed.success) {\n // Decrypt DNS credentials before pushing to agent — the stored config\n // holds encrypted ciphertext which is not valid as env var values.\n const configToPush = {\n ...parsed.data,\n dnsCredentials: traefikManager.decryptDnsCredentials(parsed.data.dnsCredentials ?? {}),\n };\n void this.pushTraefikConfig(agentId, configToPush);\n } else {\n console.error('[agent-manager] Invalid Traefik config in store for agent', agentId);\n }\n }\n }\n } catch (err) {\n console.debug('[agent-manager] Failed to parse health message for agent', agentId + ':', err);\n }\n });\n\n ws.on('close', () => {\n if (conn.aliveTimer) {\n clearTimeout(conn.aliveTimer);\n conn.aliveTimer = undefined;\n }\n conn.healthWs = undefined;\n\n if (conn.status.connected) {\n console.debug(`[agent-manager] Agent ${conn.config.name} (${agentId}) disconnected`);\n conn.status.connected = false;\n this.emit('status', { agentId, status: { ...conn.status } satisfies AgentStatus });\n }\n\n // Schedule reconnect only if still tracked\n if (this.connections.has(agentId)) {\n this.scheduleReconnect(agentId);\n }\n });\n\n ws.on('error', (err) => {\n // Error is always followed by close event, no need to handle reconnect here\n if (conn.status.connected) {\n console.debug('[agent-manager] WS error for agent', conn.config.name, '(' + agentId + '):', err.message);\n }\n });\n }\n\n private scheduleReconnect(agentId: string): void {\n const conn = this.connections.get(agentId);\n if (!conn) return;\n\n // Clear any existing reconnect timer\n if (conn.reconnectTimer) {\n clearTimeout(conn.reconnectTimer);\n }\n\n conn.reconnectTimer = setTimeout(() => {\n conn.reconnectTimer = undefined;\n if (this.connections.has(agentId)) {\n this.openHealthWs(agentId);\n }\n }, conn.reconnectDelay);\n\n // Exponential backoff: 1s → 2s → 4s → 8s → 15s (capped)\n conn.reconnectDelay = Math.min(conn.reconnectDelay * 2, MAX_RECONNECT_DELAY);\n }\n\n /**\n * On agent (re)connect, discover any AI spawns still alive on the agent.\n * Log them for now — full rehydration of ActiveSessionRegistry is a follow-up.\n */\n private async reconcileAiSpawns(agentId: string): Promise<void> {\n try {\n const spawns = await this.agentQuery<Array<{ spawnId: string; cli: string; status: string; bufferLength: number }>>(agentId, 'ai.list');\n if (spawns.length > 0) {\n const summary = spawns.map(s => `${s.spawnId} (${s.cli}, ${s.status}, buf:${s.bufferLength})`).join(', ');\n console.log('[agent-manager] Agent %s has %d AI spawn(s): %s', agentId, spawns.length, summary);\n // TODO: rehydrate ActiveSessionRegistry for running spawns that match known conversations\n // For now, ack done spawns without a matching session to allow cleanup\n for (const spawn of spawns) {\n if (spawn.status !== 'running') {\n this.agentMutation(agentId, 'ai.ack', { spawnId: spawn.spawnId }).catch(() => {});\n }\n }\n }\n } catch (err) {\n console.debug('[agent-manager] Failed to reconcile AI spawns for agent', agentId + ':', err instanceof Error ? err.message : String(err));\n }\n }\n\n // Push passthrough env variables to agent on (re)connection\n private async pushPassthroughEnv(agentId: string): Promise<void> {\n const conn = this.connections.get(agentId);\n if (conn && conn.config.passthroughEnv && conn.config.passthroughEnv.length > 0) {\n try {\n await this.agentMutation(agentId, 'config.setPassthroughEnv', {\n names: conn.config.passthroughEnv,\n values: resolvePassthroughValues(conn.config.passthroughEnv),\n });\n console.log('[agent-manager] Pushed passthroughEnv to agent', agentId + ':', conn.config.passthroughEnv.join(', '));\n } catch (err) {\n console.error('[agent-manager] Failed to push passthroughEnv to agent', agentId + ':', err instanceof Error ? err.message : String(err));\n }\n }\n }\n\n // Push Traefik config to agent on (re)connection or after update\n async pushTraefikConfig(agentId: string, config: unknown): Promise<void> {\n const conn = this.connections.get(agentId);\n if (!conn) return;\n try {\n await this.agentMutation(agentId, 'config.setTraefikConfig', config);\n } catch (err) {\n console.error('[agent-manager] Failed to push Traefik config to agent', agentId + ':', err instanceof Error ? err.message : String(err));\n }\n }\n\n /** Returns the local agent ID, or first connected agent, or null. */\n getDefaultAgentId(): string | null {\n const localId = agentSpawner.getLocalAgentId();\n if (localId && this.connections.get(localId)?.status.connected) return localId;\n for (const [id, conn] of this.connections) {\n if (conn.status.connected) return id;\n }\n return null;\n }\n\n getAgent(agentId: string): AgentConnection | undefined {\n return this.connections.get(agentId);\n }\n\n getAgentConfig(agentId: string): AgentConfig | undefined {\n return this.connections.get(agentId)?.config;\n }\n\n listAgents(): Array<{ config: AgentConfig; status: AgentStatus; isLocal: boolean }> {\n const localId = agentSpawner.getLocalAgentId();\n return Array.from(this.connections.values()).map(conn => ({\n config: { ...conn.config, passphrase: '***' }, // Don't expose passphrase\n status: conn.status,\n isLocal: conn.config.id === localId,\n }));\n }\n\n getStatus(agentId: string): AgentStatus | null {\n return this.connections.get(agentId)?.status ?? null;\n }\n\n async shutdown(): Promise<void> {\n const ids = [...this.connections.keys()];\n for (const id of ids) {\n this.disconnectAgent(id);\n }\n }\n}\n\nexport const agentManager = new AgentManager();\n","import { randomUUID, randomBytes, createCipheriv, createDecipheriv } from 'node:crypto';\nimport { readFile, writeFile, rename, mkdir, chmod } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { keyedFilePath, legacyMachineFilePath } from './vault-resolver.js';\nimport { getEncryptionKey } from '../utils/encryption-key.js';\nimport type { AgentConfig } from '@runeya/packages-shared';\n\nconst FILENAME = 'agents.json';\nconst ALGORITHM = 'aes-256-gcm';\n\ninterface StoredAgent {\n id: string;\n name: string;\n url: string;\n encrypted: string; // hex\n iv: string; // hex\n authTag: string; // hex\n}\n\nfunction encrypt(plaintext: string): { encrypted: string; iv: string; authTag: string } {\n const maybeKey = getEncryptionKey();\n if (!maybeKey) {\n throw new Error('Encryption key not loaded — please provide the key via setup UI');\n }\n const key: Buffer = maybeKey; // Type narrowing\n const iv = randomBytes(16);\n const cipher = createCipheriv(ALGORITHM, key, iv);\n let enc = cipher.update(plaintext, 'utf-8', 'hex');\n enc += cipher.final('hex');\n const authTag = cipher.getAuthTag().toString('hex');\n return { encrypted: enc, iv: iv.toString('hex'), authTag };\n}\n\nfunction decrypt(encrypted: string, ivHex: string, authTagHex: string): string {\n // Validate all hex inputs before Buffer.from()\n if (!/^[0-9a-f]+$/i.test(encrypted) || !/^[0-9a-f]+$/i.test(ivHex) || !/^[0-9a-f]+$/i.test(authTagHex)) {\n throw new Error('Invalid hex string in encrypted agent data');\n }\n const maybeKey = getEncryptionKey();\n if (!maybeKey) {\n throw new Error('Encryption key not loaded — please provide the key via setup UI');\n }\n const key: Buffer = maybeKey; // Type narrowing\n const iv = Buffer.from(ivHex, 'hex');\n const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: 16 });\n decipher.setAuthTag(Buffer.from(authTagHex, 'hex'));\n let dec = decipher.update(encrypted, 'hex', 'utf-8');\n dec += decipher.final('utf-8');\n return dec;\n}\n\ninterface AgentsFileData {\n agents: StoredAgent[];\n passthroughEnv: Record<string, string[]>;\n traefikConfigs: Record<string, unknown>;\n}\n\nclass AgentStore {\n private agents: Map<string, StoredAgent> = new Map();\n private passthroughEnv: Record<string, string[]> = {};\n private traefikConfigs: Record<string, unknown> = {};\n private loaded = false;\n\n /**\n * Encrypted, so it lives beside the key that opens it — usually the machine\n * root, but a launch directory owning its own key keeps both together.\n */\n private getFilePath(): Promise<string> {\n return keyedFilePath(FILENAME);\n }\n\n /** Where older versions kept it — read only, so an older Runeya keeps working. */\n private getLegacyFilePath(): string {\n return legacyMachineFilePath(FILENAME);\n }\n\n /**\n * Read the machine file, falling back to the launch directory of old.\n *\n * The legacy file is left in place: the next save writes the new location,\n * and a directory still opened by an older Runeya keeps working meanwhile.\n */\n private async readFromDisk(): Promise<string> {\n try {\n return await readFile(await this.getFilePath(), 'utf-8');\n } catch {\n return readFile(this.getLegacyFilePath(), 'utf-8');\n }\n }\n\n private async ensureDir(): Promise<void> {\n await mkdir(dirname(await this.getFilePath()), { recursive: true });\n }\n\n private async load(): Promise<void> {\n if (this.loaded) return;\n try {\n const raw = await this.readFromDisk();\n const data = JSON.parse(raw);\n if (Array.isArray(data)) {\n // Legacy format: plain StoredAgent[]\n for (const a of data as StoredAgent[]) this.agents.set(a.id, a);\n this.passthroughEnv = {};\n } else {\n // New format: { agents, passthroughEnv }\n const fileData = data as AgentsFileData;\n for (const a of fileData.agents) this.agents.set(a.id, a);\n this.passthroughEnv = fileData.passthroughEnv ?? {};\n this.traefikConfigs = fileData.traefikConfigs ?? {};\n }\n } catch {\n // File doesn't exist yet, start empty\n }\n this.loaded = true;\n }\n\n private async save(): Promise<void> {\n await this.ensureDir();\n const filePath = await this.getFilePath();\n const tmpPath = filePath + '.tmp';\n const fileData: AgentsFileData = {\n agents: Array.from(this.agents.values()),\n passthroughEnv: this.passthroughEnv,\n traefikConfigs: this.traefikConfigs,\n };\n await writeFile(tmpPath, JSON.stringify(fileData, null, 2), 'utf-8');\n await rename(tmpPath, filePath);\n await chmod(filePath, 0o600);\n }\n\n private toAgentConfig(stored: StoredAgent): AgentConfig {\n return {\n id: stored.id,\n name: stored.name,\n url: stored.url,\n passphrase: decrypt(stored.encrypted, stored.iv, stored.authTag),\n passthroughEnv: this.passthroughEnv[stored.id] ?? [],\n };\n }\n\n async list(): Promise<AgentConfig[]> {\n await this.load();\n // If no encryption key, return empty list (setup mode)\n if (!getEncryptionKey()) {\n return [];\n }\n return Array.from(this.agents.values()).map(a => this.toAgentConfig(a));\n }\n\n async get(id: string): Promise<AgentConfig | null> {\n await this.load();\n // If no encryption key, return null (setup mode)\n if (!getEncryptionKey()) {\n return null;\n }\n const stored = this.agents.get(id);\n if (!stored) return null;\n return this.toAgentConfig(stored);\n }\n\n async register(name: string, url: string, passphrase: string): Promise<AgentConfig> {\n await this.load();\n // Check if an agent with the same URL already exists\n const existing = Array.from(this.agents.values()).find(a => a.url === url);\n const { encrypted, iv, authTag } = encrypt(passphrase);\n if (existing) {\n // Update existing agent instead of creating duplicate\n existing.name = name;\n existing.encrypted = encrypted;\n existing.iv = iv;\n existing.authTag = authTag;\n await this.save();\n return { id: existing.id, name, url, passphrase, passthroughEnv: this.passthroughEnv[existing.id] ?? [] };\n }\n const id = randomUUID();\n const stored: StoredAgent = { id, name, url, encrypted, iv, authTag };\n this.agents.set(id, stored);\n await this.save();\n return { id, name, url, passphrase, passthroughEnv: [] };\n }\n\n async remove(id: string): Promise<boolean> {\n await this.load();\n if (!this.agents.has(id)) return false;\n this.agents.delete(id);\n delete this.passthroughEnv[id];\n delete this.traefikConfigs[id];\n await this.save();\n return true;\n }\n\n getPassthroughEnv(agentId: string): string[] {\n return this.passthroughEnv[agentId] ?? [];\n }\n\n async savePassthroughEnv(agentId: string, names: string[]): Promise<void> {\n await this.load();\n this.passthroughEnv[agentId] = names;\n await this.save();\n }\n\n getTraefikConfig(agentId: string): unknown {\n return this.traefikConfigs[agentId] ?? null;\n }\n\n async saveTraefikConfig(agentId: string, config: unknown): Promise<void> {\n await this.load();\n this.traefikConfigs[agentId] = config;\n await this.save();\n }\n\n async update(id: string, fields: { name?: string; url?: string; passphrase?: string }): Promise<AgentConfig | null> {\n await this.load();\n const stored = this.agents.get(id);\n if (!stored) return null;\n if (fields.name !== undefined) stored.name = fields.name;\n if (fields.url !== undefined) stored.url = fields.url;\n if (fields.passphrase !== undefined) {\n const { encrypted, iv, authTag } = encrypt(fields.passphrase);\n stored.encrypted = encrypted;\n stored.iv = iv;\n stored.authTag = authTag;\n }\n await this.save();\n return this.toAgentConfig(stored);\n }\n\n async updateUrl(id: string, url: string): Promise<AgentConfig | null> {\n await this.load();\n const stored = this.agents.get(id);\n if (!stored) return null;\n stored.url = url;\n this.agents.set(id, stored);\n await this.save();\n return this.toAgentConfig(stored);\n }\n}\n\nexport const agentStore = new AgentStore();\n","import { join, sep } from 'node:path';\nimport { homedir } from 'node:os';\nimport { readdir, mkdir, access, readFile, writeFile } from 'node:fs/promises';\nimport { env } from '../config/env.js';\n\n/**\n * Where a project's files live, and which key protects them.\n *\n * Runeya holds two kinds of projects, and they do not belong in the same place.\n * A local project *is* a directory on this machine: its data belongs next to\n * the code, in `<cwd>/.runeya`. A cloud project belongs to an organization and\n * is materialized from the doc; tying it to whichever directory happened to\n * launch the server is what made the same project look \"already here\" in one\n * folder and \"to download\" in another. Cloud projects therefore live under the\n * user's home, prefixed by organization and by project.\n *\n * A vault holds a project's own data — project.json, services, environments.\n * It does NOT hold the key that protects it: one key answers for the whole\n * machine (see `keyRoot` at the bottom of this file), which is what the cloud's\n * org-wide canary already assumes.\n */\n\nexport interface Vault {\n /** Directory holding this project's own files. */\n root: string;\n}\n\n/** Identifies a project well enough to place it — the stored shape, or the doc's. */\nexport interface VaultTarget {\n id: string;\n orgId?: string | null;\n}\n\n/**\n * Ids reach us from the cloud, and they end up in filesystem paths. Anything\n * outside this alphabet — a separator, a `..`, a NUL — could walk out of the\n * home directory, so it is rejected rather than sanitized: a mangled id would\n * silently point at the wrong vault.\n */\nconst SAFE_ID = /^[A-Za-z0-9._-]{1,128}$/;\n\nfunction assertSafeId(kind: 'organization' | 'project', id: string): void {\n if (!SAFE_ID.test(id) || id === '.' || id === '..') {\n throw new Error(`Invalid ${kind} id for a vault path: ${JSON.stringify(id)}`);\n }\n}\n\n/**\n * Everything that belongs to this machine rather than to a project.\n *\n * Read from `process.env` rather than the parsed config: tests that mock\n * `config/env.js` would otherwise lose the override and write cloud vaults into\n * the developer's real home directory.\n */\nexport function machineRoot(): string {\n const override = process.env['RUNEYA_HOME'];\n return join(override && override.length > 0 ? override : homedir(), '.runeya');\n}\n\n/**\n * The local vault: the `.runeya` of the directory the server was launched in.\n *\n * Kept on `env.DATA_DIR` so `--data-dir` and the tests keep working. That value\n * is already absolute, resolved once at boot — re-resolving it here would make\n * the vault follow the process's cwd, which is exactly what it must not do.\n */\nexport function localVaultRoot(): string {\n return env.DATA_DIR;\n}\n\n/** The vault of an organization: its projects, and its lock. */\nexport function orgVaultRoot(orgId: string): string {\n assertSafeId('organization', orgId);\n return join(machineRoot(), 'orgs', orgId);\n}\n\n/** The vault of one cloud project, under its organization. */\nexport function projectVaultRoot(orgId: string, projectId: string): string {\n assertSafeId('project', projectId);\n return join(orgVaultRoot(orgId), 'projects', projectId);\n}\n\n/**\n * The organization a vault path belongs to, or null for the local vault.\n *\n * The layout is the authority on ownership — `~/.runeya/orgs/<org>/projects/<id>`\n * says both which project and which organization — so an entity read from a\n * vault carries its couple in the path it came from, even though its own file\n * only ever names its project.\n */\nexport function orgIdOfRoot(root: string): string | null {\n const marker = join(machineRoot(), 'orgs') + sep;\n if (!root.startsWith(marker)) return null;\n const [orgId] = root.slice(marker.length).split(sep);\n return orgId && SAFE_ID.test(orgId) ? orgId : null;\n}\n\n/** Where to read and write a given project. */\nexport function vaultFor(target: VaultTarget): Vault {\n if (!target.orgId) return { root: localVaultRoot() };\n return { root: projectVaultRoot(target.orgId, target.id) };\n}\n\n/**\n * Which cloud instance an organization's vault came from.\n *\n * `~/.runeya/orgs/` is machine-global while a sync link is per launch directory,\n * so a machine that has ever synced against two clouds (a self-hosted or local\n * one and the hosted one) ends up with org ids from both, indistinguishable.\n * Stamping the instance next to the vault is what lets a reader tell \"an org I\n * am not a member of\" from \"an org of a cloud I am simply not signed into\".\n */\nconst ORG_CLOUD_FILE = 'cloud.json';\n\nexport async function stampOrgCloud(orgId: string, cloudUrl: string): Promise<void> {\n const root = orgVaultRoot(orgId);\n try {\n await mkdir(root, { recursive: true });\n await writeFile(join(root, ORG_CLOUD_FILE), JSON.stringify({ cloudUrl }, null, 2), 'utf-8');\n } catch {\n // Best effort: the stamp only sharpens a warning, it gates nothing.\n }\n}\n\n/** The cloud instance of every org vault that carries a stamp. */\nexport async function readOrgClouds(): Promise<Record<string, string>> {\n const orgsDir = join(machineRoot(), 'orgs');\n const out: Record<string, string> = {};\n let orgIds: string[];\n try {\n orgIds = (await readdir(orgsDir, { withFileTypes: true }))\n .filter((e) => e.isDirectory() && SAFE_ID.test(e.name))\n .map((e) => e.name);\n } catch {\n return out;\n }\n for (const orgId of orgIds) {\n try {\n const raw = await readFile(join(orgsDir, orgId, ORG_CLOUD_FILE), 'utf-8');\n const url = (JSON.parse(raw) as { cloudUrl?: unknown }).cloudUrl;\n if (typeof url === 'string' && url) out[orgId] = url;\n } catch {\n // No stamp (older vault, or never linked here) — simply unknown.\n }\n }\n return out;\n}\n\n/** One cloud project vault found on disk. */\nexport interface CloudVault {\n orgId: string;\n projectId: string;\n root: string;\n}\n\n/**\n * Every cloud project vault present on this machine, by walking\n * `~/.runeya/orgs/<orgId>/projects/<projectId>`.\n *\n * Discovery reads the disk rather than an index on purpose: an index is one\n * more thing that can disagree with what is actually there, and a project\n * present on disk but missing from it is precisely the \"already here, still\n * offered as a download\" bug. Unreadable or foreign directories are skipped in\n * silence — a half-written pull must not take a whole load down.\n */\nexport async function listCloudVaults(): Promise<CloudVault[]> {\n const orgsDir = join(machineRoot(), 'orgs');\n const found: CloudVault[] = [];\n\n let orgIds: string[];\n try {\n orgIds = (await readdir(orgsDir, { withFileTypes: true }))\n .filter((e) => e.isDirectory() && SAFE_ID.test(e.name))\n .map((e) => e.name);\n } catch {\n return found;\n }\n\n for (const orgId of orgIds) {\n const projectsDir = join(orgsDir, orgId, 'projects');\n try {\n for (const entry of await readdir(projectsDir, { withFileTypes: true })) {\n if (!entry.isDirectory() || !SAFE_ID.test(entry.name)) continue;\n found.push({ orgId, projectId: entry.name, root: join(projectsDir, entry.name) });\n }\n } catch {\n // Org directory without materialized projects yet.\n }\n }\n return found;\n}\n\n/**\n * Every vault holding data, local first — what stores must read to see it all.\n *\n * Derived from the disk, so it needs no store to have loaded beforehand: a\n * content store can resolve where to read without waiting on the project store.\n */\nexport async function allVaultRoots(): Promise<string[]> {\n const cloud = await listCloudVaults();\n return [localVaultRoot(), ...cloud.map((v) => v.root)];\n}\n\n/**\n * A file belonging to the machine rather than to any project.\n *\n * Settings, the audit log, caches: none of them describe a project, and keeping\n * them in the launch directory forced a `.runeya` to exist for someone working\n * only on cloud projects — the very thing vaults remove.\n *\n * For anything ENCRYPTED, use `keyedFilePath` instead.\n */\nexport function machineFilePath(filename: string): string {\n return join(machineRoot(), filename);\n}\n\n/**\n * A machine file whose contents are encrypted.\n *\n * It lives beside the key that opens it, never merely beside the machine. The\n * two are usually the same directory — but a launch directory that owns its own\n * key keeps it (see `keyRoot`), and a file encrypted under that key read from\n * elsewhere would decrypt to blanks, then be saved back blank. Tying the file to\n * its key is what makes that impossible.\n */\nexport async function keyedFilePath(filename: string): Promise<string> {\n return join(await keyRoot(), filename);\n}\n\n/**\n * Where such a file was kept by earlier versions: in the launch directory.\n *\n * Read as a fallback and never written, so a directory shared with an older\n * Runeya keeps working.\n */\nexport function legacyMachineFilePath(filename: string): string {\n return join(localVaultRoot(), filename);\n}\n\n/**\n * Create the local vault, on the way to writing a local project into it.\n *\n * The directory is created here and nowhere else. Runeya no longer makes a\n * `.runeya` just because it was started somewhere: a machine used only for\n * cloud projects should leave the directories it visits untouched, and a\n * `.runeya` appearing in a repository should mean \"there is a local project\n * here\" rather than \"Runeya ran here once\".\n */\nexport async function ensureLocalVault(): Promise<string> {\n const root = localVaultRoot();\n await mkdir(root, { recursive: true });\n return root;\n}\n\n/** Files that mark a directory as already holding an encryption key. */\nconst KEY_FILES = ['.encryption.key.enc', '.runeya-verify'];\n\nlet keyRootPromise: Promise<string> | null = null;\n\n/** True when a directory already holds an encryption key of its own. */\nasync function holdsKey(root: string): Promise<boolean> {\n for (const filename of KEY_FILES) {\n try {\n await access(join(root, filename));\n return true;\n } catch {\n // Not here — keep looking.\n }\n }\n return false;\n}\n\n/**\n * Where this machine's encryption key and its canary live.\n *\n * The key protects everything on the machine — agents, sessions, and the\n * environments of every vault — so there is one, not one per vault, and the\n * machine root is its home.\n *\n * Earlier versions let a launch directory keep a key of its own, which is how a\n * machine ended up with several master passwords and several cloud identities.\n * Such a directory is no longer promoted: the machine key answers as soon as it\n * exists, and the leftover local key is surfaced by `legacyVaultRoot()` so it\n * can be migrated rather than silently obeyed. A machine that has never had a\n * machine key still falls back to the local one, so an un-migrated install\n * keeps opening exactly as before.\n *\n * Resolved once per process: the answer must not change under a running server,\n * and a key written mid-session would otherwise move its own home.\n */\nexport function keyRoot(): Promise<string> {\n keyRootPromise ??= (async () => {\n if (await holdsKey(machineRoot())) return machineRoot();\n return (await holdsKey(localVaultRoot())) ? localVaultRoot() : machineRoot();\n })();\n return keyRootPromise;\n}\n\n/**\n * The launch directory's own key, when the machine key is what we opened.\n *\n * Its presence is the whole trigger for the migration page: this directory\n * holds data encrypted under a key nothing reads any more. Null once migrated,\n * and null too when the local key IS the one in use — there is nothing to\n * migrate then.\n */\nexport async function legacyVaultRoot(): Promise<string | null> {\n const local = localVaultRoot();\n if ((await keyRoot()) === local) return null;\n return (await holdsKey(local)) ? local : null;\n}\n\n/** Test seam: forget the resolved key home. */\nexport function resetKeyRoot(): void {\n keyRootPromise = null;\n}\n","import { z } from 'zod';\nimport { resolve as resolvePath } from 'node:path';\n\n/**\n * Every variable Runeya reads from the process environment is prefixed with\n * `RUNEYA_`. Generic names (PORT, HOST, MODE, DATA_DIR…) are deliberately NOT\n * read: Runeya loads the `.env` of the stack it manages, where those names very\n * often belong to the user's own services.\n *\n * The resolved object keeps short field names (`env.PORT`, `env.HOST`, …) —\n * only the environment keys are prefixed.\n */\n\n// Server port, used to derive the default agent port\nconst serverPort = z.coerce.number().int().min(1).max(65535).default(4000).parse(process.env.RUNEYA_HTTP_PORT);\n\nconst defaultAgentPort = process.env.RUNEYA_AGENT_PORT\n ? z.coerce.number().int().min(1).max(65535).parse(process.env.RUNEYA_AGENT_PORT)\n : serverPort + 1;\n\nconst EnvSchema = z.object({\n RUNEYA_HTTP_PORT: z.coerce.number().int().min(1).max(65535).default(4000),\n RUNEYA_HOST: z.string().default('127.0.0.1'),\n RUNEYA_AGENT_PORT: z.coerce.number().int().min(1).max(65535).default(defaultAgentPort),\n RUNEYA_AGENT_HOST: z.string().default('127.0.0.1'),\n RUNEYA_AGENT_BINARY_PATH: z.string().nullable().default(null),\n RUNEYA_DATA_DIR: z.preprocess((v) => (typeof v === 'string' && v.length > 0 ? v : undefined), z.string().default('.runeya')),\n // Home holding the cloud vaults (`<home>/.runeya/orgs/...`). Defaults to the\n // user's home directory; overridden by tests so they never write to the real\n // one, and usable to relocate the vaults on a shared machine.\n RUNEYA_HOME: z.preprocess((v) => (typeof v === 'string' && v.length > 0 ? v : undefined), z.string().nullable().default(null)),\n RUNEYA_CLOUD_URL: z.string().url().nullable().default(null),\n // Cloud front-end (landing) URL — used by the web app for the registration /\n // onboarding flow. Configured on the server at launch; the web fetches it.\n RUNEYA_CLOUD_APP_URL: z.string().url().nullable().default(null),\n RUNEYA_MODE: z.enum(['local-simple', 'cloud']).default('local-simple'),\n RUNEYA_CORS_ORIGIN: z.string().nullable().default(null),\n RUNEYA_LAN_PROXY: z.preprocess((v) => v === 'true' || v === '1', z.boolean()).default(false),\n // Label shown for this machine in the cloud's \"linked machines\" screen.\n // Defaults to the hostname (see `getDeviceName`); set it explicitly when a\n // single host runs several instances and you want to tell them apart.\n RUNEYA_DEVICE_NAME: z.preprocess(\n (v) => (typeof v === 'string' && v.trim().length > 0 ? v.trim() : undefined),\n z.string().max(64).nullable().default(null),\n ),\n}).transform((data) => ({\n ...data,\n // Short aliases used throughout the server code\n PORT: data.RUNEYA_HTTP_PORT,\n HOST: data.RUNEYA_HOST,\n MODE: data.RUNEYA_MODE,\n /**\n * Absolute from the start, resolved once against the launch directory.\n *\n * It defaults to a relative `.runeya`, and every caller used to re-resolve it\n * against whatever the process's cwd happened to be. A vault that moves when\n * the process changes directory is a vault that can be silently written to the\n * wrong place — so the answer is fixed here, at boot, and never recomputed.\n */\n DATA_DIR: resolvePath(data.RUNEYA_DATA_DIR),\n HOME_DIR: data.RUNEYA_HOME,\n CLOUD_URL: data.RUNEYA_CLOUD_URL,\n CLOUD_APP_URL: data.RUNEYA_CLOUD_APP_URL,\n CORS_ORIGIN: data.RUNEYA_CORS_ORIGIN,\n AGENT_BINARY_PATH: data.RUNEYA_AGENT_BINARY_PATH,\n DEVICE_NAME: data.RUNEYA_DEVICE_NAME,\n}));\n\nexport type Env = z.infer<typeof EnvSchema>;\n\nexport const env = EnvSchema.parse(process.env);\n","import { createHash } from 'node:crypto';\n\nconst KEY_SIZE_BYTES = 32;\n\n/**\n * Keys in memory, one per vault.\n *\n * A machine can hold several vaults at once — the local `.runeya` and one per\n * organization it follows — and they do not share a key. The keyring is\n * therefore indexed by vault root, with `DEFAULT_VAULT` standing for \"the vault\n * this process was launched in\".\n *\n * Every accessor keeps its no-argument form, which addresses that default\n * vault: the whole server currently runs in a single vault, and only the code\n * that knowingly juggles several has to name one.\n */\nconst DEFAULT_VAULT = '\\u0000default';\nconst keyring = new Map<string, Buffer>();\nlet _ciMode = false;\n\n// Pending legacy key holder — kept in memory between migration and setup\nlet _pendingLegacyKey: Buffer | null = null;\n\n/** True only when the key was loaded from RUNEYA_ENCRYPTION_KEY (CI/CD — no JWT required). */\nexport function isCiMode(): boolean {\n return _ciMode;\n}\n\n/** Load encryption key from env var (CI mode) */\nexport async function loadFromEnv(): Promise<boolean> {\n const keyHex = process.env['RUNEYA_ENCRYPTION_KEY'];\n if (!keyHex) return false;\n if (!/^[0-9a-f]{64}$/i.test(keyHex)) {\n throw new Error('RUNEYA_ENCRYPTION_KEY invalide : attendu 64 caractères hex');\n }\n console.log('');\n console.log('⚠ ATTENTION : RUNEYA_ENCRYPTION_KEY est défini — l\\'authentification par master password est désactivée.');\n console.log(' Cette variable d\\'environnement est réservée aux environnements CI/CD.');\n console.log(' Ne la définissez jamais sur une machine de développement.');\n console.log('');\n setEncryptionKeyInMemory(Buffer.from(keyHex, 'hex'));\n _ciMode = true;\n return true;\n}\n\n// ── Pending legacy key holder ──────────────────────────────────────────────\n// After legacy migration, the libsodium key is stored here (NOT in the main\n// singleton) so that hasEncryptionKey() returns false → server state = setup.\n// The key is consumed by /api/setup to write .encryption.key.enc.\n\nexport function setPendingLegacyKey(key: Buffer): void {\n if (key.length !== KEY_SIZE_BYTES) throw new Error('Taille de clé invalide');\n _pendingLegacyKey = key;\n}\n\nexport function getPendingLegacyKey(): Buffer | null {\n return _pendingLegacyKey;\n}\n\nexport function clearPendingLegacyKey(): void {\n _pendingLegacyKey = null;\n}\n\nexport function hasPendingLegacyKey(): boolean {\n return _pendingLegacyKey !== null;\n}\n\n/** Set the encryption key in memory (called after successful unlock/setup) */\nexport function setEncryptionKeyInMemory(key: Buffer, vault: string = DEFAULT_VAULT): void {\n if (key.length !== KEY_SIZE_BYTES) throw new Error('Taille de clé invalide');\n keyring.set(vault, key);\n}\n\n/** Clear the cached key (lock). Without a vault, clears the whole keyring. */\nexport function clearEncryptionKey(vault?: string): void {\n if (vault === undefined) keyring.clear();\n else keyring.delete(vault);\n}\n\nexport function hasEncryptionKey(vault: string = DEFAULT_VAULT): boolean {\n return keyring.has(vault);\n}\n\nexport function getEncryptionKey(vault: string = DEFAULT_VAULT): Buffer | null {\n return keyring.get(vault) ?? null;\n}\n\nexport function deriveStableSecret(purpose: string, vault: string = DEFAULT_VAULT): string | null {\n const key = getEncryptionKey(vault);\n if (!key) return null;\n return createHash('sha256').update(key).update(purpose).digest('hex');\n}\n\n/** Vault roots holding a loaded key — for callers that unlock several at once. */\nexport function unlockedVaults(): string[] {\n return Array.from(keyring.keys()).filter((v) => v !== DEFAULT_VAULT);\n}\n\n// Legacy compat: ensureEncryptionKey for code that still calls it\n// Returns null if key not loaded yet (LOCKED/SETUP state)\nexport async function ensureEncryptionKey(): Promise<Buffer | null> {\n return getEncryptionKey();\n}\n\n// Legacy compat: setEncryptionKey (used by old setup router)\nexport async function setEncryptionKey(keyHex: string): Promise<void> {\n if (!/^[0-9a-f]{64}$/i.test(keyHex)) throw new Error('Invalid key format');\n setEncryptionKeyInMemory(Buffer.from(keyHex, 'hex'));\n}\n","import { randomUUID } from 'node:crypto';\nimport { readFile, writeFile, rename, mkdir, chmod } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { getEncryptionKey } from '../utils/encryption-key.js';\nimport { allVaultRoots, localVaultRoot } from './vault-resolver.js';\nimport { rootOfService, ensureProjectsLoaded } from './vault-registry.js';\nimport { markVaultConflict, isVaultConflicted } from './vault-conflicts.js';\nimport { environmentStore } from './environment-store.js';\nimport { stableEncryptValue, decryptValue, isEncryptedValue } from './crypto-helpers.js';\nimport { ServiceConfigSchema } from '@runeya/packages-shared';\nimport type { ServiceConfig, CreateService, UpdateService, LogSourceConfig } from '@runeya/packages-shared';\n\nconst FILENAME = 'services.json';\n\n/**\n * Encrypt sensitive log source credentials before writing to disk.\n *\n * `previous` is the last ciphertext written for the same sources: reusing it\n * when the plaintext is unchanged keeps the output byte-stable. Without it,\n * every save re-encrypts with a fresh IV, so an untouched service still looks\n * modified — which shows up as phantom git diffs, and as an endless sync loop\n * once the file is mirrored into a CRDT (each side keeps \"changing\" it).\n */\nfunction encryptLogSources(logSources: LogSourceConfig[], previous?: LogSourceConfig[]): LogSourceConfig[] {\n return logSources.map((src, i) => {\n const prev = previous?.[i];\n if (src.type === 'mongo') {\n const was = prev?.type === 'mongo' ? prev.connectionString : undefined;\n return { ...src, connectionString: stableEncryptValue(src.connectionString, was) };\n }\n if (src.type === 'mysql' && src.password) {\n const was = prev?.type === 'mysql' ? prev.password : undefined;\n return { ...src, password: stableEncryptValue(src.password, was) };\n }\n return src;\n });\n}\n\n/** Decrypt sensitive log source credentials after reading from disk. */\nfunction decryptLogSources(logSources: LogSourceConfig[]): LogSourceConfig[] {\n return logSources.map((src) => {\n if (src.type === 'mongo' && isEncryptedValue(src.connectionString)) {\n try {\n return { ...src, connectionString: decryptValue(src.connectionString) };\n } catch {\n console.error('[service-store] Failed to decrypt mongo connectionString');\n return src;\n }\n }\n if (src.type === 'mysql' && src.password && isEncryptedValue(src.password)) {\n try {\n return { ...src, password: decryptValue(src.password) };\n } catch {\n console.error('[service-store] Failed to decrypt mysql password');\n return src;\n }\n }\n return src;\n });\n}\n\n/**\n * Prepare service for disk: strip transient env/envSecrets/resolvedLogParsers\n * fields and encrypt log source credentials. `previous` is the service's last\n * on-disk form, so unchanged credentials keep their existing ciphertext.\n */\nfunction prepareForDisk(service: ServiceConfig, previous?: ServiceConfig): ServiceConfig {\n return {\n ...service,\n env: {},\n envSecrets: [],\n resolvedLogParsers: undefined,\n resolvedCwd: undefined,\n logSources: encryptLogSources(service.logSources ?? [], previous?.logSources),\n };\n}\n\ntype ChangeListener = () => void;\n\nclass ServiceStore {\n private services: Map<string, ServiceConfig> = new Map();\n private loaded = false;\n private listeners: Set<ChangeListener> = new Set();\n /**\n * Last on-disk (encrypted) form per service id, so `prepareForDisk` can reuse\n * existing ciphertext instead of re-encrypting unchanged credentials.\n */\n private diskForm: Map<string, ServiceConfig> = new Map();\n\n onChange(fn: ChangeListener): () => void {\n this.listeners.add(fn);\n return () => this.listeners.delete(fn);\n }\n\n private notify(): void {\n for (const fn of this.listeners) fn();\n }\n\n /** Which vault each service was read from, used until its project is known. */\n private roots: Map<string, string> = new Map();\n\n private getFilePath(root: string): string {\n return join(root, FILENAME);\n }\n\n /**\n * The vault a service must be written to: the one of the project owning it.\n *\n * A service carries no project id — ownership lives in `project.serviceIds` —\n * so the registry answers, falling back to where the service was read and\n * finally to the local vault.\n */\n private rootFor(serviceId: string): string {\n // La provenance sert d'arbitre quand deux projets revendiquent le service.\n return rootOfService(serviceId, this.roots.get(serviceId) ?? null) ?? localVaultRoot();\n }\n\n /**\n * Read every vault: the launch directory and each materialized cloud project.\n *\n * Roots come from the disk, not from the project store, so services load\n * without waiting on projects.\n */\n private async load(): Promise<void> {\n if (this.loaded) return;\n if (!getEncryptionKey()) return;\n this.loaded = true;\n // Les projets d'abord : tant qu'ils sont inconnus, tout se résoudrait vers\n // le coffre de lancement et y serait réécrit à la première sauvegarde —\n // hors de l'organisation propriétaire.\n await ensureProjectsLoaded();\n\n for (const root of await allVaultRoots()) {\n try {\n const raw = await readFile(this.getFilePath(root), 'utf-8');\n const data: ServiceConfig[] = JSON.parse(raw);\n // Un coffre qui rapporte un service déjà tenu par un autre est une\n // copie du même projet dans une seconde organisation : on garde le\n // premier et on laisse le second intact plutôt que de l'écraser.\n const clash = data.find((s) => this.services.has(s.id) && this.roots.get(s.id) !== root);\n if (clash) {\n markVaultConflict(root, `service ${clash.id}`);\n continue;\n }\n for (const s of data) {\n // Ensure shell defaults to true for legacy commands stored without it\n if (s.commands) {\n for (const cmd of s.commands) {\n if (cmd.shell === undefined) cmd.shell = true;\n }\n }\n this.diskForm.set(s.id, s);\n this.services.set(s.id, {\n ...s,\n logSources: decryptLogSources(s.logSources ?? []),\n });\n this.roots.set(s.id, root);\n }\n } catch {\n // No services in this vault yet.\n }\n }\n }\n\n /**\n * Write each vault that holds — or held — a service.\n *\n * A vault emptied by this save is still written, as an empty list: a service\n * that moved to another vault must not survive in the one it left.\n */\n private async save(): Promise<void> {\n const byRoot = new Map<string, ServiceConfig[]>();\n for (const root of this.roots.values()) {\n if (!isVaultConflicted(root)) byRoot.set(root, []);\n }\n byRoot.set(localVaultRoot(), byRoot.get(localVaultRoot()) ?? []);\n\n for (const service of this.services.values()) {\n const root = this.rootFor(service.id);\n const prepared = prepareForDisk(service, this.diskForm.get(service.id));\n this.diskForm.set(prepared.id, prepared);\n this.roots.set(service.id, root);\n if (isVaultConflicted(root)) continue;\n const bucket = byRoot.get(root);\n if (bucket) bucket.push(prepared);\n else byRoot.set(root, [prepared]);\n }\n\n for (const [root, services] of byRoot) {\n await mkdir(root, { recursive: true });\n const filePath = this.getFilePath(root);\n const tmpPath = filePath + '.tmp';\n await writeFile(tmpPath, JSON.stringify(services, null, 2), 'utf-8');\n await rename(tmpPath, filePath);\n await chmod(filePath, 0o600);\n }\n }\n\n /**\n * Drop services from memory, without touching the disk.\n *\n * Used when their project stops being followed: its vault goes away whole,\n * and services left in memory would be written back on the next save — into\n * the local vault, since their owner is no longer known.\n */\n async forgetLocally(serviceIds: string[]): Promise<void> {\n await this.load();\n for (const id of serviceIds) {\n this.services.delete(id);\n this.diskForm.delete(id);\n this.roots.delete(id);\n }\n this.notify();\n }\n\n /**\n * Rewrite every vault, moving entities that now belong elsewhere.\n *\n * Called once the project store knows where projects live: entities read from\n * the launch directory whose project turns out to be a cloud one are written\n * into that project's vault, and disappear from the directory they came from.\n */\n async relocateAll(): Promise<void> {\n await this.load();\n await this.save();\n }\n\n async list(): Promise<ServiceConfig[]> {\n await this.load();\n return Array.from(this.services.values());\n }\n\n async get(id: string): Promise<ServiceConfig | null> {\n await this.load();\n return this.services.get(id) ?? null;\n }\n\n /**\n * Service in its on-disk (sanitized) form: transient runtime env and plaintext\n * secrets stripped. Used when exporting a project to the cloud so that no\n * secret ever leaves the machine.\n */\n async getSanitized(id: string): Promise<ServiceConfig | null> {\n await this.load();\n const service = this.services.get(id);\n return service ? prepareForDisk(service, this.diskForm.get(id)) : null;\n }\n\n async create(input: CreateService): Promise<ServiceConfig> {\n await this.load();\n const service: ServiceConfig = {\n id: randomUUID(),\n orgId: input.orgId ?? null,\n agentId: input.agentId,\n name: input.name,\n commands: input.commands ?? [],\n cwd: input.cwd,\n ports: input.ports ?? [],\n groups: input.groups ?? [],\n description: input.description,\n docsPath: input.docsPath,\n url: input.url,\n localUrls: input.localUrls ?? [],\n openapiUrl: input.openapiUrl,\n git: input.git,\n meta: input.meta,\n env: {},\n envSecrets: [],\n runner: input.runner ?? 'native',\n dockerConfig: input.dockerConfig,\n healthCheck: input.healthCheck,\n parserIds: input.parserIds ?? [],\n shortcuts: input.shortcuts ?? [],\n logSources: input.logSources ?? [],\n autoRestart: input.autoRestart ?? false,\n restartBackoffMs: input.restartBackoffMs ?? 1000,\n clearLogsOnStart: input.clearLogsOnStart ?? false,\n };\n this.services.set(service.id, service);\n await this.save();\n this.notify();\n return service;\n }\n\n async update(input: UpdateService): Promise<ServiceConfig | null> {\n await this.load();\n const existing = this.services.get(input.id);\n if (!existing) return null;\n const updated: ServiceConfig = {\n ...existing,\n ...(input.agentId !== undefined && { agentId: input.agentId ?? undefined }),\n ...(input.name !== undefined && { name: input.name }),\n ...(input.commands !== undefined && { commands: input.commands }),\n ...(input.cwd !== undefined && { cwd: input.cwd ?? undefined }),\n ...(input.ports !== undefined && { ports: input.ports }),\n ...(input.groups !== undefined && { groups: input.groups }),\n ...(input.description !== undefined && { description: input.description }),\n ...(input.docsPath !== undefined && { docsPath: input.docsPath }),\n ...(input.url !== undefined && { url: input.url }),\n ...(input.localUrls !== undefined && { localUrls: input.localUrls }),\n ...(input.openapiUrl !== undefined && { openapiUrl: input.openapiUrl }),\n ...(input.git !== undefined && { git: input.git ?? undefined }),\n ...(input.meta !== undefined && { meta: input.meta ?? undefined }),\n ...(input.runner !== undefined && { runner: input.runner }),\n ...(input.dockerConfig !== undefined && { dockerConfig: input.dockerConfig }),\n ...(input.healthCheck !== undefined && { healthCheck: input.healthCheck ?? undefined }),\n ...(input.autoRestart !== undefined && { autoRestart: input.autoRestart }),\n ...(input.clearLogsOnStart !== undefined && { clearLogsOnStart: input.clearLogsOnStart }),\n ...(input.restartBackoffMs !== undefined && { restartBackoffMs: input.restartBackoffMs }),\n ...(input.orgId !== undefined && { orgId: input.orgId }),\n ...(input.shortcuts !== undefined && { shortcuts: input.shortcuts }),\n ...(input.parserIds !== undefined && { parserIds: input.parserIds }),\n ...(input.logSources !== undefined && { logSources: input.logSources }),\n };\n this.services.set(input.id, updated);\n await this.save();\n this.notify();\n return updated;\n }\n\n async delete(id: string): Promise<boolean> {\n await this.load();\n if (!this.services.has(id)) return false;\n this.services.delete(id);\n await this.save();\n this.notify();\n // Clean up service-scoped environments\n await environmentStore.deleteByReference(id);\n return true;\n }\n\n // ---- Cloud sync ------------------------------------------------------\n\n /** The services of a project, in their on-disk form (what the cloud mirrors). */\n async listSanitizedByIds(ids: string[]): Promise<ServiceConfig[]> {\n await this.load();\n const out: ServiceConfig[] = [];\n for (const id of ids) {\n const service = this.services.get(id);\n if (service) out.push(prepareForDisk(service, this.diskForm.get(id)));\n }\n return out;\n }\n\n /**\n * Apply a service received from the cloud, in its on-disk form.\n *\n * Validated rather than trusted: a peer running a different version — or a\n * tampered doc — must not be able to write arbitrary shapes into\n * `services.json`. Diff-guarded against the on-disk form so re-applying an\n * identical service neither saves nor notifies (loop-safe).\n */\n async applyRemoteUpsert(id: string, fields: unknown): Promise<{ created: boolean }> {\n await this.load();\n const parsed = ServiceConfigSchema.safeParse({ ...(fields as object), id });\n if (!parsed.success) {\n console.error('[service-store] Rejected remote service %s:', id, parsed.error.message);\n return { created: false };\n }\n const incoming = parsed.data;\n const existing = this.services.get(id);\n if (existing) {\n const currentDisk = prepareForDisk(existing, this.diskForm.get(id));\n if (JSON.stringify(currentDisk) === JSON.stringify(incoming)) return { created: false };\n }\n this.diskForm.set(id, incoming);\n this.services.set(id, {\n ...incoming,\n // The doc carries the on-disk form, where credentials are ciphertext;\n // in memory they are expected in the clear, as `load()` keeps them.\n logSources: decryptLogSources(incoming.logSources ?? []),\n });\n await this.save();\n this.notify();\n return { created: !existing };\n }\n\n /** Delete a service that was removed on another peer. */\n async applyRemoteDelete(id: string): Promise<boolean> {\n await this.load();\n if (!this.services.has(id)) return false;\n this.services.delete(id);\n this.diskForm.delete(id);\n await this.save();\n this.notify();\n await environmentStore.deleteByReference(id);\n return true;\n }\n}\n\nexport const serviceStore = new ServiceStore();\n","/**\n * L'identité d'un projet, telle que le disque et le cloud la connaissent.\n *\n * Un `projectId` seul ne désigne rien : le même id peut exister dans plusieurs\n * organisations — c'est ce qui arrive dès qu'un projet est suivi par une org\n * puis par une autre, l'entrée précédente restant dans le doc de la première.\n * Ce qui place un projet sur disque est déjà le couple (`vaultFor`), donc c'est\n * le couple qui doit l'identifier partout au-dessus.\n */\n\nexport interface ProjectRef {\n id: string;\n orgId?: string | null;\n}\n\n/** Deux projets ont la même clé exactement quand ils sont le même projet. */\nexport function projectKey(ref: ProjectRef): string {\n return `${ref.orgId ?? 'local'}:${ref.id}`;\n}\n\n/**\n * Un `projectId` a désigné un projet à lui seul, et le désigne encore dans tout\n * ce qu'un projet contient : un environnement, une conversation, un override ne\n * nomment que leur projet. Tant que ces formats n'ont pas migré, la résolution\n * par id seul doit rester possible — mais elle doit échouer bruyamment quand\n * plusieurs projets répondent, plutôt que d'en élire un au hasard.\n */\nexport class AmbiguousProjectError extends Error {\n readonly code = 'AMBIGUOUS_PROJECT_ID';\n\n constructor(readonly projectId: string, readonly orgIds: (string | null)[]) {\n const where = orgIds.map((o) => o ?? 'local').join(', ');\n super(\n `Project id ${projectId} exists in several organizations (${where}). ` +\n 'Name the organization alongside the project id.',\n );\n this.name = 'AmbiguousProjectError';\n }\n}\n","import { localVaultRoot } from './vault-resolver.js';\nimport { projectKey, AmbiguousProjectError, type ProjectRef } from './project-key.js';\n\n/**\n * Which vault each entity belongs to.\n *\n * Projects know where they live — `vaultFor` derives it from their `orgId` —\n * but their contents do not: a service carries no project id (ownership lives\n * in `project.serviceIds`), and an environment only names its project. Rather\n * than have every store reach into the project store — and import its way into\n * a cycle — the project store publishes what it knows here, and the content\n * stores read it.\n *\n * Everything is keyed by the (organization, project) couple, because that is\n * what identifies a project: the same project id can exist in two organizations\n * and point at two different vaults. Contained entities still name their project\n * by id alone, so `rootOfProject` resolves that id — and refuses to guess when\n * more than one project answers to it.\n *\n * Anything unknown resolves to the local vault. That is the honest default: an\n * entity nobody claims belongs to the directory the server was launched in,\n * which is exactly where it used to live before vaults existed.\n */\n\n/** Set by the project store, so content stores can make sure it has loaded. */\nlet loadProjects: (() => Promise<void>) | null = null;\n\n/** key = `${orgId ?? 'local'}:${projectId}` */\nconst projectRoots = new Map<string, string>();\n/** The refs behind each bare project id, to spot an id that answers twice. */\nconst projectRefs = new Map<string, ProjectRef>();\n/**\n * Quels projets revendiquent chaque service.\n *\n * Un ensemble, pas un propriétaire unique : deux organisations portant le même\n * projet déclarent le même service, et retenir le dernier faisait écrire ce\n * service dans le coffre de l'autre — vidant celui d'où il venait.\n */\nconst serviceOwners = new Map<string, Set<string>>();\n\nexport function registerProjectLoader(load: () => Promise<void>): void {\n loadProjects = load;\n}\n\n/**\n * Make sure the project store has read the disk.\n *\n * Content stores call this before their own load: until projects are known,\n * every id would resolve to the local vault and cloud files would be missed.\n */\nexport async function ensureProjectsLoaded(): Promise<void> {\n await loadProjects?.();\n}\n\nexport function setProjectVault(ref: ProjectRef, root: string): void {\n const key = projectKey(ref);\n projectRoots.set(key, root);\n projectRefs.set(key, { id: ref.id, orgId: ref.orgId ?? null });\n}\n\nexport function forgetProject(ref: ProjectRef): void {\n const key = projectKey(ref);\n projectRoots.delete(key);\n projectRefs.delete(key);\n for (const [serviceId, owners] of serviceOwners) {\n owners.delete(key);\n if (owners.size === 0) serviceOwners.delete(serviceId);\n }\n}\n\n/** Record which services a project owns, replacing what it owned before. */\nexport function setProjectServices(ref: ProjectRef, serviceIds: string[]): void {\n const key = projectKey(ref);\n for (const [serviceId, owners] of serviceOwners) {\n if (!serviceIds.includes(serviceId)) {\n owners.delete(key);\n if (owners.size === 0) serviceOwners.delete(serviceId);\n }\n }\n for (const serviceId of serviceIds) {\n const owners = serviceOwners.get(serviceId) ?? new Set<string>();\n owners.add(key);\n serviceOwners.set(serviceId, owners);\n }\n}\n\n/** Where a project lives, when its organization is known. */\nexport function rootOfProjectRef(ref: ProjectRef): string {\n return projectRoots.get(projectKey(ref)) ?? localVaultRoot();\n}\n\n/** Every project registered under a bare id — one, usually. */\nexport function refsOfProjectId(projectId: string): ProjectRef[] {\n const matches: ProjectRef[] = [];\n for (const ref of projectRefs.values()) {\n if (ref.id === projectId) matches.push(ref);\n }\n return matches;\n}\n\n/**\n * Where a project lives, from its id alone.\n *\n * Throws when the id answers for two projects: picking one would write a\n * project's services into another organization's vault, which is precisely the\n * silent corruption the composite key exists to prevent.\n */\nexport function rootOfProject(projectId: string): string {\n return rootOfProjectAmong(projectId, null);\n}\n\n/**\n * Where a project lives, from its id and the vault an entity came from.\n *\n * Everything a project contains — an environment, an override, a conversation —\n * names its project by id alone, but sits inside that project's vault. When the\n * id answers for two projects, that directory says which one: it is the couple,\n * written down by the layout. Without such a hint, an ambiguous id still throws\n * rather than electing one of the two.\n */\nexport function rootOfProjectAmong(projectId: string, hint: string | null): string {\n const matches = refsOfProjectId(projectId);\n if (matches.length > 1) {\n const known = matches.map((ref) => rootOfProjectRef(ref));\n if (hint && known.includes(hint)) return hint;\n throw new AmbiguousProjectError(projectId, matches.map((r) => r.orgId ?? null));\n }\n // Aucun projet connu sous cet id : l'entité reste là où elle a été lue. La\n // renvoyer au coffre de lancement la sortirait de son organisation — ce qui\n // arrive précisément quand les projets ne sont pas encore chargés.\n const [ref] = matches;\n return ref ? rootOfProjectRef(ref) : (hint ?? localVaultRoot());\n}\n\n/** The couple behind a project id, disambiguated by the vault an entity came from. */\nexport function refOfProjectAmong(projectId: string, hint: string | null): ProjectRef {\n const matches = refsOfProjectId(projectId);\n if (matches.length > 1) {\n const found = hint ? matches.find((ref) => rootOfProjectRef(ref) === hint) : undefined;\n if (found) return found;\n throw new AmbiguousProjectError(projectId, matches.map((r) => r.orgId ?? null));\n }\n return matches[0] ?? { id: projectId, orgId: null };\n}\n\nexport function rootOfService(serviceId: string, hint: string | null = null): string {\n const owners = serviceOwners.get(serviceId);\n if (!owners || owners.size === 0) return hint ?? localVaultRoot();\n const roots = Array.from(owners, (key) => projectRoots.get(key)).filter((r): r is string => !!r);\n // Revendiqué par plusieurs projets — le même projet dans deux organisations :\n // le coffre d'où le service a été lu tranche, sinon le premier connu.\n if (hint && roots.includes(hint)) return hint;\n return roots[0] ?? hint ?? localVaultRoot();\n}\n\n/**\n * Every vault holding data, the local one first.\n *\n * Stores read all of them and write back each one they touched, so an entity\n * that moves between vaults never lingers in the one it came from.\n */\nexport function knownRoots(): string[] {\n const roots = new Set<string>([localVaultRoot()]);\n for (const root of projectRoots.values()) roots.add(root);\n return Array.from(roots);\n}\n\n/** Test seam: drop everything the registry learned. */\nexport function resetVaultRegistry(): void {\n projectRoots.clear();\n projectRefs.clear();\n serviceOwners.clear();\n loadProjects = null;\n}\n","/**\n * Les coffres dont le contenu ne peut pas être tenu en mémoire sans écraser\n * celui d'un autre.\n *\n * Deux organisations peuvent porter le même projet — même id de projet, et donc\n * les mêmes ids de services, d'environnements, de conversations, puisque le\n * second coffre est une copie du premier. Les stores de contenu, eux, indexent\n * par id d'entité : le dernier coffre lu écraserait le précédent, et la\n * sauvegarde suivante réécrirait le coffre perdant à partir de données qui ne\n * sont plus les siennes.\n *\n * Plutôt que d'élire un gagnant en silence, le coffre en second est déclaré en\n * conflit : son contenu est ignoré en mémoire, et surtout **plus jamais écrit**.\n * Les fichiers restent intacts sur le disque, prêts à servir dès que le conflit\n * est levé — en cessant de suivre l'un des deux projets.\n */\n\nconst conflicted = new Map<string, string>();\n\nexport function markVaultConflict(root: string, detail: string): void {\n if (conflicted.has(root)) return;\n conflicted.set(root, detail);\n console.error(\n '[vaults] %s partage des identifiants avec un autre coffre (%s) — ' +\n 'son contenu est ignoré et laissé intact. Cessez de suivre l\\'un des deux projets.',\n root, detail,\n );\n}\n\nexport function isVaultConflicted(root: string): boolean {\n return conflicted.has(root);\n}\n\n/** Les coffres écartés, pour un diagnostic exposable à l'utilisateur. */\nexport function conflictedVaults(): { root: string; detail: string }[] {\n return Array.from(conflicted, ([root, detail]) => ({ root, detail }));\n}\n\n/** Test seam, et relecture après qu'un projet a cessé d'être suivi. */\nexport function resetVaultConflicts(): void {\n conflicted.clear();\n}\n","import { randomUUID } from 'node:crypto';\nimport { readFile, writeFile, rename, mkdir, chmod } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { getEncryptionKey } from '../utils/encryption-key.js';\nimport { allVaultRoots, localVaultRoot, vaultFor } from './vault-resolver.js';\nimport { rootOfProjectAmong, refOfProjectAmong, ensureProjectsLoaded } from './vault-registry.js';\nimport { markVaultConflict, isVaultConflicted } from './vault-conflicts.js';\nimport type { ProjectRef } from './project-key.js';\nimport {\n encryptVariableSlots,\n decryptVariableSlots,\n extractEncryptedVariableSlots,\n} from './crypto-helpers.js';\nimport type { Environment, CreateEnvironment, UpdateEnvironment, VariableSlot } from '@runeya/packages-shared';\nimport { CreateEnvironmentSchema, EnvironmentSchema } from '@runeya/packages-shared';\n\nconst FILENAME = 'environments.json';\n\ninterface DiskEncryptedCache {\n envSlots: Record<string, string>;\n}\n\ntype ChangeListener = () => void;\n\nclass EnvironmentStore {\n private environments: Map<string, Environment> = new Map();\n private loaded = false;\n /** Cache of encrypted secret values as last written to disk */\n private diskEncryptedSlots: Map<string, DiskEncryptedCache> = new Map();\n /**\n * Les secrets qu'aucune clé chargée n'a ouverts, par environnement.\n *\n * Vides en mémoire, ils doivent repartir sur le disque sous leur forme\n * chiffrée : c'est ce que retient cette liste. Voir `keepUnreadableSecrets`.\n */\n private unreadableSecrets: Map<string, Set<string>> = new Map();\n private listeners: Set<ChangeListener> = new Set();\n\n /** Notified after every persisted mutation, for the cloud sync bridge. */\n onChange(fn: ChangeListener): () => void {\n this.listeners.add(fn);\n return () => this.listeners.delete(fn);\n }\n\n private notify(): void {\n for (const fn of this.listeners) fn();\n }\n\n /**\n * Which vault each environment was read from, so a save puts it back where it\n * belongs even before its project has been loaded.\n */\n private roots: Map<string, string> = new Map();\n\n private getFilePath(root: string): string {\n return join(root, FILENAME);\n }\n\n /**\n * The vault an environment must be written to: its project's.\n *\n * An environment names its project by id alone, and that id can answer for a\n * project in each organization. The vault it was read from names the couple —\n * so it is handed over as the tie-breaker rather than left as a mere fallback.\n *\n * Falls back to where it was last read, then to the local vault — an\n * environment whose project is unknown belongs to the launch directory, which\n * is where it lived before vaults existed.\n */\n private rootFor(environment: Environment): string {\n const known = this.roots.get(environment.id) ?? null;\n const projectRoot = environment.projectId\n ? rootOfProjectAmong(environment.projectId, known)\n : null;\n return projectRoot ?? known ?? localVaultRoot();\n }\n\n /**\n * Le projet d'un environnement, organisation comprise.\n *\n * L'environnement ne nomme que l'id ; le coffre d'où il vient fournit\n * l'organisation, et c'est ce couple qu'il faut pour agir sur son projet.\n */\n projectRefOf(environment: Environment): ProjectRef | null {\n if (!environment.projectId) return null;\n return refOfProjectAmong(environment.projectId, this.roots.get(environment.id) ?? null);\n }\n\n /**\n * The vault holding the environment that defines a variable.\n *\n * Overrides answer a variable, not a project: this is what lets them find the\n * same vault without re-resolving an id that may be ambiguous.\n */\n async rootOfVariable(variableId: string): Promise<string | null> {\n await this.load();\n for (const environment of this.environments.values()) {\n if (environment.variables && variableId in environment.variables) {\n return this.rootFor(environment);\n }\n }\n return null;\n }\n\n private extractEncryptedCache(environment: Environment): DiskEncryptedCache {\n const envSlots = extractEncryptedVariableSlots(\n environment.variables as Record<string, { value: VariableSlot }>,\n );\n return { envSlots };\n }\n\n private encryptEnvironment(environment: Environment): Environment {\n const cache = this.diskEncryptedSlots.get(environment.id);\n\n // Encrypt env variables\n let encryptedVars = environment.variables;\n if (environment.variables && Object.keys(environment.variables).length > 0) {\n encryptedVars = encryptVariableSlots(\n environment.variables as Record<string, { value: VariableSlot }>,\n cache?.envSlots,\n ) as Environment['variables'];\n }\n\n return { ...environment, variables: this.keepUnreadableSecrets(environment.id, encryptedVars) };\n }\n\n /**\n * Réécrire un secret illisible tel qu'il est sur le disque, jamais à blanc.\n *\n * Un secret qui ne s'ouvre pas est vide en mémoire (voir\n * `decryptVariableSlots`) : le chiffrer donnerait un chiffré de la chaîne\n * vide, et la sauvegarde effacerait pour de bon une valeur dont il ne\n * manquait que la clé. Son chiffré d'origine est encore là — c'est celui que\n * `diskEncryptedSlots` a mis de côté avant le déchiffrement — et c'est lui\n * qui repart sur le disque.\n *\n * La condition tient à la valeur en mémoire : tant qu'elle est vide, la\n * variable n'a pas été retouchée et son chiffré fait foi. Dès que\n * l'utilisateur en saisit une nouvelle, elle l'emporte — et vider un secret\n * volontairement reste possible, puisque cela ne concerne que les variables\n * dont le déchiffrement a échoué.\n */\n private keepUnreadableSecrets(\n environmentId: string,\n variables: Environment['variables'],\n ): Environment['variables'] {\n const failed = this.unreadableSecrets.get(environmentId);\n if (!failed?.size || !variables) return variables;\n const onDisk = this.diskEncryptedSlots.get(environmentId)?.envSlots ?? {};\n const result = { ...variables };\n for (const variableId of failed) {\n const ciphertext = onDisk[variableId];\n const variable = result[variableId];\n if (!ciphertext || !variable || variable.value.value) continue;\n result[variableId] = { ...variable, value: { ...variable.value, value: ciphertext } };\n }\n return result;\n }\n\n private decryptEnvironment(environment: Environment): Environment {\n // Decrypt env variables\n let decryptedVars = environment.variables;\n if (environment.variables && Object.keys(environment.variables).length > 0) {\n const failed = new Set<string>();\n decryptedVars = decryptVariableSlots(\n environment.variables as Record<string, { value: VariableSlot }>,\n `environment ${environment.id}`,\n (variableId) => failed.add(variableId),\n ) as Environment['variables'];\n if (failed.size > 0) this.unreadableSecrets.set(environment.id, failed);\n else this.unreadableSecrets.delete(environment.id);\n }\n\n return { ...environment, variables: decryptedVars };\n }\n\n /**\n * Read every vault — the launch directory and each materialized cloud project.\n *\n * The roots come from the disk rather than from the project store, so loading\n * environments never has to wait on projects being loaded first (the project\n * store reads environments while absorbing a project, which would deadlock).\n */\n private async load(): Promise<void> {\n if (this.loaded) return;\n this.loaded = true;\n // Les projets d'abord : tant qu'ils sont inconnus, chaque environnement\n // résoudrait vers le coffre de lancement et y serait réécrit à la première\n // sauvegarde — hors de son organisation.\n await ensureProjectsLoaded();\n if (!getEncryptionKey()) {\n // Locked: nothing can be decrypted, and marking the store loaded with\n // half the data would hide the rest until a restart.\n this.loaded = false;\n return;\n }\n for (const root of await allVaultRoots()) {\n try {\n const raw = await readFile(this.getFilePath(root), 'utf-8');\n const data: Environment[] = JSON.parse(raw);\n const clash = data.find((e) => this.environments.has(e.id) && this.roots.get(e.id) !== root);\n if (clash) {\n markVaultConflict(root, `environnement ${clash.id}`);\n continue;\n }\n for (const e of data) {\n // Cache encrypted slots before decrypting\n this.diskEncryptedSlots.set(e.id, this.extractEncryptedCache(e));\n const decrypted = this.decryptEnvironment(e);\n this.environments.set(e.id, decrypted);\n this.roots.set(e.id, root);\n }\n } catch {\n // No environments in this vault yet.\n }\n }\n }\n\n /**\n * Write each vault that holds — or held — an environment.\n *\n * Vaults emptied by this save are still written, as an empty list: an\n * environment that moved to another vault must not survive in the old one.\n */\n private async save(): Promise<void> {\n const byRoot = new Map<string, Environment[]>();\n // Every vault seen so far starts empty, so one that lost its last\n // environment is rewritten rather than left behind — sauf un coffre en\n // conflit, dont le contenu n'est pas à nous.\n for (const root of this.roots.values()) {\n if (!isVaultConflicted(root)) byRoot.set(root, []);\n }\n byRoot.set(localVaultRoot(), byRoot.get(localVaultRoot()) ?? []);\n\n for (const environment of this.environments.values()) {\n const root = this.rootFor(environment);\n const prepared = this.encryptEnvironment(environment);\n // Update disk cache with newly written encrypted values\n this.diskEncryptedSlots.set(prepared.id, this.extractEncryptedCache(prepared));\n this.roots.set(environment.id, root);\n if (isVaultConflicted(root)) continue;\n const bucket = byRoot.get(root);\n if (bucket) bucket.push(prepared);\n else byRoot.set(root, [prepared]);\n }\n\n for (const [root, environments] of byRoot) {\n await mkdir(root, { recursive: true });\n const filePath = this.getFilePath(root);\n const tmpPath = filePath + '.tmp';\n await writeFile(tmpPath, JSON.stringify(environments, null, 2), 'utf-8');\n await rename(tmpPath, filePath);\n await chmod(filePath, 0o600);\n }\n this.notify();\n }\n\n /**\n * Rewrite every vault, moving entities that now belong elsewhere.\n *\n * Called once the project store knows where projects live: entities read from\n * the launch directory whose project turns out to be a cloud one are written\n * into that project's vault, and disappear from the directory they came from.\n */\n async relocateAll(): Promise<void> {\n await this.load();\n await this.save();\n }\n\n /**\n * Which project a variable belongs to, by walking the environments that\n * define it.\n *\n * Overrides are keyed by variable id alone — nothing in an override says\n * which project it belongs to — so this is what lets them be stored with\n * their project rather than in one machine-wide pile.\n */\n /**\n * Drop a project's environments from memory, without touching the disk.\n *\n * Used when a project stops being followed: its vault is removed as a whole,\n * and environments left in memory would be written back on the next save —\n * into the local vault, since their project is no longer known.\n */\n async forgetByProject(projectId: string): Promise<void> {\n await this.load();\n for (const [id, environment] of this.environments) {\n if (environment.projectId !== projectId) continue;\n this.environments.delete(id);\n this.diskEncryptedSlots.delete(id);\n this.unreadableSecrets.delete(id);\n this.roots.delete(id);\n }\n this.notify();\n }\n\n /**\n * Les environnements d'un projet.\n *\n * `orgId` restreint au projet de cette organisation : deux projets homonymes\n * ont chacun les siens, et filtrer sur le seul `projectId` mélangeait les deux\n * listes à l'écran. Omis, le filtre reste sur l'id — ce que fait un appelant\n * qui n'a pas d'organisation à donner.\n */\n async list(projectId: string, orgId?: string | null): Promise<Environment[]> {\n await this.load();\n return this.ofProject(projectId, orgId);\n }\n\n /** Le filtre commun : l'id, puis le coffre quand l'organisation est connue. */\n private ofProject(projectId: string, orgId?: string | null): Environment[] {\n const byId = Array.from(this.environments.values()).filter(e => e.projectId === projectId);\n if (orgId === undefined) return byId;\n const root = vaultFor({ id: projectId, orgId }).root;\n return byId.filter(e => this.rootFor(e) === root);\n }\n\n async get(id: string): Promise<Environment | null> {\n await this.load();\n return this.environments.get(id) ?? null;\n }\n\n /**\n * `orgId` ne fait pas partie de l'environnement : il dit dans quel coffre le\n * poser. Un environnement neuf n'a pas encore de provenance, et son\n * `projectId` seul peut répondre pour un projet de chaque organisation — sans\n * cette précision, la création échouerait sur l'ambiguïté au lieu de viser le\n * bon coffre.\n */\n async create(input: CreateEnvironment, orgId?: string | null): Promise<Environment> {\n await this.load();\n const parsed = CreateEnvironmentSchema.parse(input);\n const environment: Environment = {\n id: randomUUID(),\n projectId: parsed.projectId,\n name: parsed.name,\n description: parsed.description,\n parentIds: parsed.parentIds,\n variables: parsed.variables,\n scope: parsed.scope,\n reference: parsed.reference,\n activateOn: parsed.activateOn,\n immutable: parsed.immutable,\n default: parsed.default,\n color: parsed.color,\n bgColor: parsed.bgColor,\n agentId: parsed.agentId,\n };\n // Exclusivity: if this env is default, unset default on all others in the same project\n if (environment.default) {\n for (const [id, e] of this.environments) {\n if (e.projectId === environment.projectId && e.default) {\n this.environments.set(id, { ...e, default: false });\n }\n }\n }\n this.environments.set(environment.id, environment);\n if (environment.projectId && orgId !== undefined) {\n this.roots.set(environment.id, vaultFor({ id: environment.projectId, orgId }).root);\n }\n await this.save();\n return environment;\n }\n\n async update(input: UpdateEnvironment): Promise<Environment | null> {\n await this.load();\n const existing = this.environments.get(input.id);\n if (!existing) return null;\n const updated: Environment = {\n ...existing,\n // Immutable environments: allow changing variables, color, description — but not name\n ...(!existing.immutable && input.name !== undefined && { name: input.name }),\n ...(input.description !== undefined && { description: input.description }),\n ...(input.parentIds !== undefined && { parentIds: input.parentIds }),\n ...(input.variables !== undefined && { variables: input.variables }),\n ...(input.scope !== undefined && { scope: input.scope }),\n ...(input.reference !== undefined && { reference: input.reference }),\n ...(input.activateOn !== undefined && { activateOn: input.activateOn }),\n ...(input.color !== undefined && { color: input.color }),\n ...(input.bgColor !== undefined && { bgColor: input.bgColor }),\n ...(input.default !== undefined && { default: input.default }),\n ...(input.agentId !== undefined && { agentId: input.agentId ?? undefined }),\n };\n // Exclusivity: if setting default: true, unset default on all others in the same project\n if (updated.default) {\n for (const [id, e] of this.environments) {\n if (id !== input.id && e.projectId === updated.projectId && e.default) {\n this.environments.set(id, { ...e, default: false });\n }\n }\n }\n this.environments.set(input.id, updated);\n await this.save();\n return updated;\n }\n\n async upsertVariable(environmentId: string, variableId: string, variable: Environment['variables'][string]): Promise<Environment | null> {\n const existing = this.environments.get(environmentId);\n if (!existing) return null;\n const variables = { ...existing.variables, [variableId]: variable };\n return this.update({ id: environmentId, variables });\n }\n\n async removeVariable(environmentId: string, variableId: string): Promise<Environment | null> {\n const existing = this.environments.get(environmentId);\n if (!existing) return null;\n const variables = { ...existing.variables };\n delete variables[variableId];\n return this.update({ id: environmentId, variables });\n }\n\n async delete(id: string): Promise<boolean> {\n await this.load();\n const env = this.environments.get(id);\n if (!env) return false;\n if (env.immutable) return false; // Can't delete immutable environments\n this.environments.delete(id);\n await this.save();\n return true;\n }\n\n async getByProjectId(projectId: string, orgId?: string | null): Promise<Environment[]> {\n await this.load();\n return this.ofProject(projectId, orgId);\n }\n\n async listAllGlobal(): Promise<Environment[]> {\n await this.load();\n return Array.from(this.environments.values()).filter(e => e.scope === 'global');\n }\n\n // --- Scope-based Query Methods ---\n\n async listByScope(\n projectId: string, scope: 'global' | 'service', orgId?: string | null,\n ): Promise<Environment[]> {\n await this.load();\n return this.ofProject(projectId, orgId).filter(e => e.scope === scope);\n }\n\n async findServiceEnvironment(serviceId: string, globalEnvId: string): Promise<Environment | null> {\n await this.load();\n for (const e of this.environments.values()) {\n if (e.scope === 'service' && e.reference === serviceId && e.activateOn === globalEnvId) return e;\n }\n return null;\n }\n\n async findServiceEnvironments(serviceId: string): Promise<Environment[]> {\n await this.load();\n return Array.from(this.environments.values()).filter(e => e.scope === 'service' && e.reference === serviceId);\n }\n\n async deleteByReference(serviceId: string): Promise<void> {\n await this.load();\n let changed = false;\n for (const [id, e] of this.environments) {\n if (e.scope === 'service' && e.reference === serviceId) {\n this.environments.delete(id);\n changed = true;\n }\n }\n if (changed) await this.save();\n }\n\n async deleteByActivateOn(globalEnvId: string): Promise<void> {\n await this.load();\n let changed = false;\n for (const [id, e] of this.environments) {\n if (e.scope === 'service' && e.activateOn === globalEnvId) {\n this.environments.delete(id);\n changed = true;\n }\n }\n if (changed) await this.save();\n }\n\n /**\n * When a service is renamed, update the name of all its service-scoped environments\n * to keep the `${serviceName} (${globalEnvName})` pattern in sync.\n */\n async renameByReference(serviceId: string, newServiceName: string): Promise<void> {\n await this.load();\n let changed = false;\n for (const [id, e] of this.environments) {\n if (e.scope === 'service' && e.reference === serviceId && e.activateOn) {\n const globalEnv = this.environments.get(e.activateOn);\n if (!globalEnv) continue;\n this.environments.set(id, { ...e, name: `${newServiceName} (${globalEnv.name})` });\n changed = true;\n }\n }\n if (changed) await this.save();\n }\n\n /**\n * When a global environment is renamed, update the name of all service-scoped\n * environments that activateOn it to keep the naming pattern in sync.\n * Caller provides a serviceId→name map since environmentStore can't access serviceStore.\n */\n async renameByActivateOn(globalEnvId: string, newGlobalName: string, serviceNames: Map<string, string>): Promise<void> {\n await this.load();\n let changed = false;\n for (const [id, e] of this.environments) {\n if (e.scope === 'service' && e.activateOn === globalEnvId && e.reference) {\n const serviceName = serviceNames.get(e.reference);\n if (!serviceName) continue;\n this.environments.set(id, { ...e, name: `${serviceName} (${newGlobalName})` });\n changed = true;\n }\n }\n if (changed) await this.save();\n }\n\n // ---- Cloud sync ------------------------------------------------------\n\n /** Environments of the given projects, in their on-disk (encrypted) form. */\n async listEncryptedByProjectIds(projectIds: string[]): Promise<Environment[]> {\n await this.load();\n const wanted = new Set(projectIds);\n return Array.from(this.environments.values())\n .filter((e) => wanted.has(e.projectId))\n .map((e) => this.encryptEnvironment(e));\n }\n\n /**\n * Apply an environment received from the cloud, in its on-disk form.\n *\n * Validated rather than trusted, and diff-guarded against the on-disk form so\n * re-applying an identical environment neither saves nor notifies (loop-safe).\n */\n async applyRemoteUpsert(id: string, fields: unknown): Promise<{ created: boolean }> {\n await this.load();\n const parsed = EnvironmentSchema.safeParse({ ...(fields as object), id });\n if (!parsed.success) {\n console.error('[environment-store] Rejected remote environment %s:', id, parsed.error.message);\n return { created: false };\n }\n const incoming = parsed.data;\n const existing = this.environments.get(id);\n if (existing && JSON.stringify(this.encryptEnvironment(existing)) === JSON.stringify(incoming)) {\n return { created: false };\n }\n this.diskEncryptedSlots.set(id, this.extractEncryptedCache(incoming));\n // The doc carries ciphertext for secret slots; in memory they are expected\n // in the clear, as `load()` keeps them.\n this.environments.set(id, this.decryptEnvironment(incoming));\n await this.save();\n return { created: !existing };\n }\n\n /** Delete an environment that was removed on another peer. */\n async applyRemoteDelete(id: string): Promise<boolean> {\n await this.load();\n if (!this.environments.has(id)) return false;\n this.environments.delete(id);\n this.diskEncryptedSlots.delete(id);\n this.unreadableSecrets.delete(id);\n await this.save();\n return true;\n }\n}\n\nexport const environmentStore = new EnvironmentStore();\n","import { randomBytes, createCipheriv, createDecipheriv } from 'node:crypto';\nimport { getEncryptionKey } from '../utils/encryption-key.js';\nimport type { VariableSlot } from '@runeya/packages-shared';\n\nconst ALGORITHM = 'aes-256-gcm';\n\n/**\n * Encrypt under a caller-supplied key.\n *\n * The no-key forms below read the process keyring, which is the right default\n * everywhere except migration: converting a vault means holding two keys at\n * once, and neither of them is \"the\" current one.\n */\nexport function encryptValueWith(key: Buffer, plaintext: string): string {\n const iv = randomBytes(16);\n const cipher = createCipheriv(ALGORITHM, key, iv);\n let enc = cipher.update(plaintext, 'utf-8', 'hex');\n enc += cipher.final('hex');\n const authTag = cipher.getAuthTag().toString('hex');\n return `${iv.toString('hex')}:${authTag}:${enc}`;\n}\n\n/** Decrypt under a caller-supplied key. Throws when the key does not open it. */\nexport function decryptValueWith(key: Buffer, encrypted: string): string {\n const parts = encrypted.split(':');\n if (parts.length !== 3) throw new Error('Invalid encrypted value format — expected iv:authTag:ciphertext');\n const [ivHex, authTagHex, ciphertext] = parts;\n if (!/^[0-9a-f]+$/i.test(ivHex) || !/^[0-9a-f]+$/i.test(authTagHex) || (ciphertext !== '' && !/^[0-9a-f]+$/i.test(ciphertext))) {\n throw new Error('Invalid hex in encrypted value — possible data corruption');\n }\n const decipher = createDecipheriv(ALGORITHM, key, Buffer.from(ivHex, 'hex'), { authTagLength: 16 });\n decipher.setAuthTag(Buffer.from(authTagHex, 'hex'));\n let dec = decipher.update(ciphertext, 'hex', 'utf-8');\n dec += decipher.final('utf-8');\n return dec;\n}\n\nexport function encryptValue(plaintext: string): string {\n const maybeKey = getEncryptionKey();\n if (!maybeKey) {\n throw new Error('Encryption key not loaded — please provide the key via setup UI');\n }\n const key: Buffer = maybeKey;\n const iv = randomBytes(16);\n const cipher = createCipheriv(ALGORITHM, key, iv);\n let enc = cipher.update(plaintext, 'utf-8', 'hex');\n enc += cipher.final('hex');\n const authTag = cipher.getAuthTag().toString('hex');\n return `${iv.toString('hex')}:${authTag}:${enc}`;\n}\n\nexport function decryptValue(encrypted: string): string {\n const parts = encrypted.split(':');\n if (parts.length !== 3) throw new Error('Invalid encrypted value format — expected iv:authTag:ciphertext');\n const [ivHex, authTagHex, ciphertext] = parts;\n if (!/^[0-9a-f]+$/i.test(ivHex) || !/^[0-9a-f]+$/i.test(authTagHex) || (ciphertext !== '' && !/^[0-9a-f]+$/i.test(ciphertext))) {\n throw new Error('Invalid hex in encrypted value — possible data corruption');\n }\n const maybeKey = getEncryptionKey();\n if (!maybeKey) {\n throw new Error('Encryption key not loaded — please provide the key via setup UI');\n }\n const key: Buffer = maybeKey;\n const iv = Buffer.from(ivHex, 'hex');\n const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: 16 });\n decipher.setAuthTag(Buffer.from(authTagHex, 'hex'));\n let dec = decipher.update(ciphertext, 'hex', 'utf-8');\n dec += decipher.final('utf-8');\n return dec;\n}\n\n/** Reuse existing ciphertext if plaintext is unchanged — keeps diffs stable */\nexport function stableEncryptValue(plaintext: string, existingEncrypted?: string): string {\n if (existingEncrypted) {\n try {\n if (decryptValue(existingEncrypted) === plaintext) return existingEncrypted;\n } catch {\n // Existing value is corrupt — fall through to re-encrypt\n }\n }\n return encryptValue(plaintext);\n}\n\ntype HasValueSlot = { value: VariableSlot; [k: string]: unknown };\n\n/** Encrypt secret Variable.value slots (environment variables — {value: VariableSlot}) */\nexport function encryptVariableSlots(\n variables: Record<string, HasValueSlot>,\n existingEncrypted?: Record<string, string>,\n): Record<string, HasValueSlot> {\n const result: Record<string, HasValueSlot> = {};\n for (const [key, variable] of Object.entries(variables)) {\n const slot = variable.value;\n if (slot.isSecret && slot.value) {\n result[key] = { ...variable, value: { ...slot, value: stableEncryptValue(slot.value, existingEncrypted?.[key]) } };\n } else {\n result[key] = { ...variable, value: { ...slot } };\n }\n }\n return result;\n}\n\n/**\n * Decrypt secret Variable.value slots (environment variables).\n *\n * A value that does not open becomes a blank *in memory* — nothing downstream\n * can be handed a ciphertext as if it were a secret. But a blank in memory is\n * one save away from a blank on disk, which destroys the only copy of a secret\n * whose key is merely absent (a vault read under another key, a key not loaded\n * yet). `onFailure` is how the caller learns which slots must keep their\n * on-disk form no matter what memory says.\n */\nexport function decryptVariableSlots(\n variables: Record<string, HasValueSlot>,\n contextLabel: string,\n onFailure?: (key: string) => void,\n): Record<string, HasValueSlot> {\n const result: Record<string, HasValueSlot> = {};\n for (const [key, variable] of Object.entries(variables)) {\n const slot = variable.value;\n if (slot.isSecret && slot.value) {\n try {\n result[key] = { ...variable, value: { ...slot, value: decryptValue(slot.value) } };\n } catch (err) {\n console.error(`[crypto-helpers] Failed to decrypt variable \"${key}\" for ${contextLabel}: ${(err as Error).message} — la valeur chiffrée est conservée telle quelle sur le disque`);\n onFailure?.(key);\n result[key] = { ...variable, value: { ...slot, value: '' } };\n }\n } else {\n result[key] = { ...variable, value: { ...slot } };\n }\n }\n return result;\n}\n\n/** Extract encrypted slot values from Variable records (for stable-encrypt cache) */\nexport function extractEncryptedVariableSlots(\n variables: Record<string, HasValueSlot>,\n): Record<string, string> {\n const slots: Record<string, string> = {};\n for (const [key, variable] of Object.entries(variables)) {\n if (variable.value?.isSecret && variable.value?.value) {\n slots[key] = variable.value.value;\n }\n }\n return slots;\n}\n\n/**\n * Returns true if `s` looks like a value encrypted by `encryptValue()`.\n * Format: `<32hex>:<32hex>:<Nhex>` (iv:authTag:ciphertext).\n */\nexport function isEncryptedValue(s: string): boolean {\n const parts = s.split(':');\n return parts.length === 3 && /^[0-9a-f]{32}$/i.test(parts[0]) && /^[0-9a-f]{32}$/i.test(parts[1]);\n}\n","import { z } from 'zod';\n\nexport const UserSchema = z.object({\n id: z.string().max(128),\n email: z.string().email().max(320),\n name: z.string().min(1).max(500),\n avatar: z.string().url().max(2048).nullable().optional(),\n});\n\nexport type User = z.infer<typeof UserSchema>;\n","import { z } from 'zod';\n\nexport const OrgSchema = z.object({\n id: z.string().max(128),\n name: z.string().min(1).max(100),\n slug: z.string().min(1).max(100).regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/),\n ownerId: z.string().max(128),\n});\n\nexport type Org = z.infer<typeof OrgSchema>;\n\nexport const OrgMemberSchema = z.object({\n id: z.string().max(128),\n orgId: z.string().max(128),\n userId: z.string().max(128),\n globalRole: z.enum(['owner', 'admin', 'member']),\n invitedAt: z.coerce.date(),\n joinedAt: z.coerce.date().nullable().optional(),\n});\n\nexport type OrgMember = z.infer<typeof OrgMemberSchema>;\n","import { z } from 'zod';\n\nexport const ProjectSchema = z.object({\n id: z.string().max(128),\n orgId: z.string().max(128).nullable().optional(),\n name: z.string().min(1).max(200),\n description: z.string().max(10000).optional().default(''),\n serviceIds: z.array(z.string().max(128)).max(10000).default([]),\n\n // Environment support\n // NOTE: activeEnvironmentId is runtime-only (not persisted to JSON)\n // It's initialized to 'local' by default at load time\n activeEnvironmentId: z.string().max(128).optional(),\n environmentIds: z.array(z.string().max(128)).max(100).default([]),\n\n // Ordre d'affichage des groupes de services dans la sidebar (noms de groupes).\n // Les groupes absents de cette liste sont affichés après, par ordre alphabétique.\n groupOrder: z.array(z.string().max(200)).max(100).default([]),\n});\n\nexport type Project = z.infer<typeof ProjectSchema>;\n\nexport const CreateProjectSchema = ProjectSchema.omit({ id: true }).partial().required({ name: true });\nexport type CreateProject = z.infer<typeof CreateProjectSchema>;\n\nexport const UpdateProjectSchema = ProjectSchema.partial().required({ id: true });\nexport type UpdateProject = z.infer<typeof UpdateProjectSchema>;\n","import { z } from 'zod';\nimport { JSLogParserSchema } from './settings.schema.js';\nimport { LogSourceConfigSchema } from './log-source.schema.js';\n\nexport const HealthCheckSchema = z.object({\n type: z.enum(['http', 'command']).default('http'),\n // HTTP-specific (required when type=http)\n path: z.string().min(1).max(500).startsWith('/').optional(),\n method: z.enum(['GET', 'HEAD', 'POST', 'PUT']).optional().default('GET'),\n expectedStatus: z.number().int().min(100).max(599).optional().default(200),\n // Command-specific (required when type=command)\n command: z.string().min(1).max(4096).optional(),\n // Shared\n interval: z.number().int().positive().default(1000),\n timeout: z.number().int().positive().default(1000),\n retries: z.number().int().nonnegative().default(3),\n initialDelay: z.number().int().nonnegative().optional().default(0),\n}).refine(\n (data) => data.type === 'http' ? !!data.path : !!data.command,\n { message: 'HTTP type requires path; command type requires command' },\n);\n\nexport type HealthCheck = z.infer<typeof HealthCheckSchema>;\n\nexport const BootstrapCommandSchema = z.object({\n id: z.string().min(1).max(64),\n label: z.string().max(200).default(''),\n entrypoint: z.string().max(4096).optional(),\n command: z.string().max(4096).default(''),\n user: z.string().max(256).optional(),\n});\n\nexport type BootstrapCommand = z.infer<typeof BootstrapCommandSchema>;\n\nexport const DockerConfigSchema = z.object({\n // Image mode (pull from registry) — mutually exclusive with build mode in UI\n image: z.string().min(1).max(1024).optional(),\n\n // Build mode — Dockerfile stored inline in services.json\n dockerfile: z.string().max(65536).optional(),\n buildContext: z.string().max(4096).optional(),\n buildArgs: z.record(z.string().max(256), z.string().max(4096)).default({}).refine(\n (obj) => Object.keys(obj).length <= 50,\n { message: 'Max 50 build args' },\n ),\n targetStage: z.string().max(256).optional(),\n\n // Runtime config\n networkMode: z.enum(['host', 'bridge']).default('host'),\n ports: z.array(z.string().max(64)).max(100).default([]),\n volumes: z.array(z.string().max(1024)).max(100).default([]),\n mountRootpath: z.boolean().default(false),\n entrypoint: z.string().max(4096).optional(),\n command: z.string().max(4096).optional(),\n user: z.string().max(256).optional(),\n useNativeCommand: z.boolean().default(false),\n nativeCommandMode: z.enum(['shared', 'isolated']).default('isolated'),\n nativeShell: z.string().max(256).default('sh'),\n bootstrapCommands: z.array(BootstrapCommandSchema).max(20).default([]),\n});\n\nexport type DockerConfig = z.infer<typeof DockerConfigSchema>;\n\nexport const RestartStrategySchema = z.enum(['none', 'on-failure', 'always', 'unless-stopped']).default('none');\nexport type RestartStrategy = z.infer<typeof RestartStrategySchema>;\n\nexport const ServiceShortcutSchema = z.object({\n id: z.string().min(1).max(64),\n label: z.string().max(200).default(''),\n command: z.string().max(4096).default(''),\n cwd: z.string().max(4096).optional(),\n});\n\nexport type ServiceShortcut = z.infer<typeof ServiceShortcutSchema>;\n\nexport const ServiceCommandSchema = z.object({\n id: z.string().min(1).max(64),\n label: z.string().max(200).default(''),\n command: z.string().max(4096).default(''),\n cwd: z.string().max(4096).optional(),\n shell: z.boolean().optional().default(true),\n});\n\nexport type ServiceCommand = z.infer<typeof ServiceCommandSchema>;\n\n// --- Variable Slot Schema ---\n// A VariableSlot represents a single value with optional pre/post concatenation.\n// The final resolved value is: pre + interpolate(value) + post\nexport const VariableSlotSchema = z.object({\n value: z.string().max(8192).default(''),\n pre: z.string().max(8192).default(''),\n post: z.string().max(8192).default(''),\n isSecret: z.boolean().default(false),\n // When true, this variable is injected into the process environment of AI\n // agents (Claude Code, Codex, …) spawned while this environment is active.\n // Opt-in: defaults to false so secrets are never leaked to AI agents by default.\n injectIntoAi: z.boolean().default(false),\n});\n\nexport type VariableSlot = z.infer<typeof VariableSlotSchema>;\n\n// A Variable has a key (env var name) and a value slot.\nexport const VariableSchema = z.object({\n key: z.string().min(1).max(256),\n value: VariableSlotSchema,\n});\n\nexport type Variable = z.infer<typeof VariableSchema>;\n\n// Record of variableId → Variable. Max 200 entries.\n// The key is a unique variable ID (UUID), the Variable contains the env var name in `key`.\nexport const VariablesRecordSchema = z.record(\n z.string().max(128),\n VariableSchema,\n).refine(\n (obj) => Object.keys(obj).length <= 200,\n { message: 'Max 200 variables' },\n);\n\nexport type VariablesRecord = z.infer<typeof VariablesRecordSchema>;\n\n// Record of variable name → VariableSlot (used on disk for base values and overrides separately)\nexport const VariableSlotsRecordSchema = z.record(\n z.string().max(256),\n VariableSlotSchema,\n).refine(\n (obj) => Object.keys(obj).length <= 200,\n { message: 'Max 200 variable slots' },\n);\n\nexport type VariableSlotsRecord = z.infer<typeof VariableSlotsRecordSchema>;\n\nexport const ServiceConfigSchema = z.object({\n id: z.string().max(128),\n orgId: z.string().max(128).nullable().optional(),\n agentId: z.string().max(128).optional(), // Optional: if absent, inherited from active environment's agentId\n name: z.string().min(1).max(200),\n commands: z.array(ServiceCommandSchema).max(50).optional().default([]),\n cwd: z.string().max(4096).optional(),\n ports: z.array(z.number().int().positive().max(65535)).max(20).optional().default([]),\n\n // Metadata fields (migration from old Runeya)\n groups: z.array(z.string().max(200)).max(20).optional().default([]),\n description: z.string().max(2000).optional(),\n /** Path (relative to service.cwd or absolute) where the service's docs/wiki markdown files live. Optional — defaults to service.cwd. */\n docsPath: z.string().max(4096).optional(),\n url: z.string().max(2048).optional(),\n localUrls: z.array(z.object({\n url: z.string().max(253).regex(/^([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]{2,}$/),\n port: z.number().int().min(1).max(65535),\n })).max(20).optional().default([]),\n openapiUrl: z.string().max(2048).optional(),\n git: z.object({\n remote: z.string().max(2048).optional(),\n home: z.string().max(2048).optional(),\n }).optional(),\n meta: z.record(z.string().max(256), z.string().max(2000)).optional()\n .refine((obj) => !obj || Object.keys(obj).length <= 100, { message: 'Too many meta keys (max 100)' }),\n\n // Transient env dict (resolved by server before deployment, used directly by agent runner — NOT persisted)\n env: z.record(z.string().max(256), z.string().max(8192)).default({}).refine(\n (obj) => Object.keys(obj).length <= 200,\n { message: 'Too many env vars (max 200)' },\n ),\n envSecrets: z.array(z.string().max(256)).max(200).default([]),\n\n // Transient: resolved JS log parsers (from parserIds, resolved by server before deployment — NOT persisted)\n resolvedLogParsers: z.array(JSLogParserSchema).default([]).optional(),\n\n // Transient: resolved working directory (cwd with env vars expanded — NOT persisted)\n resolvedCwd: z.string().optional(),\n\n runner: z.enum(['native', 'docker']).optional().default('native'),\n dockerConfig: DockerConfigSchema.optional(),\n healthCheck: HealthCheckSchema.optional(),\n parserIds: z.array(z.string().max(128)).max(50).default([]),\n shortcuts: z.array(ServiceShortcutSchema).max(50).optional().default([]),\n autoRestart: z.boolean().optional().default(false),\n clearLogsOnStart: z.boolean().optional().default(false),\n restartStrategy: RestartStrategySchema.optional(),\n maxRestarts: z.number().int().nonnegative().optional(),\n restartBackoffMs: z.number().int().positive().optional().default(1000),\n\n // Log sources additionnelles (au-delà du stdout/stderr console par défaut)\n logSources: z.array(LogSourceConfigSchema).max(20).optional().default([]),\n});\n\nexport type ServiceConfig = z.infer<typeof ServiceConfigSchema>;\n\nexport const CreateServiceSchema = ServiceConfigSchema.omit({ id: true }).partial().required({ name: true });\nexport type CreateService = z.infer<typeof CreateServiceSchema>;\n\nexport const UpdateServiceSchema = ServiceConfigSchema.partial().required({ id: true }).extend({\n agentId: z.string().max(128).nullable().optional(), // null = clear (inherit from env), undefined = no change\n cwd: z.string().max(4096).nullable().optional(),\n git: z.object({ remote: z.string().max(2048).optional(), home: z.string().max(2048).optional() }).nullable().optional(),\n meta: z.record(z.string().max(256), z.string().max(2000)).nullable().optional()\n .refine((obj) => !obj || Object.keys(obj).length <= 100, { message: 'Too many meta keys (max 100)' }),\n healthCheck: HealthCheckSchema.nullable().optional(),\n});\nexport type UpdateService = z.infer<typeof UpdateServiceSchema>;\n","import { z } from 'zod';\nimport { ScenarioSchema } from './scenario.schema.js';\n\nexport const AI_PROVIDERS = ['anthropic', 'openai', 'mistral', 'groq', 'ollama'] as const;\nexport type AIProviderType = (typeof AI_PROVIDERS)[number];\n\nexport const AIProviderSchema = z.object({\n id: z.string().min(1).max(128),\n name: z.string().min(1).max(200),\n provider: z.enum(AI_PROVIDERS),\n encryptedApiKey: z.string().max(2000).default(''),\n model: z.string().max(200).optional(),\n active: z.boolean().default(false),\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n});\n\nexport type AIProvider = z.infer<typeof AIProviderSchema>;\n\nexport const JSLogParserSchema = z.object({\n id: z.string().min(1).max(128),\n name: z.string().min(1).max(200),\n description: z.string().max(2000).optional(),\n code: z.string().min(1).max(50000).refine(\n (s) => !s.includes('require(') && !s.includes('import ') && !s.includes('eval('),\n { message: 'Code must not contain require, import, or eval patterns' }\n ),\n enabled: z.boolean().default(true),\n builtin: z.boolean().optional(),\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n});\n\nexport type JSLogParser = z.infer<typeof JSLogParserSchema>;\n\nexport const NOTIFICATION_CATEGORIES = [\n 'scenario_waiting_input',\n 'ai_conversation_complete',\n 'ai_conversation_error',\n 'service_error_log',\n 'service_status_changed',\n 'service_health_changed',\n] as const;\nexport type NotificationCategory = (typeof NOTIFICATION_CATEGORIES)[number];\n\nexport const NotificationPreferencesSchema = z.object({\n scenario_waiting_input: z.boolean().default(true),\n ai_conversation_complete: z.boolean().default(true),\n ai_conversation_error: z.boolean().default(true),\n service_error_log: z.boolean().default(true),\n service_status_changed: z.boolean().default(true),\n service_health_changed: z.boolean().default(true),\n /** Service IDs excluded from error-log notifications */\n service_error_log_excluded: z.array(z.string().max(100)).max(500).default([]),\n /** Service IDs excluded from status-change notifications */\n service_status_changed_excluded: z.array(z.string().max(100)).max(500).default([]),\n /** Service IDs excluded from health-change notifications */\n service_health_changed_excluded: z.array(z.string().max(100)).max(500).default([]),\n});\nexport type NotificationPreferences = z.infer<typeof NotificationPreferencesSchema>;\n\nexport const SettingsSchema = z.object({\n mode: z.enum(['local-simple', 'cloud']),\n cloudUrl: z.string().url().max(2048).nullable().optional(),\n logParsers: z.array(JSLogParserSchema).max(100).default([]),\n scenarios: z.array(ScenarioSchema).max(100).default([]),\n /** Absolute path to the folder where the global wiki/docs markdown files live. Optional. */\n globalDocsPath: z.string().max(4096).optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n\n\nexport const TraefikConfigSchema = z.object({\n enabled: z.boolean().default(false),\n acmeEmail: z.string().email().max(256).optional(),\n wildcardDomain: z.string().max(253).optional(),\n httpPort: z.number().int().min(1).max(65535).default(80),\n httpsPort: z.number().int().min(1).max(65535).default(443),\n dnsProvider: z.string().max(64).optional(),\n dnsCredentials: z.record(z.string().max(64), z.string().max(2048)).default({}),\n acmeStaging: z.boolean().default(false),\n encryptedCert: z.string().max(65536).optional(),\n encryptedCertKey: z.string().max(65536).optional(),\n});\n\nexport type TraefikConfig = z.infer<typeof TraefikConfigSchema>;\n\nexport const SettingsPrivateSchema = z.object({\n aiProviders: z.array(AIProviderSchema).max(50).default([]),\n scenarios: z.array(ScenarioSchema).max(100).default([]),\n notifications: NotificationPreferencesSchema.default(() => ({\n scenario_waiting_input: true,\n ai_conversation_complete: true,\n ai_conversation_error: true,\n service_error_log: true,\n service_status_changed: true,\n service_health_changed: true,\n service_error_log_excluded: [],\n service_status_changed_excluded: [],\n service_health_changed_excluded: [],\n })),\n traefikConfig: TraefikConfigSchema.optional(),\n});\n\nexport type SettingsPrivate = z.infer<typeof SettingsPrivateSchema>;\n\nexport const SchemaVersionSchema = z.object({\n version: z.number().int().positive(),\n migratedAt: z.coerce.date(),\n});\n\nexport type SchemaVersion = z.infer<typeof SchemaVersionSchema>;\n","import { z } from 'zod';\n\nconst PositionSchema = z.object({\n x: z.number(),\n y: z.number(),\n});\n\nexport const ScenarioGroupSchema = z.object({\n id: z.string().min(1).max(128),\n name: z.string().min(1).max(200),\n description: z.string().max(1000).optional(),\n color: z.string().max(32).optional(),\n position: PositionSchema.default({ x: 0, y: 0 }),\n width: z.number().default(300),\n height: z.number().default(200),\n});\n\nexport type ScenarioGroup = z.infer<typeof ScenarioGroupSchema>;\n\nexport const SCENARIO_ROLES = [\n 'manager',\n 'engineer',\n 'designer',\n 'analyst',\n 'qa',\n 'devops',\n 'product',\n 'writer',\n 'researcher',\n 'other',\n] as const;\n\nexport type ScenarioRole = typeof SCENARIO_ROLES[number];\n\n// --- Presets ---\n\nexport const ScenarioPresetRoleSchema = z.object({\n id: z.string().min(1).max(64),\n name: z.string().min(1).max(200),\n systemPrompt: z.string().max(10_000).default(''),\n prompt: z.string().max(10_000).default(''),\n});\n\nexport type ScenarioPresetRole = z.infer<typeof ScenarioPresetRoleSchema>;\n\nexport const ScenarioPresetInitialDataSchema = z.object({\n leaderId: z.string().min(1).max(128),\n groups: z.array(z.object({\n id: z.string().min(1).max(128),\n name: z.string().min(1).max(200),\n description: z.string().max(1000).optional(),\n color: z.string().max(32).optional(),\n position: z.object({ x: z.number(), y: z.number() }).default({ x: 0, y: 0 }),\n width: z.number().default(300),\n height: z.number().default(200),\n })).max(100).default([]),\n nodes: z.array(z.object({\n id: z.string().min(1).max(128),\n type: z.enum(['ai', 'ask']).default('ai'),\n parentIds: z.array(z.string().max(128)).default([]),\n groupId: z.string().max(128).nullable().default(null),\n label: z.string().max(240).default(''),\n role: z.string().max(64).default('other'),\n prompt: z.string().max(50_000).default(''),\n question: z.string().max(2_000).default(''),\n autoGenerated: z.boolean().default(true),\n canAddNode: z.boolean().default(false),\n aiCli: z.enum(['claude-code', 'codex']).default('claude-code'),\n model: z.string().max(128).default('sonnet'),\n position: z.object({ x: z.number(), y: z.number() }).default({ x: 0, y: 0 }),\n })).min(1).max(500),\n});\n\nexport type ScenarioPresetInitialData = z.infer<typeof ScenarioPresetInitialDataSchema>;\n\nconst LocalizedStringSchema = z.record(z.string(), z.string().max(100));\n\nexport const ScenarioPresetLabelsSchema = z.object({\n group: LocalizedStringSchema.optional(),\n node: LocalizedStringSchema.optional(),\n role: LocalizedStringSchema.optional(),\n leader: LocalizedStringSchema.optional(),\n});\n\nexport type ScenarioPresetLabels = z.infer<typeof ScenarioPresetLabelsSchema>;\n\nexport const ScenarioPresetSchema = z.object({\n id: z.string().min(1).max(128),\n name: z.string().min(1).max(200),\n icon: z.string().max(64).optional(),\n defaultTraversalMode: z.enum(['hierarchical', 'topological']).optional(),\n canChangeTraversalMode: z.boolean().default(true),\n roles: z.array(ScenarioPresetRoleSchema).min(1).max(100),\n initialData: ScenarioPresetInitialDataSchema.optional(),\n labels: ScenarioPresetLabelsSchema.optional(),\n});\n\nexport type ScenarioPreset = z.infer<typeof ScenarioPresetSchema>;\n\n// --- Node ---\n\nexport const ScenarioNodeSchema = z.object({\n id: z.string().min(1).max(128),\n type: z.enum(['ai', 'ask']).default('ai'),\n parentIds: z.array(z.string().max(128)).default([]),\n groupId: z.string().max(128).nullable().default(null),\n label: z.string().max(240).default(''),\n role: z.string().max(64).default('other'),\n prompt: z.string().max(50_000).default(''),\n question: z.string().max(2_000).default(''),\n autoGenerated: z.boolean().default(true),\n canAddNode: z.boolean().default(false),\n aiCli: z.enum(['claude-code', 'codex']).default('claude-code'),\n model: z.string().max(128).default('sonnet'),\n position: PositionSchema.default({ x: 0, y: 0 }),\n injectParentOutputs: z.boolean().default(false),\n injectedAncestorIds: z.array(z.string().max(128)).default([]),\n});\n\nexport type ScenarioNode = z.infer<typeof ScenarioNodeSchema>;\n\nexport const ScenarioSchema = z.object({\n id: z.string().min(1).max(128),\n name: z.string().min(1).max(200),\n icon: z.string().max(64).optional(),\n description: z.string().max(2000).optional(),\n leaderId: z.string().min(1).max(128),\n groups: z.array(ScenarioGroupSchema).max(100).default([]),\n nodes: z.array(ScenarioNodeSchema).min(1).max(500),\n traversalMode: z.enum(['hierarchical', 'topological']).default('hierarchical'),\n presetId: z.string().max(128).optional(),\n isPublished: z.boolean().default(false),\n createdAt: z.number(),\n updatedAt: z.number(),\n});\n\nexport type Scenario = z.infer<typeof ScenarioSchema>;\n","import { z } from 'zod';\n\nconst safePath = z\n .string()\n .min(1)\n .max(4096)\n .refine(\n (p) => !p.includes('\\0'),\n { message: 'path must not contain null bytes' },\n )\n .refine(\n (p) => !/(^|[/\\\\])\\.\\.([/\\\\]|$)/.test(p),\n { message: 'path must not contain path-traversal sequences (..)' },\n )\n;\n\nexport const ConsoleLogSourceSchema = z.object({\n type: z.literal('console'),\n});\nexport type ConsoleLogSource = z.infer<typeof ConsoleLogSourceSchema>;\n\nexport const FileLogSourceSchema = z.object({\n type: z.literal('file'),\n path: safePath,\n encoding: z.string().max(32).default('utf-8'),\n startFromEnd: z.boolean().default(true),\n createIfNotExists: z.boolean().default(false),\n});\nexport type FileLogSource = z.infer<typeof FileLogSourceSchema>;\n\nexport const MongoLogSourceSchema = z.object({\n type: z.literal('mongo'),\n /** @sensitive — stored encrypted (AES-256-GCM) on disk */\n connectionString: z.string().min(1).max(2048),\n database: z.string().min(1).max(256),\n collection: z.string().min(1).max(256),\n filter: z.record(z.string(), z.unknown()).optional(),\n timestampField: z.string().max(128).default('timestamp'),\n messageField: z.string().max(128).default('message'),\n levelField: z.string().max(128).optional(),\n});\nexport type MongoLogSource = z.infer<typeof MongoLogSourceSchema>;\n\nexport const MySQLLogSourceSchema = z.object({\n type: z.literal('mysql'),\n host: z.string().min(1).max(253),\n port: z.number().int().min(1).max(65535).default(3306),\n user: z.string().min(1).max(256),\n /** @sensitive — stored encrypted (AES-256-GCM) on disk */\n password: z.string().max(2048),\n database: z.string().min(1).max(256),\n table: z.string().min(1).max(256),\n query: z.string().max(8192).optional(),\n timestampColumn: z.string().max(128).default('created_at'),\n messageColumn: z.string().max(128).default('message'),\n levelColumn: z.string().max(128).optional(),\n pollIntervalMs: z.number().int().min(500).max(60000).default(2000),\n});\nexport type MySQLLogSource = z.infer<typeof MySQLLogSourceSchema>;\n\nexport const LogSourceConfigSchema = z.discriminatedUnion('type', [\n ConsoleLogSourceSchema,\n FileLogSourceSchema,\n MongoLogSourceSchema,\n MySQLLogSourceSchema,\n]);\nexport type LogSourceConfig = z.infer<typeof LogSourceConfigSchema>;\nexport type LogSourceType = LogSourceConfig['type'];\n","import { z } from 'zod';\n\nexport const ProcessStateSchema = z.enum(['starting', 'running', 'stopped', 'errored']);\nexport type ProcessState = z.infer<typeof ProcessStateSchema>;\n\nexport const HealthStatusSchema = z.enum(['healthy', 'unhealthy', 'unknown']);\nexport type HealthStatus = z.infer<typeof HealthStatusSchema>;\n\nexport const ProcessStatusSchema = z.object({\n id: z.string().max(128),\n serviceId: z.string().max(128),\n agentId: z.string().max(128),\n state: ProcessStateSchema,\n pid: z.number().int().nullable().optional(),\n pids: z.array(z.number().int()).optional().default([]),\n exitCode: z.number().int().nullable().optional(),\n startedAt: z.coerce.date().nullable().optional(),\n restartCount: z.number().int().nonnegative().default(0),\n uptime: z.number().nonnegative().default(0),\n healthStatus: HealthStatusSchema.default('unknown'),\n});\n\nexport type ProcessStatus = z.infer<typeof ProcessStatusSchema>;\n","import { z } from 'zod';\n\nexport const LogLevelSchema = z.enum(['debug', 'info', 'warn', 'error', 'fatal']);\nexport type LogLevel = z.infer<typeof LogLevelSchema>;\n\nexport const LogLineSchema = z.object({\n /** Raw log line as received from the process (immutable context) */\n raw: z.string(),\n /** Source stream (immutable context) */\n stream: z.enum(['stdout', 'stderr']),\n /** Severity level */\n level: LogLevelSchema,\n /** Parsed/enriched message to display */\n message: z.string(),\n /** When true, the line is hidden from the log view */\n hidden: z.boolean(),\n /** Arbitrary key/value pairs shown in the detail panel */\n metadata: z.record(z.string().max(256), z.unknown()).refine(\n (obj) => Object.keys(obj).length <= 100,\n { message: 'Too many metadata keys (max 100)' },\n ),\n /** Full parsed JSON object when the line is JSON */\n json: z.record(z.string(), z.unknown()).optional(),\n /** Custom header for the JSON log card (supports HTML, sanitized before display) */\n jsonHeader: z.string().max(256).optional(),\n});\n\nexport type LogLine = z.infer<typeof LogLineSchema>;\n\nexport const LogCardDirectiveSchema = z.object({\n id: z.string().max(128),\n type: z.string().max(64),\n header: z.string().max(256),\n collapsable: z.boolean().optional(),\n collapsed: z.boolean().optional(),\n state: z.enum(['open', 'append', 'close', 'self']),\n});\nexport type LogCardDirective = z.infer<typeof LogCardDirectiveSchema>;\n\nexport const ParsedLogSchema = z.object({\n id: z.string().max(128),\n processId: z.string().max(128),\n pid: z.number().int().nullable().optional(),\n timestamp: z.coerce.date(),\n level: LogLevelSchema.default('info'),\n message: z.string().max(16384),\n raw: z.string().max(16384),\n stream: z.enum(['stdout', 'stderr']).default('stdout'),\n hidden: z.boolean().optional().default(false),\n metadata: z.record(z.string().max(256), z.unknown()).optional().refine(\n (obj) => !obj || Object.keys(obj).length <= 100,\n { message: 'Too many metadata keys (max 100)' },\n ),\n json: z.record(z.string(), z.unknown()).optional(),\n logCard: LogCardDirectiveSchema.optional(),\n sourceType: z.enum(['console', 'file', 'mongo', 'mysql']).optional(),\n sourcePath: z.string().max(4096).optional(),\n});\n\nexport type ParsedLog = z.infer<typeof ParsedLogSchema>;\n","import { z } from 'zod';\n\n/** Regex for valid POSIX environment variable names */\nexport const ENV_VAR_NAME_REGEX = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nexport const AgentConfigSchema = z.object({\n id: z.string().max(128),\n name: z.string().min(1).max(100),\n url: z.string().url().max(2048),\n passphrase: z.string().min(1).max(1024),\n passthroughEnv: z.array(\n z.string().regex(ENV_VAR_NAME_REGEX).max(256),\n ).max(100).default([]),\n});\n\nexport type AgentConfig = z.infer<typeof AgentConfigSchema>;\n\nexport const AgentStatusSchema = z.object({\n connected: z.boolean(),\n lastSeen: z.string().nullable().optional(),\n uptime: z.number().nonnegative().default(0),\n runnersAvailable: z.array(z.enum(['native', 'docker'])).default(['native']),\n lanIp: z.string().optional(),\n});\n\nexport type AgentStatus = z.infer<typeof AgentStatusSchema>;\n","import { z } from 'zod';\n\nexport const GlobalRoleSchema = z.enum(['owner', 'admin', 'member']);\nexport type GlobalRole = z.infer<typeof GlobalRoleSchema>;\n\nexport const ProjectRoleSchema = z.enum(['admin', 'editor', 'viewer']);\nexport type ProjectRole = z.infer<typeof ProjectRoleSchema>;\n\nexport const ProjectMemberRoleSchema = z.object({\n id: z.string().max(128),\n projectId: z.string().max(128),\n userId: z.string().max(128),\n role: ProjectRoleSchema,\n});\n\nexport type ProjectMemberRole = z.infer<typeof ProjectMemberRoleSchema>;\n","import { z } from 'zod';\n\nexport const ConfigVersionSchema = z.object({\n id: z.string().max(128),\n entityType: z.enum(['project', 'service']),\n entityId: z.string().max(128),\n version: z.string().max(128),\n parentVersion: z.string().max(128),\n data: z.record(z.string(), z.unknown()).refine(\n (obj) => Object.keys(obj).length <= 1000,\n 'Too many data keys (max 1000)',\n ),\n patch: z.array(z.record(z.string(), z.unknown())).max(1000),\n userId: z.string().max(128),\n timestamp: z.coerce.date(),\n resolved: z.boolean().default(false),\n});\n\nexport type ConfigVersion = z.infer<typeof ConfigVersionSchema>;\n\nexport const ConfigChangeSchema = z.object({\n entityType: z.enum(['project', 'service']),\n entityId: z.string().max(128),\n version: z.string().max(128),\n parentVersion: z.string().max(128),\n data: z.record(z.string(), z.unknown()).refine(\n (obj) => Object.keys(obj).length <= 1000,\n 'Too many data keys (max 1000)',\n ),\n patch: z.array(z.record(z.string(), z.unknown())).max(1000),\n});\n\nexport type ConfigChange = z.infer<typeof ConfigChangeSchema>;\n\nexport const SyncStatusSchema = z.object({\n connected: z.boolean(),\n lastSync: z.coerce.date().nullable().optional(),\n pendingChanges: z.number().int().nonnegative().default(0),\n conflicts: z.number().int().nonnegative().default(0),\n});\n\nexport type SyncStatus = z.infer<typeof SyncStatusSchema>;\n","import { z } from 'zod';\n\nexport const AuditActionSchema = z.enum([\n 'create', 'update', 'delete',\n 'invite', 'remove',\n 'deploy', 'start', 'stop',\n 'roleChange',\n]);\n\nexport type AuditAction = z.infer<typeof AuditActionSchema>;\n\nexport const AuditEntityTypeSchema = z.enum([\n 'org', 'project', 'service', 'member', 'permission',\n]);\n\nexport type AuditEntityType = z.infer<typeof AuditEntityTypeSchema>;\n\nexport const AuditLogSchema = z.object({\n id: z.string().max(128),\n orgId: z.string().max(128),\n userId: z.string().max(128),\n action: AuditActionSchema,\n entityType: AuditEntityTypeSchema,\n entityId: z.string().max(128),\n metadata: z.record(z.string().max(256), z.unknown()).default({}).refine(\n (obj) => Object.keys(obj).length <= 100,\n { message: 'Too many metadata keys (max 100)' },\n ),\n timestamp: z.coerce.date(),\n});\n\nexport type AuditLog = z.infer<typeof AuditLogSchema>;\n","import { z } from 'zod';\n\nexport const ProcessMetricsSchema = z.object({\n processId: z.string().max(128),\n cpu: z.number().nonnegative(),\n memory: z.number().int().nonnegative(),\n timestamp: z.string(),\n});\n\nexport type ProcessMetrics = z.infer<typeof ProcessMetricsSchema>;\n","import { z } from 'zod';\nimport { VariableSchema } from './service.schema.js';\n\n// Environment schema — uses VariablesRecord for variable storage\nexport const EnvironmentVariablesSchema = z.record(\n z.string().max(256),\n VariableSchema,\n).refine(\n (obj) => Object.keys(obj).length <= 200,\n { message: 'Max 200 variables' },\n);\n\nexport const EnvironmentSchema = z.object({\n id: z.string().max(128),\n projectId: z.string().max(128),\n name: z.string().min(1).max(200),\n description: z.string().max(2000).optional().default(''),\n parentIds: z.array(z.string().max(128)).max(10).default([]),\n variables: EnvironmentVariablesSchema.default({}),\n // Scope: 'global' = project-level env, 'service' = per-service env\n scope: z.enum(['global', 'service']).default('global'),\n // When scope='service': the serviceId this env belongs to\n reference: z.string().max(128).optional(),\n // When scope='service': the globalEnvId this env activates on\n activateOn: z.string().max(128).optional(),\n immutable: z.boolean().default(false),\n default: z.boolean().optional().default(false),\n color: z.string().max(20).optional(),\n bgColor: z.string().max(20).optional(),\n // When scope='global': the default agent used by services that don't have an explicit agentId\n agentId: z.string().max(128).optional(),\n});\n\nexport type Environment = z.infer<typeof EnvironmentSchema>;\n\n// Resolved environment: flattened env dict + secrets list + source tracking\nexport const ResolvedEnvironmentSchema = z.object({\n variables: z.record(z.string().max(256), VariableSchema)\n .refine((obj) => Object.keys(obj).length <= 500, { message: 'Max 500 resolved variables' }),\n env: z.record(z.string().max(256), z.string().max(8192))\n .refine((obj) => Object.keys(obj).length <= 500, { message: 'Max 500 resolved env vars' }),\n envSecrets: z.array(z.string().max(256)).max(500),\n sources: z.record(z.string().max(256), z.object({\n environmentId: z.string().max(128),\n environmentName: z.string().max(200),\n overridden: z.boolean(),\n resolvedFrom: z.object({\n environmentId: z.string().max(128),\n environmentName: z.string().max(200),\n }).optional(),\n // Set when a machine-local override was applied to this variable, pointing\n // at the environment that carries the winning override. Distinct from\n // `overridden`, which also covers \"shadows an inherited variable\".\n overriddenBy: z.object({\n environmentId: z.string().max(128),\n environmentName: z.string().max(200),\n }).optional(),\n })).refine((obj) => Object.keys(obj).length <= 500, { message: 'Max 500 source entries' }),\n});\n\nexport type ResolvedEnvironment = z.infer<typeof ResolvedEnvironmentSchema>;\n\nexport const CreateEnvironmentSchema = EnvironmentSchema.omit({ id: true }).extend({\n description: z.string().max(2000).optional().default(''),\n parentIds: z.array(z.string().max(128)).max(10).optional().default([]),\n variables: EnvironmentVariablesSchema.optional().default({}),\n scope: z.enum(['global', 'service']).optional().default('global'),\n reference: z.string().max(128).optional(),\n activateOn: z.string().max(128).optional(),\n immutable: z.boolean().optional().default(false),\n});\nexport type CreateEnvironment = z.input<typeof CreateEnvironmentSchema>;\n\n// IMPORTANT: Do NOT simplify this to `EnvironmentSchema.partial().required({ id: true })`.\n//\n// EnvironmentSchema has .default() on several fields (variables: {}, parentIds: [], description: '',\n// scope: 'global', immutable: false, default: false). When Zod parses a partial update input that\n// omits those fields, .partial() alone does NOT strip the defaults — Zod still fills them in.\n// The store checks `input.variables !== undefined` to decide whether to overwrite, so if Zod\n// silently injects `variables: {}`, the store wipes ALL existing variables on every save.\n//\n// The .extend() below overrides those fields without .default(), making them truly optional\n// (undefined when absent). DO NOT remove it or merge the .extend() back into EnvironmentSchema.\nexport const UpdateEnvironmentSchema = EnvironmentSchema\n .partial()\n .required({ id: true })\n .extend({\n description: z.string().max(2000).optional(),\n parentIds: z.array(z.string().max(128)).max(10).optional(),\n variables: EnvironmentVariablesSchema.optional(),\n scope: z.enum(['global', 'service']).optional(),\n immutable: z.boolean().optional(),\n default: z.boolean().optional(),\n agentId: z.string().max(128).nullable().optional(), // null = clear (no default agent)\n });\nexport type UpdateEnvironment = z.infer<typeof UpdateEnvironmentSchema>;\n","import { z } from 'zod';\nimport { VariableSlotSchema } from './service.schema.js';\n\n// An override carries ONLY a value slot: the env var name always comes from the\n// variable definition in `environments.json`, looked up by variable ID. Storing\n// a `key` here would go stale as soon as the variable is renamed in the UI.\nexport const VariableOverrideSchema = z.object({\n value: VariableSlotSchema,\n});\n\nexport type VariableOverride = z.infer<typeof VariableOverrideSchema>;\n\n// Environment overrides: Record<variableId, VariableOverride>\n// Flat structure — each override is keyed by the variable's unique ID.\nexport const EnvironmentOverridesSchema = z.record(\n z.string().max(128),\n VariableOverrideSchema,\n).refine(\n (obj) => Object.keys(obj).length <= 5000,\n { message: 'Max 5000 overrides' },\n);\n\nexport type EnvironmentOverrides = z.infer<typeof EnvironmentOverridesSchema>;\n","import { z } from 'zod';\n\nexport const ApiServiceActionSchema = z.enum([\n 'service:read',\n 'service:start',\n 'service:stop',\n 'service:restart',\n 'service:healthcheck',\n 'service:status',\n 'logs:read',\n]);\nexport type ApiServiceAction = z.infer<typeof ApiServiceActionSchema>;\n\nexport const ApiEnvActionSchema = z.enum(['env:read', 'env:write']);\nexport type ApiEnvAction = z.infer<typeof ApiEnvActionSchema>;\n\nexport const ApiEnvPermSchema = z.object({\n environmentId: z.string().max(128),\n actions: z.array(ApiEnvActionSchema).max(10).default(['env:read']),\n includeSecrets: z.boolean().default(false),\n});\nexport type ApiEnvPerm = z.infer<typeof ApiEnvPermSchema>;\n\nexport const ApiServicePermSchema = z.object({\n serviceId: z.string().max(128),\n actions: z.array(ApiServiceActionSchema).max(10).default(['service:read']),\n environments: z.array(ApiEnvPermSchema).max(100).default([]),\n});\nexport type ApiServicePerm = z.infer<typeof ApiServicePermSchema>;\n\nexport const ApiKeyScopeSchema = z.object({\n services: z.array(ApiServicePermSchema).max(500).default([]),\n});\nexport type ApiKeyScope = z.infer<typeof ApiKeyScopeSchema>;\n\nexport const ApiKeySchema = z.object({\n id: z.string().max(128),\n name: z.string().min(1).max(200),\n key: z.string().regex(/^[0-9a-f]{64}$/i),\n scopes: ApiKeyScopeSchema,\n createdAt: z.string().max(64),\n isPublic: z.boolean().default(false),\n});\nexport type ApiKey = z.infer<typeof ApiKeySchema>;\n\n/**\n * Shape of an API key as it sits on disk: `key` holds the *encrypted* secret,\n * so it no longer matches the 64-hex form the in-memory type guarantees.\n * Legacy files written before encryption still parse — the store decrypts only\n * what looks encrypted and re-persists.\n */\nexport const PersistedApiKeySchema = ApiKeySchema.extend({\n key: z.string().min(1).max(4096),\n});\nexport type PersistedApiKey = z.infer<typeof PersistedApiKeySchema>;\n\nexport const ApiKeysFileSchema = z.object({\n keys: z.array(PersistedApiKeySchema).max(100),\n});\n\n/** An API key as exposed by the API: the secret is never part of it. */\nexport const MaskedApiKeySchema = ApiKeySchema.omit({ key: true }).extend({\n /** Last 4 characters of the secret, for recognising a key in a list. */\n keyPreview: z.string().max(8),\n});\nexport type MaskedApiKey = z.infer<typeof MaskedApiKeySchema>;\n\n","import { z } from 'zod';\n\nexport const ALLOWED_IMAGE_MIME_TYPES = ['image/png', 'image/jpeg', 'image/webp', 'image/gif'] as const;\n\nexport const ImagePartSchema = z.object({\n type: z.literal('image'),\n imageId: z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, 'Must be a valid UUID'),\n url: z.string().min(1),\n mimeType: z.enum(ALLOWED_IMAGE_MIME_TYPES),\n altText: z.string().max(500).optional(),\n});\n\nexport type ImagePart = z.infer<typeof ImagePartSchema>;\n\nexport const ImageUploadResponseSchema = z.object({\n imageId: z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, 'Must be a valid UUID'),\n url: z.string().min(1),\n mimeType: z.enum(ALLOWED_IMAGE_MIME_TYPES),\n originalName: z.string(),\n});\n\nexport type ImageUploadResponse = z.infer<typeof ImageUploadResponseSchema>;\n\nexport const ImageMetaSchema = z.object({\n imageId: z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, 'Must be a valid UUID'),\n filePath: z.string().min(1),\n mimeType: z.enum(ALLOWED_IMAGE_MIME_TYPES),\n originalName: z.string().min(1),\n createdAt: z.number().positive(),\n size: z.number().positive().optional(),\n});\n\nexport type ImageMeta = z.infer<typeof ImageMetaSchema>;\n","import { z } from 'zod';\n\n// --- Attachments ---\n/**\n * A file attached to a card. The bytes live in object storage; the card keeps\n * only this descriptor, so a board document stays small no matter how many\n * files it carries.\n */\nexport const KanbanAttachmentSchema = z.object({\n /** Server-issued id, also the storage key. */\n id: z.string().max(128),\n name: z.string().max(255),\n size: z.number().int().nonnegative(),\n contentType: z.string().max(128),\n});\nexport type KanbanAttachment = z.infer<typeof KanbanAttachmentSchema>;\n\n// --- Card History ---\nexport const KanbanCardEventSchema = z.object({\n type: z.enum(['created', 'edited', 'moved', 'image_added', 'image_removed', 'title_changed', 'conversation_started', 'scenario_started', 'comment']),\n timestamp: z.string(),\n /** Extra context: old/new column name, old/new title, comment text, etc. */\n detail: z.string().max(5000).optional(),\n /**\n * Stable identity of the event, used to tell an edit from an insertion when a\n * whole history is written back. Absent on events recorded before the field\n * existed; those fall back to (type, timestamp).\n */\n id: z.string().max(128).optional(),\n /** Who authored this event — 'ai' or 'user'. Only set for comment events. */\n author: z.enum(['ai', 'user']).optional(),\n /**\n * The human behind a comment, stamped by the server. This is what makes\n * \"my own comment\" answerable; `author` only separates AI from human.\n */\n authorUser: z.object({ id: z.string().max(128), name: z.string().max(200) }).optional(),\n /** Set when the author amended their comment, so the UI can say so. */\n editedAt: z.string().optional(),\n /** Files attached to a comment — same storage as a card's own attachments. */\n attachments: z.array(KanbanAttachmentSchema).max(20).optional(),\n /** Conversation that produced this event (comments only). Used to navigate back to the conversation. */\n conversationId: z.string().optional(),\n});\nexport type KanbanCardEvent = z.infer<typeof KanbanCardEventSchema>;\n\n// --- Card ---\nexport const KanbanCardSchema = z.object({\n id: z.string(),\n title: z.string().min(1).max(500),\n markdown: z.string().max(100_000).default(''),\n /**\n * Legacy inline images, kept so boards written before object storage still\n * render. New uploads go to `attachments` instead.\n */\n images: z.array(z.string()).default([]),\n /** Files attached to the card — stored out of band, referenced here. */\n attachments: z.array(KanbanAttachmentSchema).max(50).default([]),\n order: z.number().int(),\n /**\n * Le journal de la carte — commentaires compris.\n *\n * Optionnel, et c'est tout l'intérêt : c'est la partie qui grossit sans fin\n * (une IA bavarde y écrit des pages), alors les lectures de tableau ne le\n * transportent plus. `undefined` veut dire « pas chargé », et une écriture\n * qui l'omet laisse au serveur celui qu'il a en base — à ne pas confondre\n * avec `[]`, qui demanderait bel et bien de le vider.\n */\n history: z.array(KanbanCardEventSchema).optional(),\n /**\n * Ce que le journal absent laisse quand même dire : combien de commentaires,\n * et quand fut le dernier. Posés par le serveur en lecture, ignorés en\n * écriture — la carte ne les stocke pas, ils se déduisent de `history`.\n */\n commentCount: z.number().int().nonnegative().optional(),\n lastCommentAt: z.string().optional(),\n /**\n * Les entrées de journal qui ouvrent une conversation IA. Elles restent dans\n * la lecture allégée — il y en a une poignée par carte, et l'hôte s'en sert\n * pour dire, sans ouvrir la carte, qu'une IA y travaille.\n */\n conversationEvents: z.array(KanbanCardEventSchema).optional(),\n createdAt: z.string(),\n updatedAt: z.string(),\n /**\n * People assigned to the card. Names are denormalized for display; the server\n * keeps only members of the owning organization, and notifies newcomers.\n */\n assignees: z\n .array(z.object({ id: z.string().max(128), name: z.string().max(200) }))\n .max(20)\n .default([]),\n /**\n * Who first created the card. Stamped by the server the first time a card id\n * appears in a board write, never taken from the client — a member could\n * otherwise claim any authorship. Absent on cards created before this field\n * existed, so readers must treat it as unknown rather than assume.\n */\n createdBy: z\n .object({ id: z.string().max(128), name: z.string().max(200) })\n .optional(),\n});\nexport type KanbanCard = z.infer<typeof KanbanCardSchema>;\n\n// --- Column ---\nexport const KanbanColumnSchema = z.object({\n id: z.string(),\n title: z.string().min(1).max(200),\n order: z.number().int(),\n cards: z.array(KanbanCardSchema).default([]),\n});\nexport type KanbanColumn = z.infer<typeof KanbanColumnSchema>;\n\n// --- Board ---\nexport const KanbanBoardSchema = z.object({\n id: z.string(),\n name: z.string().min(1).max(200),\n description: z.string().max(10_000).default(''),\n /**\n * Le mode d'emploi du tableau, en texte libre : ce que veulent dire ses\n * colonnes, quand une carte a le droit d'avancer, les conventions de\n * l'équipe. Écrit par les humains, lu surtout par l'IA — il est injecté dans\n * le prompt des agents pour qu'ils travaillent selon les règles du tableau\n * plutôt que selon les leurs.\n */\n instructions: z.string().max(20_000).default(''),\n columns: z.array(KanbanColumnSchema).default([]),\n archived: z.boolean().default(false),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\nexport type KanbanBoard = z.infer<typeof KanbanBoardSchema>;\n\n// --- Inputs ---\nexport const CreateKanbanBoardInput = z.object({\n name: z.string().min(1).max(200),\n description: z.string().max(10_000).optional(),\n instructions: z.string().max(20_000).optional(),\n});\nexport type CreateKanbanBoardInput = z.infer<typeof CreateKanbanBoardInput>;\n\nexport const UpdateKanbanBoardInput = z.object({\n id: z.string(),\n name: z.string().min(1).max(200).optional(),\n description: z.string().max(10_000).optional(),\n instructions: z.string().max(20_000).optional(),\n columns: z.array(KanbanColumnSchema).optional(),\n archived: z.boolean().optional(),\n});\nexport type UpdateKanbanBoardInput = z.infer<typeof UpdateKanbanBoardInput>;\n","import { createCipheriv, createDecipheriv, randomBytes, pbkdf2Sync } from 'node:crypto';\n\nconst PREFIX = 'aes256gcm:';\nconst IV_LENGTH = 12;\nconst AUTH_TAG_LENGTH = 16;\nconst KEY_LENGTH = 32;\nconst PBKDF2_ITERATIONS = 100_000;\nconst PBKDF2_DIGEST = 'sha256';\n/** Fixed salt for key derivation — the purpose is the salt (lazy to avoid Buffer at module init) */\nlet _KDF_SALT: Buffer | undefined;\nfunction getKdfSalt(): Buffer {\n if (!_KDF_SALT) _KDF_SALT = Buffer.from('runeya-log-sources-key-v1', 'utf8');\n return _KDF_SALT;\n}\n\n/**\n * Derives a 32-byte AES-256 key from `rawKey` using PBKDF2-SHA256.\n * The input key may be any Buffer (e.g. the raw passphrase bytes).\n */\nexport function deriveKey(rawKey: Buffer): Buffer {\n return pbkdf2Sync(rawKey, getKdfSalt(), PBKDF2_ITERATIONS, KEY_LENGTH, PBKDF2_DIGEST);\n}\n\n/**\n * Encrypts `plaintext` using AES-256-GCM.\n * Returns a string in the format: `aes256gcm:<iv_hex>:<authTag_hex>:<ciphertext_hex>`\n */\nexport function encrypt(plaintext: string, key: Buffer): string {\n const iv = randomBytes(IV_LENGTH);\n const cipher = createCipheriv('aes-256-gcm', key, iv);\n const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);\n const authTag = cipher.getAuthTag();\n return `${PREFIX}${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted.toString('hex')}`;\n}\n\n/**\n * Decrypts a ciphertext string produced by `encrypt()`.\n * Throws if the format is invalid or authentication fails.\n */\nexport function decrypt(ciphertext: string, key: Buffer): string {\n if (!isEncrypted(ciphertext)) {\n throw new Error('Value is not in encrypted format');\n }\n const parts = ciphertext.slice(PREFIX.length).split(':');\n if (parts.length !== 3) {\n throw new Error('Invalid encrypted value format');\n }\n const [ivHex, authTagHex, encryptedHex] = parts;\n const iv = Buffer.from(ivHex, 'hex');\n const authTag = Buffer.from(authTagHex, 'hex');\n const encryptedBuffer = Buffer.from(encryptedHex, 'hex');\n\n if (iv.length !== IV_LENGTH) throw new Error('Invalid IV length');\n if (authTag.length !== AUTH_TAG_LENGTH) throw new Error('Invalid authTag length');\n\n const decipher = createDecipheriv('aes-256-gcm', key, iv, { authTagLength: 16 });\n decipher.setAuthTag(authTag);\n return Buffer.concat([decipher.update(encryptedBuffer), decipher.final()]).toString('utf8');\n}\n\n/**\n * Returns true if `value` is in the encrypted format produced by `encrypt()`.\n * Safe to call on plain-text values (returns false).\n */\nexport function isEncrypted(value: string): boolean {\n return value.startsWith(PREFIX);\n}\n","import type { JSLogParser } from './schemas/settings.schema.js';\n\n/**\n * Built-in log parsers that ship with Runeya.\n * IDs are prefixed with `native:` to distinguish from user-created parsers.\n *\n * All native parsers use the v2 pipeline signature: (line: LogLine) => LogLine\n * Each parser enriches the LogLine and passes it through. Order matters — the\n * service's parserIds array determines execution order.\n */\n\nconst epoch = new Date('2025-01-01T00:00:00Z');\n\nexport const nativeParsers: JSLogParser[] = [\n {\n id: 'native:json',\n name: 'JSON Log Parser',\n description: 'Parses JSON log lines and extracts level, message, timestamp, metadata, and the full parsed object.',\n code: `(line) => {\n var trimmed = line.message.trim();\n if (!trimmed.startsWith('{')) return line;\n try {\n var obj = JSON.parse(trimmed);\n var level = (obj.level || obj.severity || obj.loglevel || '').toString().toLowerCase();\n var levelMap = { trace: 'debug', debug: 'debug', info: 'info', warn: 'warn', warning: 'warn', error: 'error', fatal: 'fatal', err: 'error' };\n var mappedLevel = levelMap[level] || line.level;\n var message = obj.message || obj.msg || obj.text || trimmed;\n var metadata = {};\n for (var k in obj) {\n if (['level','severity','loglevel','message','msg','text','timestamp','time','ts'].indexOf(k) !== -1) continue;\n metadata[k] = typeof obj[k] === 'string' ? obj[k] : JSON.stringify(obj[k]);\n }\n var merged = {};\n for (var mk in line.metadata) merged[mk] = line.metadata[mk];\n for (var nk in metadata) merged[nk] = metadata[nk];\n return { raw: line.raw, stream: line.stream, level: mappedLevel, message: String(message).slice(0, 16384), hidden: line.hidden, metadata: merged, json: obj, jsonHeader: line.jsonHeader };\n } catch (e) { return line; }\n}`,\n enabled: true,\n builtin: true,\n createdAt: epoch,\n updatedAt: epoch,\n },\n {\n id: 'native:debug',\n name: 'Runeya Debug Parser',\n description: 'Detects Runeya internal debug logs emitted as JSON arrays: [\"runeya\", payload]. Marks them as debug level.',\n code: `(line) => {\n var trimmed = line.message.trim();\n if (!trimmed.startsWith('[')) return line;\n try {\n var parsed = JSON.parse(trimmed);\n if (!Array.isArray(parsed) || parsed[0] !== 'runeya') return line;\n var debug = parsed.length === 2 ? parsed[1] : parsed.slice(1);\n var message = typeof debug === 'string' ? debug : JSON.stringify(debug);\n var merged = {};\n for (var k in line.metadata) merged[k] = line.metadata[k];\n merged.runeya_debug = JSON.stringify(debug);\n return { raw: line.raw, stream: line.stream, level: 'debug', message: message, hidden: line.hidden, metadata: merged, jsonHeader: line.jsonHeader };\n } catch (e) { return line; }\n}`,\n enabled: true,\n builtin: true,\n createdAt: epoch,\n updatedAt: epoch,\n },\n {\n id: 'native:links',\n name: 'Link Detector',\n description: 'Detects URLs in plain-text log lines and exposes them in metadata.links for frontend rendering.',\n code: `(line) => {\n var urlRegex = /(https?|ftp):\\\\/\\\\/[\\\\w_-]+(?:\\\\.[\\\\w_-]+)+([\\\\w.,@?^=%&:/~+#-]*[\\\\w@?^=%&/~+#-])?/gi;\n var urls = line.message.match(urlRegex);\n if (!urls || urls.length === 0) return line;\n var merged = {};\n for (var k in line.metadata) merged[k] = line.metadata[k];\n merged.links = urls.join(' ');\n return { raw: line.raw, stream: line.stream, level: line.level, message: line.message, hidden: line.hidden, metadata: merged, jsonHeader: line.jsonHeader };\n}`,\n enabled: true,\n builtin: true,\n createdAt: epoch,\n updatedAt: epoch,\n },\n];\n\n/** Look up a native parser by ID */\nexport function getNativeParser(id: string): JSLogParser | undefined {\n return nativeParsers.find(p => p.id === id);\n}\n","import vm from 'node:vm';\nimport type { JSLogParser as JSLogParserDef } from './schemas/settings.schema.js';\nimport type { LogLine } from './schemas/log.schema.js';\nimport type { LogLevel } from './schemas/log.schema.js';\n\ninterface CompiledParser {\n id: string;\n name: string;\n enabled: boolean;\n fn: (line: LogLine) => LogLine;\n}\n\nconst VALID_LEVELS = new Set<string>(['debug', 'info', 'warn', 'error', 'fatal']);\n\n/** Budget CPU accordé à un parseur pour *une* ligne. */\nconst PARSE_TIMEOUT_MS = 50;\n/** Au-delà, le parseur est considéré hostile et désactivé pour la session. */\nconst MAX_CONSECUTIVE_TIMEOUTS = 10;\n\nexport class JSLogParser {\n private parsers: CompiledParser[] = [];\n\n constructor(definitions: JSLogParserDef[] = []) {\n this.setParsers(definitions);\n }\n\n setParsers(definitions: JSLogParserDef[]): void {\n this.parsers = [];\n\n for (const def of definitions) {\n if (!def.enabled) continue;\n\n try {\n const compiled = this.compileParser(def);\n this.parsers.push({\n id: def.id,\n name: def.name,\n enabled: true,\n fn: compiled,\n });\n } catch (err) {\n console.warn(\n `[js-log-parser] Failed to compile parser \"${def.name}\" (${def.id}): ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n }\n }\n\n parse(line: LogLine): LogLine {\n let current = line;\n\n for (const parser of this.parsers) {\n try {\n current = parser.fn(current);\n } catch (err) {\n console.warn(\n `[js-log-parser] Parser \"${parser.name}\" threw error: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n }\n\n return this.sanitize(current);\n }\n\n /**\n * Compile le code utilisateur en une fonction bornée en temps.\n *\n * Le `timeout` de `runInNewContext` ne couvre que l'évaluation de la factory :\n * la closure retournée s'exécutait ensuite ligne par ligne directement sur\n * l'event loop, sans aucune borne. Une regex à backtracking exponentiel\n * fournie par l'utilisateur figeait donc l'agent entier — logs, statuts et\n * métriques de *tous* les services. Chaque invocation repasse maintenant par\n * la vm, avec son propre budget.\n */\n private compileParser(def: JSLogParserDef): (line: LogLine) => LogLine {\n const forbidden = ['require(', 'import ', 'eval('];\n for (const pat of forbidden) {\n if (def.code.includes(pat)) {\n throw new Error('Code contains forbidden patterns (require, import, eval)');\n }\n }\n\n const sandbox = {\n RegExp,\n String,\n Object,\n Array,\n JSON,\n Math,\n Date,\n undefined,\n null: null,\n };\n\n let script: vm.Script;\n try {\n script = new vm.Script(`(${def.code})`, { filename: `parser-${def.id}.js` });\n } catch (err) {\n throw new Error(`Compilation failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n // Le contexte est conservé : c'est lui qui permet de ré-entrer dans la vm\n // à chaque ligne, et donc d'armer un timeout par invocation.\n const context = vm.createContext({ ...sandbox, __line: null as unknown, __result: null as unknown });\n\n let parserFn: unknown;\n try {\n parserFn = script.runInContext(context, { timeout: 100 });\n } catch (err) {\n throw new Error(`Execution failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n if (typeof parserFn !== 'function') {\n throw new Error('Parser code must export a function');\n }\n\n (context as Record<string, unknown>)['__parserFn'] = parserFn;\n const callScript = new vm.Script('__result = __parserFn(__line);', {\n filename: `parser-${def.id}-call.js`,\n });\n\n let consecutiveTimeouts = 0;\n let disabled = false;\n\n return (line: LogLine): LogLine => {\n if (disabled) return line;\n\n const ctx = context as Record<string, unknown>;\n ctx['__line'] = line;\n ctx['__result'] = null;\n try {\n callScript.runInContext(context, { timeout: PARSE_TIMEOUT_MS });\n consecutiveTimeouts = 0;\n } catch (err) {\n // `instanceof Error` est faux ici : l'erreur de timeout ne vient pas du\n // même realm que ce module. On la reconnaît par son code/message.\n const e = err as { code?: unknown; message?: unknown } | null;\n const timedOut = !!e\n && (e.code === 'ERR_SCRIPT_EXECUTION_TIMEOUT'\n || (typeof e.message === 'string' && /execution timed out/i.test(e.message)));\n if (!timedOut) throw err;\n consecutiveTimeouts += 1;\n if (consecutiveTimeouts >= MAX_CONSECUTIVE_TIMEOUTS) {\n disabled = true;\n console.warn(\n `[js-log-parser] Parser \"${def.name}\" (${def.id}) disabled after ${MAX_CONSECUTIVE_TIMEOUTS} consecutive timeouts`,\n );\n }\n return line;\n }\n\n const result = ctx['__result'];\n if (result === null || result === undefined || typeof result !== 'object') {\n return line;\n }\n return result as LogLine;\n };\n }\n\n /** Sanitize the final LogLine: truncate message, limit metadata, validate level */\n private sanitize(line: LogLine): LogLine {\n let { message, metadata, level } = line;\n\n if (message.length > 16384) {\n message = message.substring(0, 16384) + '...[truncated]';\n }\n\n metadata = metadata ?? {};\n const metaKeys = Object.keys(metadata);\n if (metaKeys.length > 100) {\n const limited: Record<string, unknown> = {};\n for (let i = 0; i < 100; i++) {\n limited[metaKeys[i]] = metadata[metaKeys[i]];\n }\n metadata = limited;\n }\n\n if (!VALID_LEVELS.has(level)) {\n level = 'info' as LogLevel;\n }\n\n if (message !== line.message || metadata !== line.metadata || level !== line.level) {\n return { ...line, message, metadata, level };\n }\n return line;\n }\n}\n","/** Health check default interval (ms) */\nexport const HEALTH_CHECK_INTERVAL = 30_000;\n\n/** Metrics collection interval (ms) */\nexport const METRICS_INTERVAL = 5_000;\n\n/** Agent health polling interval (ms) */\nexport const AGENT_HEALTH_POLL_INTERVAL = 15_000;\n\n/** UI search/filter debounce (ms) */\nexport const SEARCH_DEBOUNCE = 300;\n\n/** Health check initial delay before first check (ms) */\nexport const HEALTH_CHECK_INITIAL_DELAY = 5_000;\n\n/** Agent health WS interval (ms) */\nexport const HEALTH_WS_INTERVAL = 10_000;\n","/** Default log ring buffer size */\nexport const LOG_BUFFER_SIZE = 5_000;\n\n/** Max log entries displayed in UI */\nexport const LOG_DISPLAY_LIMIT = 500;\n","/** Default process grace period before SIGKILL (ms) */\nexport const GRACE_PERIOD = 10_000;\n\n/** HTTP fetch timeout for agent calls (ms) */\nexport const AGENT_FETCH_TIMEOUT = 10_000;\n\n/** HTTP fetch timeout for long-running agent calls like shortcuts/ad-hoc commands (ms) — 10 minutes */\nexport const AGENT_LONG_FETCH_TIMEOUT = 600_000;\n\n/** HTTP fetch timeout for process stop calls (ms) — grace period + generous buffer */\nexport const AGENT_STOP_FETCH_TIMEOUT = GRACE_PERIOD + 15_000;\n\n/** Passphrase extraction timeout during agent spawn (ms) */\nexport const PASSPHRASE_TIMEOUT = 30_000;\n\n/** Min WS reconnect delay (ms) */\nexport const WS_RECONNECT_MIN = 1_000;\n\n/** Max WS reconnect delay (ms) */\nexport const WS_RECONNECT_MAX = 15_000;\n\n/** Max WS reconnect attempts */\nexport const WS_RECONNECT_MAX_ATTEMPTS = 5;\n\n/** Base retry delay for subscriptions (ms) */\nexport const SUBSCRIPTION_RETRY_BASE = 1_000;\n","export interface EditorDefinition {\n key: string;\n name: string;\n command: string;\n}\n\nexport const SUPPORTED_EDITORS: EditorDefinition[] = [\n { key: 'vscode', name: 'Visual Studio Code', command: 'code' },\n { key: 'cursor', name: 'Cursor', command: 'cursor' },\n { key: 'windsurf', name: 'Windsurf', command: 'windsurf' },\n { key: 'sublime', name: 'Sublime Text', command: 'subl' },\n { key: 'atom', name: 'Atom', command: 'atom' },\n { key: 'antigravity', name: 'Antigravity', command: 'antigravity' },\n { key: 'intellij', name: 'IntelliJ IDEA', command: 'idea' },\n { key: 'android-studio', name: 'Android Studio', command: 'studio' },\n { key: 'webstorm', name: 'WebStorm', command: 'webstorm' },\n { key: 'zed', name: 'Zed', command: 'zed' },\n { key: 'neovim', name: 'Neovim', command: 'nvim' },\n { key: 'vim', name: 'Vim', command: 'vim' },\n { key: 'emacs', name: 'Emacs', command: 'emacs' },\n { key: 'fleet', name: 'Fleet', command: 'fleet' },\n];\n\nexport const EDITOR_BY_KEY = new Map<string, EditorDefinition>(\n SUPPORTED_EDITORS.map((e) => [e.key, e]),\n);\n","import * as Y from 'yjs';\n\n/**\n * Generic JSON ↔ Yjs mapping.\n *\n * The cloud must share exactly what git shares: the contents of the `.runeya`\n * files, whatever fields they happen to carry today. Enumerating those fields\n * would make this a hand-maintained allowlist — adding a field to a schema and\n * forgetting it here would not break anything, it would just silently stop\n * syncing. So nothing here names a field: any JSON shape round-trips.\n *\n * The mapping is structural rather than blob-per-file, because a blob makes\n * every concurrent edit last-writer-wins across a whole file. Mapping objects to\n * `Y.Map` and arrays to `Y.Array` lets Yjs merge edits to different fields — and\n * different array elements — the way it is meant to.\n *\n * Every write is a *diff*: identical input must produce no Yjs update at all.\n * Anything less loops forever (local → doc → local → doc).\n */\n\nexport type Json = null | boolean | number | string | Json[] | { [k: string]: Json };\n\n/**\n * Strip `undefined` and other non-JSON values by round-tripping.\n *\n * Zod leaves optional fields absent while JS code tends to set them to\n * `undefined`; `Y.Map.set(k, undefined)` is not `delete(k)`, so without this the\n * diff would see a change on every pass and never settle.\n */\nexport function normalize(value: unknown): Json {\n return JSON.parse(JSON.stringify(value ?? null)) as Json;\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, Json> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\n/** Yjs value → plain JSON. */\nexport function toPlain(value: unknown): Json {\n if (value instanceof Y.Map) {\n const out: Record<string, Json> = {};\n for (const [k, v] of value.entries()) out[k] = toPlain(v);\n return out;\n }\n if (value instanceof Y.Array) return value.toArray().map(toPlain);\n return (value ?? null) as Json;\n}\n\n/**\n * Identity of an array element, used to align two versions of an array.\n *\n * An element with an `id` keeps that identity across edits, so a concurrent\n * change to one element and an insertion of another merge cleanly. Anything\n * else (scalars, objects with no id) is identified by its whole value: editing\n * it reads as delete + insert, i.e. last-writer-wins for that element.\n */\nfunction identityOf(value: Json): string {\n if (isPlainObject(value) && typeof value['id'] === 'string') return `id:${value['id']}`;\n return `v:${JSON.stringify(value)}`;\n}\n\nfunction identityOfY(value: unknown): string {\n if (value instanceof Y.Map) {\n const id = value.get('id');\n if (typeof id === 'string') return `id:${id}`;\n }\n return `v:${JSON.stringify(toPlain(value))}`;\n}\n\n/** Convert a JSON value into the Yjs type that represents it. */\nfunction toY(value: Json): unknown {\n if (Array.isArray(value)) {\n const arr = new Y.Array<unknown>();\n if (value.length > 0) arr.insert(0, value.map(toY));\n return arr;\n }\n if (isPlainObject(value)) {\n const map = new Y.Map<unknown>();\n for (const [k, v] of Object.entries(value)) map.set(k, toY(v));\n return map;\n }\n return value;\n}\n\n/**\n * Diff `next` into a `Y.Map`, recursing into nested objects and arrays and\n * deleting keys that `next` no longer has.\n */\nexport function applyToMap(map: Y.Map<unknown>, next: Record<string, Json>): void {\n for (const key of Array.from(map.keys())) {\n if (!(key in next)) map.delete(key);\n }\n for (const [key, value] of Object.entries(next)) {\n const current = map.get(key);\n if (Array.isArray(value)) {\n if (!(current instanceof Y.Array)) map.set(key, toY(value));\n else applyToArray(current, value);\n } else if (isPlainObject(value)) {\n if (!(current instanceof Y.Map)) map.set(key, toY(value));\n else applyToMap(current, value);\n } else if (current instanceof Y.Map || current instanceof Y.Array || current !== value) {\n map.set(key, value);\n }\n }\n}\n\n/**\n * Diff `next` into a `Y.Array` by aligning elements on their identity.\n *\n * Targeted inserts/deletes are what let Yjs keep both sides of a concurrent\n * append; rewriting the array wholesale (delete-all + insert) would drop one of\n * them, which is exactly the data loss this mapping exists to avoid.\n */\nexport function applyToArray(arr: Y.Array<unknown>, next: Json[]): void {\n const wanted = next.map(identityOf);\n const wantedCount = new Map<string, number>();\n for (const k of wanted) wantedCount.set(k, (wantedCount.get(k) ?? 0) + 1);\n\n // Drop elements `next` no longer contains (respecting duplicate counts).\n const seen = new Map<string, number>();\n for (let i = arr.length - 1; i >= 0; i--) {\n const key = identityOfY(arr.get(i));\n const used = seen.get(key) ?? 0;\n if (used >= (wantedCount.get(key) ?? 0)) arr.delete(i, 1);\n else seen.set(key, used + 1);\n }\n\n // Walk both sides in order: recurse into matches, insert what is missing.\n for (let j = 0; j < next.length; j++) {\n const key = wanted[j]!;\n if (j < arr.length && identityOfY(arr.get(j)) === key) {\n const current = arr.get(j);\n const value = next[j]!;\n if (current instanceof Y.Map && isPlainObject(value)) applyToMap(current, value);\n else if (current instanceof Y.Array && Array.isArray(value)) applyToArray(current, value);\n continue;\n }\n // Pull a later match into place rather than re-creating it, so a reorder\n // does not read as a delete + insert of unrelated content.\n let found = -1;\n for (let k = j + 1; k < arr.length; k++) {\n if (identityOfY(arr.get(k)) === key) {\n found = k;\n break;\n }\n }\n if (found !== -1) {\n const moved = toPlain(arr.get(found));\n arr.delete(found, 1);\n arr.insert(j, [toY(moved)]);\n } else {\n arr.insert(j, [toY(next[j]!)]);\n }\n }\n}\n\n/** A collection of entities keyed by id: `doc.getMap(name)` → `{ [id]: Y.Map }`. */\nexport function getCollection(doc: Y.Doc, name: string): Y.Map<unknown> {\n return doc.getMap(name);\n}\n\n/** Read one entity as plain JSON, or null when absent/malformed. */\nexport function readEntity(collection: Y.Map<unknown>, id: string): Record<string, Json> | null {\n const entity = collection.get(id);\n if (!(entity instanceof Y.Map)) return null;\n const plain = toPlain(entity);\n return isPlainObject(plain) ? plain : null;\n}\n\n/**\n * Write one entity, mutating only what differs. Must run inside\n * `doc.transact(..., origin)` so the bridge can tell local writes from remote.\n */\nexport function writeEntity(collection: Y.Map<unknown>, id: string, entity: unknown): void {\n const next = normalize(entity);\n if (!isPlainObject(next)) return;\n const current = collection.get(id);\n if (!(current instanceof Y.Map)) {\n collection.set(id, toY(next));\n return;\n }\n applyToMap(current, next);\n}\n","import { spawn, type ChildProcess } from 'node:child_process';\nimport { createInterface } from 'node:readline';\nimport { watch } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { env } from '../config/env.js';\nimport { PASSPHRASE_TIMEOUT } from '@runeya/packages-shared';\nimport { agentManager } from './agent-manager.js';\nimport { deriveStableSecret } from '../utils/encryption-key.js';\n\n/**\n * Build a minimal environment for the spawned agent process.\n * Only pass system-essential and explicitly needed variables —\n * never spread all of process.env to avoid leaking secrets.\n *\n * Returns null if encryption key is not available (setup mode).\n */\nfunction buildAgentEnv(): Record<string, string> | null {\n const safeKeys = [\n 'PATH', 'HOME', 'USER', 'SHELL', 'LANG', 'TERM', 'NODE_ENV', 'TMPDIR', 'TZ',\n 'DBUS_SESSION_BUS_ADDRESS', 'XDG_RUNTIME_DIR',\n // Needed so the agent can talk to the user's clipboard for the chat image-paste flow\n // (xclip needs DISPLAY/XAUTHORITY, wl-copy needs WAYLAND_DISPLAY).\n 'DISPLAY', 'XAUTHORITY', 'WAYLAND_DISPLAY', 'XDG_SESSION_TYPE',\n ];\n const agentEnv: Record<string, string> = {\n RUNEYA_AGENT_PORT: String(env.RUNEYA_AGENT_PORT),\n RUNEYA_AGENT_HOST: env.RUNEYA_AGENT_HOST,\n };\n\n // In local-simple mode, use a stable passphrase derived from encryption key\n // (allows committing agents.json without constant changes on restart)\n if (env.MODE === 'local-simple') {\n const passphrase = deriveStableSecret('local-agent-passphrase');\n if (!passphrase) {\n // Encryption key not available — cannot spawn agent\n return null;\n }\n agentEnv.PASSPHRASE_OVERRIDE = passphrase;\n }\n\n for (const key of safeKeys) {\n if (process.env[key]) {\n agentEnv[key] = process.env[key]!;\n }\n }\n\n return agentEnv;\n}\n\nconst LOCAL_AGENT_ID = 'local-agent';\nconst LOCAL_AGENT_NAME = 'local';\n\nclass AgentSpawner {\n private agentProcess: ChildProcess | null = null;\n private exitHandlerRegistered = false;\n private fileWatcher: ReturnType<typeof watch> | null = null;\n private isRestarting = false;\n private agentDistPath: string | null = null;\n\n async spawnLocalAgent(): Promise<void> {\n const agentUrl = `http://${env.RUNEYA_AGENT_HOST}:${env.RUNEYA_AGENT_PORT}`;\n\n // Check if encryption key is available\n const agentEnv = buildAgentEnv();\n if (!agentEnv) {\n console.log('[agent-spawner] ⚠️ Cannot spawn local agent: encryption key not available');\n console.log('[agent-spawner] Please provide the encryption key via the setup UI');\n return;\n }\n\n console.log(`[agent-spawner] Spawning local agent on ${agentUrl}...`);\n\n const isDev = process.env.NODE_ENV === 'development';\n // Use AGENT_BINARY_PATH if provided (e.g., from CLI), otherwise resolve\n // relative to this file's location — process.cwd() is unreliable because\n // the server chdir's into the user's stack root when DATA_DIR is set.\n this.agentDistPath = env.AGENT_BINARY_PATH\n || join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'agent', 'dist', 'index.js');\n\n // Always spawn from dist/index.js (built by tsup watch in dev mode)\n this.agentProcess = spawn('node', [this.agentDistPath], {\n env: agentEnv,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n if (isDev) {\n // In dev mode, watch dist/index.js and restart agent when it changes\n // (tsup --watch rebuilds this file when src/ changes)\n this.setupFileWatcher();\n }\n\n // Safety net: kill agent synchronously when server process exits for any reason\n // (e.g. Ctrl+C via Turbo/tsup where async shutdown may not complete)\n if (!this.exitHandlerRegistered) {\n this.exitHandlerRegistered = true;\n process.on('exit', () => {\n if (this.agentProcess && !this.agentProcess.killed) {\n this.agentProcess.kill('SIGKILL');\n }\n });\n }\n\n // Parse passphrase from stdout\n const passphrase = await this.waitForPassphrase();\n if (!passphrase) {\n console.error('[agent-spawner] Failed to get passphrase from local agent');\n return;\n }\n\n console.log('[agent-spawner] Local agent started, passphrase received');\n\n // Register the local agent (in-memory only — no persistence to agents.json)\n await agentManager.registerLocal({ id: LOCAL_AGENT_ID, name: LOCAL_AGENT_NAME, url: agentUrl, passphrase, passthroughEnv: [] });\n console.log(`[agent-spawner] Local agent registered as ${LOCAL_AGENT_ID}`);\n }\n\n private waitForPassphrase(): Promise<string | null> {\n return new Promise((resolve) => {\n if (!this.agentProcess?.stdout) {\n resolve(null);\n return;\n }\n\n const rl = createInterface({ input: this.agentProcess.stdout });\n const timeout = setTimeout(() => {\n resolve(null);\n }, PASSPHRASE_TIMEOUT);\n\n let initialPassphraseFound = false;\n\n rl.on('line', (line) => {\n const match = line.match(/^RUNEYA_PASSPHRASE=([a-f0-9]{64})$/);\n if (match) {\n const newPassphrase = match[1];\n\n if (!initialPassphraseFound) {\n // First passphrase - resolve the promise to complete initial spawn\n initialPassphraseFound = true;\n clearTimeout(timeout);\n resolve(newPassphrase);\n } else {\n // Agent reloaded (tsx watch) - update the passphrase\n console.log('[agent-spawner] 🔄 Agent reloaded, updating passphrase...');\n this.updateAgentPassphrase(newPassphrase).catch((err: Error) => {\n console.error('[agent-spawner] Failed to update passphrase after reload:', err);\n });\n }\n // Don't print the passphrase line\n return;\n }\n // Print all non-passphrase agent stdout\n console.log(`[agent] ${line}`);\n });\n\n // Forward stderr permanently\n if (this.agentProcess?.stderr) {\n const stderrRl = createInterface({ input: this.agentProcess.stderr });\n stderrRl.on('line', (line) => {\n console.error(`[agent:err] ${line}`);\n });\n }\n\n this.agentProcess?.on('error', (err) => {\n console.error('[agent-spawner] Failed to spawn agent:', err);\n clearTimeout(timeout);\n if (!initialPassphraseFound) resolve(null);\n });\n\n this.agentProcess?.on('exit', (code) => {\n if (code !== null && code !== 0) {\n console.error(`[agent-spawner] Agent exited with code ${code}`);\n }\n clearTimeout(timeout);\n if (!initialPassphraseFound) resolve(null);\n });\n });\n }\n\n async shutdown(): Promise<void> {\n if (this.fileWatcher) {\n this.fileWatcher.close();\n this.fileWatcher = null;\n }\n\n if (this.agentProcess) {\n console.log('[agent-spawner] Stopping local agent...');\n // SIGKILL for immediate port release — the local agent is stateless\n // so graceful shutdown is unnecessary.\n this.agentProcess.kill('SIGKILL');\n\n await new Promise<void>((resolve) => {\n this.agentProcess?.on('exit', () => resolve());\n // Safety timeout in case 'exit' never fires\n setTimeout(resolve, 2_000);\n });\n\n this.agentProcess = null;\n }\n }\n\n getLocalAgentId(): string | null {\n return LOCAL_AGENT_ID;\n }\n\n private async updateAgentPassphrase(newPassphrase: string): Promise<void> {\n const agentUrl = `http://${env.RUNEYA_AGENT_HOST}:${env.RUNEYA_AGENT_PORT}`;\n await agentManager.registerLocal({ id: LOCAL_AGENT_ID, name: LOCAL_AGENT_NAME, url: agentUrl, passphrase: newPassphrase, passthroughEnv: [] });\n console.log(`[agent-spawner] ✅ Agent passphrase updated, re-registered as ${LOCAL_AGENT_ID}`);\n }\n\n private setupFileWatcher(): void {\n if (!this.agentDistPath) return;\n\n // Close previous watcher if it exists (important for hot reload to keep working)\n if (this.fileWatcher) {\n this.fileWatcher.close();\n }\n\n console.log('[agent-spawner] 🔍 Watching agent dist for changes (hot reload enabled)');\n\n // Watch the dist/ directory instead of the file itself — tsup \"cleans\" the folder\n // (delete + recreate) on every rebuild, which causes fs.watch on a file to lose\n // its inode and stop firing. Watching the directory captures rename/add events too.\n const distDir = join(this.agentDistPath, '..');\n this.fileWatcher = watch(distDir, { persistent: false }, (eventType, filename) => {\n if ((eventType === 'change' || eventType === 'rename') && filename === 'index.js' && !this.isRestarting) {\n this.isRestarting = true;\n console.log('[agent-spawner] 🔄 Agent code changed, restarting...');\n\n // In dev mode, kill immediately for fast hot reload (no graceful shutdown needed)\n if (this.agentProcess && !this.agentProcess.killed) {\n const oldProcess = this.agentProcess;\n\n // Wait for process to fully exit before restarting\n oldProcess.once('exit', () => {\n // Give OS a moment to release the port\n setTimeout(() => {\n this.restartAgent().catch((err: Error) => {\n console.error('[agent-spawner] Failed to restart agent:', err);\n this.isRestarting = false;\n });\n }, 100);\n });\n\n // SIGKILL immediately for instant hot reload\n oldProcess.kill('SIGKILL');\n }\n }\n });\n this.fileWatcher.on('error', (err: NodeJS.ErrnoException) => {\n console.error('[agent-spawner] File watcher error:', err.message);\n });\n }\n\n private async restartAgent(): Promise<void> {\n if (!this.agentDistPath) return;\n\n const agentEnv = buildAgentEnv();\n if (!agentEnv) {\n console.log('[agent-spawner] Cannot restart agent: encryption key not available');\n this.isRestarting = false;\n return;\n }\n\n const agentUrl = `http://${env.RUNEYA_AGENT_HOST}:${env.RUNEYA_AGENT_PORT}`;\n const isDev = process.env.NODE_ENV === 'development';\n\n // Spawn new agent process\n this.agentProcess = spawn('node', [this.agentDistPath], {\n env: agentEnv,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n // Setup stdout/stderr forwarding and passphrase detection\n if (this.agentProcess?.stdout) {\n const rl = createInterface({ input: this.agentProcess.stdout });\n rl.on('line', (line) => {\n const match = line.match(/^RUNEYA_PASSPHRASE=([a-f0-9]{64})$/);\n if (match) {\n const newPassphrase = match[1];\n // Update agent registration with new passphrase (in-memory only)\n agentManager.registerLocal({ id: LOCAL_AGENT_ID, name: LOCAL_AGENT_NAME, url: agentUrl, passphrase: newPassphrase, passthroughEnv: [] })\n .then(() => {\n console.log(`[agent-spawner] ✅ Agent restarted and re-registered as ${LOCAL_AGENT_ID}`);\n this.isRestarting = false;\n\n // Recreate file watcher for next hot reload (fs.watch can lose tracking after file replace)\n if (isDev) {\n this.setupFileWatcher();\n }\n })\n .catch((err: Error) => {\n console.error('[agent-spawner] Failed to register agent after restart:', err);\n this.isRestarting = false;\n });\n return;\n }\n console.log(`[agent] ${line}`);\n });\n }\n\n if (this.agentProcess?.stderr) {\n const stderrRl = createInterface({ input: this.agentProcess.stderr });\n stderrRl.on('line', (line) => {\n console.error(`[agent:err] ${line}`);\n });\n }\n }\n}\n\nexport const agentSpawner = new AgentSpawner();\n","import { stableEncryptValue, decryptValue, isEncryptedValue } from './crypto-helpers.js';\n\nclass TraefikManager {\n encryptDnsCredentials(credentials: Record<string, string>): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(credentials)) {\n result[key] = isEncryptedValue(value) ? value : stableEncryptValue(value);\n }\n return result;\n }\n\n decryptDnsCredentials(credentials: Record<string, string>): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(credentials)) {\n if (isEncryptedValue(value)) {\n try {\n result[key] = decryptValue(value);\n } catch {\n console.error(`[traefik-manager] Failed to decrypt credential: ${key}`);\n result[key] = '';\n }\n } else {\n result[key] = value;\n }\n }\n return result;\n }\n}\n\nexport const traefikManager = new TraefikManager();\n","import { EventEmitter } from 'node:events';\nimport WebSocket from 'ws';\nimport { WS_RECONNECT_MIN, WS_RECONNECT_MAX } from '@runeya/packages-shared';\n\n/**\n * tRPC WS JSON-RPC protocol message types:\n * → { id, method: \"subscription\", params: { path, input } }\n * ← { id, result: { type: \"started\" } }\n * ← { id, result: { type: \"data\", data } }\n * ← { id, result: { type: \"stopped\" } }\n */\n\ninterface TRPCRequest {\n id: number;\n method: 'subscription';\n params: { path: string; input?: unknown };\n}\n\ninterface TRPCResponse {\n id: number;\n result?: {\n type: 'started' | 'data' | 'stopped';\n data?: unknown;\n };\n error?: unknown;\n}\n\ninterface SubscriptionInfo {\n eventType?: string; // e.g. 'process:status' — for static fan-out subscriptions\n onData?: (data: unknown) => void; // for dynamic per-session subscriptions\n onStop?: () => void;\n}\n\nconst SUBSCRIPTION_PATHS: Array<{ path: string; eventType: string }> = [\n { path: 'process.onStatus', eventType: 'process:status' },\n { path: 'process.onLog', eventType: 'process:log' },\n { path: 'process.onHealth', eventType: 'process:health' },\n { path: 'process.onMetrics', eventType: 'process:metrics' },\n];\n\n/**\n * AgentWSBridge opens a WebSocket connection to an agent's tRPC endpoint\n * and subscribes to all process-related subscriptions using the raw\n * tRPC JSON-RPC protocol. Events are emitted with the agentId attached.\n */\nconst PING_INTERVAL_MS = 30_000;\nconst PONG_TIMEOUT_MS = 10_000;\n\nexport class AgentWSBridge extends EventEmitter {\n private ws: WebSocket | null = null;\n private nextId = 1;\n private subscriptions: Map<number, SubscriptionInfo> = new Map();\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private currentReconnectDelay = WS_RECONNECT_MIN;\n private closed = false;\n private pingInterval: ReturnType<typeof setInterval> | null = null;\n private pongTimeout: ReturnType<typeof setTimeout> | null = null;\n private connectionErrorLogged = false;\n\n constructor(\n private agentId: string,\n private url: string,\n private passphrase: string,\n ) {\n super();\n }\n\n connect(): void {\n if (this.closed) return;\n this.cleanup();\n\n const httpUrl = new URL(this.url);\n const wsProtocol = httpUrl.protocol === 'https:' ? 'wss:' : 'ws:';\n // tRPC WS endpoint is at the root (default upgrade path, not /ws/health)\n const wsUrl = `${wsProtocol}//${httpUrl.host}`;\n\n try {\n this.ws = new WebSocket(wsUrl, {\n headers: { 'Authorization': `Bearer ${this.passphrase}` },\n });\n } catch {\n this.scheduleReconnect();\n return;\n }\n\n this.ws.on('open', () => {\n console.log(`[agent-ws-bridge] ✅ Connected to agent ${this.agentId}`);\n this.currentReconnectDelay = WS_RECONNECT_MIN;\n this.connectionErrorLogged = false;\n this.startHeartbeat();\n this.subscribeAll();\n console.log(`[agent-ws-bridge] Created ${SUBSCRIPTION_PATHS.length} subscriptions for agent ${this.agentId}`);\n });\n\n this.ws.on('message', (raw: Buffer | string) => {\n try {\n const msg: TRPCResponse = JSON.parse(\n typeof raw === 'string' ? raw : raw.toString(),\n );\n this.handleMessage(msg);\n } catch {\n // Ignore unparseable messages\n }\n });\n\n this.ws.on('pong', () => {\n if (this.pongTimeout) { clearTimeout(this.pongTimeout); this.pongTimeout = null; }\n });\n\n this.ws.on('close', () => {\n if (!this.connectionErrorLogged) {\n console.log(`[agent-ws-bridge] ❌ Disconnected from agent ${this.agentId}`);\n }\n this.stopHeartbeat();\n this.ws = null;\n this.subscriptions.clear();\n if (!this.closed) {\n if (!this.connectionErrorLogged) {\n console.log(`[agent-ws-bridge] Scheduling reconnect for agent ${this.agentId} in ${this.currentReconnectDelay}ms`);\n }\n this.scheduleReconnect();\n }\n });\n\n this.ws.on('error', (err) => {\n if (!this.connectionErrorLogged) {\n console.debug('[agent-ws-bridge] WS error for agent', this.agentId + ':', err.message);\n this.connectionErrorLogged = true;\n }\n // 'error' is always followed by 'close'\n });\n }\n\n /**\n * Subscribe to a dynamic tRPC path with an input payload.\n * Returns an unsubscribe function that cleans up on the agent side.\n * Used for per-session subscriptions (e.g. terminal.onData).\n */\n subscribeWithInput(\n path: string,\n input: unknown,\n onData: (data: unknown) => void,\n onStop?: () => void,\n ): () => void {\n const id = this.nextId++;\n this.subscriptions.set(id, { onData, onStop });\n\n if (this.ws?.readyState === WebSocket.OPEN) {\n const msg: TRPCRequest = { id, method: 'subscription', params: { path, input } };\n this.ws.send(JSON.stringify(msg));\n }\n // If WS is not open, we still store the subscription — but it won't receive data.\n // The caller should handle this (e.g. create session only when agent is connected).\n\n return () => {\n this.subscriptions.delete(id);\n if (this.ws?.readyState === WebSocket.OPEN) {\n // tRPC v11 stop message\n this.ws.send(JSON.stringify({ id, method: 'subscription.stop' }));\n }\n };\n }\n\n disconnect(): void {\n this.closed = true;\n this.cleanup();\n }\n\n private startHeartbeat(): void {\n this.stopHeartbeat();\n this.pingInterval = setInterval(() => {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;\n this.pongTimeout = setTimeout(() => {\n console.log(`[agent-ws-bridge] Pong timeout for agent ${this.agentId}, closing connection`);\n this.ws?.terminate();\n }, PONG_TIMEOUT_MS);\n this.ws.ping();\n }, PING_INTERVAL_MS);\n }\n\n private stopHeartbeat(): void {\n if (this.pingInterval) { clearInterval(this.pingInterval); this.pingInterval = null; }\n if (this.pongTimeout) { clearTimeout(this.pongTimeout); this.pongTimeout = null; }\n }\n\n private cleanup(): void {\n this.stopHeartbeat();\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n // Remove all user listeners, but keep a no-op error handler\n // to prevent unhandled error events when closing in CONNECTING state\n this.ws.removeAllListeners();\n this.ws.on('error', () => {});\n this.ws.close();\n this.ws = null;\n }\n this.subscriptions.clear();\n }\n\n private subscribeAll(): void {\n for (const { path, eventType } of SUBSCRIPTION_PATHS) {\n this.sendSubscription(path, eventType);\n }\n }\n\n private sendSubscription(path: string, eventType: string): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;\n\n const id = this.nextId++;\n this.subscriptions.set(id, { eventType });\n\n const msg: TRPCRequest = {\n id,\n method: 'subscription',\n params: { path },\n };\n\n this.ws.send(JSON.stringify(msg));\n }\n\n private handleMessage(msg: TRPCResponse): void {\n const sub = this.subscriptions.get(msg.id);\n if (!sub) return;\n\n if (msg.result?.type === 'data' && msg.result.data !== undefined) {\n const data = msg.result.data;\n\n if (sub.onData) {\n // Dynamic subscription — forward raw data to callback\n sub.onData(data);\n } else if (sub.eventType) {\n if (typeof data !== 'object' || data === null) return;\n // Log batches arrive as arrays — emit with agentId attached for filtering\n if (Array.isArray(data)) {\n this.emit(sub.eventType, { batch: data, agentId: this.agentId });\n } else {\n // Spread agent data first, then override agentId with the trusted value\n // to prevent a compromised agent from spoofing its identity\n this.emit(sub.eventType, {\n ...(data as Record<string, unknown>),\n agentId: this.agentId,\n });\n }\n }\n } else if (msg.result?.type === 'started') {\n const label = sub.eventType ?? '(dynamic)';\n console.log(`[agent-ws-bridge] ✅ Subscription ${label} started for agent ${this.agentId}`);\n } else if (msg.result?.type === 'stopped') {\n const label = sub.eventType ?? '(dynamic)';\n console.log(`[agent-ws-bridge] ⏹️ Subscription ${label} stopped for agent ${this.agentId}`);\n if (sub.onStop) sub.onStop();\n this.subscriptions.delete(msg.id);\n } else if (msg.error) {\n const label = sub.eventType ?? '(dynamic)';\n console.debug('[agent-ws-bridge] Subscription error for', label, 'on agent', this.agentId + ':', msg.error);\n if (sub.onStop) sub.onStop();\n this.subscriptions.delete(msg.id);\n }\n }\n\n private scheduleReconnect(): void {\n if (this.closed || this.reconnectTimer) return;\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n if (!this.closed) {\n this.connect();\n }\n }, this.currentReconnectDelay);\n\n this.currentReconnectDelay = Math.min(this.currentReconnectDelay * 2, WS_RECONNECT_MAX);\n }\n}\n"],"mappings":"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","names":["EventEmitter","WebSocket","z","readFile","writeFile","mkdir","readFile","mkdir","writeFile","randomUUID","readFile","writeFile","rename","mkdir","chmod","join","ref","randomUUID","readFile","writeFile","rename","mkdir","chmod","join","randomBytes","createCipheriv","createDecipheriv","ALGORITHM","randomBytes","createCipheriv","createDecipheriv","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","createCipheriv","createDecipheriv","randomBytes","FILENAME","join","readFile","mkdir","writeFile","rename","chmod","randomUUID","env","FILENAME","join","readFile","mkdir","writeFile","rename","chmod","randomUUID","dirname","join","join","dirname","z","EventEmitter","conn","WebSocket","spawn"]}
|