@runeya/runeya 2.0.102 → 2.0.103
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-manager-OWHTBG46.js +9 -0
- package/assets/icon-alert.ico +0 -0
- package/assets/icon-alert.png +0 -0
- package/assets/icon-alert.svg +19 -0
- package/{chat-OXRRBDB3.js → chat-JZ4UQDWV.js} +8 -7
- package/chunk-KY6KYSOU.js +279 -0
- package/chunk-KY6KYSOU.js.map +1 -0
- package/{chunk-PSTMO7EE.js → chunk-NZNIWJDT.js} +18 -16
- package/{chunk-PSTMO7EE.js.map → chunk-NZNIWJDT.js.map} +1 -1
- package/chunk-PH4E5WDN.js +137 -0
- package/chunk-PH4E5WDN.js.map +1 -0
- package/{chunk-BHLCBARP.js → chunk-QIBUMYR6.js} +29 -11
- package/chunk-QIBUMYR6.js.map +1 -0
- package/{chunk-NDO5VFZY.js → chunk-QRMG6GMX.js} +694 -917
- package/chunk-QRMG6GMX.js.map +1 -0
- package/{chunk-BDVQB5RK.js → chunk-UYOWIH4R.js} +23 -21
- package/{chunk-BDVQB5RK.js.map → chunk-UYOWIH4R.js.map} +1 -1
- package/{chunk-F3HKV5AU.js → chunk-Z67WBWKD.js} +7 -5
- package/{chunk-F3HKV5AU.js.map → chunk-Z67WBWKD.js.map} +1 -1
- package/{companion-JQGNL4U7.js → companion-6J6NK7H7.js} +5 -4
- package/{desktop-launcher-FHNURZA7.js → desktop-launcher-N7WRF3LC.js} +11 -17
- package/desktop-launcher-N7WRF3LC.js.map +1 -0
- package/index.js +64 -2
- package/index.js.map +1 -1
- package/instances-command-KZ5UGXOR.js +17 -0
- package/package.json +4 -1
- package/settings-manager-NZV26BC3.js +9 -0
- package/settings-manager-NZV26BC3.js.map +1 -0
- package/{src-HZ2XO6TV.js → src-V7DPPFCF.js} +447 -254
- package/src-V7DPPFCF.js.map +1 -0
- package/tray-TRWZNOUD.js +291 -0
- package/tray-TRWZNOUD.js.map +1 -0
- package/web/assets/AgentScalarChatInterface.vue-CvG5ha3R.js +13 -0
- package/web/assets/AgentTerminalPage-DcGppuzO.js +1 -0
- package/web/assets/AiChatPage-BDr5tG0A.js +1 -0
- package/web/assets/{AppLayout-DeWqCLuK.css → AppLayout-CYQBjQBU.css} +1 -1
- package/web/assets/AppLayout-Dv3ViAk2.js +1 -0
- package/web/assets/AuditPage-Bc2jlgZJ.js +1 -0
- package/web/assets/CloudAccountPage-4BLXSOix.js +1 -0
- package/web/assets/CloudAccountPage-B3MX6DNn.js +1 -0
- package/web/assets/CloudMessagingPage-CVzUalxx.js +2 -0
- package/web/assets/DashboardPage-Bo51pbzt.js +1 -0
- package/web/assets/DirectoryPickerDialog-CIVjWKUm.js +1 -0
- package/web/assets/{EditorIcon-C9XKLhc7.js → EditorIcon-BguaWtZg.js} +2 -2
- package/web/assets/{EnvironmentForm-bS48MK8k.js → EnvironmentForm-D8dq0ffR.js} +2 -2
- package/web/assets/EnvironmentFormPage-d8p3q8Yt.js +1 -0
- package/web/assets/EnvironmentListPage-DWo2lWjE.js +1 -0
- package/web/assets/KanbanBoardPage-DkwIz3J1.js +4 -0
- package/web/assets/KanbanListPage-xIQRLcrS.js +1 -0
- package/web/assets/LaunchProjectPage-CXWixUmf.js +1 -0
- package/web/assets/LaunchServicesPage-nv-chYgX.js +1 -0
- package/web/assets/LogViewer-DLupfjjf.js +3 -0
- package/web/assets/OrgKeyPrompt-DePcB-8f.js +1 -0
- package/web/assets/ProcessControls-D3zTnHb2.js +1 -0
- package/web/assets/ProcessDetailPage-CgVGzRoJ.js +1 -0
- package/web/assets/{ProcessMetrics-CBPR5ozp.js → ProcessMetrics-Dwd5lzqY.js} +2 -2
- package/web/assets/ProjectDetailPage-HR20KyJ3.js +1 -0
- package/web/assets/ProjectListPage-DcH4uTTX.js +1 -0
- package/web/assets/RandomJobTestPage-BYTkVcdE.js +2 -0
- package/web/assets/ScenarioEditorPage-zRxR03Ud.js +14 -0
- package/web/assets/SendToChatDialog-Cm5eKBOb.js +1 -0
- package/web/assets/ServiceControlsBar-oBpAP9yX.js +1 -0
- package/web/assets/ServiceDetailPage-CahBi-or.js +2 -0
- package/web/assets/ServiceFormPage-DfmPM_mI.js +1 -0
- package/web/assets/SettingsPage-CDMXFJ4k.js +2063 -0
- package/web/assets/SettingsPage-Dw6tbcbw.css +1 -0
- package/web/assets/UnlockPage-BUyBEPzQ.js +1 -0
- package/web/assets/VariablesTable-Dc6CyVQW.js +1 -0
- package/web/assets/VaultMigrationPage-BUmzyDXN.js +1 -0
- package/web/assets/VersionBadge-Dx_67FtC.js +1 -0
- package/web/assets/WikiPage-DEMJLDpD.js +1 -0
- package/web/assets/WikiView-CcrQ2ySx.js +1 -0
- package/web/assets/add-scalar-classes-M_EBdf4f.js +387 -0
- package/web/assets/{autocomplete-CtIxw1IN.js → autocomplete-QtPLLzzV.js} +3 -3
- package/web/assets/{basic-shape-diamond.svg-BErisM9Y.js → basic-shape-diamond.svg-Dyx8FJkS.js} +1 -1
- package/web/assets/{basic-shape-hexagon.svg-yC7RoYpa.js → basic-shape-hexagon.svg-1RKdVP3_.js} +1 -1
- package/web/assets/{basic-shape-primary-circle-ellipse-round.svg-DRmanUIO.js → basic-shape-primary-circle-ellipse-round.svg-CSa69hok.js} +1 -1
- package/web/assets/{basic-shape-primary-square-rectangle.svg-DxuoouSj.js → basic-shape-primary-square-rectangle.svg-B9TXktd4.js} +1 -1
- package/web/assets/{basic-shape-shield.svg-Cy_Frn-W.js → basic-shape-shield.svg-BZvKXoiw.js} +1 -1
- package/web/assets/{browser-h0mxWbci.js → browser-CYeKc8Uo.js} +1 -1
- package/web/assets/{browser-Dj3qxJqB.js → browser-VlhbsseI.js} +1 -1
- package/web/assets/card-tEWfv-Op.js +32 -0
- package/web/assets/{checkbox-CTw-YDe_.js → checkbox-CyPqKR6H.js} +3 -3
- package/web/assets/{chip-DwSSTlaC.js → chip-wM0gJ_FI.js} +2 -2
- package/web/assets/client-B919VgbS.js +24 -0
- package/web/assets/cloud-chat.store-C-A9nIqG.js +1 -0
- package/web/assets/cloud-session-g6ewm0UI.js +1 -0
- package/web/assets/column-DihIO4Zd.js +907 -0
- package/web/assets/{computer-device-desktop-monitor.svg-TLZAKrIM.js → computer-device-desktop-monitor.svg-ClbIVuot.js} +1 -1
- package/web/assets/{computer-device-desktop.svg-YRcL_Qxn.js → computer-device-desktop.svg-CXpOovTP.js} +1 -1
- package/web/assets/{computer-device-laptop.svg-CZUEbqra.js → computer-device-laptop.svg-C9sY1wZv.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-android-samsung-back.svg-CcsmeFGb.js → computer-device-mobile-phone-android-samsung-back.svg-CPWC2QHX.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-android-samsung.svg-CXjVvTBT.js → computer-device-mobile-phone-android-samsung.svg-B0H-mnfh.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-iphone-x-back.svg-BQQXUoZZ.js → computer-device-mobile-phone-iphone-x-back.svg-BbIunxoN.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-iphone-x.svg-CG8VbAP-.js → computer-device-mobile-phone-iphone-x.svg-qLGK_oVA.js} +1 -1
- package/web/assets/{computer-device-mobile-tablet-touch.svg-DDMUt0S4.js → computer-device-mobile-tablet-touch.svg-BDpuB6SD.js} +1 -1
- package/web/assets/{computer-device-mobile-tablet.svg-CBXtF47n.js → computer-device-mobile-tablet.svg-44THWP9E.js} +1 -1
- package/web/assets/{computer-device-network-ethernet-cat6.svg-ObjUhwds.js → computer-device-network-ethernet-cat6.svg-tlgWltl_.js} +1 -1
- package/web/assets/{computer-device-network-lan-www.svg-NGYEGuba.js → computer-device-network-lan-www.svg-Bd7Ch4QN.js} +1 -1
- package/web/assets/{computer-device-network-wifi-connection.svg-CSnNdKGm.js → computer-device-network-wifi-connection.svg-D_XjoY-a.js} +1 -1
- package/web/assets/{computer-device-network-wifi-router.svg-CG7iHt_n.js → computer-device-network-wifi-router.svg-BRpuwgUx.js} +1 -1
- package/web/assets/{cssMode-Bclh_xI1.js → cssMode-D0M5mbRd.js} +1 -1
- package/web/assets/{divider-Bb31-CFf.js → divider-gPnMjjpJ.js} +2 -2
- package/web/assets/{docx-preview-seOy1U3d.js → docx-preview-CBPtwrA0.js} +1 -1
- package/web/assets/{ecology-science-erlenmeyer-flask.svg-B8emvJ_p.js → ecology-science-erlenmeyer-flask.svg-CZ3uUeBT.js} +1 -1
- package/web/assets/{fieldset-Czp1Leik.js → fieldset-BSGgRmpr.js} +2 -2
- package/web/assets/{freemarker2-D87vjb6-.js → freemarker2-BWsK2SIi.js} +1 -1
- package/web/assets/{handlebars-CjY4u0vA.js → handlebars-CHNB1gG0.js} +1 -1
- package/web/assets/{html-C5pOjLe-.js → html-COwA9Dtl.js} +1 -1
- package/web/assets/{htmlMode-CunB4Bjm.js → htmlMode-gZ2_PUDA.js} +1 -1
- package/web/assets/{image-flash-lightning.svg-7dRFt_k5.js → image-flash-lightning.svg-Iiwm_7-K.js} +1 -1
- package/web/assets/{image-picture-flower.svg-ATG6mf9B.js → image-picture-flower.svg-BP9U6YP8.js} +1 -1
- package/web/assets/{index-BMuqGGPP.js → index-mBPGEldp.js} +285 -285
- package/web/assets/{interface-alert-exclamation-diamond.svg-DuAtIVtT.js → interface-alert-exclamation-diamond.svg-BYWgnbUp.js} +1 -1
- package/web/assets/{interface-alert-exclamation-triangle-warning.svg-Bg9-FBLP.js → interface-alert-exclamation-triangle-warning.svg-CWGfXHx_.js} +1 -1
- package/web/assets/{interface-alert-information-circle.svg-C5etvhA3.js → interface-alert-information-circle.svg-88Bga8qr.js} +1 -1
- package/web/assets/{interface-award-crown.svg-zuAFLs7y.js → interface-award-crown.svg-3hO77oiy.js} +1 -1
- package/web/assets/{interface-bookmark.svg-CfBz0NE3.js → interface-bookmark-tag.svg-DcHwQsr0.js} +1 -1
- package/web/assets/{interface-bookmark-tag.svg-C3EKMHOq.js → interface-bookmark.svg-SfHcE95h.js} +1 -1
- package/web/assets/{interface-calendar-date-one.svg-DGYz2Prk.js → interface-calendar-date-one.svg-DdXOM9VZ.js} +1 -1
- package/web/assets/{interface-content-book-open-pages.svg-DGiJpxy1.js → interface-content-book-open-pages.svg-DD7QTDn_.js} +1 -1
- package/web/assets/{interface-content-book-page.svg-DydK46P0.js → interface-content-book-page.svg-Dd45mFzB.js} +1 -1
- package/web/assets/{interface-content-file.svg-D0pUOvAN.js → interface-content-file.svg-slPoMF5K.js} +1 -1
- package/web/assets/interface-content-folder.svg-D90zbTLh.js +1 -0
- package/web/assets/{interface-content-folder.svg-DiJ3Pfaa.js → interface-content-folder.svg-cSgXwhRh.js} +1 -1
- package/web/assets/{interface-copy-clipboard.svg-Dl3aROYy.js → interface-copy-clipboard.svg-DNy0VeWx.js} +1 -1
- package/web/assets/{interface-edit-attachment.svg-UmDFMIt5.js → interface-edit-attachment.svg-VyCAm1jc.js} +1 -1
- package/web/assets/{interface-edit-binocular.svg-Bp_8Pfer.js → interface-edit-binocular.svg-DA6QB2sn.js} +1 -1
- package/web/assets/{interface-edit-magic-wand.svg-B2A8V7mt.js → interface-edit-magic-wand.svg-D0uagBk7.js} +1 -1
- package/web/assets/{interface-edit-tool-paint-roller.svg-DKjdsVsS.js → interface-edit-tool-paint-roller.svg-ConlubSG.js} +1 -1
- package/web/assets/{interface-edit-tool-pencil.svg-DuUybI4h.js → interface-edit-tool-pencil.svg-BgNzCwXf.js} +1 -1
- package/web/assets/{interface-favorite-award.svg-DHeTFQv8.js → interface-favorite-award.svg-MLL88pIy.js} +1 -1
- package/web/assets/{interface-favorite-flag.svg-kKzUSQkq.js → interface-favorite-flag.svg-ZhM_9XJZ.js} +1 -1
- package/web/assets/{interface-favorite-heart.svg-CqMgA2mm.js → interface-favorite-heart.svg-Cqq1PV9O.js} +1 -1
- package/web/assets/{interface-favorite-star.svg-CuLj8HV6.js → interface-favorite-star.svg-YumblcRD.js} +1 -1
- package/web/assets/{interface-favorite-stars-sparkles.svg-lFQTnGOR.js → interface-favorite-stars-sparkles.svg-BH5BXXOe.js} +1 -1
- package/web/assets/{interface-hierarchy-flowchart.svg-CBbliSZq.js → interface-hierarchy-flowchart.svg-CEfCPIyC.js} +1 -1
- package/web/assets/{interface-home-house.svg-BoFlxzre.js → interface-home-house.svg-DJE_g94c.js} +1 -1
- package/web/assets/{interface-hyperlink.svg-DcKs1Vcm.js → interface-hyperlink.svg-BFhnDXDD.js} +1 -1
- package/web/assets/{interface-lighting-brightness.svg-BSNKEyEg.js → interface-lighting-brightness.svg-NwOV0KEv.js} +1 -1
- package/web/assets/{interface-lock-closed.svg-DSP-B9Ze.js → interface-lock-closed.svg-qVkplX0W.js} +1 -1
- package/web/assets/{interface-lock-open-unlock.svg-Bzg-oBHY.js → interface-lock-open-unlock.svg-D18OlPEP.js} +1 -1
- package/web/assets/{interface-login-key.svg-DG61Q1lR.js → interface-login-key.svg-CccXX7_b.js} +1 -1
- package/web/assets/{interface-search.svg-CODjdPxd.js → interface-search.svg-C6ncELaU.js} +1 -1
- package/web/assets/{interface-setting-cog.svg-CgiaBO1E.js → interface-setting-cog.svg-5LrIeBav.js} +1 -1
- package/web/assets/{interface-share-megaphone-bullhorn.svg-DM0PsgtH.js → interface-share-megaphone-bullhorn.svg-C-qB4VYi.js} +1 -1
- package/web/assets/{interface-share-rocket.svg-B0geTs35.js → interface-share-rocket.svg-Citzuyng.js} +1 -1
- package/web/assets/{interface-share-satellite.svg-v9Q6QwAp.js → interface-share-satellite.svg-BldpdKdo.js} +1 -1
- package/web/assets/{interface-share-space-ship.svg-CLdqgzgZ.js → interface-share-space-ship.svg-B_Ni34rB.js} +1 -1
- package/web/assets/{interface-share.svg-Cx3VhLuj.js → interface-share.svg-FAt7Kgad.js} +1 -1
- package/web/assets/{interface-signal-square.svg-By_pQLw8.js → interface-signal-square.svg-DeBP6Pim.js} +1 -1
- package/web/assets/{interface-time-clock-circle.svg-Co3P-TM3.js → interface-time-clock-circle.svg-dQfNY8BC.js} +1 -1
- package/web/assets/{interface-time-hour-glass.svg-BYSOzVeD.js → interface-time-hour-glass.svg-ylbFnlwY.js} +1 -1
- package/web/assets/{interface-users-multiple.svg-moFZaev3.js → interface-users-multiple.svg-DXts3WMC.js} +1 -1
- package/web/assets/{interface-weather-moon.svg-DhyTNivv.js → interface-weather-moon.svg-BG6mjCih.js} +1 -1
- package/web/assets/{javascript-B1fZNcy6.js → javascript-C_ENjImO.js} +1 -1
- package/web/assets/{jsonMode-BxZ6OjkS.js → jsonMode-Bt-LEknD.js} +2 -2
- package/web/assets/{liquid-B58z0z3s.js → liquid-CVshgHmY.js} +1 -1
- package/web/assets/{lspLanguageFeatures-VksJLqpV.js → lspLanguageFeatures-D1e-RcOs.js} +3 -3
- package/web/assets/{mail-chat-bubble-square.svg-DU4TDENX.js → mail-chat-bubble-square.svg-RUMLqiUI.js} +1 -1
- package/web/assets/{mail-send-email-paper-airplane.svg-jk90Puk3.js → mail-send-email-paper-airplane.svg-JDe3yqOH.js} +1 -1
- package/web/assets/{mail-send-envelope.svg-CrEPc3pm.js → mail-send-envelope.svg-CCzWaeO-.js} +1 -1
- package/web/assets/{mdx-l-DSKi30.js → mdx-D9G2-Bj8.js} +1 -1
- package/web/assets/{minus-CjETE6Jb.js → minus-BMxEQL_C.js} +2 -2
- package/web/assets/modal-CZ7zYg5t.js +1 -0
- package/web/assets/modal-CmpFIC5N.js +5 -0
- package/web/assets/{money-cashier-receipt.svg-veUsiwvj.js → money-cashier-receipt.svg-DfbOr89U.js} +1 -1
- package/web/assets/{money-currency-dollar-pay.svg-C5PNkn4j.js → money-currency-dollar-pay.svg-DY7fQ7jz.js} +1 -1
- package/web/assets/{money-graph-arrow-increase.svg-BkCcnTWU.js → money-graph-arrow-increase.svg-jewlEZEL.js} +1 -1
- package/web/assets/{money-graph-bar-chart-increase.svg-BDiFSuKt.js → money-graph-bar-chart-increase.svg-BChD8dZv.js} +1 -1
- package/web/assets/multiselect-CoRzeHvy.js +251 -0
- package/web/assets/{nature-ecology-leaf.svg-CHyv9oDB.js → nature-ecology-leaf.svg-AQimnw3F.js} +1 -1
- package/web/assets/{password-BYosjMhB.js → password-4Ykb_Ejn.js} +4 -4
- package/web/assets/{phone-telephone.svg-Ce1dgyK9.js → phone-telephone.svg-BdkwIhmo.js} +1 -1
- package/web/assets/{plus-CVoE_j-e.js → plus-CYVYZlQL.js} +6 -6
- package/web/assets/process.store-CtXpHndZ.js +1 -0
- package/web/assets/{programming-bug.svg-D87My2Ok.js → programming-bug.svg-DzT817WD.js} +1 -1
- package/web/assets/{programming-cloud.svg-jUe8apKw.js → programming-cloud.svg-eKZD46YP.js} +1 -1
- package/web/assets/{programming-computer-database-server.svg-D4etrIBX.js → programming-computer-database-server.svg-BXOhjcQy.js} +1 -1
- package/web/assets/{programming-computer-database.svg-BtfkmLTx.js → programming-computer-database.svg-DUzhimFY.js} +1 -1
- package/web/assets/{programming-module-four-layout.svg-BkzsDKDq.js → programming-module-four-layout.svg-CYGX7Rlj.js} +1 -1
- package/web/assets/{programming-module-three.svg-CpzTvjGS.js → programming-module-three.svg-BhQr1m-R.js} +1 -1
- package/web/assets/{programming-module.svg-wyvB3tSR.js → programming-module.svg-Bik697Ne.js} +1 -1
- package/web/assets/{programming-script-code.svg-Dek4khNq.js → programming-script-code.svg-BaTanEvH.js} +1 -1
- package/web/assets/{python-IeHrvMxp.js → python-wDvaXe-V.js} +1 -1
- package/web/assets/{razor-CMgDmoNn.js → razor-C-cEFJP1.js} +1 -1
- package/web/assets/router-CqYmBKhe.js +1 -0
- package/web/assets/settings-scope-DD7SbjFz.js +1 -0
- package/web/assets/settings.store-DcQmvBBv.js +1 -0
- package/web/assets/{shopping-cart.svg-DeBhxyDX.js → shopping-cart.svg-BwUFrGEq.js} +1 -1
- package/web/assets/{shopping-gift-present.svg-Bt0oKBk9.js → shopping-gift-present.svg-Bs4b94QF.js} +1 -1
- package/web/assets/{shopping-shipping-box-parcel-package.svg-BEQNmjMi.js → shopping-shipping-box-parcel-package.svg-DhVaYapE.js} +1 -1
- package/web/assets/{src-C3dPv05m.js → src-CpoqK21I.js} +13 -13
- package/web/assets/src-De5rZb3_.js +1 -0
- package/web/assets/src-NB2ZR0ON.js +572 -0
- package/web/assets/tabpanel-DMt8G5AA.js +150 -0
- package/web/assets/{tag-new-circle.svg-B1i0Y1yt.js → tag-new-circle.svg-B4Z8uL1_.js} +1 -1
- package/web/assets/{toggleswitch-CcQEgLiT.js → toggleswitch-CawhRFb7.js} +2 -2
- package/web/assets/{travel-map-earth-globe.svg-CB5sqhKh.js → travel-map-earth-globe.svg-D0s5cc-W.js} +1 -1
- package/web/assets/trpc-B17uPEkC.js +1 -0
- package/web/assets/{tsMode-DoUs-yH0.js → tsMode-NHDuTjcd.js} +5 -5
- package/web/assets/{typescript-fw9OMJ0N.js → typescript-DGkgFTtn.js} +1 -1
- package/web/assets/useAiChatDrawer-BxE6EYFc.js +1 -0
- package/web/assets/{useCloudOrg-CRpEZ-iE.js → useCloudOrg-BJTjZPZ9.js} +1 -1
- package/web/assets/useProjectCatalog-DifZyVY5.js +1 -0
- package/web/assets/useProjectCloudOrg-EvyyjH6E.js +1 -0
- package/web/assets/{xml-Df6_yGan.js → xml-CJaXEqLW.js} +1 -1
- package/web/assets/{yaml-LMvM57fn.js → yaml-bl8i8xOf.js} +1 -1
- package/web/index.html +1 -1
- package/agent-manager-SNVPZNLC.js +0 -8
- package/chunk-BHLCBARP.js.map +0 -1
- package/chunk-NDO5VFZY.js.map +0 -1
- package/desktop-launcher-FHNURZA7.js.map +0 -1
- package/settings-manager-YHQ5YHUH.js +0 -8
- package/src-HZ2XO6TV.js.map +0 -1
- package/web/assets/AgentScalarChatInterface.vue-CxmPaQaj.js +0 -13
- package/web/assets/AgentTerminalPage-Bbx4zyQY.js +0 -1
- package/web/assets/AiChatPage-GPPQggxZ.js +0 -1
- package/web/assets/AppLayout-BuwGeA1p.js +0 -1
- package/web/assets/AuditPage-CDsJsoKA.js +0 -1
- package/web/assets/CloudAccountPage-BCP8icYZ.js +0 -1
- package/web/assets/CloudAccountPage-DzpS3_gc.js +0 -1
- package/web/assets/CloudMessagingPage-01hLQzZ5.js +0 -2
- package/web/assets/DashboardPage-CKo-sf8A.js +0 -1
- package/web/assets/DirectoryPickerDialog-B1tSWoOM.js +0 -1
- package/web/assets/EnvironmentFormPage-9yxN-uI3.js +0 -1
- package/web/assets/EnvironmentListPage-BbfptXAU.js +0 -1
- package/web/assets/KanbanBoardPage-BWkqTc1a.js +0 -4
- package/web/assets/KanbanListPage-GxI1nlON.js +0 -1
- package/web/assets/LaunchProjectPage-DKMoGXIC.js +0 -1
- package/web/assets/LaunchServicesPage-6dfxPQMB.js +0 -1
- package/web/assets/LogViewer-DAzGy_T2.js +0 -3
- package/web/assets/OrgKeyPrompt-CQ087D4g.js +0 -1
- package/web/assets/ProcessControls-D8uc4x7M.js +0 -1
- package/web/assets/ProcessDetailPage-BPxLPGeh.js +0 -1
- package/web/assets/ProjectDetailPage-CnZ_CpVU.js +0 -1
- package/web/assets/ProjectListPage-D8Svc5e3.js +0 -1
- package/web/assets/RandomJobTestPage-BdEiEnSi.js +0 -2
- package/web/assets/ScenarioEditorPage-COrL715B.js +0 -14
- package/web/assets/SendToChatDialog-D8YB5RM6.js +0 -1
- package/web/assets/ServiceControlsBar-BKwvqgHw.js +0 -1
- package/web/assets/ServiceDetailPage-BmPRfQN6.js +0 -2
- package/web/assets/ServiceFormPage-rVvnwWkb.js +0 -1
- package/web/assets/SettingsPage-C-OfBHjn.css +0 -1
- package/web/assets/SettingsPage-DmQB6t1_.js +0 -2063
- package/web/assets/UnlockPage-BgVF3XMO.js +0 -1
- package/web/assets/VariablesTable-D4_sssPN.js +0 -1
- package/web/assets/VaultMigrationPage-BRZJnfVg.js +0 -1
- package/web/assets/VersionBadge-Df7iJWvF.js +0 -1
- package/web/assets/WikiPage-UkaH8BqR.js +0 -1
- package/web/assets/WikiView-BQqP4b9A.js +0 -1
- package/web/assets/add-scalar-classes-B9WxxjAm.js +0 -387
- package/web/assets/card-nJdNoKgd.js +0 -32
- package/web/assets/client-DYNnTrNm.js +0 -24
- package/web/assets/cloud-chat.store-_qILavCL.js +0 -1
- package/web/assets/cloud-session-Ml5g5J1-.js +0 -1
- package/web/assets/column-Bc4-F_tF.js +0 -907
- package/web/assets/interface-content-folder.svg-bb6GV0G0.js +0 -1
- package/web/assets/modal-D2-cZ2mf.js +0 -5
- package/web/assets/modal-DmgVDXcS.js +0 -1
- package/web/assets/multiselect-CDBfo7-0.js +0 -251
- package/web/assets/process.store-BsCJ-VuI.js +0 -1
- package/web/assets/router-KIdzwvCZ.js +0 -1
- package/web/assets/settings-scope-D8l1sq9K.js +0 -1
- package/web/assets/settings.store-VVqF8QkO.js +0 -1
- package/web/assets/src-CJFQ3yWc.js +0 -1
- package/web/assets/src-Cgn_TWXn.js +0 -572
- package/web/assets/tabpanel-B8oBjoSG.js +0 -150
- package/web/assets/trpc-B1bTQz_t.js +0 -1
- package/web/assets/useAiChatDrawer-BpR9XWop.js +0 -1
- package/web/assets/useProjectCatalog-mk8A95KQ.js +0 -1
- package/web/assets/useProjectCloudOrg-CKgvcUWI.js +0 -1
- /package/{agent-manager-SNVPZNLC.js.map → agent-manager-OWHTBG46.js.map} +0 -0
- /package/{chat-OXRRBDB3.js.map → chat-JZ4UQDWV.js.map} +0 -0
- /package/{companion-JQGNL4U7.js.map → companion-6J6NK7H7.js.map} +0 -0
- /package/{settings-manager-YHQ5YHUH.js.map → instances-command-KZ5UGXOR.js.map} +0 -0
package/chunk-NDO5VFZY.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../server/src/config/env.ts","../../server/src/services/vault-resolver.ts","../../../packages/shared/src/schemas/settings.schema.ts","../../../packages/shared/src/schemas/scenario.schema.ts","../../../packages/shared/src/utils/companion-markers.ts","../../../packages/shared/src/constants/intervals.ts","../../../packages/shared/src/constants/timeouts.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/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/schemas/cloud-api-key.schema.ts","../../../packages/shared/src/schemas/changelog.schema.ts","../../../packages/shared/src/utils/crypto.ts","../../../packages/shared/src/native-parsers.ts","../../../packages/shared/src/js-log-parser.ts","../../../packages/shared/src/builtins.ts","../../../packages/shared/src/constants/buffers.ts","../../../packages/shared/src/constants/editors.ts","../../../packages/shared/src/sync/json-crdt.ts"],"sourcesContent":["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 // Set by the CLI when it was started from a desktop launcher rather than a\n // terminal. The web app surfaces it so the user knows which Runeya they are\n // looking at when several are running.\n RUNEYA_FROM_DESKTOP: 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 FROM_DESKTOP: data.RUNEYA_FROM_DESKTOP,\n}));\n\nexport type Env = z.infer<typeof EnvSchema>;\n\nexport const env = EnvSchema.parse(process.env);\n","import { join, sep } from 'node:path';\nimport { homedir } from 'node:os';\nimport { readdir, mkdir, access, readFile, writeFile, unlink } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\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/**\n * La clé sous laquelle une donnée de ce coffre est chiffrée.\n *\n * L'identifiant d'organisation quand le coffre lui appartient, `undefined` pour\n * la clé machine. Le rangement décide donc du chiffrement, sans qu'aucune\n * entité ait à porter un champ de plus : le coffre où on l'écrit dit déjà à qui\n * elle est.\n */\nexport function vaultIdOfRoot(root: string): string | undefined {\n return orgIdOfRoot(root) ?? undefined;\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, so a machine that has ever synced against\n * two clouds (a self-hosted or local one and the hosted one) ends up with org\n * ids from both, indistinguishable. Stamping the instance next to the vault is\n * what lets a reader tell \"an org I am not a member of\" from \"an org of a cloud\n * I am simply not signed into\" — and what keeps the sync from offering one\n * cloud's organizations to another.\n */\nconst ORG_CLOUD_FILE = 'cloud.json';\n\nexport async function stampOrgCloud(orgId: string, cloudUrl: string, name?: string): Promise<void> {\n const root = orgVaultRoot(orgId);\n // Not best-effort any more: the stamp is now what tells a later boot which\n // cloud an org's vault came from, and syncing follows those vaults. A stamp\n // silently skipped would leave the org to be claimed by whatever cloud is\n // configured then — so a failure here has to stop the pull it precedes.\n await mkdir(root, { recursive: true });\n // Le nom rejoint le tampon plutôt qu'un fichier à lui : il se connaît au même\n // instant, et une organisation sans nom local n'a plus qu'un hash à montrer\n // dès que la session cloud est éteinte.\n const known = name ?? (await readOrgNames())[orgId];\n const stamp = known ? { cloudUrl, name: known } : { cloudUrl };\n await writeFile(join(root, ORG_CLOUD_FILE), JSON.stringify(stamp, null, 2), 'utf-8');\n}\n\n/**\n * Retenir le nom d'une organisation déjà présente ici.\n *\n * Appelé quand le cloud vient de le dire, pour qu'il survive à la déconnexion.\n * Aucun COFFRE n'est créé : une organisation dont ce poste n'a rien n'a pas à\n * recevoir un répertoire pour un simple nom.\n *\n * Le tampon, lui, est écrit même s'il manque — c'est la nuance qui manquait.\n * Tous les coffres ne naissent pas d'une synchronisation : un simple\n * `settingsManager.getSettings(orgId)` crée le répertoire sans passer par\n * `stampOrgCloud`. Renoncer faute de fichier condamnait ces coffres-là à\n * n'afficher qu'un hash pour toujours, quel que soit le nombre de fois où le\n * cloud redit leur nom.\n *\n * Le tampon posé ici ne porte pas de `cloudUrl` : personne ici ne sait de quel\n * cloud vient le coffre, et l'inventer rangerait l'organisation sous le mauvais.\n * Un tampon sans cloud se lit exactement comme l'absence de tampon.\n */\nexport async function rememberOrgName(orgId: string, name: string): Promise<void> {\n const root = orgVaultRoot(orgId);\n if (!existsSync(root)) return;\n const file = join(root, ORG_CLOUD_FILE);\n let stamp: Record<string, unknown> = {};\n try {\n stamp = JSON.parse(await readFile(file, 'utf-8')) as Record<string, unknown>;\n } catch {\n // Pas de tampon, ou illisible : le nom en fonde un.\n }\n if (stamp['name'] === name) return;\n await writeFile(file, JSON.stringify({ ...stamp, name }, null, 2), 'utf-8');\n}\n\n/** Le nom de chaque organisation dont le tampon en porte un. */\nexport async function readOrgNames(): Promise<Record<string, string>> {\n const out: Record<string, string> = {};\n for (const orgId of await listOrgVaults()) {\n try {\n const raw = await readFile(join(orgVaultRoot(orgId), ORG_CLOUD_FILE), 'utf-8');\n const name = (JSON.parse(raw) as { name?: unknown }).name;\n if (typeof name === 'string' && name) out[orgId] = name;\n } catch {\n // Pas de tampon, ou pas encore de nom : l'id fera l'affaire.\n }\n }\n return out;\n}\n\n/**\n * Le logo d'une organisation, gardé à côté de son nom.\n *\n * Même raison d'être que le nom recopié dans le tampon : ce que le poste sait\n * de ses organisations ne doit dépendre ni d'une session cloud ni du réseau.\n * Le nom tient dans le tampon ; les octets, eux, méritent leur propre fichier —\n * `cloud.json` est relu et réécrit à chaque pull, et y mêler 40 Ko de base64\n * ferait payer l'image à des lectures qui n'en veulent pas.\n */\nconst ORG_LOGO_FILE = 'logo.json';\n\ninterface StoredLogo {\n contentType: string;\n base64: string;\n fetchedAt: string;\n}\n\n/** Formats matriciels inertes, la même liste que celle acceptée par le cloud. */\nconst LOGO_TYPES = new Set(['image/png', 'image/jpeg', 'image/webp', 'image/gif']);\n\n/** Garder (ou remplacer) le logo d'une organisation présente ici. */\nexport async function rememberOrgLogo(orgId: string, contentType: string, base64: string): Promise<void> {\n if (!LOGO_TYPES.has(contentType)) return;\n const root = orgVaultRoot(orgId);\n const stored: StoredLogo = { contentType, base64, fetchedAt: new Date().toISOString() };\n await mkdir(root, { recursive: true });\n await writeFile(join(root, ORG_LOGO_FILE), JSON.stringify(stored), 'utf-8');\n}\n\n/** Oublier le logo d'une organisation — elle n'en a plus. */\nexport async function forgetOrgLogo(orgId: string): Promise<void> {\n try {\n await unlink(join(orgVaultRoot(orgId), ORG_LOGO_FILE));\n } catch {\n // Il n'y en avait pas : c'est le résultat voulu.\n }\n}\n\n/**\n * Les logos retenus, en data URL, prêts pour un `src`.\n *\n * Le type est revalidé à la lecture : un fichier trafiqué sur le disque ne doit\n * pas pouvoir faire servir un `image/svg+xml` — donc du script — à l'interface.\n */\nexport async function readOrgLogos(): Promise<Record<string, string>> {\n const out: Record<string, string> = {};\n for (const orgId of await listOrgVaults()) {\n try {\n const raw = await readFile(join(orgVaultRoot(orgId), ORG_LOGO_FILE), 'utf-8');\n const { contentType, base64 } = JSON.parse(raw) as Partial<StoredLogo>;\n if (typeof contentType !== 'string' || !LOGO_TYPES.has(contentType)) continue;\n if (typeof base64 !== 'string' || !base64) continue;\n out[orgId] = `data:${contentType};base64,${base64}`;\n } catch {\n // Pas de logo retenu, ou fichier illisible : l'initiale fera l'affaire.\n }\n }\n return out;\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/**\n * Les organisations présentes sur ce disque, projets ou non.\n *\n * Distinct de `listCloudVaults`, qui ne voit une organisation qu'à travers ses\n * projets matérialisés : une organisation peut porter des données à elle —\n * agents, clés d'API — sans qu'aucun projet n'ait encore été ouvert ici, et\n * l'ignorer alors reviendrait à les perdre au prochain démarrage.\n */\nexport async function listOrgVaults(): Promise<string[]> {\n const orgsDir = join(machineRoot(), 'orgs');\n try {\n return (await readdir(orgsDir, { withFileTypes: true }))\n .filter((e) => e.isDirectory() && SAFE_ID.test(e.name))\n .map((e) => e.name);\n } catch {\n return [];\n }\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 const root = join(projectsDir, entry.name);\n // Un répertoire n'est pas un projet : il faut qu'il en porte la fiche.\n //\n // Tout ce qui traînait ici était pris pour un coffre — une copie de\n // sauvegarde, un dossier oublié — et les stores le lisaient, le\n // comptaient, pouvaient le réécrire. Une sauvegarde déposée à côté\n // d'un projet s'est ainsi retrouvée annoncée comme dix-neuf\n // conversations illisibles appartenant à l'organisation.\n //\n // `project.json` est déjà ce qui fait foi ailleurs (`isMaterialized`\n // dans org-sync-scope) : la même règle vaut ici, pour tout le monde.\n if (!(await access(join(root, 'project.json')).then(() => true, () => false))) continue;\n found.push({ orgId, projectId: entry.name, root });\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 { 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\n/**\n * Réglages du compagnon de relecture.\n *\n * Au niveau du POSTE, en clair, et non dans le coffre d'une organisation (§9) :\n * ce n'est pas un réglage d'équipe. Il décrit comment cette machine fait\n * travailler ses agents, il ne contient aucun secret, et le ranger dans un\n * coffre chiffré le rendrait dépendant de l'organisation qu'on regarde — un\n * même poste aurait autant de compagnons que d'organisations, sans raison.\n */\nexport const CompanionSettingsSchema = z.object({\n /** Activer le compagnon d'office sur les conversations créées ensuite. */\n enabledByDefault: z.boolean().default(false),\n /**\n * Spécificités ajoutées aux consignes Runeya.\n *\n * Vide — l'absence — signifie « aucune spécificité ». On ne recopie pas le\n * texte par défaut dans le réglage : les consignes Runeya restent dans le\n * code, pour profiter de leurs corrections.\n *\n * Rejeté au-delà de la borne plutôt que tronqué (§1) : un prompt coupé en\n * plein milieu produirait des relectures incohérentes sans rien signaler.\n */\n prompt: z.string().max(20_000).optional(),\n});\n\nexport type CompanionSettings = z.infer<typeof CompanionSettingsSchema>;\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 * Optionnel plutôt que défauté : un réglage absent est un réglage jamais\n * touché, et le rendre obligatoire dans le type forcerait chaque appelant qui\n * construit un objet de réglages à inventer une valeur.\n */\n companion: CompanionSettingsSchema.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\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","/**\n * Les bornes du message que le compagnon veut transmettre.\n *\n * Partagées serveur ↔ front parce que les deux en ont besoin pour la même\n * raison : le serveur extrait ce qu'il relaie, le panneau affiche la même chose\n * plutôt que le texte brut avec ses bornes. Recopiées de part et d'autre, une\n * borne renommée d'un seul côté casserait l'affichage sans rien faire échouer.\n */\nexport const COMPANION_RELAY_OPEN = '[RUNEYA_COMPAGNON_RESPONSE]';\nexport const COMPANION_RELAY_CLOSE = '[/RUNEYA_COMPAGNON_RESPONSE]';\n\n/**\n * Le contenu entre les bornes, ou `null` quand il n'y en a pas.\n *\n * La dernière ouverture l'emporte : si le compagnon s'y reprend à deux fois,\n * c'est la seconde qu'il assume. Un bloc non refermé rend ce qui suit\n * l'ouverture — la réponse a été coupée, on ne devine pas où elle s'arrêtait.\n */\nexport function extractCompanionRelay(raw: string): string | null {\n const text = (raw ?? '').trim();\n const open = text.lastIndexOf(COMPANION_RELAY_OPEN);\n if (open === -1) return null;\n const after = text.slice(open + COMPANION_RELAY_OPEN.length);\n const close = after.indexOf(COMPANION_RELAY_CLOSE);\n const inner = (close === -1 ? after : after.slice(0, close)).trim();\n return inner || null;\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 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","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';\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 * Le répertoire où le processus s'exécute VRAIMENT, absolutisé par l'agent.\n *\n * Rapporté par l'agent plutôt que déduit de la config : entre le `cwd` de la\n * commande, celui du service, l'ancrage sur le projet et les variables que\n * l'agent étend lui-même, la valeur affichée n'aurait rien prouvé. Ce qui\n * intéresse quand un service tourne contre le mauvais dépôt, c'est le chemin\n * final — y compris quand il retombe sur le répertoire de l'agent.\n */\n cwd: z.string().max(4096).nullable().optional(),\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 * Ce que la machine de l'agent vaut pour les builtins de portée `agent`.\n * Sert à PRÉVISUALISER — la valeur injectée reste calculée au lancement, par\n * l'agent lui-même : une IP change, un agent se déconnecte, et un statut\n * n'est qu'un cliché.\n */\n os: z.string().max(64).optional(),\n home: z.string().max(4096).optional(),\n cwd: z.string().max(4096).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', 'archived', 'unarchived']),\n timestamp: z.string(),\n /** Extra context: old/new column name, old/new title, comment text, etc. */\n /**\n * Le texte de l'entrée : le corps d'un commentaire, ou le contexte du geste.\n *\n * Borné comme le corps d'une carte (100 000), et non plus à 5 000 : un\n * commentaire est de la prose comme une description, et rien de technique ne\n * justifiait un écart de vingt fois. La borne étroite s'est vue à l'import\n * d'un Kanbanize, où des commentaires de 12 000 caractères passaient par\n * l'API publique — bornée, elle, à 20 000 — pour écrire en base une donnée que\n * ce schéma déclarait invalide, et qu'aucune reprise depuis l'interface\n * n'aurait ensuite pu enregistrer.\n */\n detail: z.string().max(100_000).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 * Qui est derrière l'événement, estampillé par le serveur — jamais pris du\n * client, sans quoi n'importe qui pourrait signer au nom d'un autre.\n *\n * Posé sur les commentaires (c'est ce qui rend « mon propre commentaire »\n * répondable ; `author` ne sépare que l'IA de l'humain) et sur les\n * déplacements. Absent des événements écrits avant qu'on l'estampille : un\n * lecteur doit donc afficher « on ne sait pas », pas un nom vide.\n *\n * Pour une clé d'API, c'est le nom de la clé et non son porteur : la clé\n * emprunte les droits de son créateur, pas son identité — personne ne doit\n * croire qu'un humain a déplacé ce qu'un robot de CI a déplacé.\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 * La priorité de la carte, de 1 à 10 — 10 étant le plus urgent.\n *\n * Facultative, et absente veut dire « pas de priorité », pas « la plus\n * basse » : une carte qu'on n'a pas encore arbitrée ne doit pas se ranger\n * d'office au fond de la pile.\n */\n priority: z.number().int().min(1).max(10).optional(),\n\n /**\n * Les groupes de la carte — des étiquettes libres, posées par l'équipe.\n *\n * Rien ne les déclare ailleurs : un groupe existe parce qu'une carte le\n * porte, et disparaît avec la dernière qui le portait. C'est ce qui permet\n * d'en créer un en le tapant, sans passer par un écran d'administration.\n */\n groups: z.array(z.string().min(1).max(60)).max(30).optional(),\n /**\n * L'échéance de la carte : le jour où elle est attendue, `AAAA-MM-JJ`.\n *\n * Un jour, pas un instant, et c'est une décision : une équipe se dit « pour\n * vendredi », jamais « pour vendredi 23:59:59 UTC ». Stocker un instant\n * ferait afficher une échéance au 4 mars comme le 3 mars à qui travaille à\n * l'ouest de Greenwich — la carte serait en retard d'un jour pour la moitié\n * de l'équipe, et personne ne saurait pourquoi.\n *\n * Facultative, et absente veut dire « pas d'échéance », pas « en retard » :\n * une carte qu'on n'a pas datée ne doit pas s'annoncer comme urgente.\n */\n deadline: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n\n /**\n * La couleur de la carte, en hexadécimal (`#RRGGBB`) — un liseré en haut de\n * la carte, et rien d'autre : ce qu'elle veut dire appartient à l'équipe.\n *\n * Bornée à une notation stricte plutôt qu'à une chaîne libre : cette valeur\n * finit dans un attribut `style`, et une couleur ne doit pouvoir contenir\n * qu'une couleur. Absente sur les cartes sans couleur.\n */\n color: z.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),\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 * Quand la carte a été archivée — absente tant qu'elle est au tableau.\n *\n * Une carte archivée reste dans sa colonne en base : c'est la lecture qui la\n * retire du tableau, jamais une écriture qui la déplace. Rien à recoller donc\n * au désarchivage, et aucun cimetière où une carte pourrait se perdre.\n */\n archivedAt: z.string().optional(),\n /**\n * La colonne d'où la carte a été archivée, telle qu'elle s'appelait alors.\n *\n * L'identifiant sert à l'y remettre, le titre à le dire dans l'archive même\n * quand la colonne a disparu depuis — auquel cas le désarchivage repose la\n * carte dans la première colonne, sans se taire sur son origine.\n */\n archivedFrom: z\n .object({ columnId: z.string().max(128), columnTitle: z.string().max(200) })\n .optional(),\n /**\n * Quand la carte a été supprimée. Rien n'est effacé : la carte reste en base,\n * et toutes les lectures l'écartent.\n *\n * Une suppression est le seul geste que rien ne rattrape — sauf à ne pas\n * l'exécuter vraiment. La colonne et le tableau portent le même champ, pour\n * que supprimer l'un n'emporte jamais les cartes de l'autre.\n */\n deletedAt: z.string().optional(),\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 /**\n * Le regroupement auquel la colonne appartient, s'il y en a un.\n *\n * Un pointeur vers le parent, et rien dans l'autre sens : le groupe ne tient\n * pas la liste de ses membres. Deux listes qui prétendent dire qui contient\n * quoi finissent par se contredire, et un déplacement devient alors deux\n * écritures au lieu d'une.\n */\n groupId: z.string().optional(),\n /** Supprimée, mais conservée — voir `deletedAt` sur la carte. */\n deletedAt: z.string().optional(),\n});\nexport type KanbanColumn = z.infer<typeof KanbanColumnSchema>;\n\n// --- Column group ---\n/**\n * Un regroupement de colonnes : un bandeau au-dessus d'elles, pas une colonne.\n *\n * Il ne porte aucune carte — jamais — et c'est ce qui le rend inoffensif :\n * `columnId`, les rangs fractionnaires et tout le déplacement de cartes\n * ignorent son existence. Un groupe peut en contenir un autre (`parentId`).\n *\n * Il n'a délibérément **pas** d'`order` : sa place se déduit de celle de ses\n * colonnes, dont l'ordre reste l'unique source de vérité. Un groupe qui aurait\n * son propre rang pourrait contredire celui de ses membres, et il n'existerait\n * alors aucune bonne réponse à « laquelle des deux positions gagne ».\n */\nexport const KanbanColumnGroupSchema = z.object({\n id: z.string(),\n title: z.string().min(1).max(200),\n /** La couleur du bandeau, en hexadécimal — l'interface décide du défaut. */\n color: z.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),\n /** Le groupe parent, pour les regroupements imbriqués. */\n parentId: z.string().optional(),\n /** Supprimé, mais conservé — comme une colonne. */\n deletedAt: z.string().optional(),\n});\nexport type KanbanColumnGroup = z.infer<typeof KanbanColumnGroupSchema>;\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 /** Les regroupements de colonnes — vide sur un tableau qui n'en a jamais eu. */\n columnGroups: z.array(KanbanColumnGroupSchema).default([]),\n archived: z.boolean().default(false),\n /** Supprimé, mais conservé avec ses cartes — voir `deletedAt` sur la carte. */\n deletedAt: z.string().optional(),\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\n// --- Card links ---\n/**\n * Un lien entre deux cartes, rangé hors des tableaux.\n *\n * Le lien ne vit pas dans la carte, et c'est délibéré : une carte se réécrit\n * par tableau entier, et un client plus ancien — dont le Zod ignore le champ —\n * effacerait silencieusement le lien en sauvegardant le tableau. Dans sa propre\n * collection, il survit à toutes les écritures de tableau, y compris celles des\n * versions qui ne le connaissent pas.\n *\n * Un seul type pour l'instant, la filiation : `parent` est la carte au-dessus,\n * `child` celle qui en dépend. Une carte a au plus un parent (c'est le\n * `parent_id` habituel), et les deux extrémités peuvent vivre sur des tableaux\n * différents — la même organisation, en revanche, toujours.\n */\nexport const KanbanCardLinkSchema = z.object({\n id: z.string().max(128),\n /** Le tableau et la carte qui *dépendent* de l'autre. */\n childBoardId: z.string().max(64),\n childCardId: z.string().max(128),\n /** Le tableau et la carte *dont* on dépend. */\n parentBoardId: z.string().max(64),\n parentCardId: z.string().max(128),\n createdAt: z.string(),\n createdBy: z.object({ id: z.string().max(128), name: z.string().max(200) }).optional(),\n});\nexport type KanbanCardLink = z.infer<typeof KanbanCardLinkSchema>;\n\n/**\n * De quoi afficher une carte liée sans ouvrir son tableau : son titre, sa\n * colonne, et le tableau où elle se trouve. Résolu à la lecture plutôt que\n * recopié dans le lien — un titre recopié devient faux au premier renommage.\n */\nexport const KanbanCardRefSchema = z.object({\n cardId: z.string().max(128),\n boardId: z.string().max(64),\n boardName: z.string().max(200),\n columnId: z.string().max(128),\n columnTitle: z.string().max(200),\n title: z.string().max(500),\n /** Les mêmes informations qu'une ligne de tableau montre d'une carte d'ici. */\n assignees: z.array(z.object({ id: z.string().max(128), name: z.string().max(200) })).default([]),\n commentCount: z.number().int().nonnegative().default(0),\n});\nexport type KanbanCardRef = z.infer<typeof KanbanCardRefSchema>;\n","import { z } from 'zod';\n\n/**\n * Les clés d'API du cloud : ce qu'un système tiers présente pour alimenter un\n * kanban sans être un humain connecté.\n *\n * Distinctes des clés de `api-key.schema.ts`, qui ouvrent l'API du serveur\n * *local* et nomment des services. Celles-ci appartiennent à une organisation\n * cloud et ne parlent que de tableaux — deux mondes, deux durées de vie, deux\n * écrans : les mélanger ferait qu'une clé de CI dépendrait d'un poste allumé.\n */\n\n/**\n * Ce qu'une clé a le droit de faire. Des portées séparées plutôt qu'un booléen\n * lecture/écriture : commenter est le geste d'un robot de CI qui rend compte, et\n * il n'a aucune raison de pouvoir aussi créer ou déplacer des cartes.\n *\n * `kanban:delete` est à part pour la même raison, en plus net : effacer est le\n * seul geste que rien ne rattrape. Une clé d'alimentation qui pourrait aussi\n * supprimer transformerait un bogue de script en perte de travail.\n */\nexport const CloudApiScopeSchema = z.enum([\n 'kanban:read',\n 'kanban:write',\n 'kanban:comment',\n 'kanban:delete',\n]);\nexport type CloudApiScope = z.infer<typeof CloudApiScopeSchema>;\n\nexport const CLOUD_API_SCOPES: CloudApiScope[] = [\n 'kanban:read',\n 'kanban:write',\n 'kanban:comment',\n 'kanban:delete',\n];\n\n/**\n * Le préfixe de tout secret émis. Il ne protège rien — il se lit dans un dépôt\n * ou un journal, et c'est le but : un scanner de secrets sait quoi chercher, et\n * un humain qui voit `rk_` dans un fichier sait ce qu'il tient.\n */\nexport const CLOUD_API_KEY_PREFIX = 'rk_';\n\n/** `rk_` suivi de 64 caractères hexadécimaux — 32 octets d'aléa. */\nexport const CloudApiKeySecretSchema = z.string().regex(/^rk_[0-9a-f]{64}$/);\n\nexport const CloudApiKeySchema = z.object({\n id: z.string().max(128),\n organizationId: z.string().max(128),\n name: z.string().min(1).max(200),\n scopes: z.array(CloudApiScopeSchema).min(1).max(10),\n /**\n * Les tableaux que la clé peut atteindre, ou `null` pour « tous ceux de\n * l'organisation ».\n *\n * `null` et `[]` ne sont pas la même chose : la liste vide n'ouvre rien, et\n * c'est délibéré — un tableau supprimé ne doit pas élargir une clé qui ne le\n * nommait plus que lui.\n */\n boards: z.array(z.string().max(64)).max(200).nullable(),\n createdAt: z.string().max(64),\n /** Dernier usage constaté, pour reconnaître une clé oubliée. */\n lastUsedAt: z.string().max(64).nullable(),\n /** Qui l'a émise — une clé sans visage ne se révoque jamais sereinement. */\n createdBy: z.object({ id: z.string().max(128), name: z.string().max(200) }),\n /** Les 4 derniers caractères du secret, pour reconnaître une clé dans une liste. */\n keyPreview: z.string().max(8),\n});\nexport type CloudApiKey = z.infer<typeof CloudApiKeySchema>;\n\n/**\n * La réponse de création — la seule fois où le secret circule.\n *\n * Le serveur n'en garde qu'un condensat : personne, pas même l'organisation, ne\n * peut le relire ensuite. Perdue, une clé se remplace, elle ne se retrouve pas.\n */\nexport const CreatedCloudApiKeySchema = z.object({\n key: CloudApiKeySchema,\n secret: CloudApiKeySecretSchema,\n});\nexport type CreatedCloudApiKey = z.infer<typeof CreatedCloudApiKeySchema>;\n\nexport const CreateCloudApiKeyInput = z.object({\n organizationId: z.string().min(1).max(128),\n name: z.string().min(1).max(200),\n scopes: z.array(CloudApiScopeSchema).min(1).max(10),\n boards: z.array(z.string().max(64)).max(200).nullable().default(null),\n});\nexport type CreateCloudApiKeyInput = z.infer<typeof CreateCloudApiKeyInput>;\n\nexport const UpdateCloudApiKeyInput = z.object({\n id: z.string().min(1).max(128),\n name: z.string().min(1).max(200).optional(),\n scopes: z.array(CloudApiScopeSchema).min(1).max(10).optional(),\n boards: z.array(z.string().max(64)).max(200).nullable().optional(),\n});\nexport type UpdateCloudApiKeyInput = z.infer<typeof UpdateCloudApiKeyInput>;\n","import { z } from 'zod';\n\n/**\n * Le journal des nouveautés, tel qu'il est publié par le cloud.\n *\n * **Deux surfaces, jamais mélangées.** `app` est l'application locale, dont la\n * version est celle du CLI publié sur npm. `cloud` est l'API et son application\n * web, déployées au push et donc sans numéro de version : leurs entrées sont\n * datées. Un même travail qui touche les deux donne DEUX entrées — c'est ce qui\n * permet à un poste resté sur une vieille version de ne pas se voir annoncer des\n * nouveautés qu'il n'a pas, et au cloud d'annoncer les siennes sans attendre une\n * publication npm.\n *\n * L'ordre se déduit de `version` seule (voir `compareChangelogVersions`) : les\n * deux formes — `1.4.2` et `2026-09-03` — se comparent par segments numériques.\n */\n\nexport const ChangelogSurfaceSchema = z.enum(['app', 'cloud']);\nexport type ChangelogSurface = z.infer<typeof ChangelogSurfaceSchema>;\n\n/** Ce que le lecteur doit comprendre en un coup d'œil : est-ce un ajout, un correctif, une rupture. */\nexport const ChangelogChangeKindSchema = z.enum(['feature', 'improvement', 'fix', 'breaking']);\nexport type ChangelogChangeKind = z.infer<typeof ChangelogChangeKindSchema>;\n\n/**\n * Les deux langues de l'interface, toutes deux obligatoires : une entrée\n * publiée dans une seule langue laisserait la moitié des lecteurs devant un\n * trou, et rien dans l'affichage ne pourrait le rattraper.\n */\nexport const ChangelogTextSchema = z.object({\n fr: z.string().min(1).max(500),\n en: z.string().min(1).max(500),\n});\nexport type ChangelogText = z.infer<typeof ChangelogTextSchema>;\n\nexport const ChangelogChangeSchema = z.object({\n kind: ChangelogChangeKindSchema,\n text: ChangelogTextSchema,\n});\nexport type ChangelogChange = z.infer<typeof ChangelogChangeSchema>;\n\n/**\n * Une entrée en attente, telle que l'écrit celui qui fait le travail.\n *\n * Elle ne porte PAS de version : au moment où on l'écrit, le numéro n'existe pas\n * encore — l'app attend sa publication npm, et le cloud n'a jamais de numéro,\n * seulement sa date. Un fichier par entrée, pour que deux branches qui en\n * ajoutent chacune une ne se marchent pas dessus : un tableau partagé produirait\n * un conflit à chaque fusion, et le réflexe sous conflit est d'en perdre une.\n *\n * `title` est facultatif : il nomme la version, pas le changement. La première\n * entrée qui en porte un le donne à sa version ; une version peut n'en avoir\n * aucun, et s'annoncer par son seul numéro.\n */\nexport const ChangelogDraftSchema = ChangelogChangeSchema.extend({\n date: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/),\n title: ChangelogTextSchema.optional(),\n});\nexport type ChangelogDraft = z.infer<typeof ChangelogDraftSchema>;\n\nexport const ChangelogReleaseSchema = z.object({\n surface: ChangelogSurfaceSchema,\n /** `1.4.2` pour l'app (version npm publiée), `2026-09-03` — ou `2026-09-03.2` — pour le cloud. */\n version: z.string().min(1).max(32).regex(/^[0-9][0-9.-]*$/),\n /** Date de publication, `YYYY-MM-DD`. */\n date: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/),\n /** Facultatif : une version peut s'annoncer par son seul numéro. */\n title: ChangelogTextSchema.optional(),\n /** Une version sans changement n'a rien à annoncer : elle n'a pas sa place ici. */\n changes: z.array(ChangelogChangeSchema).min(1).max(50),\n});\nexport type ChangelogRelease = z.infer<typeof ChangelogReleaseSchema>;\n\n/** L'index : de quoi lister et dater, sans transporter les corps. */\nexport const ChangelogIndexItemSchema = ChangelogReleaseSchema.omit({ changes: true }).extend({\n changeCount: z.number().int().nonnegative(),\n});\nexport type ChangelogIndexItem = z.infer<typeof ChangelogIndexItemSchema>;\n\n/**\n * Ordonne deux versions de changelog, quelle que soit leur forme.\n *\n * Les segments sont comparés numériquement (`1.10.0` après `1.9.0`, que la\n * comparaison de chaînes aurait inversé), et une version plus courte perd contre\n * son préfixe plus long (`2026-09-03` avant `2026-09-03.2`).\n */\nexport function compareChangelogVersions(a: string, b: string): number {\n const pa = a.split(/[.-]/).map((n) => Number.parseInt(n, 10) || 0);\n const pb = b.split(/[.-]/).map((n) => Number.parseInt(n, 10) || 0);\n const len = Math.max(pa.length, pb.length);\n for (let i = 0; i < len; i++) {\n const da = pa[i] ?? 0;\n const db = pb[i] ?? 0;\n if (da > db) return 1;\n if (da < db) return -1;\n }\n return 0;\n}\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","/**\n * Variables intégrées — les `{{…}}` que Runeya remplit lui-même, par opposition\n * aux `{{environment.KEY}}` que l'utilisateur définit et que le résolveur\n * d'environnement traite (`apps/server/src/services/environment-resolver.ts`).\n *\n * Cette table est la SEULE déclaration : le serveur et l'agent y lisent ce\n * qu'ils doivent produire, l'interface ce qu'elle doit proposer et documenter.\n * Elle a été introduite parce que la liste vivait en trois exemplaires — dans\n * le routeur de service, dans le gestionnaire de processus et dans le tableau\n * de variables du web — et que le web en avait déjà oublié un.\n *\n * ## Portées\n *\n * - `server` : connu à la résolution, quand le serveur prépare la config à\n * déployer (nom, ports, projet, environnement actif).\n * - `agent` : ne peut être résolu QUE sur la machine qui exécute le service —\n * son IP, son utilisateur, son système, son répertoire de travail. Les\n * résoudre côté serveur graverait la machine qui a fait le déploiement, ce\n * qui ne se voit qu'en multi-machines, et tard.\n */\n\nexport type BuiltinScope = 'server' | 'agent';\n\nexport interface BuiltinVariable {\n /** Nom tel qu'il s'écrit entre accolades, sans les accolades */\n name: string;\n scope: BuiltinScope;\n /** Suffixe de la clé i18n de l'interface : `builtins.<descriptionKey>` */\n descriptionKey: string;\n /** Nom conservé pour ne pas casser les configurations existantes */\n deprecatedAlias?: string;\n}\n\nexport const BUILTIN_VARIABLES: readonly BuiltinVariable[] = [\n // ── Le service ───────────────────────────────────────────────────────────\n { name: 'service.NAME', scope: 'server', descriptionKey: 'serviceName' },\n { name: 'service.ID', scope: 'server', descriptionKey: 'serviceId' },\n { name: 'service.PORT', scope: 'server', descriptionKey: 'servicePort' },\n { name: 'service.URL', scope: 'server', descriptionKey: 'serviceUrl' },\n { name: 'service.BASE_URL', scope: 'server', descriptionKey: 'serviceBaseUrl' },\n { name: 'service.CWD', scope: 'agent', descriptionKey: 'serviceCwd' },\n\n // ── Le projet et l'environnement actif ───────────────────────────────────\n { name: 'project.NAME', scope: 'server', descriptionKey: 'projectName' },\n { name: 'runeya.ENV_NAME', scope: 'server', descriptionKey: 'envName' },\n\n // ── Le serveur Runeya ────────────────────────────────────────────────────\n // `service.HOST` a toujours désigné l'adresse d'écoute du SERVEUR, pas une\n // propriété du service : le nom trompait, il devient un alias.\n { name: 'runeya.HOST', scope: 'server', descriptionKey: 'runeyaHost', deprecatedAlias: 'service.HOST' },\n\n // ── La machine qui exécute ───────────────────────────────────────────────\n { name: 'agent.HOST_LAN', scope: 'agent', descriptionKey: 'agentHostLan', deprecatedAlias: 'service.HOST_LAN' },\n // Le NOM de l'agent est une étiquette de la configuration du serveur, pas\n // une propriété de la machine : c'est le serveur qui le connaît et le résout.\n { name: 'agent.NAME', scope: 'server', descriptionKey: 'agentName' },\n { name: 'agent.OS', scope: 'agent', descriptionKey: 'agentOs' },\n { name: 'agent.HOME', scope: 'agent', descriptionKey: 'agentHome' },\n];\n\nexport const BUILTINS_BY_SCOPE = (scope: BuiltinScope): readonly BuiltinVariable[] =>\n BUILTIN_VARIABLES.filter((b) => b.scope === scope);\n\n/**\n * Une référence `{{nom}}`. Le nom accepte les points (`service.PORT`,\n * `services.api.URL`) mais ni espace ni accolade : une référence ne peut donc\n * pas se former à la couture entre deux morceaux de texte.\n */\nconst BUILTIN_REFERENCE_RE = /\\{\\{([A-Za-z][A-Za-z0-9_.-]*)\\}\\}/g;\n\n/** Les `{{environment.KEY}}` appartiennent au résolveur, jamais aux builtins. */\nconst ENVIRONMENT_NAMESPACE = 'environment.';\n\n/**\n * Remplace les références présentes dans `values`, et laisse les autres\n * intactes : une passe unique, jamais récursive — une valeur qui contient\n * elle-même une référence ne relance pas la substitution, faute de quoi deux\n * variables se pointant l'une l'autre boucleraient.\n */\nexport function interpolateBuiltins(text: string, values: Record<string, string>): string {\n return text.replace(BUILTIN_REFERENCE_RE, (match, name: string) => {\n if (name.startsWith(ENVIRONMENT_NAMESPACE)) return match;\n return values[name] ?? match;\n });\n}\n\n/** `interpolateBuiltins` appliqué à chaque valeur d'un dictionnaire d'env. */\nexport function interpolateBuiltinsInEnv(\n env: Record<string, string>,\n values: Record<string, string>,\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(env)) {\n out[key] = interpolateBuiltins(value, values);\n }\n return out;\n}\n\n/**\n * Ajoute au dictionnaire les alias hérités, pour que `{{service.HOST}}`\n * continue de rendre ce que rend `{{runeya.HOST}}`.\n */\nexport function withDeprecatedAliases(values: Record<string, string>): Record<string, string> {\n const out = { ...values };\n for (const builtin of BUILTIN_VARIABLES) {\n if (builtin.deprecatedAlias && out[builtin.name] !== undefined) {\n out[builtin.deprecatedAlias] = out[builtin.name];\n }\n }\n return out;\n}\n\n/**\n * Nom sous lequel un service est adressable depuis un autre\n * (`{{services.<slug>.PORT}}`).\n *\n * Un nom de service est libre — accents, espaces, majuscules — alors qu'une\n * référence doit rester un mot sans espace. D'où ce passage en minuscules\n * tiretées, appliqué de la même façon par le serveur qui produit les valeurs\n * et par l'interface qui les propose.\n */\nexport function serviceSlug(name: string): string {\n return name\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\n/**\n * Les ports d'un service : `service.PORT` pour le premier — celui qu'on cite\n * dans neuf cas sur dix — puis `service.PORT_2`, `_3`… pour les suivants.\n */\nexport function servicePortValues(ports: readonly number[] | undefined, prefix = 'service'): Record<string, string> {\n const values: Record<string, string> = {};\n (ports ?? []).forEach((port, i) => {\n values[i === 0 ? `${prefix}.PORT` : `${prefix}.PORT_${i + 1}`] = String(port);\n });\n return values;\n}\n\n/**\n * Une adresse d'écoute « toutes interfaces » n'est pas une adresse à laquelle\n * on se connecte. En mode LAN, le serveur écoute sur `0.0.0.0` : bâtir\n * `http://0.0.0.0:3000` donnerait une URL que rien ne peut joindre.\n */\nexport function isWildcardHost(host: string): boolean {\n const h = host.trim();\n return h === '' || h === '0.0.0.0' || h === '::' || h === '[::]';\n}\n\n/** L'adresse de bouclage, sous ses écritures possibles. */\nfunction isLoopbackHost(host: string): boolean {\n const h = host.trim();\n return h === '127.0.0.1' || h === '::1' || h === '[::1]';\n}\n\n/**\n * L'hôte à écrire dans une URL, à partir de l'adresse d'écoute du serveur.\n *\n * La boucle locale devient `localhost` : c'est le nom que les développeurs\n * écrivent, celui des origines autorisées du dépôt, et celui qu'on colle dans\n * un navigateur. `{{runeya.HOST}}` continue de rendre l'adresse réelle — c'est\n * elle qu'un service met dans son bind, et la traduire là serait faux.\n *\n * Un hôte explicitement configuré (une IP de LAN, un nom de machine) n'est\n * jamais réécrit : le seul cas traduit est celui où l'adresse ne désigne que\n * « cette machine ». Une adresse « toutes interfaces » rend `null` — à\n * l'appelant de décider, l'agent connaissant seul son IP joignable.\n */\nexport function urlHostFor(host: string): string | null {\n if (isWildcardHost(host)) return null;\n return isLoopbackHost(host) ? 'localhost' : host.trim();\n}\n\n/**\n * Les URL par lesquelles on joint un service, une par port : `service.URL`,\n * `service.URL_2`… numérotées comme les ports, si bien que `URL_2` désigne\n * toujours le service sur `PORT_2`.\n *\n * Un domaine local est déclaré AVEC son port (c'est ce que le proxy route) :\n * l'URL d'un port est donc son domaine s'il en a un, sinon l'hôte et le port.\n * Un domaine déclaré sur un port absent de la liste des ports est ajouté à la\n * suite, pour ne pas se perdre.\n *\n * À ne pas confondre avec le champ `url` du service — son « URL de base »,\n * saisie librement, souvent l'adresse publique : celle-là s'écrit\n * `{{service.BASE_URL}}`. Faire rendre l'une par l'autre romprait la\n * correspondance entre `URL_n` et `PORT_n`.\n */\nexport function serviceUrlValues(service: {\n ports?: number[];\n localUrls?: { url: string; port: number }[];\n}, host: string, prefix = 'service'): Record<string, string> {\n const domainByPort = new Map((service.localUrls ?? []).map((lu) => [lu.port, lu.url]));\n const ports = [...(service.ports ?? [])];\n for (const local of service.localUrls ?? []) {\n if (!ports.includes(local.port)) ports.push(local.port);\n }\n\n const values: Record<string, string> = {};\n ports.forEach((port, i) => {\n const domain = domainByPort.get(port);\n values[i === 0 ? `${prefix}.URL` : `${prefix}.URL_${i + 1}`] =\n domain ? `http://${domain}` : `http://${host}:${port}`;\n });\n return values;\n}\n\n/** Les clés `services.<slug>.*` exposées pour un service voisin. */\nexport function crossServiceValues(service: {\n name: string;\n id: string;\n ports?: number[];\n localUrls?: { url: string; port: number }[];\n url?: string;\n}, host: string): Record<string, string> {\n const slug = serviceSlug(service.name);\n if (!slug) return {};\n return {\n [`services.${slug}.NAME`]: service.name,\n [`services.${slug}.ID`]: service.id,\n ...servicePortValues(service.ports, `services.${slug}`),\n ...serviceUrlValues(service, host, `services.${slug}`),\n ...(service.url ? { [`services.${slug}.BASE_URL`]: service.url } : {}),\n };\n}\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","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"],"mappings":"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","names":["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","z","z","z","env"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/desktop-launcher.ts"],"sourcesContent":["/**\n * Cross-platform desktop launcher (`runeya install-desktop`).\n *\n * Deliberately an explicit sub-command rather than a postinstall hook: npm 12\n * blocks lifecycle scripts by default, so a launcher created that way would be\n * silently missing. Here the user asks for it, and gets the paths back.\n *\n * Nothing is embedded — the launcher points at the Node binary and the CLI\n * entry point currently in use. If the user switches Node version manager,\n * re-running the command re-pins the paths.\n */\nimport { mkdir, writeFile, rm, copyFile, access } from 'node:fs/promises';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { homedir } from 'node:os';\nimport { join, basename, dirname } from 'node:path';\n\nconst exec = promisify(execFile);\n\nexport type InstallOptions = {\n /** Absolute path to the Node binary the launcher must use. */\n nodePath: string;\n /** Absolute path to the CLI entry point (dist/index.js). */\n cliEntry: string;\n /** Directory holding the CLI dist — used to find the bundled icons in assets/. */\n distDir: string;\n /** Working directory to pin, or null to let the desktop decide. */\n workingDir: string | null;\n /** Display name, e.g. \"Runeya\" or \"Runeya — my-stack\". */\n name: string;\n /** Filesystem-safe id derived from the name, e.g. \"runeya-my-stack\". */\n id: string;\n /** Port baked into the launcher, or null to follow Runeya's default. */\n port: number | null;\n /** Agent port, or null to let Runeya derive it from `port + 1`. */\n agentPort: number | null;\n};\n\n/**\n * Arguments the launcher passes to the CLI.\n *\n * `--agent-port` is omitted when it is exactly what Runeya would derive on its\n * own, so the command line stays readable and keeps following the derivation\n * if it ever changes.\n */\nexport function launcherArgs(opts: Pick<InstallOptions, 'port' | 'agentPort'>): string[] {\n const args = ['--from-desktop'];\n if (opts.port !== null) args.push('--port', String(opts.port));\n if (opts.agentPort !== null && opts.agentPort !== (opts.port ?? 4000) + 1) {\n args.push('--agent-port', String(opts.agentPort));\n }\n return args;\n}\n\nexport type LauncherResult = {\n /** Files created or removed, for reporting back to the user. */\n paths: string[];\n /** Non-fatal problems (missing icon, desktop database refresh failed…). */\n warnings: string[];\n};\n\n/** Turn a display name into a filesystem- and desktop-id-safe slug. */\nexport function slugify(name: string): string {\n const slug = name\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return slug || 'runeya';\n}\n\n/**\n * The id is a pure function of the display name, so `uninstall-desktop --name`\n * always resolves to the launcher that `install-desktop` created. Names that\n * already slug to something starting with \"runeya\" are not prefixed again —\n * without that, the default \"Runeya — my-stack\" would yield the unreachable\n * id \"runeya-runeya-my-stack\".\n */\nexport function idFromName(name: string): string {\n const slug = slugify(name);\n return slug.startsWith('runeya') ? slug : `runeya-${slug}`;\n}\n\n/**\n * Derive the display name and id for a launcher.\n * Pinning a directory yields \"Runeya — <folder>\" so several stacks can each\n * have their own entry without colliding.\n */\n/**\n * Le dossier de travail d'un lanceur, avec un repli qui n'est jamais la racine.\n *\n * Sans dossier épinglé, un lanceur hérite du cwd du système — `/` pour le\n * Finder comme pour systemd — et Runeya y placerait son `.runeya`. La racine\n * est en lecture seule sous macOS et interdite d'écriture sous Linux : le home\n * est le seul repli toujours disponible. Le CLI applique la même garde à\n * l'exécution, pour les lanceurs posés avant ce correctif.\n */\nexport function launcherWorkingDir(workingDir: string | null): string {\n return workingDir ?? homedir();\n}\n\nexport function deriveIdentity(explicitName: string | undefined, workingDir: string | null): { name: string; id: string } {\n const name = explicitName ?? (workingDir ? `Runeya — ${basename(workingDir)}` : 'Runeya');\n return { name, id: idFromName(name) };\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Best-effort command: never fails the install, just reports a warning. */\nasync function tryExec(file: string, args: string[], warnings: string[]): Promise<void> {\n try {\n await exec(file, args);\n } catch {\n warnings.push(`Commande optionnelle échouée : ${file} (le lanceur est créé, le menu peut mettre un instant à l'afficher)`);\n }\n}\n\n// ─── Linux ───────────────────────────────────────────────────────────────────\n\n/**\n * Quote a value for the `Exec=` key of a .desktop file.\n * Per the Desktop Entry spec, inside a quoted argument the characters\n * `\"`, backtick, `$` and `\\` must each be preceded by a backslash.\n */\nexport function desktopExecQuote(value: string): string {\n return `\"${value.replace(/[\"`$\\\\]/g, (c) => `\\\\${c}`)}\"`;\n}\n\n/** Escape a value for a non-Exec .desktop key (only backslashes are special). */\nfunction desktopValue(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\\n/g, ' ');\n}\n\nfunction xdgDataHome(): string {\n return process.env['XDG_DATA_HOME'] || join(homedir(), '.local/share');\n}\n\nfunction linuxPaths(id: string) {\n const dataHome = xdgDataHome();\n const appsDir = join(dataHome, 'applications');\n return {\n appsDir,\n entry: join(appsDir, `${id}.desktop`),\n iconDir: join(dataHome, 'icons/hicolor/scalable/apps'),\n icon: join(dataHome, `icons/hicolor/scalable/apps/${id}.svg`),\n };\n}\n\nasync function installLinux(opts: InstallOptions): Promise<LauncherResult> {\n const paths: string[] = [];\n const warnings: string[] = [];\n const p = linuxPaths(opts.id);\n\n // The icon is an SVG, which the scalable hicolor directory takes as-is.\n const sourceIcon = join(opts.distDir, 'assets/icon.svg');\n let iconName = 'application-x-executable';\n if (await exists(sourceIcon)) {\n await mkdir(p.iconDir, { recursive: true });\n await copyFile(sourceIcon, p.icon);\n paths.push(p.icon);\n iconName = opts.id;\n } else {\n warnings.push(`Icône introuvable (${sourceIcon}), icône générique utilisée`);\n }\n\n // --from-desktop: nobody is watching a terminal, so startup failures must be\n // reported in a browser window rather than written to a discarded stderr.\n const exec_ = [opts.nodePath, opts.cliEntry, ...launcherArgs(opts)]\n .map(desktopExecQuote)\n .join(' ');\n const lines = [\n '[Desktop Entry]',\n 'Type=Application',\n `Name=${desktopValue(opts.name)}`,\n 'Comment=Process and service manager',\n `Exec=${exec_}`,\n `Icon=${iconName}`,\n 'Terminal=false',\n 'Categories=Development;',\n 'StartupNotify=true',\n // Marker used by uninstall-desktop to refuse deleting a hand-written entry\n 'X-Runeya-Managed=true',\n ];\n lines.push(`Path=${desktopValue(launcherWorkingDir(opts.workingDir))}`);\n\n await mkdir(p.appsDir, { recursive: true });\n await writeFile(p.entry, lines.join('\\n') + '\\n', { mode: 0o755 });\n paths.push(p.entry);\n\n await tryExec('update-desktop-database', [p.appsDir], warnings);\n\n return { paths, warnings };\n}\n\nasync function uninstallLinux(id: string): Promise<LauncherResult> {\n const paths: string[] = [];\n const warnings: string[] = [];\n const p = linuxPaths(id);\n for (const target of [p.entry, p.icon]) {\n if (await exists(target)) {\n await rm(target, { force: true });\n paths.push(target);\n }\n }\n if (paths.length) await tryExec('update-desktop-database', [p.appsDir], warnings);\n return { paths, warnings };\n}\n\n// ─── macOS ───────────────────────────────────────────────────────────────────\n\n/** Escape a value destined for a <string> node of an Info.plist. */\nfunction plistString(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n}\n\n/** Single-quote a value for the POSIX shell inside the .app stub script. */\nfunction shQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction macAppPath(name: string): string {\n return join(homedir(), 'Applications', `${name}.app`);\n}\n\nasync function installMac(opts: InstallOptions): Promise<LauncherResult> {\n const warnings: string[] = [];\n const appPath = macAppPath(opts.name);\n const macosDir = join(appPath, 'Contents/MacOS');\n const resourcesDir = join(appPath, 'Contents/Resources');\n const execName = opts.id;\n\n await mkdir(macosDir, { recursive: true });\n await mkdir(resourcesDir, { recursive: true });\n\n // The bundle executable is a shell stub: no compiled code, no signing needed.\n // A locally generated .app carries no quarantine attribute, so Gatekeeper\n // lets it run even unsigned.\n const stub = [\n '#!/bin/sh',\n '# Generated by `runeya install-desktop` — safe to delete.',\n `cd ${shQuote(launcherWorkingDir(opts.workingDir))} || exit 1`,\n `exec ${[opts.nodePath, opts.cliEntry, ...launcherArgs(opts)].map(shQuote).join(' ')} \"$@\"`,\n '',\n ].filter(Boolean).join('\\n');\n await writeFile(join(macosDir, execName), stub, { mode: 0o755 });\n\n // CFBundleIconFile is only emitted when the .icns actually made it into the\n // bundle — a key pointing at a missing file makes Finder fall back silently,\n // which is harder to diagnose than no key at all.\n const sourceIcns = join(opts.distDir, 'assets/icon.icns');\n let iconKey = '';\n if (await exists(sourceIcns)) {\n await copyFile(sourceIcns, join(resourcesDir, `${execName}.icns`));\n iconKey = `\\n <key>CFBundleIconFile</key><string>${plistString(execName)}</string>`;\n } else {\n warnings.push(`Icône introuvable (${sourceIcns}), icône générique utilisée`);\n }\n\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>CFBundleName</key><string>${plistString(opts.name)}</string>\n <key>CFBundleDisplayName</key><string>${plistString(opts.name)}</string>\n <key>CFBundleExecutable</key><string>${plistString(execName)}</string>\n <key>CFBundleIdentifier</key><string>dev.runeya.launcher.${plistString(opts.id)}</string>\n <key>CFBundlePackageType</key><string>APPL</string>${iconKey}\n <key>CFBundleInfoDictionaryVersion</key><string>6.0</string>\n <key>CFBundleShortVersionString</key><string>1.0</string>\n <key>NSHighResolutionCapable</key><true/>\n</dict>\n</plist>\n`;\n await writeFile(join(appPath, 'Contents/Info.plist'), plist);\n\n // Ask LaunchServices to notice the new bundle so Spotlight finds it right away.\n await tryExec(\n '/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister',\n ['-f', appPath],\n warnings,\n );\n\n return { paths: [appPath], warnings };\n}\n\nasync function uninstallMac(name: string): Promise<LauncherResult> {\n const appPath = macAppPath(name);\n if (!(await exists(appPath))) return { paths: [], warnings: [] };\n await rm(appPath, { recursive: true, force: true });\n return { paths: [appPath], warnings: [] };\n}\n\n// ─── Windows ─────────────────────────────────────────────────────────────────\n\n/** Single-quote a value for a PowerShell literal string. */\nexport function psQuote(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\nfunction windowsLnkPath(name: string): string {\n const appData = process.env['APPDATA'] || join(homedir(), 'AppData/Roaming');\n return join(appData, 'Microsoft/Windows/Start Menu/Programs', `${name}.lnk`);\n}\n\n/**\n * Où vit le script qui lance Runeya sans console.\n *\n * Hors du dossier du menu Démarrer — un `.vbs` posé là apparaîtrait dans la\n * recherche Windows à côté du raccourci — et hors du `dist` du paquet, qu'une\n * réinstallation npm remplace : le script y disparaîtrait sans que rien ne le\n * recrée, faute de postinstall (npm 12 les bloque).\n */\nfunction windowsVbsPath(id: string): string {\n const localAppData = process.env['LOCALAPPDATA'] || join(homedir(), 'AppData/Local');\n return join(localAppData, 'Runeya', `${id}.vbs`);\n}\n\n/** Double-quote a value for a VBScript string literal. */\nexport function vbsQuote(value: string): string {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n}\n\n/**\n * Le script qui lance Runeya **sans fenêtre**.\n *\n * `node.exe` est une application console : Windows lui alloue une console, et\n * un raccourci ne sait que la réduire (`WindowStyle = 7`) — d'où une fenêtre de\n * commande dans la barre des tâches pendant tout l'usage de l'application.\n *\n * `wscript.exe`, lui, est une application graphique : il n'ouvre aucune console\n * et lance sa cible en `SW_HIDE` (le `0` de `Run`). La console de Node existe\n * donc toujours — c'est ce qui compte : **elle est seulement cachée, pas\n * absente**, et tout ce que Runeya lance ensuite (l'agent, git, docker, les\n * services) l'hérite sans rien afficher. C'est la même intention que le\n * `windowsHide` des runners, posée une fois pour toute la descendance.\n *\n * Le `False` rend la main immédiatement : `wscript` sort, Runeya reste.\n */\nexport function windowsVbsScript(\n opts: Pick<InstallOptions, 'nodePath' | 'cliEntry' | 'port' | 'agentPort'> & { workingDir: string | null },\n): string {\n const command = [opts.nodePath, opts.cliEntry, ...launcherArgs(opts)]\n .map((part) => `\"${part}\"`)\n .join(' ');\n return [\n // Commentaires en ASCII : wscript lit un .vbs sans BOM comme de l'ANSI, et\n // des accents s'y afficheraient de travers à qui l'ouvre.\n \"' Runeya launcher - created by 'runeya install-desktop', do not edit.\",\n \"' wscript.exe opens no console; the 0 below starts Runeya hidden.\",\n 'Set sh = CreateObject(\"WScript.Shell\")',\n `sh.CurrentDirectory = ${vbsQuote(launcherWorkingDir(opts.workingDir))}`,\n `sh.Run ${vbsQuote(command)}, 0, False`,\n '',\n ].join('\\n');\n}\n\nasync function runPowerShell(script: string, warnings: string[]): Promise<void> {\n // -EncodedCommand avoids every layer of cmd.exe quoting.\n const encoded = Buffer.from(script, 'utf16le').toString('base64');\n try {\n await exec('powershell.exe', ['-NoProfile', '-NonInteractive', '-EncodedCommand', encoded]);\n } catch (err) {\n warnings.push(`PowerShell a échoué : ${(err as Error).message}`);\n throw err;\n }\n}\n\nasync function installWindows(opts: InstallOptions): Promise<LauncherResult> {\n const warnings: string[] = [];\n const lnk = windowsLnkPath(opts.name);\n\n // The .ico is referenced in place inside the installed dist rather than\n // copied: the shortcut already breaks if that dist moves, so a second copy\n // would only add a file to leave behind.\n const icoPath = join(opts.distDir, 'assets/icon.ico');\n const iconPath = (await exists(icoPath)) ? icoPath : null;\n if (!iconPath) warnings.push(`Icône introuvable (${icoPath}), icône de Node utilisée`);\n\n // Le raccourci ne lance pas Node : il lance `wscript.exe`, qui lance Node\n // sans console. Un raccourci pointant sur `node.exe` laissait une fenêtre de\n // commande dans la barre des tâches, `WindowStyle` ne sachant que la réduire.\n const vbs = windowsVbsPath(opts.id);\n await mkdir(dirname(vbs), { recursive: true });\n await writeFile(vbs, windowsVbsScript(opts), 'utf8');\n\n const wscript = join(process.env['SystemRoot'] || 'C:\\\\Windows', 'System32', 'wscript.exe');\n\n const script = [\n `$ws = New-Object -ComObject WScript.Shell`,\n `$sc = $ws.CreateShortcut(${psQuote(lnk)})`,\n `$sc.TargetPath = ${psQuote(wscript)}`,\n `$sc.Arguments = ${psQuote(`\"${vbs}\"`)}`,\n `$sc.WorkingDirectory = ${psQuote(launcherWorkingDir(opts.workingDir))}`,\n `$sc.Description = 'Runeya — process and service manager'`,\n // L'icône reste celle de Runeya : elle est déclarée à part de la cible.\n iconPath ? `$sc.IconLocation = ${psQuote(iconPath)}` : '',\n `$sc.Save()`,\n ].filter(Boolean).join('\\n');\n\n await mkdir(dirname(lnk), { recursive: true });\n await runPowerShell(script, warnings);\n\n return { paths: [lnk, vbs], warnings };\n}\n\nasync function uninstallWindows(name: string, id: string): Promise<LauncherResult> {\n // Les deux fichiers, et chacun pour lui-même : un raccourci posé avant que le\n // lanceur ne passe par `wscript` n'a pas de `.vbs` à côté de lui, et son\n // absence n'est pas une raison de laisser le raccourci en place.\n const removed: string[] = [];\n for (const path of [windowsLnkPath(name), windowsVbsPath(id)]) {\n if (!(await exists(path))) continue;\n await rm(path, { force: true });\n removed.push(path);\n }\n return { paths: removed, warnings: [] };\n}\n\n// ─── Entry points ────────────────────────────────────────────────────────────\n\nexport async function installDesktopLauncher(opts: InstallOptions): Promise<LauncherResult> {\n switch (process.platform) {\n case 'linux':\n case 'freebsd':\n case 'openbsd':\n return installLinux(opts);\n case 'darwin':\n return installMac(opts);\n case 'win32':\n return installWindows(opts);\n default:\n throw new Error(`Plateforme non supportée : ${process.platform}`);\n }\n}\n\nexport async function uninstallDesktopLauncher(name: string, id: string): Promise<LauncherResult> {\n switch (process.platform) {\n case 'linux':\n case 'freebsd':\n case 'openbsd':\n return uninstallLinux(id);\n case 'darwin':\n return uninstallMac(name);\n case 'win32':\n return uninstallWindows(name, id);\n default:\n throw new Error(`Plateforme non supportée : ${process.platform}`);\n }\n}\n"],"mappings":"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","names":[]}
|