@runeya/runeya 2.0.103 → 2.0.104

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.
Files changed (334) hide show
  1. package/agent-manager-4XJUIZKL.js +9 -0
  2. package/{chat-JZ4UQDWV.js → chat-3XDVULFH.js} +7 -7
  3. package/{chunk-Z67WBWKD.js → chunk-5GYBAMHV.js} +7 -7
  4. package/{chunk-NZNIWJDT.js → chunk-AAK7ACHG.js} +18 -18
  5. package/{chunk-UYOWIH4R.js → chunk-IOAGFK3P.js} +24 -18
  6. package/{chunk-UYOWIH4R.js.map → chunk-IOAGFK3P.js.map} +1 -1
  7. package/{chunk-KY6KYSOU.js → chunk-LTLOVQJQ.js} +26 -14
  8. package/chunk-LTLOVQJQ.js.map +1 -0
  9. package/{chunk-QIBUMYR6.js → chunk-NPORVPEO.js} +13 -13
  10. package/{companion-6J6NK7H7.js → companion-MUFVXURV.js} +5 -5
  11. package/index.js +9 -5
  12. package/index.js.map +1 -1
  13. package/package.json +1 -1
  14. package/settings-manager-Y4GNAXOH.js +9 -0
  15. package/{src-V7DPPFCF.js → src-TEL7L4K2.js} +299 -34
  16. package/src-TEL7L4K2.js.map +1 -0
  17. package/{tray-TRWZNOUD.js → tray-NZOXYN5G.js} +19 -3
  18. package/tray-NZOXYN5G.js.map +1 -0
  19. package/vault-resolver-JR7TCITD.js +55 -0
  20. package/vault-resolver-JR7TCITD.js.map +1 -0
  21. package/web/assets/AgentScalarChatInterface.vue-CveVquKX.js +13 -0
  22. package/web/assets/AgentTerminalPage-DkNOUzXx.js +1 -0
  23. package/web/assets/AiChatPage-CTF8FIV4.js +1 -0
  24. package/web/assets/AppLayout-agjOv6PY.js +1 -0
  25. package/web/assets/AuditPage-dgYwbpdR.js +1 -0
  26. package/web/assets/CloudAccountPage-Bx9gNcJQ.js +1 -0
  27. package/web/assets/CloudAccountPage-DEnVoeik.js +1 -0
  28. package/web/assets/CloudMessagingPage-qKrKfB-F.js +2 -0
  29. package/web/assets/DashboardPage-Bwq2Nhg2.js +1 -0
  30. package/web/assets/DirectoryPickerDialog-D8XDtgZh.js +1 -0
  31. package/web/assets/{EditorIcon-BguaWtZg.js → EditorIcon-CA5ff6aq.js} +2 -2
  32. package/web/assets/{EnvironmentForm-D8dq0ffR.js → EnvironmentForm-CzSZiA51.js} +2 -2
  33. package/web/assets/EnvironmentFormPage-CuSgaY1_.js +1 -0
  34. package/web/assets/EnvironmentListPage-Dsw3CJvc.js +1 -0
  35. package/web/assets/KanbanBoardPage-CUVcQ4YW.js +4 -0
  36. package/web/assets/KanbanListPage-CGhlz8Pe.js +1 -0
  37. package/web/assets/LaunchProjectPage-BveJC98q.js +1 -0
  38. package/web/assets/LaunchServicesPage-B0W02JDF.js +1 -0
  39. package/web/assets/LogViewer-Rr_WYaUa.js +3 -0
  40. package/web/assets/OrgKeyPrompt-CG2-L3Lf.js +1 -0
  41. package/web/assets/{ProcessControls-D3zTnHb2.js → ProcessControls-DvSw2AQV.js} +1 -1
  42. package/web/assets/ProcessDetailPage-Decf7LjW.js +1 -0
  43. package/web/assets/{ProcessMetrics-Dwd5lzqY.js → ProcessMetrics-xWpkhjoe.js} +2 -2
  44. package/web/assets/ProjectDetailPage-xg7x2vFI.js +1 -0
  45. package/web/assets/ProjectListPage-Bv2fwGla.js +1 -0
  46. package/web/assets/RandomJobTestPage-BEn1gSo3.js +2 -0
  47. package/web/assets/ScenarioEditorPage-CLiTQe4B.js +14 -0
  48. package/web/assets/SendToChatDialog-DdvfNdWg.js +1 -0
  49. package/web/assets/ServiceControlsBar-DKc2e9Ns.js +1 -0
  50. package/web/assets/ServiceDetailPage-BfkVlUEh.js +2 -0
  51. package/web/assets/ServiceFormPage-BTJBk_wB.js +1 -0
  52. package/web/assets/SettingsPage-BlOHIALT.js +2063 -0
  53. package/web/assets/UnlockPage-u3Zqu1aU.js +1 -0
  54. package/web/assets/VariablesTable-MFZSG4LV.js +1 -0
  55. package/web/assets/VaultMigrationPage-CTMCgOtW.js +1 -0
  56. package/web/assets/VersionBadge-D5zxX_zs.js +1 -0
  57. package/web/assets/WikiPage-BkQZP60x.js +1 -0
  58. package/web/assets/WikiView-CFX5gG2s.js +1 -0
  59. package/web/assets/add-scalar-classes-ClMP-KRl.js +387 -0
  60. package/web/assets/{autocomplete-QtPLLzzV.js → autocomplete-CBY4HTQR.js} +3 -3
  61. package/web/assets/{basic-shape-diamond.svg-Dyx8FJkS.js → basic-shape-diamond.svg-irIu-f9l.js} +1 -1
  62. package/web/assets/{basic-shape-hexagon.svg-1RKdVP3_.js → basic-shape-hexagon.svg-DasEKbDT.js} +1 -1
  63. package/web/assets/{basic-shape-primary-circle-ellipse-round.svg-CSa69hok.js → basic-shape-primary-circle-ellipse-round.svg-DFanDXAm.js} +1 -1
  64. package/web/assets/{basic-shape-primary-square-rectangle.svg-B9TXktd4.js → basic-shape-primary-square-rectangle.svg-Dkyo9dlJ.js} +1 -1
  65. package/web/assets/{basic-shape-shield.svg-BZvKXoiw.js → basic-shape-shield.svg-3imE69mJ.js} +1 -1
  66. package/web/assets/{browser-CYeKc8Uo.js → browser-Aa5s7rfo.js} +1 -1
  67. package/web/assets/{browser-VlhbsseI.js → browser-DUQZPder.js} +1 -1
  68. package/web/assets/{card-tEWfv-Op.js → card-D-ziPwAg.js} +2 -2
  69. package/web/assets/{checkbox-CyPqKR6H.js → checkbox-tdxfIWhT.js} +3 -3
  70. package/web/assets/{chip-wM0gJ_FI.js → chip-DQ2M3lMV.js} +2 -2
  71. package/web/assets/client-w--F512m.js +24 -0
  72. package/web/assets/cloud-chat.store-DwSl7oKq.js +1 -0
  73. package/web/assets/{cloud-session-g6ewm0UI.js → cloud-session-Do-zjE8q.js} +1 -1
  74. package/web/assets/column-Bv9vDejf.js +907 -0
  75. package/web/assets/{computer-device-desktop-monitor.svg-ClbIVuot.js → computer-device-desktop-monitor.svg-CYOP3WaB.js} +1 -1
  76. package/web/assets/{computer-device-desktop.svg-CXpOovTP.js → computer-device-desktop.svg-qlrBIvQY.js} +1 -1
  77. package/web/assets/{computer-device-laptop.svg-C9sY1wZv.js → computer-device-laptop.svg-IHPj_lEm.js} +1 -1
  78. package/web/assets/{computer-device-mobile-phone-android-samsung-back.svg-CPWC2QHX.js → computer-device-mobile-phone-android-samsung-back.svg-DKPSbT77.js} +1 -1
  79. package/web/assets/{computer-device-mobile-phone-android-samsung.svg-B0H-mnfh.js → computer-device-mobile-phone-android-samsung.svg-s5qvH0rw.js} +1 -1
  80. package/web/assets/{computer-device-mobile-phone-iphone-x-back.svg-BbIunxoN.js → computer-device-mobile-phone-iphone-x-back.svg-B77oIjAn.js} +1 -1
  81. package/web/assets/{computer-device-mobile-phone-iphone-x.svg-qLGK_oVA.js → computer-device-mobile-phone-iphone-x.svg-Cnz0nuie.js} +1 -1
  82. package/web/assets/{computer-device-mobile-tablet-touch.svg-BDpuB6SD.js → computer-device-mobile-tablet-touch.svg-CGw0OJdZ.js} +1 -1
  83. package/web/assets/{computer-device-mobile-tablet.svg-44THWP9E.js → computer-device-mobile-tablet.svg-BllNUwYz.js} +1 -1
  84. package/web/assets/{computer-device-network-ethernet-cat6.svg-tlgWltl_.js → computer-device-network-ethernet-cat6.svg-CDcu8JSm.js} +1 -1
  85. package/web/assets/{computer-device-network-lan-www.svg-Bd7Ch4QN.js → computer-device-network-lan-www.svg-Cr2Mzrgm.js} +1 -1
  86. package/web/assets/{computer-device-network-wifi-connection.svg-D_XjoY-a.js → computer-device-network-wifi-connection.svg-BdIGk-iA.js} +1 -1
  87. package/web/assets/{computer-device-network-wifi-router.svg-BRpuwgUx.js → computer-device-network-wifi-router.svg-ChrqaXoE.js} +1 -1
  88. package/web/assets/{cssMode-D0M5mbRd.js → cssMode-DQ3QWGDZ.js} +1 -1
  89. package/web/assets/{divider-gPnMjjpJ.js → divider-BnVkpmcn.js} +2 -2
  90. package/web/assets/{docx-preview-CBPtwrA0.js → docx-preview-DOVrOL2W.js} +1 -1
  91. package/web/assets/{ecology-science-erlenmeyer-flask.svg-CZ3uUeBT.js → ecology-science-erlenmeyer-flask.svg-Bz0bzqPi.js} +1 -1
  92. package/web/assets/{fieldset-BSGgRmpr.js → fieldset-CaBT4en1.js} +2 -2
  93. package/web/assets/{freemarker2-BWsK2SIi.js → freemarker2-e7ZK44f9.js} +1 -1
  94. package/web/assets/{handlebars-CHNB1gG0.js → handlebars-BunSmNEk.js} +1 -1
  95. package/web/assets/{html-COwA9Dtl.js → html-t6Ga4VcA.js} +1 -1
  96. package/web/assets/{htmlMode-gZ2_PUDA.js → htmlMode-CjsAz81L.js} +1 -1
  97. package/web/assets/{image-flash-lightning.svg-Iiwm_7-K.js → image-flash-lightning.svg-CSanVzgy.js} +1 -1
  98. package/web/assets/{image-picture-flower.svg-BP9U6YP8.js → image-picture-flower.svg-DUlCxHzi.js} +1 -1
  99. package/web/assets/{index-mBPGEldp.js → index-CNqv4qMO.js} +262 -262
  100. package/web/assets/{interface-alert-exclamation-diamond.svg-BYWgnbUp.js → interface-alert-exclamation-diamond.svg-C-uhPFKN.js} +1 -1
  101. package/web/assets/{interface-alert-exclamation-triangle-warning.svg-CWGfXHx_.js → interface-alert-exclamation-triangle-warning.svg-BnSCXw68.js} +1 -1
  102. package/web/assets/{interface-alert-information-circle.svg-88Bga8qr.js → interface-alert-information-circle.svg-CTGCb0Yf.js} +1 -1
  103. package/web/assets/{interface-award-crown.svg-3hO77oiy.js → interface-award-crown.svg-T-Lov9NP.js} +1 -1
  104. package/web/assets/{interface-bookmark.svg-SfHcE95h.js → interface-bookmark-tag.svg-DLjS0Lnz.js} +1 -1
  105. package/web/assets/{interface-bookmark-tag.svg-DcHwQsr0.js → interface-bookmark.svg-CZekkdj9.js} +1 -1
  106. package/web/assets/{interface-calendar-date-one.svg-DdXOM9VZ.js → interface-calendar-date-one.svg-DmD4yfdS.js} +1 -1
  107. package/web/assets/{interface-content-book-open-pages.svg-DD7QTDn_.js → interface-content-book-open-pages.svg-wHqGX15c.js} +1 -1
  108. package/web/assets/{interface-content-book-page.svg-Dd45mFzB.js → interface-content-book-page.svg-MCSanA32.js} +1 -1
  109. package/web/assets/{interface-content-file.svg-slPoMF5K.js → interface-content-file.svg-DBpf8dcs.js} +1 -1
  110. package/web/assets/{interface-content-folder.svg-cSgXwhRh.js → interface-content-folder.svg-DZSoYO0L.js} +1 -1
  111. package/web/assets/interface-content-folder.svg-ZujlG0Az.js +1 -0
  112. package/web/assets/{interface-copy-clipboard.svg-DNy0VeWx.js → interface-copy-clipboard.svg-C1-sJNwr.js} +1 -1
  113. package/web/assets/{interface-edit-attachment.svg-VyCAm1jc.js → interface-edit-attachment.svg-CpxThva3.js} +1 -1
  114. package/web/assets/{interface-edit-binocular.svg-DA6QB2sn.js → interface-edit-binocular.svg-BHfWW26z.js} +1 -1
  115. package/web/assets/{interface-edit-magic-wand.svg-D0uagBk7.js → interface-edit-magic-wand.svg-DcC6CJBy.js} +1 -1
  116. package/web/assets/{interface-edit-tool-paint-roller.svg-ConlubSG.js → interface-edit-tool-paint-roller.svg-BhReRG-a.js} +1 -1
  117. package/web/assets/{interface-edit-tool-pencil.svg-BgNzCwXf.js → interface-edit-tool-pencil.svg-CztZ4Olx.js} +1 -1
  118. package/web/assets/{interface-favorite-award.svg-MLL88pIy.js → interface-favorite-award.svg-C0kleqGy.js} +1 -1
  119. package/web/assets/{interface-favorite-flag.svg-ZhM_9XJZ.js → interface-favorite-flag.svg-B-VJ_w7p.js} +1 -1
  120. package/web/assets/{interface-favorite-heart.svg-Cqq1PV9O.js → interface-favorite-heart.svg-CuRtXB-S.js} +1 -1
  121. package/web/assets/{interface-favorite-star.svg-YumblcRD.js → interface-favorite-star.svg-DtEkT0h3.js} +1 -1
  122. package/web/assets/{interface-favorite-stars-sparkles.svg-BH5BXXOe.js → interface-favorite-stars-sparkles.svg-ffOT-I95.js} +1 -1
  123. package/web/assets/{interface-hierarchy-flowchart.svg-CEfCPIyC.js → interface-hierarchy-flowchart.svg-C5eB0vng.js} +1 -1
  124. package/web/assets/{interface-home-house.svg-DJE_g94c.js → interface-home-house.svg-Djr3DBJk.js} +1 -1
  125. package/web/assets/{interface-hyperlink.svg-BFhnDXDD.js → interface-hyperlink.svg-BaesgCsY.js} +1 -1
  126. package/web/assets/{interface-lighting-brightness.svg-NwOV0KEv.js → interface-lighting-brightness.svg-CiNPNypw.js} +1 -1
  127. package/web/assets/{interface-lock-closed.svg-qVkplX0W.js → interface-lock-closed.svg-Dk3IIjH4.js} +1 -1
  128. package/web/assets/{interface-lock-open-unlock.svg-D18OlPEP.js → interface-lock-open-unlock.svg-DGG8lod0.js} +1 -1
  129. package/web/assets/{interface-login-key.svg-CccXX7_b.js → interface-login-key.svg-ZREdsGBv.js} +1 -1
  130. package/web/assets/{interface-search.svg-C6ncELaU.js → interface-search.svg-AF3hFV8X.js} +1 -1
  131. package/web/assets/{interface-setting-cog.svg-5LrIeBav.js → interface-setting-cog.svg-CxjXHOho.js} +1 -1
  132. package/web/assets/{interface-share-megaphone-bullhorn.svg-C-qB4VYi.js → interface-share-megaphone-bullhorn.svg-C-Ou9l0X.js} +1 -1
  133. package/web/assets/{interface-share-rocket.svg-Citzuyng.js → interface-share-rocket.svg-CERB2Bts.js} +1 -1
  134. package/web/assets/{interface-share-satellite.svg-BldpdKdo.js → interface-share-satellite.svg-BfHWK0sr.js} +1 -1
  135. package/web/assets/{interface-share-space-ship.svg-B_Ni34rB.js → interface-share-space-ship.svg-lWM8H0aF.js} +1 -1
  136. package/web/assets/{interface-share.svg-FAt7Kgad.js → interface-share.svg-CFf-5WEt.js} +1 -1
  137. package/web/assets/{interface-signal-square.svg-DeBP6Pim.js → interface-signal-square.svg-BIiI1WkB.js} +1 -1
  138. package/web/assets/{interface-time-clock-circle.svg-dQfNY8BC.js → interface-time-clock-circle.svg-MloMulBj.js} +1 -1
  139. package/web/assets/{interface-time-hour-glass.svg-ylbFnlwY.js → interface-time-hour-glass.svg-BOxCCGI2.js} +1 -1
  140. package/web/assets/{interface-users-multiple.svg-DXts3WMC.js → interface-users-multiple.svg-4T9srtFC.js} +1 -1
  141. package/web/assets/{interface-weather-moon.svg-BG6mjCih.js → interface-weather-moon.svg-CKHzp1q9.js} +1 -1
  142. package/web/assets/{javascript-C_ENjImO.js → javascript-D9xsJ3Az.js} +1 -1
  143. package/web/assets/{jsonMode-Bt-LEknD.js → jsonMode-DuBcXIAs.js} +2 -2
  144. package/web/assets/{liquid-CVshgHmY.js → liquid-DEC7GfIV.js} +1 -1
  145. package/web/assets/{lspLanguageFeatures-D1e-RcOs.js → lspLanguageFeatures-BWtjzx_b.js} +3 -3
  146. package/web/assets/{mail-chat-bubble-square.svg-RUMLqiUI.js → mail-chat-bubble-square.svg-Bnr_lHI8.js} +1 -1
  147. package/web/assets/{mail-send-email-paper-airplane.svg-JDe3yqOH.js → mail-send-email-paper-airplane.svg-BX3SaAOF.js} +1 -1
  148. package/web/assets/{mail-send-envelope.svg-CCzWaeO-.js → mail-send-envelope.svg-ZUoORksb.js} +1 -1
  149. package/web/assets/{mdx-D9G2-Bj8.js → mdx-HOoxTDWS.js} +1 -1
  150. package/web/assets/{minus-BMxEQL_C.js → minus-BBEVgxJH.js} +2 -2
  151. package/web/assets/modal-DM9X_PVj.js +5 -0
  152. package/web/assets/modal-lOChu0a6.js +1 -0
  153. package/web/assets/{money-cashier-receipt.svg-DfbOr89U.js → money-cashier-receipt.svg-DZ3PFTDB.js} +1 -1
  154. package/web/assets/{money-currency-dollar-pay.svg-DY7fQ7jz.js → money-currency-dollar-pay.svg-MP_zZSsR.js} +1 -1
  155. package/web/assets/{money-graph-arrow-increase.svg-jewlEZEL.js → money-graph-arrow-increase.svg-zF1qoCJ1.js} +1 -1
  156. package/web/assets/{money-graph-bar-chart-increase.svg-BChD8dZv.js → money-graph-bar-chart-increase.svg-BDD2RhNd.js} +1 -1
  157. package/web/assets/multiselect-BGmyQeLC.js +251 -0
  158. package/web/assets/{nature-ecology-leaf.svg-AQimnw3F.js → nature-ecology-leaf.svg-C8ROcT5o.js} +1 -1
  159. package/web/assets/{password-4Ykb_Ejn.js → password-4B0Jk2Id.js} +4 -4
  160. package/web/assets/{phone-telephone.svg-BdkwIhmo.js → phone-telephone.svg-DKK-lUXQ.js} +1 -1
  161. package/web/assets/{plus-CYVYZlQL.js → plus-CTzNAMSa.js} +6 -6
  162. package/web/assets/process.store-hTCiNh-E.js +1 -0
  163. package/web/assets/{programming-bug.svg-DzT817WD.js → programming-bug.svg-D2E8tMFA.js} +1 -1
  164. package/web/assets/{programming-cloud.svg-eKZD46YP.js → programming-cloud.svg-BGnh40iK.js} +1 -1
  165. package/web/assets/{programming-computer-database-server.svg-BXOhjcQy.js → programming-computer-database-server.svg-BVAuZnpu.js} +1 -1
  166. package/web/assets/{programming-computer-database.svg-DUzhimFY.js → programming-computer-database.svg-Cw61nQGg.js} +1 -1
  167. package/web/assets/{programming-module-four-layout.svg-CYGX7Rlj.js → programming-module-four-layout.svg-DoU0KSeo.js} +1 -1
  168. package/web/assets/{programming-module-three.svg-BhQr1m-R.js → programming-module-three.svg-DVhh6Qdu.js} +1 -1
  169. package/web/assets/{programming-module.svg-Bik697Ne.js → programming-module.svg-DvJfoHtJ.js} +1 -1
  170. package/web/assets/{programming-script-code.svg-BaTanEvH.js → programming-script-code.svg-C-tp6SrH.js} +1 -1
  171. package/web/assets/{python-wDvaXe-V.js → python--BJI87h8.js} +1 -1
  172. package/web/assets/{razor-C-cEFJP1.js → razor-CyKegkVq.js} +1 -1
  173. package/web/assets/router-CjeDvoXv.js +1 -0
  174. package/web/assets/settings-scope-78RP25Qh.js +1 -0
  175. package/web/assets/settings.store-D0Rg-dsM.js +1 -0
  176. package/web/assets/{shopping-cart.svg-BwUFrGEq.js → shopping-cart.svg-LfGHmiMy.js} +1 -1
  177. package/web/assets/{shopping-gift-present.svg-Bs4b94QF.js → shopping-gift-present.svg-DQxn6jVj.js} +1 -1
  178. package/web/assets/{shopping-shipping-box-parcel-package.svg-DhVaYapE.js → shopping-shipping-box-parcel-package.svg-0_aBSgUi.js} +1 -1
  179. package/web/assets/src-BVvRi5bZ.js +1 -0
  180. package/web/assets/src-COTZAWP1.js +572 -0
  181. package/web/assets/{src-CpoqK21I.js → src-DmAdua1A.js} +14 -14
  182. package/web/assets/{tabpanel-DMt8G5AA.js → tabpanel-DHCbTagN.js} +3 -3
  183. package/web/assets/{tag-new-circle.svg-B4Z8uL1_.js → tag-new-circle.svg-83yDHm_4.js} +1 -1
  184. package/web/assets/theme-CDWRcPhl.js +1 -0
  185. package/web/assets/{toggleswitch-CawhRFb7.js → toggleswitch-98WbJy1b.js} +2 -2
  186. package/web/assets/{travel-map-earth-globe.svg-D0s5cc-W.js → travel-map-earth-globe.svg-Ih5Yi-jq.js} +1 -1
  187. package/web/assets/trpc-BOcC0r-H.js +1 -0
  188. package/web/assets/{tsMode-NHDuTjcd.js → tsMode-ocCX3Kwn.js} +4 -4
  189. package/web/assets/{typescript-DGkgFTtn.js → typescript-BNLFcH9T.js} +1 -1
  190. package/web/assets/useAiChatDrawer-DVacYOFX.js +1 -0
  191. package/web/assets/{useCloudOrg-BJTjZPZ9.js → useCloudOrg-D_o0-v2z.js} +1 -1
  192. package/web/assets/useProjectCatalog-CSqoTWGy.js +1 -0
  193. package/web/assets/useProjectCloudOrg-iblWkaw9.js +1 -0
  194. package/web/assets/{xml-CJaXEqLW.js → xml-DcSXqrs-.js} +1 -1
  195. package/web/assets/{yaml-bl8i8xOf.js → yaml-BNINCoLr.js} +1 -1
  196. package/web/index.html +1 -1
  197. package/agent-manager-OWHTBG46.js +0 -9
  198. package/chunk-KY6KYSOU.js.map +0 -1
  199. package/settings-manager-NZV26BC3.js +0 -9
  200. package/src-V7DPPFCF.js.map +0 -1
  201. package/tray-TRWZNOUD.js.map +0 -1
  202. package/web/assets/AgentScalarChatInterface.vue-CvG5ha3R.js +0 -13
  203. package/web/assets/AgentTerminalPage-DcGppuzO.js +0 -1
  204. package/web/assets/AiChatPage-BDr5tG0A.js +0 -1
  205. package/web/assets/AppLayout-Dv3ViAk2.js +0 -1
  206. package/web/assets/AuditPage-Bc2jlgZJ.js +0 -1
  207. package/web/assets/CloudAccountPage-4BLXSOix.js +0 -1
  208. package/web/assets/CloudAccountPage-B3MX6DNn.js +0 -1
  209. package/web/assets/CloudMessagingPage-CVzUalxx.js +0 -2
  210. package/web/assets/DashboardPage-Bo51pbzt.js +0 -1
  211. package/web/assets/DirectoryPickerDialog-CIVjWKUm.js +0 -1
  212. package/web/assets/EnvironmentFormPage-d8p3q8Yt.js +0 -1
  213. package/web/assets/EnvironmentListPage-DWo2lWjE.js +0 -1
  214. package/web/assets/KanbanBoardPage-DkwIz3J1.js +0 -4
  215. package/web/assets/KanbanListPage-xIQRLcrS.js +0 -1
  216. package/web/assets/LaunchProjectPage-CXWixUmf.js +0 -1
  217. package/web/assets/LaunchServicesPage-nv-chYgX.js +0 -1
  218. package/web/assets/LogViewer-DLupfjjf.js +0 -3
  219. package/web/assets/OrgKeyPrompt-DePcB-8f.js +0 -1
  220. package/web/assets/ProcessDetailPage-CgVGzRoJ.js +0 -1
  221. package/web/assets/ProjectDetailPage-HR20KyJ3.js +0 -1
  222. package/web/assets/ProjectListPage-DcH4uTTX.js +0 -1
  223. package/web/assets/RandomJobTestPage-BYTkVcdE.js +0 -2
  224. package/web/assets/ScenarioEditorPage-zRxR03Ud.js +0 -14
  225. package/web/assets/SendToChatDialog-Cm5eKBOb.js +0 -1
  226. package/web/assets/ServiceControlsBar-oBpAP9yX.js +0 -1
  227. package/web/assets/ServiceDetailPage-CahBi-or.js +0 -2
  228. package/web/assets/ServiceFormPage-DfmPM_mI.js +0 -1
  229. package/web/assets/SettingsPage-CDMXFJ4k.js +0 -2063
  230. package/web/assets/UnlockPage-BUyBEPzQ.js +0 -1
  231. package/web/assets/VariablesTable-Dc6CyVQW.js +0 -1
  232. package/web/assets/VaultMigrationPage-BUmzyDXN.js +0 -1
  233. package/web/assets/VersionBadge-Dx_67FtC.js +0 -1
  234. package/web/assets/WikiPage-DEMJLDpD.js +0 -1
  235. package/web/assets/WikiView-CcrQ2ySx.js +0 -1
  236. package/web/assets/add-scalar-classes-M_EBdf4f.js +0 -387
  237. package/web/assets/client-B919VgbS.js +0 -24
  238. package/web/assets/cloud-chat.store-C-A9nIqG.js +0 -1
  239. package/web/assets/column-DihIO4Zd.js +0 -907
  240. package/web/assets/interface-content-folder.svg-D90zbTLh.js +0 -1
  241. package/web/assets/modal-CZ7zYg5t.js +0 -1
  242. package/web/assets/modal-CmpFIC5N.js +0 -5
  243. package/web/assets/multiselect-CoRzeHvy.js +0 -251
  244. package/web/assets/process.store-CtXpHndZ.js +0 -1
  245. package/web/assets/router-CqYmBKhe.js +0 -1
  246. package/web/assets/settings-scope-DD7SbjFz.js +0 -1
  247. package/web/assets/settings.store-DcQmvBBv.js +0 -1
  248. package/web/assets/src-De5rZb3_.js +0 -1
  249. package/web/assets/src-NB2ZR0ON.js +0 -572
  250. package/web/assets/trpc-B17uPEkC.js +0 -1
  251. package/web/assets/useAiChatDrawer-BxE6EYFc.js +0 -1
  252. package/web/assets/useProjectCatalog-DifZyVY5.js +0 -1
  253. package/web/assets/useProjectCloudOrg-EvyyjH6E.js +0 -1
  254. /package/{agent-manager-OWHTBG46.js.map → agent-manager-4XJUIZKL.js.map} +0 -0
  255. /package/{chat-JZ4UQDWV.js.map → chat-3XDVULFH.js.map} +0 -0
  256. /package/{chunk-Z67WBWKD.js.map → chunk-5GYBAMHV.js.map} +0 -0
  257. /package/{chunk-NZNIWJDT.js.map → chunk-AAK7ACHG.js.map} +0 -0
  258. /package/{chunk-QIBUMYR6.js.map → chunk-NPORVPEO.js.map} +0 -0
  259. /package/{companion-6J6NK7H7.js.map → companion-MUFVXURV.js.map} +0 -0
  260. /package/{settings-manager-NZV26BC3.js.map → settings-manager-Y4GNAXOH.js.map} +0 -0
  261. /package/web/assets/{abap-BvxTqXT2.js → abap-PT-N0eyj.js} +0 -0
  262. /package/web/assets/{apex-CIPCCkBr.js → apex-BYovhaVz.js} +0 -0
  263. /package/web/assets/{azcli-Rs0NIwkA.js → azcli-DOxZ9r2f.js} +0 -0
  264. /package/web/assets/{bat-BxAhM6gR.js → bat-B29juGG4.js} +0 -0
  265. /package/web/assets/{bicep-oV_ehPcG.js → bicep-7-ApPSlE.js} +0 -0
  266. /package/web/assets/{browser-DNbnH79q.js → browser-N7UrAcvB.js} +0 -0
  267. /package/web/assets/{cameligo-CJLaUyQs.js → cameligo-BipBUQCp.js} +0 -0
  268. /package/web/assets/{clojure-CjvMureh.js → clojure-DBgUdyK0.js} +0 -0
  269. /package/web/assets/{coffee-motWC5XQ.js → coffee-DIU_x8Zp.js} +0 -0
  270. /package/web/assets/{cpp-DiWIfYNM.js → cpp-CAPjLTys.js} +0 -0
  271. /package/web/assets/{csharp-GBlGBeai.js → csharp-kFCIHjec.js} +0 -0
  272. /package/web/assets/{csp-tSyK5eO1.js → csp-BFKsjgRE.js} +0 -0
  273. /package/web/assets/{css-BkFK9HG_.js → css-C3uiAvXV.js} +0 -0
  274. /package/web/assets/{cypher-Bcp8PXr2.js → cypher-BC8El989.js} +0 -0
  275. /package/web/assets/{dart-uz9Rxe0M.js → dart-BAClpSRO.js} +0 -0
  276. /package/web/assets/{dockerfile-iJizx3Zp.js → dockerfile-DVZSJ3rq.js} +0 -0
  277. /package/web/assets/{ecl-BalaS36Z.js → ecl-Dis7T_5W.js} +0 -0
  278. /package/web/assets/{elixir-D6CLrLGy.js → elixir-B0xfsmfq.js} +0 -0
  279. /package/web/assets/{flow9-CFt3-vVY.js → flow9-DbTJxEBz.js} +0 -0
  280. /package/web/assets/{fsharp-DGa7raxa.js → fsharp-DTOqftZo.js} +0 -0
  281. /package/web/assets/{go-wlqInk4z.js → go-KWOR5hag.js} +0 -0
  282. /package/web/assets/{graphql-CP1guigM.js → graphql-DjYFSl6G.js} +0 -0
  283. /package/web/assets/{hcl-CK0UkKD0.js → hcl-D8RrENjV.js} +0 -0
  284. /package/web/assets/{ini-Ch56nrUj.js → ini-BOtkgeoY.js} +0 -0
  285. /package/web/assets/{java-C9_WIayl.js → java-DKd4_eEX.js} +0 -0
  286. /package/web/assets/{julia-Can2_mhR.js → julia-XpEGblEj.js} +0 -0
  287. /package/web/assets/{kotlin-DUvGf_BX.js → kotlin-BZv3QweN.js} +0 -0
  288. /package/web/assets/{less-DoTbG-rc.js → less-H5kV6pUj.js} +0 -0
  289. /package/web/assets/{lexon-BFMO2_kL.js → lexon-Bg4gEB0s.js} +0 -0
  290. /package/web/assets/{lua-CC-QtBo7.js → lua-D7eb4Dnq.js} +0 -0
  291. /package/web/assets/{m3-C51MyH5Q.js → m3-BjDYXZ0c.js} +0 -0
  292. /package/web/assets/{markdown-CDwLHhgZ.js → markdown-Cl5YxO_y.js} +0 -0
  293. /package/web/assets/{mips-YuxZtPGU.js → mips-sklxJ87A.js} +0 -0
  294. /package/web/assets/{msdax-CJjWhmte.js → msdax-C0nZ2Nk3.js} +0 -0
  295. /package/web/assets/{mysql-B1riwLaD.js → mysql-D6eZPdeQ.js} +0 -0
  296. /package/web/assets/{objective-c-drXT-gmc.js → objective-c-W10E2fSz.js} +0 -0
  297. /package/web/assets/{pascal-KUYgrN-Z.js → pascal-Cd0rtL9J.js} +0 -0
  298. /package/web/assets/{pascaligo-DQmQJP-r.js → pascaligo-BbE09f5f.js} +0 -0
  299. /package/web/assets/{perl-09XLBmCS.js → perl-bnuvlUCT.js} +0 -0
  300. /package/web/assets/{pgsql-BFj9IFFu.js → pgsql-BETeeS25.js} +0 -0
  301. /package/web/assets/{php-UnC5BqwY.js → php-zaSPUC-m.js} +0 -0
  302. /package/web/assets/{pla-BFuYrPHG.js → pla-ChOKgzpJ.js} +0 -0
  303. /package/web/assets/{postiats-n4ft3jnO.js → postiats-By_SllB5.js} +0 -0
  304. /package/web/assets/{powerquery-D-s-oFSc.js → powerquery-CB5gIeJ1.js} +0 -0
  305. /package/web/assets/{powershell-CTboTf93.js → powershell-CgdaEQwq.js} +0 -0
  306. /package/web/assets/{protobuf-Dt62GuJP.js → protobuf-P7fNUpCt.js} +0 -0
  307. /package/web/assets/{pug-CEFWkUzw.js → pug-DZaxV_Nc.js} +0 -0
  308. /package/web/assets/{qsharp-B0DUmgPZ.js → qsharp-BdkO9QAN.js} +0 -0
  309. /package/web/assets/{r-BVnF0c4T.js → r-C-pPWc3R.js} +0 -0
  310. /package/web/assets/{redis-DLl3KQXi.js → redis-BT1HxrEq.js} +0 -0
  311. /package/web/assets/{redshift-cif1I7h1.js → redshift-CDnJNPnz.js} +0 -0
  312. /package/web/assets/{restructuredtext-PNfql36m.js → restructuredtext-Bt8v-MuE.js} +0 -0
  313. /package/web/assets/{ruby-j3jxDjUN.js → ruby-BLxqHkKg.js} +0 -0
  314. /package/web/assets/{rust-BaIO-mAt.js → rust-CIh7vugr.js} +0 -0
  315. /package/web/assets/{sb-D8XNVNUQ.js → sb-eE41pfwD.js} +0 -0
  316. /package/web/assets/{scala-DiK9Ps90.js → scala-COBuWHwn.js} +0 -0
  317. /package/web/assets/{scheme-DPKqXHmF.js → scheme-BsGc_ajc.js} +0 -0
  318. /package/web/assets/{scss-DpMwfP2H.js → scss-DLmucKJk.js} +0 -0
  319. /package/web/assets/{shared-sse-CTMtESqe.js → shared-sse---by8uTc.js} +0 -0
  320. /package/web/assets/{shell-Dw9mKVg2.js → shell-8IUXMVcg.js} +0 -0
  321. /package/web/assets/{solidity-DTxo-7fe.js → solidity-DUTott7T.js} +0 -0
  322. /package/web/assets/{sophia-BjA3Q87y.js → sophia-GqIrTWz8.js} +0 -0
  323. /package/web/assets/{sparql-q1EpMUqb.js → sparql-BfkJA0CL.js} +0 -0
  324. /package/web/assets/{sql-CjcQ4wIr.js → sql-BF_o1CCN.js} +0 -0
  325. /package/web/assets/{st-AuOpxVl7.js → st-B6_wiXyW.js} +0 -0
  326. /package/web/assets/{swift-BUWnv6f7.js → swift-BHDD2Ajh.js} +0 -0
  327. /package/web/assets/{systemverilog-FhXn-3OZ.js → systemverilog-BG_Ebh2a.js} +0 -0
  328. /package/web/assets/{tcl-B0lqcTtS.js → tcl-ocTQVTM_.js} +0 -0
  329. /package/web/assets/{twig-B0OeGPVa.js → twig-CF5whnDX.js} +0 -0
  330. /package/web/assets/{typespec-Bmh6VX11.js → typespec-5BWfbhTE.js} +0 -0
  331. /package/web/assets/{uuid-Q0SWZmaT.js → uuid-FpfcaBnR.js} +0 -0
  332. /package/web/assets/{vb-bmgX6veu.js → vb-agPNUcOk.js} +0 -0
  333. /package/web/assets/{w3c-keyname-2TLn3EjF.js → w3c-keyname-2_K_z_q5.js} +0 -0
  334. /package/web/assets/{wgsl-FflLnFqI.js → wgsl-CufoMn6o.js} +0 -0
@@ -1,3 +1,9 @@
1
+ // ../server/src/services/vault-resolver.ts
2
+ import { join, sep } from "path";
3
+ import { homedir } from "os";
4
+ import { readdir, mkdir, access, readFile, writeFile, unlink } from "fs/promises";
5
+ import { existsSync } from "fs";
6
+
1
7
  // ../server/src/config/env.ts
2
8
  import { z } from "zod";
3
9
  import { resolve as resolvePath } from "path";
@@ -58,10 +64,6 @@ var EnvSchema = z.object({
58
64
  var env = EnvSchema.parse(process.env);
59
65
 
60
66
  // ../server/src/services/vault-resolver.ts
61
- import { join, sep } from "path";
62
- import { homedir } from "os";
63
- import { readdir, mkdir, access, readFile, writeFile, unlink } from "fs/promises";
64
- import { existsSync } from "fs";
65
67
  var SAFE_ID = /^[A-Za-z0-9._-]{1,128}$/;
66
68
  function assertSafeId(kind, id) {
67
69
  if (!SAFE_ID.test(id) || id === "." || id === "..") {
@@ -143,17 +145,22 @@ async function forgetOrgLogo(orgId) {
143
145
  } catch {
144
146
  }
145
147
  }
148
+ async function readOrgLogo(orgId) {
149
+ try {
150
+ const raw = await readFile(join(orgVaultRoot(orgId), ORG_LOGO_FILE), "utf-8");
151
+ const { contentType, base64 } = JSON.parse(raw);
152
+ if (typeof contentType !== "string" || !LOGO_TYPES.has(contentType)) return null;
153
+ if (typeof base64 !== "string" || !base64) return null;
154
+ return { contentType, bytes: new Uint8Array(Buffer.from(base64, "base64")) };
155
+ } catch {
156
+ return null;
157
+ }
158
+ }
146
159
  async function readOrgLogos() {
147
160
  const out = {};
148
161
  for (const orgId of await listOrgVaults()) {
149
- try {
150
- const raw = await readFile(join(orgVaultRoot(orgId), ORG_LOGO_FILE), "utf-8");
151
- const { contentType, base64 } = JSON.parse(raw);
152
- if (typeof contentType !== "string" || !LOGO_TYPES.has(contentType)) continue;
153
- if (typeof base64 !== "string" || !base64) continue;
154
- out[orgId] = `data:${contentType};base64,${base64}`;
155
- } catch {
156
- }
162
+ const logo = await readOrgLogo(orgId);
163
+ if (logo) out[orgId] = `data:${logo.contentType};base64,${Buffer.from(logo.bytes).toString("base64")}`;
157
164
  }
158
165
  return out;
159
166
  }
@@ -249,6 +256,9 @@ async function legacyVaultRoot() {
249
256
  if (await keyRoot() === local) return null;
250
257
  return await holdsKey(local) ? local : null;
251
258
  }
259
+ function resetKeyRoot() {
260
+ keyRootPromise = null;
261
+ }
252
262
 
253
263
  export {
254
264
  env,
@@ -264,6 +274,7 @@ export {
264
274
  readOrgNames,
265
275
  rememberOrgLogo,
266
276
  forgetOrgLogo,
277
+ readOrgLogo,
267
278
  readOrgLogos,
268
279
  readOrgClouds,
269
280
  listOrgVaults,
@@ -274,6 +285,7 @@ export {
274
285
  legacyMachineFilePath,
275
286
  ensureLocalVault,
276
287
  keyRoot,
277
- legacyVaultRoot
288
+ legacyVaultRoot,
289
+ resetKeyRoot
278
290
  };
279
- //# sourceMappingURL=chunk-KY6KYSOU.js.map
291
+ //# sourceMappingURL=chunk-LTLOVQJQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../server/src/services/vault-resolver.ts","../../server/src/config/env.ts"],"sourcesContent":["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 * Le logo retenu d'une organisation : ses octets et leur type.\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 readOrgLogo(orgId: string): Promise<{ contentType: string; bytes: Uint8Array } | null> {\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)) return null;\n if (typeof base64 !== 'string' || !base64) return null;\n return { contentType, bytes: new Uint8Array(Buffer.from(base64, 'base64')) };\n } catch {\n // Pas de logo retenu, ou fichier illisible.\n return null;\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 const logo = await readOrgLogo(orgId);\n // Pas de logo retenu : l'initiale fera l'affaire.\n if (logo) out[orgId] = `data:${logo.contentType};base64,${Buffer.from(logo.bytes).toString('base64')}`;\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 { 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"],"mappings":"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","names":[]}
@@ -1,15 +1,3 @@
1
- import {
2
- allVaultRoots,
3
- env,
4
- keyedFilePath,
5
- legacyMachineFilePath,
6
- listOrgVaults,
7
- localVaultRoot,
8
- machineRoot,
9
- orgVaultRoot,
10
- vaultFor,
11
- vaultIdOfRoot
12
- } from "./chunk-KY6KYSOU.js";
13
1
  import {
14
2
  AGENT_FETCH_TIMEOUT,
15
3
  AGENT_HEALTH_POLL_INTERVAL,
@@ -21,6 +9,18 @@ import {
21
9
  WS_RECONNECT_MAX,
22
10
  WS_RECONNECT_MIN
23
11
  } from "./chunk-QRMG6GMX.js";
12
+ import {
13
+ allVaultRoots,
14
+ env,
15
+ keyedFilePath,
16
+ legacyMachineFilePath,
17
+ listOrgVaults,
18
+ localVaultRoot,
19
+ machineRoot,
20
+ orgVaultRoot,
21
+ vaultFor,
22
+ vaultIdOfRoot
23
+ } from "./chunk-LTLOVQJQ.js";
24
24
 
25
25
  // ../server/src/services/agent-manager.ts
26
26
  import { EventEmitter as EventEmitter2 } from "events";
@@ -3024,4 +3024,4 @@ export {
3024
3024
  traefikManager,
3025
3025
  agentManager
3026
3026
  };
3027
- //# sourceMappingURL=chunk-QIBUMYR6.js.map
3027
+ //# sourceMappingURL=chunk-NPORVPEO.js.map
@@ -21,11 +21,11 @@ import {
21
21
  resetRelaunches,
22
22
  reviewWindow,
23
23
  takeRelaunchSlot
24
- } from "./chunk-NZNIWJDT.js";
25
- import "./chunk-QIBUMYR6.js";
26
- import "./chunk-KY6KYSOU.js";
27
- import "./chunk-QRMG6GMX.js";
24
+ } from "./chunk-AAK7ACHG.js";
28
25
  import "./chunk-MD3VW4HQ.js";
26
+ import "./chunk-NPORVPEO.js";
27
+ import "./chunk-QRMG6GMX.js";
28
+ import "./chunk-LTLOVQJQ.js";
29
29
  export {
30
30
  COMPANION_SIGNATURE,
31
31
  MAX_CONSECUTIVE_RELAUNCHES,
@@ -50,4 +50,4 @@ export {
50
50
  reviewWindow,
51
51
  takeRelaunchSlot
52
52
  };
53
- //# sourceMappingURL=companion-6J6NK7H7.js.map
53
+ //# sourceMappingURL=companion-MUFVXURV.js.map
package/index.js CHANGED
@@ -135,7 +135,7 @@ if (subCommand === "install-desktop" || subCommand === "uninstall-desktop") {
135
135
  }
136
136
  }
137
137
  if (subCommand === "instances") {
138
- const { listInstances, killInstance, restartInstance } = await import("./src-V7DPPFCF.js");
138
+ const { listInstances, killInstance, restartInstance } = await import("./src-TEL7L4K2.js");
139
139
  const { runInstancesCommand } = await import("./instances-command-KZ5UGXOR.js");
140
140
  process.exit(await runInstancesCommand(args.slice(1), {
141
141
  listInstances,
@@ -299,7 +299,7 @@ async function main() {
299
299
  ensureNodeBinOnPath();
300
300
  await ensureUserBinsOnPath();
301
301
  if (!isPullEnv) stampConsole();
302
- const { createLocalServer, pullEnv, PullEnvError, registerInstance, registerCliLocation } = await import("./src-V7DPPFCF.js");
302
+ const { createLocalServer, pullEnv, PullEnvError, registerInstance, registerCliLocation } = await import("./src-TEL7L4K2.js");
303
303
  registerCliLocation({ execPath: process.execPath, cliEntry: fileURLToPath(import.meta.url) });
304
304
  if (isPullEnv) {
305
305
  if (!serviceArg) {
@@ -395,7 +395,7 @@ async function main() {
395
395
  process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
396
396
  process.on("SIGINT", () => gracefulShutdown("SIGINT"));
397
397
  if (!noTray) {
398
- const { startInstanceTray } = await import("./tray-TRWZNOUD.js");
398
+ const { startInstanceTray } = await import("./tray-NZOXYN5G.js");
399
399
  const {
400
400
  scheduleSelfRestart,
401
401
  listTrayServices,
@@ -404,8 +404,9 @@ async function main() {
404
404
  stopProcess,
405
405
  restartProcess,
406
406
  networkInfo,
407
- setLanMode
408
- } = await import("./src-V7DPPFCF.js");
407
+ setLanMode,
408
+ resolveTrayIcon
409
+ } = await import("./src-TEL7L4K2.js");
409
410
  tray = await startInstanceTray({
410
411
  info: { cwd: process.cwd(), port, version, url: appUrl },
411
412
  assetsDir: join(__dirname, "assets"),
@@ -423,6 +424,9 @@ async function main() {
423
424
  },
424
425
  restartService: (id) => restartProcess(id),
425
426
  onServicesChanged: onTrayServicesChanged,
427
+ // Le logo de l'organisation du projet ouvert, quand il y en a un : c'est ce
428
+ // qui distingue deux Runeya dans la barre système.
429
+ projectIcon: () => resolveTrayIcon(),
426
430
  lan: {
427
431
  read: () => {
428
432
  const info = networkInfo();
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/port-resolution.ts"],"sourcesContent":["#!/usr/bin/env node\nimport type { Server } from 'node:http';\nimport type { WebSocketServer } from 'ws';\nimport type { Request, Response } from 'express';\nimport { fileURLToPath, URL as NodeURL } from 'node:url';\nimport { dirname, join, resolve } from 'node:path';\nimport { readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport express from 'express';\nimport dotenv from 'dotenv'\nimport open from 'open';\nimport { resolvePort } from './port-resolution.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nconst { version } = JSON.parse(\n readFileSync(new NodeURL('./package.json', import.meta.url), 'utf8'),\n) as { version: string };\n\nfunction printStartupTable(port: number, appUrl: string): void {\n const rows: [string, string][] = [\n ['Version', version],\n ['Port', String(port)],\n ['Url', appUrl],\n ];\n\n const col0 = Math.max(...rows.map(([k]) => k.length));\n const col1 = Math.max(...rows.map(([, v]) => v.length));\n\n const pad = (s: string, n: number) => s.padEnd(n);\n const hr = (l: string, m: string, r: string, f: string) =>\n l + f.repeat(col0 + 2) + m + f.repeat(col1 + 2) + r;\n\n console.log('');\n console.log(hr('┌', '┬', '┐', '─'));\n for (const [key, value] of rows) {\n console.log(`│ ${pad(key, col0)} │ ${pad(value, col1)} │`);\n }\n console.log(hr('└', '┴', '┘', '─'));\n console.log('');\n}\n\n// Parse CLI flags\nconst args = process.argv.slice(2);\n\n/**\n * Set by the desktop launcher. It means nobody is watching a terminal, so a\n * startup failure has to be reported through a window of its own.\n */\nconst isFromDesktop = args.includes('--from-desktop');\n\n// Capture must start before anything logs, hence this early import.\nconst startupFailure = isFromDesktop ? await import('./startup-failure.js') : null;\nstartupFailure?.captureOutput();\n\nfunction getFlagValue(flags: string[]): string | undefined {\n for (const flag of flags) {\n const idx = args.indexOf(flag);\n if (idx !== -1 && idx + 1 < args.length) return args[idx + 1];\n }\n return undefined;\n}\n\n/**\n * Flags that mirror a RUNEYA_* environment variable. The flag always wins over\n * the variable, and both are equivalent otherwise.\n *\n * Secrets (RUNEYA_ENCRYPTION_KEY, RUNEYA_MASTER_PASSWORD) deliberately have no\n * flag: process arguments are world-readable through `ps` on most systems.\n */\nconst ENV_FLAGS: { flag: string; env: string }[] = [\n { flag: '--host', env: 'RUNEYA_HOST' },\n { flag: '--agent-port', env: 'RUNEYA_AGENT_PORT' },\n { flag: '--agent-host', env: 'RUNEYA_AGENT_HOST' },\n { flag: '--agent-binary-path', env: 'RUNEYA_AGENT_BINARY_PATH' },\n { flag: '--data-dir', env: 'RUNEYA_DATA_DIR' },\n { flag: '--mode', env: 'RUNEYA_MODE' },\n { flag: '--cloud-url', env: 'RUNEYA_CLOUD_URL' },\n { flag: '--cloud-app-url', env: 'RUNEYA_CLOUD_APP_URL' },\n { flag: '--cors-origin', env: 'RUNEYA_CORS_ORIGIN' },\n { flag: '--claude-pty', env: 'RUNEYA_CLAUDE_PTY' },\n];\n\n// Flags taking a value — needed so their value is not mistaken for the target directory\nconst flagsWithValues = new Set([\n '--port',\n '--name',\n '-e', '--environment',\n '-s', '--service',\n ...ENV_FLAGS.map((f) => f.flag),\n]);\n\n// Apply value flags to their env var (flag wins over an already-set variable).\n// Done before dotenv so a .env file can never override an explicit flag.\nfor (const { flag, env: key } of ENV_FLAGS) {\n const value = getFlagValue([flag]);\n if (value !== undefined) process.env[key] = value;\n}\n// --debug is a boolean shortcut for RUNEYA_DEBUG=1\nif (args.includes('--debug')) process.env['RUNEYA_DEBUG'] = '1';\n\n/**\n * `install-desktop` / `uninstall-desktop` — handled before anything else so the\n * sub-command name is never mistaken for a target directory, and so the current\n * working directory is still the user's when we capture it.\n *\n * Bare on a TTY it opens a wizard; any flag that pre-answers a question skips\n * straight to the action so scripts stay unattended.\n */\nconst subCommand = args[0];\nif (subCommand === 'install-desktop' || subCommand === 'uninstall-desktop') {\n const { installDesktopLauncher, uninstallDesktopLauncher, deriveIdentity } =\n await import('./desktop-launcher.js');\n const { shouldRunWizard, runInstallWizard, printInstallReport, printUninstallReport } =\n await import('./desktop-wizard.js');\n\n const { parsePort } = await import('./free-port.js');\n\n const rest = args.slice(1);\n // Every flag of this sub-command that takes a value: without this, the value\n // itself (a port number, a name) is mistaken for the target directory.\n const subFlagsWithValues = new Set(['--name', '--port', '--agent-port']);\n const positional = rest.find((a, i) => !a.startsWith('-') && !subFlagsWithValues.has(rest[i - 1] ?? ''));\n const nameFlag = getFlagValue(['--name']);\n\n // Ports baked into the shortcut. Null means \"follow Runeya's default\", so a\n // launcher created without them keeps tracking the default if it changes.\n const portFlagRaw = getFlagValue(['--port']);\n const agentPortFlagRaw = getFlagValue(['--agent-port']);\n for (const [flag, raw] of [['--port', portFlagRaw], ['--agent-port', agentPortFlagRaw]] as const) {\n if (raw !== undefined && parsePort(raw) === null) {\n console.error(`Erreur : ${flag} attend un entier entre 1 et 65535 (reçu ${JSON.stringify(raw)}).`);\n process.exit(1);\n }\n }\n let port = parsePort(portFlagRaw);\n let agentPort = parsePort(agentPortFlagRaw);\n\n // The data directory is resolved from the working directory, so a launcher\n // that does not pin one would start Runeya in the desktop's cwd (usually the\n // home directory) and create a stray .runeya there. Pin the cwd by default.\n let workingDir = rest.includes('--no-cwd') ? null : resolve(positional ?? process.cwd());\n let displayName = nameFlag;\n\n if (subCommand === 'install-desktop' && shouldRunWizard(rest, positional !== undefined)) {\n const answers = await runInstallWizard(process.cwd());\n if (!answers) process.exit(130); // aborted with Ctrl+C\n workingDir = answers.workingDir;\n displayName = answers.name;\n port = answers.port;\n agentPort = answers.agentPort;\n }\n\n const { name, id } = deriveIdentity(displayName, workingDir);\n\n try {\n if (subCommand === 'install-desktop') {\n const result = await installDesktopLauncher({\n nodePath: process.execPath,\n cliEntry: fileURLToPath(import.meta.url),\n distDir: __dirname,\n workingDir,\n name,\n id,\n port,\n agentPort,\n });\n printInstallReport({ name, workingDir, nodePath: process.execPath, port, agentPort, result });\n } else {\n printUninstallReport(name, await uninstallDesktopLauncher(name, id));\n }\n process.exit(0);\n } catch (err) {\n console.error(`Erreur : ${(err as Error).message}`);\n process.exit(1);\n }\n}\n\n/**\n * `runeya instances` — voir et piloter les Runeya de cette machine depuis un\n * terminal. Traité ici, avec les autres sous-commandes, pour que le mot\n * « instances » ne soit jamais pris pour un répertoire cible.\n *\n * Le pendant de l'icône de barre système, qui ne montre qu'une instance — la\n * sienne — et n'existe pas partout. Celle-ci les montre toutes, partout.\n *\n * Aucun serveur n'est démarré : le registre machine est un dossier de fichiers,\n * et le lire ne demande rien d'autre que de le lire.\n */\nif (subCommand === 'instances') {\n // Importé ici et pas en tête de fichier : charger `@runeya/apps-server` a un\n // coût, et un `runeya` ordinaire n'a pas à le payer pour une sous-commande\n // qu'il n'utilise pas.\n const { listInstances, killInstance, restartInstance } = await import('@runeya/apps-server');\n const { runInstancesCommand } = await import('./instances-command.js');\n\n process.exit(await runInstancesCommand(args.slice(1), {\n listInstances,\n stopInstance: killInstance,\n restartInstance: async (pid: number) => {\n const { pid: newPid, portReleased } = await restartInstance(pid);\n return { pid: newPid, portReleased };\n },\n openUrl: (url: string) => open(url),\n log: (message: string) => console.log(message),\n warn: (message: string) => console.error(message),\n }));\n}\n\n// Resolve target directory (first positional arg, skipping flag values)\nconst targetDir = args.find((a, i) => !a.startsWith('-') && !flagsWithValues.has(args[i - 1] ?? ''));\nif (targetDir) {\n const resolved = resolve(targetDir);\n process.chdir(resolved);\n console.log(`[cli] Working directory: ${resolved}`);\n} else if (process.env['RUNEYA_DATA_DIR']) {\n const resolved = resolve(process.env['RUNEYA_DATA_DIR'], '..');\n process.chdir(resolved);\n console.log(`[cli] Working directory: ${resolved} (from RUNEYA_DATA_DIR)`);\n} else if (process.cwd() === '/') {\n /**\n * On n'écrit jamais à la racine.\n *\n * Un lanceur global — installé sans dossier épinglé — démarre avec le cwd que\n * lui donne le système, et le Finder comme les services systemd donnent `/`.\n * `DATA_DIR` y vaudrait `/.runeya` : sous macOS la racine est le volume\n * système signé, monté en lecture seule, et la première écriture locale\n * échouerait en EROFS — que même root ne peut pas lever sans\n * `/etc/synthetic.conf` et un redémarrage. Sous Linux elle demanderait les\n * droits du superutilisateur pour un dossier qui n'a rien à faire là.\n *\n * Le repli vaut aussi pour les lanceurs DÉJÀ installés, que corriger le stub\n * ne rattraperait pas.\n */\n const home = homedir();\n process.chdir(home);\n console.log(`[cli] Working directory: ${home} (lanceur sans dossier épinglé)`);\n}\n\ndotenv.config({ quiet: true });\n\nif (args.includes('--help') || args.includes('-h')) {\n console.log(`Usage: runeya [path-to-your-stack] [options]\n\nCommands:\n install-desktop [path] Create a desktop/menu launcher for this machine\n Bare on a terminal, this opens a short wizard.\n uninstall-desktop Remove a launcher created by install-desktop\n --name <label> Launcher name (default: \"Runeya — <folder>\")\n --no-cwd Global launcher — do not pin a working directory\n --port <n> Port baked into the launcher (default: Runeya's own)\n --agent-port <n> Agent port baked in (default: launcher port + 1)\n -y, --yes Skip the wizard and take the defaults\n instances [open|stop|restart <pid>]\n List the Runeya running on this machine, and act on\n one. --json for the raw records.\n --from-desktop Set by desktop launchers: report startup failures\n in a browser window instead of a silent exit\n\nOptions:\n --version Show version number\n --pe, --pull-env Print env vars for a service to stdout (requires -e and -s)\n -e, --environment <n> Environment name or id\n -s, --service <name> Service name or id\n --lan Expose server on the local network (shortcut for --host 0.0.0.0)\n --no-open Do not open browser on startup\n --no-tray Do not put this instance in the system tray\n --agent Run as agent only (no server, no UI) — for remote machines\n -h, --help Show this help message\n\nConfiguration:\n Each setting has a flag and an equivalent RUNEYA_ environment variable; the\n flag wins. Variables are prefixed so they cannot collide with those of the\n services you manage. A .env file in the working directory is loaded\n automatically, but never overrides a flag.\n\n Flag Environment variable Default\n --port <n> RUNEYA_HTTP_PORT 4000\n (binds the agent instead when --agent is used)\n --host <address> RUNEYA_HOST 127.0.0.1\n --agent-port <n> RUNEYA_AGENT_PORT server port + 1\n --agent-host <address> RUNEYA_AGENT_HOST 127.0.0.1\n --agent-binary-path <path> RUNEYA_AGENT_BINARY_PATH bundled with the CLI\n --data-dir <path> RUNEYA_DATA_DIR <cwd>/.runeya\n --mode <mode> RUNEYA_MODE local-simple\n 'local-simple' | 'cloud'\n --cloud-url <url> RUNEYA_CLOUD_URL —\n --cloud-app-url <url> RUNEYA_CLOUD_APP_URL —\n --cors-origin <origin> RUNEYA_CORS_ORIGIN —\n --lan RUNEYA_LAN_PROXY false\n --debug RUNEYA_DEBUG false\n --claude-pty <0|1> RUNEYA_CLAUDE_PTY 1\n PTY mode for the Claude Code runner\n\n Secrets have no flag — process arguments are readable by other users via 'ps':\n RUNEYA_ENCRYPTION_KEY 64-char hex key for CI/CD — unlocks secrets without a\n master password AND disables tRPC authentication.\n Never set this on a machine reachable by others.\n RUNEYA_MASTER_PASSWORD Master password used by --pull-env instead of prompting\n\n Standard variables Runeya also honours: NODE_ENV, CI (skips opening the browser).\n`);\n process.exit(0);\n}\n\nif (args.includes('--version')) {\n console.log(version);\n process.exit(0);\n}\n\n/**\n * L'icône de barre système, sauf `--no-tray`.\n *\n * Chaque Runeya pose la sienne au démarrage et la retire en s'arrêtant : une\n * icône par instance en cours. Là où la barre système n'existe pas (serveur\n * sans bureau, arm64, paquet optionnel absent), il n'y a rien à désactiver —\n * l'icône ne se pose pas, et Runeya démarre pareil.\n */\nconst noTray = args.includes('--no-tray');\n\nconst noOpen =\n args.includes('--no-open') ||\n !!process.env['VITEST'] ||\n !!process.env['CI'] ||\n process.env['NODE_ENV'] === 'test';\n\n// --pull-env flag — detect early so we can silence stdout before any log\nconst isPullEnv = args.includes('--pull-env') || args.includes('--pe');\n\n// In pull-env mode, redirect console.log/info to stderr so only KEY=VALUE goes to stdout\nif (isPullEnv) {\n const toStderr = (...a: unknown[]) => process.stderr.write(a.join(' ') + '\\n');\n console.log = toStderr;\n console.info = toStderr;\n}\n\nconst serviceArg = getFlagValue(['-s', '--service']);\nconst environmentArg = getFlagValue(['-e', '--environment']);\n\n// Configure environment BEFORE importing server (env is parsed at module load)\n// --agent mode: run as standalone agent only (no server, no UI)\nconst isAgentOnly = args.includes('--agent');\n\n// --port targets the server, except in agent mode where it binds the agent\nconst portFlag = getFlagValue(['--port']);\nif (portFlag) {\n process.env[isAgentOnly ? 'RUNEYA_AGENT_PORT' : 'RUNEYA_HTTP_PORT'] = portFlag;\n}\n\n// --lan binds to 0.0.0.0. As an explicit flag it outranks RUNEYA_HOST; coming\n// from RUNEYA_LAN_PROXY it only fills in a host nobody else set.\nconst hostFlag = getFlagValue(['--host']);\nconst isLan = args.includes('--lan');\nconst isLanProxy = isLan || process.env.RUNEYA_LAN_PROXY === 'true' || process.env.RUNEYA_LAN_PROXY === '1';\nif (isLanProxy) {\n process.env.RUNEYA_LAN_PROXY = 'true';\n if (!hostFlag && isLan) process.env.RUNEYA_HOST = '0.0.0.0';\n else process.env.RUNEYA_HOST ??= '0.0.0.0';\n}\n\n// In agent mode --host binds the agent rather than the server\nif (isAgentOnly) {\n if (hostFlag) {\n process.env.RUNEYA_AGENT_HOST = hostFlag;\n } else if (isLan) {\n process.env.RUNEYA_AGENT_HOST = '0.0.0.0';\n } else if (isLanProxy) {\n process.env.RUNEYA_AGENT_HOST ??= '0.0.0.0';\n }\n}\n\n// Agent binary shipped inside the CLI dist — overridable via --agent-binary-path\nprocess.env.RUNEYA_AGENT_BINARY_PATH ??= join(__dirname, 'agent/index.js');\n// Expose CLI version to server\nprocess.env.RUNEYA_VERSION = version;\n// Tell the server it was launched from a shortcut, so the UI can say so\nif (isFromDesktop) process.env.RUNEYA_FROM_DESKTOP = '1';\n// Data directory defaults to CWD/.runeya (server env.ts default)\n// so Runeya data lives alongside the target project.\n\n/**\n * Listen with retry for EADDRINUSE — handles the race condition when the CLI\n * restarts the server before the old process has fully released the port.\n *\n * The `wss` parameter is needed because the `ws` library re-emits HTTP server\n * errors on the WebSocketServer — without a handler the error becomes unhandled.\n */\nfunction listenWithRetry(\n server: Server,\n port: number,\n host: string,\n wss?: WebSocketServer,\n maxRetries = 20,\n delay = 500,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n let attempts = 0;\n\n // Absorb EADDRINUSE errors re-emitted by the ws library on the WSS\n // during the retry window. Without this, Node.js crashes on unhandled error.\n const wssErrorHandler = () => { /* absorbed — handled via server 'error' */ };\n wss?.on('error', wssErrorHandler);\n\n const tryListen = () => {\n const onError = (err: NodeJS.ErrnoException) => {\n // Clean up the 'listening' callback that server.listen() registered\n server.removeAllListeners('listening');\n\n if (err.code === 'EADDRINUSE' && attempts < maxRetries) {\n attempts++;\n console.log(`[cli] Port ${port} in use, retrying in ${delay}ms (${attempts}/${maxRetries})...`);\n setTimeout(tryListen, delay);\n } else {\n wss?.removeListener('error', wssErrorHandler);\n reject(err);\n }\n };\n\n server.once('error', onError);\n server.listen(port, host, () => {\n server.removeListener('error', onError);\n wss?.removeListener('error', wssErrorHandler);\n resolve();\n });\n };\n\n tryListen();\n });\n}\n\nasync function main() {\n // Avant tout : ce que ce process hérite ici, le serveur, l'agent local et\n // chaque service lancé ensuite en héritent à leur tour. Un raccourci de bureau\n // reçoit le PATH de la session graphique, où ni les gestionnaires de version\n // ni les binaires installés par l'utilisateur (claude, codex) ne figurent.\n const { ensureNodeBinOnPath, ensureUserBinsOnPath, stampConsole } = await import('@runeya/packages-shared/node');\n ensureNodeBinOnPath();\n await ensureUserBinsOnPath();\n\n // Journaux datés du temps écoulé depuis le démarrage. Jamais en --pull-env :\n // sa sortie est lue par un script, pas par un humain.\n if (!isPullEnv) stampConsole();\n\n // Dynamic import ensures env is parsed AFTER we configure it\n const { createLocalServer, pullEnv, PullEnvError, registerInstance, registerCliLocation } = await import('@runeya/apps-server');\n\n // D'où ce CLI a été lancé, pour que l'interface puisse proposer `install-desktop`\n // sans que le serveur ait à deviner un exécutable.\n registerCliLocation({ execPath: process.execPath, cliEntry: fileURLToPath(import.meta.url) });\n\n // Handle --pull-env mode: resolve env vars and print, then exit\n if (isPullEnv) {\n if (!serviceArg) {\n console.error('Error: --service (-s) is required with --pull-env');\n process.exit(1);\n }\n if (!environmentArg) {\n console.error('Error: --environment (-e) is required with --pull-env');\n process.exit(1);\n }\n try {\n const output = await pullEnv({ service: serviceArg, environment: environmentArg });\n if (output) process.stdout.write(output + '\\n');\n process.exit(0);\n } catch (err: unknown) {\n if (err instanceof PullEnvError) {\n console.error(`Error: ${err.message}`);\n process.exit(err.exitCode);\n }\n throw err;\n }\n }\n\n // --agent mode: standalone agent, no server, no UI\n if (isAgentOnly) {\n const { spawn } = await import('node:child_process');\n const agentBin = join(__dirname, 'agent/index.js');\n const child = spawn(process.execPath, [agentBin], { stdio: 'inherit', windowsHide: true });\n child.on('exit', (code) => process.exit(code ?? 0));\n // SIGINT is already delivered to the child by the terminal (same process group).\n // Intercept it here only to suppress Node's default exit so we stay alive\n // until the child finishes its graceful shutdown.\n process.on('SIGINT', () => { /* wait for child to exit */ });\n process.on('SIGTERM', () => child.kill('SIGTERM'));\n return;\n }\n\n /**\n * A shortcut clicked twice must not fail.\n *\n * Starting a second instance on a port a Runeya already holds ends in\n * EADDRINUSE after ten seconds of retries — and from a launcher there is no\n * terminal to read that in. So the port is asked first: if Runeya answers,\n * the right move is to bring up the window that already exists.\n *\n * Only for launcher starts. From a terminal, `runeya` twice on one port is a\n * mistake worth reporting, not one worth papering over.\n */\n if (isFromDesktop) {\n const port = resolvePort();\n const { probeRuneya } = await import('./free-port.js');\n const existing = await probeRuneya(port);\n if (existing) {\n const url = `http://localhost:${port}`;\n console.log(`[cli] Runeya v${existing.version} déjà en cours sur le port ${port} — ouverture de ${url}`);\n if (!noOpen) await open(url);\n return;\n }\n }\n\n console.log('[cli] Starting Runeya...');\n\n // Create server (automatically spawns local agent)\n const { app, server, wss, shutdown } = await createLocalServer();\n\n // Serve static files from web frontend (embedded in CLI dist during build)\n const webDistPath = join(__dirname, 'web');\n\n /**\n * Les fichiers d'`assets/` portent un hash de leur contenu dans leur nom : une\n * mise à jour produit un NOUVEAU nom, jamais un contenu différent sous le même\n * nom. Ils peuvent donc être gardés indéfiniment, et `immutable` dit au\n * navigateur de ne même pas revalider.\n *\n * Sans cela, `express.static` répond `max-age=0` : chaque rechargement\n * redemande les 295 fichiers pour s'entendre répondre 304. Ce sont des\n * requêtes vides, mais elles occupent les six connexions qu'un navigateur\n * accorde par hôte — pour tous ses onglets à la fois. Avec plusieurs onglets\n * rechargés ensemble, l'ouverture du WebSocket attendait derrière cette file.\n */\n app.use('/assets', express.static(join(webDistPath, 'assets'), {\n immutable: true,\n maxAge: '1y',\n fallthrough: false,\n }));\n\n // Tout le reste (favicon…) : revalidation à chaque fois, ces noms ne changent\n // pas d'une version à l'autre.\n app.use(express.static(webDistPath, {\n index: false,\n setHeaders: (res) => res.setHeader('Cache-Control', 'no-cache'),\n }));\n\n // Fallback to index.html for client-side routing (Vue Router)\n // Express 5 requires explicit path patterns (not '*')\n //\n // JAMAIS mis en cache : c'est lui qui nomme les assets de la version courante.\n // Un index.html périmé rappellerait les fichiers de l'ancienne version — qui,\n // eux, ne sont plus là.\n //\n // `root` + nom relatif, jamais un chemin absolu : `sendFile` refuse tout\n // segment commençant par un point (`dotfiles: 'ignore'` par défaut) et\n // répond 404. Or l'installation la plus courante — `npx @runeya/runeya` —\n // vit sous `~/.npm/_npx/…`. Avec un chemin absolu, la page d'accueil était\n // donc introuvable sur toute machine lancée par npx (ou depuis `~/.nvm`),\n // alors que `/index.html` répondait : `express.static` ne teste, lui, que la\n // partie relative à sa racine.\n app.use((_req: Request, res: Response) => {\n res.setHeader('Cache-Control', 'no-cache');\n res.sendFile('index.html', { root: webDistPath });\n });\n\n const port = resolvePort();\n const host = process.env.RUNEYA_HOST ?? '127.0.0.1';\n\n await listenWithRetry(server, port, host, wss);\n\n // Announce this instance now that the port is really ours, so the settings\n // panel of any Runeya on this machine can list it.\n await registerInstance();\n\n /**\n * L'adresse d'écoute n'est pas une adresse de visite.\n *\n * `0.0.0.0` (et son équivalent IPv6 `::`) dit « toutes les interfaces » à\n * bind ; ce n'est pas une destination. Sous Linux une connexion vers elle\n * retombe sur la boucle locale, ce qui a longtemps masqué le problème — sous\n * Windows elle n'est pas routable du tout, et les navigateurs la bloquent\n * désormais ailleurs aussi. On écoute donc partout, mais on ouvre localhost.\n */\n const browseHost = host === '0.0.0.0' || host === '::' ? 'localhost' : host;\n const appUrl = `http://${browseHost}:${port}`;\n\n if (!noOpen) {\n await open(appUrl);\n }\n\n console.log('\\n🚀 Runeya is running!');\n if (isLanProxy) {\n console.log('🌐 LAN mode: server and service ports exposed on local network');\n }\n printStartupTable(port, appUrl);\n console.log('[cli] Press Ctrl+C to stop');\n\n // Assignée plus bas : l'arrêt doit pouvoir la retirer, et la poser demande\n // de savoir arrêter — les deux se référencent.\n let tray: { stop: () => Promise<void> } | null = null;\n\n let shuttingDown = false;\n const gracefulShutdown = async (signal: string) => {\n if (shuttingDown) {\n console.log(`[cli] Forced exit (second ${signal})`);\n process.exit(1);\n }\n shuttingDown = true;\n console.log(`\\n[cli] Received ${signal}, shutting down gracefully...`);\n\n // L'icône part en premier : elle annonce une instance vivante, et la\n // laisser pendant l'extinction inviterait à cliquer dans le vide.\n await tray?.stop();\n\n // In dev, exit immediately — ports are freed on process death,\n // and the 'exit' handler in agent-spawner SIGKILLs the agent.\n if (process.env.NODE_ENV === 'development') {\n process.exit(0);\n }\n\n await shutdown();\n console.log('[cli] Shutdown complete');\n process.exit(0);\n };\n\n process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));\n process.on('SIGINT', () => gracefulShutdown('SIGINT'));\n\n if (!noTray) {\n const { startInstanceTray } = await import('./tray.js');\n const {\n scheduleSelfRestart,\n listTrayServices,\n onTrayServicesChanged,\n startProcess,\n stopProcess,\n restartProcess,\n networkInfo,\n setLanMode,\n } = await import('@runeya/apps-server');\n\n tray = await startInstanceTray({\n info: { cwd: process.cwd(), port, version, url: appUrl },\n assetsDir: join(__dirname, 'assets'),\n openUrl: (target) => open(target),\n restart: () => scheduleSelfRestart(),\n stop: () => void gracefulShutdown('tray'),\n\n listServices: listTrayServices,\n startService: (id) => startProcess(id),\n // L'arrêt exige l'agent qui le fait tourner : il est dans la vue, et\n // seul un service en cours propose ce geste.\n stopService: async (id) => {\n const service = (await listTrayServices()).find((s) => s.id === id);\n if (!service?.agentId) throw new Error(`Aucun agent pour ${id}`);\n return stopProcess(id, service.agentId);\n },\n restartService: (id) => restartProcess(id),\n onServicesChanged: onTrayServicesChanged,\n\n lan: {\n read: () => {\n const info = networkInfo();\n // `lanUrls` est déjà ce qu'on voudrait lire au survol : des adresses\n // joignables, pas des IP brutes. Vide hors mode réseau local.\n return { enabled: info.lanEnabled, addresses: info.lanUrls };\n },\n toggle: (enabled) => setLanMode(enabled),\n },\n\n warn: (message) => console.log(message),\n });\n }\n}\n\nmain().catch(async (err) => {\n console.error('[cli] Fatal error:', err);\n\n // With a terminal, the message above is the report. Without one, it goes\n // nowhere: serve it as a page and open it in the browser instead.\n if (startupFailure) {\n try {\n const { diagnose, renderFailurePage, capturedLines, showStartupFailure } = startupFailure;\n const html = renderFailurePage(\n diagnose(err, resolvePort()),\n capturedLines(),\n {\n 'Version': version,\n 'Dossier de travail': process.cwd(),\n 'Node': process.execPath,\n 'Runeya': fileURLToPath(import.meta.url),\n },\n );\n await showStartupFailure(html);\n } catch (reportErr) {\n console.error('[cli] Impossible d\\'afficher le rapport d\\'erreur:', reportErr);\n }\n }\n\n process.exit(1);\n});\n","/**\n * Resolve the HTTP port Runeya should listen on.\n *\n * Only RUNEYA_HTTP_PORT is read (default 4000) — the generic PORT variable is\n * intentionally ignored so it can stay reserved for the user's own services.\n *\n * Throws if the resolved value is not an integer in [1, 65535].\n */\nexport function resolvePort(): number {\n const raw = process.env.RUNEYA_HTTP_PORT;\n if (raw === undefined) return 4000;\n\n const port = Number(raw);\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new Error(\n `Invalid port: ${JSON.stringify(raw)}. Must be an integer between 1 and 65535.`,\n );\n }\n return port;\n}\n"],"mappings":"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","names":["resolve","port"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/port-resolution.ts"],"sourcesContent":["#!/usr/bin/env node\nimport type { Server } from 'node:http';\nimport type { WebSocketServer } from 'ws';\nimport type { Request, Response } from 'express';\nimport { fileURLToPath, URL as NodeURL } from 'node:url';\nimport { dirname, join, resolve } from 'node:path';\nimport { readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport express from 'express';\nimport dotenv from 'dotenv'\nimport open from 'open';\nimport { resolvePort } from './port-resolution.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nconst { version } = JSON.parse(\n readFileSync(new NodeURL('./package.json', import.meta.url), 'utf8'),\n) as { version: string };\n\nfunction printStartupTable(port: number, appUrl: string): void {\n const rows: [string, string][] = [\n ['Version', version],\n ['Port', String(port)],\n ['Url', appUrl],\n ];\n\n const col0 = Math.max(...rows.map(([k]) => k.length));\n const col1 = Math.max(...rows.map(([, v]) => v.length));\n\n const pad = (s: string, n: number) => s.padEnd(n);\n const hr = (l: string, m: string, r: string, f: string) =>\n l + f.repeat(col0 + 2) + m + f.repeat(col1 + 2) + r;\n\n console.log('');\n console.log(hr('┌', '┬', '┐', '─'));\n for (const [key, value] of rows) {\n console.log(`│ ${pad(key, col0)} │ ${pad(value, col1)} │`);\n }\n console.log(hr('└', '┴', '┘', '─'));\n console.log('');\n}\n\n// Parse CLI flags\nconst args = process.argv.slice(2);\n\n/**\n * Set by the desktop launcher. It means nobody is watching a terminal, so a\n * startup failure has to be reported through a window of its own.\n */\nconst isFromDesktop = args.includes('--from-desktop');\n\n// Capture must start before anything logs, hence this early import.\nconst startupFailure = isFromDesktop ? await import('./startup-failure.js') : null;\nstartupFailure?.captureOutput();\n\nfunction getFlagValue(flags: string[]): string | undefined {\n for (const flag of flags) {\n const idx = args.indexOf(flag);\n if (idx !== -1 && idx + 1 < args.length) return args[idx + 1];\n }\n return undefined;\n}\n\n/**\n * Flags that mirror a RUNEYA_* environment variable. The flag always wins over\n * the variable, and both are equivalent otherwise.\n *\n * Secrets (RUNEYA_ENCRYPTION_KEY, RUNEYA_MASTER_PASSWORD) deliberately have no\n * flag: process arguments are world-readable through `ps` on most systems.\n */\nconst ENV_FLAGS: { flag: string; env: string }[] = [\n { flag: '--host', env: 'RUNEYA_HOST' },\n { flag: '--agent-port', env: 'RUNEYA_AGENT_PORT' },\n { flag: '--agent-host', env: 'RUNEYA_AGENT_HOST' },\n { flag: '--agent-binary-path', env: 'RUNEYA_AGENT_BINARY_PATH' },\n { flag: '--data-dir', env: 'RUNEYA_DATA_DIR' },\n { flag: '--mode', env: 'RUNEYA_MODE' },\n { flag: '--cloud-url', env: 'RUNEYA_CLOUD_URL' },\n { flag: '--cloud-app-url', env: 'RUNEYA_CLOUD_APP_URL' },\n { flag: '--cors-origin', env: 'RUNEYA_CORS_ORIGIN' },\n { flag: '--claude-pty', env: 'RUNEYA_CLAUDE_PTY' },\n];\n\n// Flags taking a value — needed so their value is not mistaken for the target directory\nconst flagsWithValues = new Set([\n '--port',\n '--name',\n '-e', '--environment',\n '-s', '--service',\n ...ENV_FLAGS.map((f) => f.flag),\n]);\n\n// Apply value flags to their env var (flag wins over an already-set variable).\n// Done before dotenv so a .env file can never override an explicit flag.\nfor (const { flag, env: key } of ENV_FLAGS) {\n const value = getFlagValue([flag]);\n if (value !== undefined) process.env[key] = value;\n}\n// --debug is a boolean shortcut for RUNEYA_DEBUG=1\nif (args.includes('--debug')) process.env['RUNEYA_DEBUG'] = '1';\n\n/**\n * `install-desktop` / `uninstall-desktop` — handled before anything else so the\n * sub-command name is never mistaken for a target directory, and so the current\n * working directory is still the user's when we capture it.\n *\n * Bare on a TTY it opens a wizard; any flag that pre-answers a question skips\n * straight to the action so scripts stay unattended.\n */\nconst subCommand = args[0];\nif (subCommand === 'install-desktop' || subCommand === 'uninstall-desktop') {\n const { installDesktopLauncher, uninstallDesktopLauncher, deriveIdentity } =\n await import('./desktop-launcher.js');\n const { shouldRunWizard, runInstallWizard, printInstallReport, printUninstallReport } =\n await import('./desktop-wizard.js');\n\n const { parsePort } = await import('./free-port.js');\n\n const rest = args.slice(1);\n // Every flag of this sub-command that takes a value: without this, the value\n // itself (a port number, a name) is mistaken for the target directory.\n const subFlagsWithValues = new Set(['--name', '--port', '--agent-port']);\n const positional = rest.find((a, i) => !a.startsWith('-') && !subFlagsWithValues.has(rest[i - 1] ?? ''));\n const nameFlag = getFlagValue(['--name']);\n\n // Ports baked into the shortcut. Null means \"follow Runeya's default\", so a\n // launcher created without them keeps tracking the default if it changes.\n const portFlagRaw = getFlagValue(['--port']);\n const agentPortFlagRaw = getFlagValue(['--agent-port']);\n for (const [flag, raw] of [['--port', portFlagRaw], ['--agent-port', agentPortFlagRaw]] as const) {\n if (raw !== undefined && parsePort(raw) === null) {\n console.error(`Erreur : ${flag} attend un entier entre 1 et 65535 (reçu ${JSON.stringify(raw)}).`);\n process.exit(1);\n }\n }\n let port = parsePort(portFlagRaw);\n let agentPort = parsePort(agentPortFlagRaw);\n\n // The data directory is resolved from the working directory, so a launcher\n // that does not pin one would start Runeya in the desktop's cwd (usually the\n // home directory) and create a stray .runeya there. Pin the cwd by default.\n let workingDir = rest.includes('--no-cwd') ? null : resolve(positional ?? process.cwd());\n let displayName = nameFlag;\n\n if (subCommand === 'install-desktop' && shouldRunWizard(rest, positional !== undefined)) {\n const answers = await runInstallWizard(process.cwd());\n if (!answers) process.exit(130); // aborted with Ctrl+C\n workingDir = answers.workingDir;\n displayName = answers.name;\n port = answers.port;\n agentPort = answers.agentPort;\n }\n\n const { name, id } = deriveIdentity(displayName, workingDir);\n\n try {\n if (subCommand === 'install-desktop') {\n const result = await installDesktopLauncher({\n nodePath: process.execPath,\n cliEntry: fileURLToPath(import.meta.url),\n distDir: __dirname,\n workingDir,\n name,\n id,\n port,\n agentPort,\n });\n printInstallReport({ name, workingDir, nodePath: process.execPath, port, agentPort, result });\n } else {\n printUninstallReport(name, await uninstallDesktopLauncher(name, id));\n }\n process.exit(0);\n } catch (err) {\n console.error(`Erreur : ${(err as Error).message}`);\n process.exit(1);\n }\n}\n\n/**\n * `runeya instances` — voir et piloter les Runeya de cette machine depuis un\n * terminal. Traité ici, avec les autres sous-commandes, pour que le mot\n * « instances » ne soit jamais pris pour un répertoire cible.\n *\n * Le pendant de l'icône de barre système, qui ne montre qu'une instance — la\n * sienne — et n'existe pas partout. Celle-ci les montre toutes, partout.\n *\n * Aucun serveur n'est démarré : le registre machine est un dossier de fichiers,\n * et le lire ne demande rien d'autre que de le lire.\n */\nif (subCommand === 'instances') {\n // Importé ici et pas en tête de fichier : charger `@runeya/apps-server` a un\n // coût, et un `runeya` ordinaire n'a pas à le payer pour une sous-commande\n // qu'il n'utilise pas.\n const { listInstances, killInstance, restartInstance } = await import('@runeya/apps-server');\n const { runInstancesCommand } = await import('./instances-command.js');\n\n process.exit(await runInstancesCommand(args.slice(1), {\n listInstances,\n stopInstance: killInstance,\n restartInstance: async (pid: number) => {\n const { pid: newPid, portReleased } = await restartInstance(pid);\n return { pid: newPid, portReleased };\n },\n openUrl: (url: string) => open(url),\n log: (message: string) => console.log(message),\n warn: (message: string) => console.error(message),\n }));\n}\n\n// Resolve target directory (first positional arg, skipping flag values)\nconst targetDir = args.find((a, i) => !a.startsWith('-') && !flagsWithValues.has(args[i - 1] ?? ''));\nif (targetDir) {\n const resolved = resolve(targetDir);\n process.chdir(resolved);\n console.log(`[cli] Working directory: ${resolved}`);\n} else if (process.env['RUNEYA_DATA_DIR']) {\n const resolved = resolve(process.env['RUNEYA_DATA_DIR'], '..');\n process.chdir(resolved);\n console.log(`[cli] Working directory: ${resolved} (from RUNEYA_DATA_DIR)`);\n} else if (process.cwd() === '/') {\n /**\n * On n'écrit jamais à la racine.\n *\n * Un lanceur global — installé sans dossier épinglé — démarre avec le cwd que\n * lui donne le système, et le Finder comme les services systemd donnent `/`.\n * `DATA_DIR` y vaudrait `/.runeya` : sous macOS la racine est le volume\n * système signé, monté en lecture seule, et la première écriture locale\n * échouerait en EROFS — que même root ne peut pas lever sans\n * `/etc/synthetic.conf` et un redémarrage. Sous Linux elle demanderait les\n * droits du superutilisateur pour un dossier qui n'a rien à faire là.\n *\n * Le repli vaut aussi pour les lanceurs DÉJÀ installés, que corriger le stub\n * ne rattraperait pas.\n */\n const home = homedir();\n process.chdir(home);\n console.log(`[cli] Working directory: ${home} (lanceur sans dossier épinglé)`);\n}\n\ndotenv.config({ quiet: true });\n\nif (args.includes('--help') || args.includes('-h')) {\n console.log(`Usage: runeya [path-to-your-stack] [options]\n\nCommands:\n install-desktop [path] Create a desktop/menu launcher for this machine\n Bare on a terminal, this opens a short wizard.\n uninstall-desktop Remove a launcher created by install-desktop\n --name <label> Launcher name (default: \"Runeya — <folder>\")\n --no-cwd Global launcher — do not pin a working directory\n --port <n> Port baked into the launcher (default: Runeya's own)\n --agent-port <n> Agent port baked in (default: launcher port + 1)\n -y, --yes Skip the wizard and take the defaults\n instances [open|stop|restart <pid>]\n List the Runeya running on this machine, and act on\n one. --json for the raw records.\n --from-desktop Set by desktop launchers: report startup failures\n in a browser window instead of a silent exit\n\nOptions:\n --version Show version number\n --pe, --pull-env Print env vars for a service to stdout (requires -e and -s)\n -e, --environment <n> Environment name or id\n -s, --service <name> Service name or id\n --lan Expose server on the local network (shortcut for --host 0.0.0.0)\n --no-open Do not open browser on startup\n --no-tray Do not put this instance in the system tray\n --agent Run as agent only (no server, no UI) — for remote machines\n -h, --help Show this help message\n\nConfiguration:\n Each setting has a flag and an equivalent RUNEYA_ environment variable; the\n flag wins. Variables are prefixed so they cannot collide with those of the\n services you manage. A .env file in the working directory is loaded\n automatically, but never overrides a flag.\n\n Flag Environment variable Default\n --port <n> RUNEYA_HTTP_PORT 4000\n (binds the agent instead when --agent is used)\n --host <address> RUNEYA_HOST 127.0.0.1\n --agent-port <n> RUNEYA_AGENT_PORT server port + 1\n --agent-host <address> RUNEYA_AGENT_HOST 127.0.0.1\n --agent-binary-path <path> RUNEYA_AGENT_BINARY_PATH bundled with the CLI\n --data-dir <path> RUNEYA_DATA_DIR <cwd>/.runeya\n --mode <mode> RUNEYA_MODE local-simple\n 'local-simple' | 'cloud'\n --cloud-url <url> RUNEYA_CLOUD_URL —\n --cloud-app-url <url> RUNEYA_CLOUD_APP_URL —\n --cors-origin <origin> RUNEYA_CORS_ORIGIN —\n --lan RUNEYA_LAN_PROXY false\n --debug RUNEYA_DEBUG false\n --claude-pty <0|1> RUNEYA_CLAUDE_PTY 1\n PTY mode for the Claude Code runner\n\n Secrets have no flag — process arguments are readable by other users via 'ps':\n RUNEYA_ENCRYPTION_KEY 64-char hex key for CI/CD — unlocks secrets without a\n master password AND disables tRPC authentication.\n Never set this on a machine reachable by others.\n RUNEYA_MASTER_PASSWORD Master password used by --pull-env instead of prompting\n\n Standard variables Runeya also honours: NODE_ENV, CI (skips opening the browser).\n`);\n process.exit(0);\n}\n\nif (args.includes('--version')) {\n console.log(version);\n process.exit(0);\n}\n\n/**\n * L'icône de barre système, sauf `--no-tray`.\n *\n * Chaque Runeya pose la sienne au démarrage et la retire en s'arrêtant : une\n * icône par instance en cours. Là où la barre système n'existe pas (serveur\n * sans bureau, arm64, paquet optionnel absent), il n'y a rien à désactiver —\n * l'icône ne se pose pas, et Runeya démarre pareil.\n */\nconst noTray = args.includes('--no-tray');\n\nconst noOpen =\n args.includes('--no-open') ||\n !!process.env['VITEST'] ||\n !!process.env['CI'] ||\n process.env['NODE_ENV'] === 'test';\n\n// --pull-env flag — detect early so we can silence stdout before any log\nconst isPullEnv = args.includes('--pull-env') || args.includes('--pe');\n\n// In pull-env mode, redirect console.log/info to stderr so only KEY=VALUE goes to stdout\nif (isPullEnv) {\n const toStderr = (...a: unknown[]) => process.stderr.write(a.join(' ') + '\\n');\n console.log = toStderr;\n console.info = toStderr;\n}\n\nconst serviceArg = getFlagValue(['-s', '--service']);\nconst environmentArg = getFlagValue(['-e', '--environment']);\n\n// Configure environment BEFORE importing server (env is parsed at module load)\n// --agent mode: run as standalone agent only (no server, no UI)\nconst isAgentOnly = args.includes('--agent');\n\n// --port targets the server, except in agent mode where it binds the agent\nconst portFlag = getFlagValue(['--port']);\nif (portFlag) {\n process.env[isAgentOnly ? 'RUNEYA_AGENT_PORT' : 'RUNEYA_HTTP_PORT'] = portFlag;\n}\n\n// --lan binds to 0.0.0.0. As an explicit flag it outranks RUNEYA_HOST; coming\n// from RUNEYA_LAN_PROXY it only fills in a host nobody else set.\nconst hostFlag = getFlagValue(['--host']);\nconst isLan = args.includes('--lan');\nconst isLanProxy = isLan || process.env.RUNEYA_LAN_PROXY === 'true' || process.env.RUNEYA_LAN_PROXY === '1';\nif (isLanProxy) {\n process.env.RUNEYA_LAN_PROXY = 'true';\n if (!hostFlag && isLan) process.env.RUNEYA_HOST = '0.0.0.0';\n else process.env.RUNEYA_HOST ??= '0.0.0.0';\n}\n\n// In agent mode --host binds the agent rather than the server\nif (isAgentOnly) {\n if (hostFlag) {\n process.env.RUNEYA_AGENT_HOST = hostFlag;\n } else if (isLan) {\n process.env.RUNEYA_AGENT_HOST = '0.0.0.0';\n } else if (isLanProxy) {\n process.env.RUNEYA_AGENT_HOST ??= '0.0.0.0';\n }\n}\n\n// Agent binary shipped inside the CLI dist — overridable via --agent-binary-path\nprocess.env.RUNEYA_AGENT_BINARY_PATH ??= join(__dirname, 'agent/index.js');\n// Expose CLI version to server\nprocess.env.RUNEYA_VERSION = version;\n// Tell the server it was launched from a shortcut, so the UI can say so\nif (isFromDesktop) process.env.RUNEYA_FROM_DESKTOP = '1';\n// Data directory defaults to CWD/.runeya (server env.ts default)\n// so Runeya data lives alongside the target project.\n\n/**\n * Listen with retry for EADDRINUSE — handles the race condition when the CLI\n * restarts the server before the old process has fully released the port.\n *\n * The `wss` parameter is needed because the `ws` library re-emits HTTP server\n * errors on the WebSocketServer — without a handler the error becomes unhandled.\n */\nfunction listenWithRetry(\n server: Server,\n port: number,\n host: string,\n wss?: WebSocketServer,\n maxRetries = 20,\n delay = 500,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n let attempts = 0;\n\n // Absorb EADDRINUSE errors re-emitted by the ws library on the WSS\n // during the retry window. Without this, Node.js crashes on unhandled error.\n const wssErrorHandler = () => { /* absorbed — handled via server 'error' */ };\n wss?.on('error', wssErrorHandler);\n\n const tryListen = () => {\n const onError = (err: NodeJS.ErrnoException) => {\n // Clean up the 'listening' callback that server.listen() registered\n server.removeAllListeners('listening');\n\n if (err.code === 'EADDRINUSE' && attempts < maxRetries) {\n attempts++;\n console.log(`[cli] Port ${port} in use, retrying in ${delay}ms (${attempts}/${maxRetries})...`);\n setTimeout(tryListen, delay);\n } else {\n wss?.removeListener('error', wssErrorHandler);\n reject(err);\n }\n };\n\n server.once('error', onError);\n server.listen(port, host, () => {\n server.removeListener('error', onError);\n wss?.removeListener('error', wssErrorHandler);\n resolve();\n });\n };\n\n tryListen();\n });\n}\n\nasync function main() {\n // Avant tout : ce que ce process hérite ici, le serveur, l'agent local et\n // chaque service lancé ensuite en héritent à leur tour. Un raccourci de bureau\n // reçoit le PATH de la session graphique, où ni les gestionnaires de version\n // ni les binaires installés par l'utilisateur (claude, codex) ne figurent.\n const { ensureNodeBinOnPath, ensureUserBinsOnPath, stampConsole } = await import('@runeya/packages-shared/node');\n ensureNodeBinOnPath();\n await ensureUserBinsOnPath();\n\n // Journaux datés du temps écoulé depuis le démarrage. Jamais en --pull-env :\n // sa sortie est lue par un script, pas par un humain.\n if (!isPullEnv) stampConsole();\n\n // Dynamic import ensures env is parsed AFTER we configure it\n const { createLocalServer, pullEnv, PullEnvError, registerInstance, registerCliLocation } = await import('@runeya/apps-server');\n\n // D'où ce CLI a été lancé, pour que l'interface puisse proposer `install-desktop`\n // sans que le serveur ait à deviner un exécutable.\n registerCliLocation({ execPath: process.execPath, cliEntry: fileURLToPath(import.meta.url) });\n\n // Handle --pull-env mode: resolve env vars and print, then exit\n if (isPullEnv) {\n if (!serviceArg) {\n console.error('Error: --service (-s) is required with --pull-env');\n process.exit(1);\n }\n if (!environmentArg) {\n console.error('Error: --environment (-e) is required with --pull-env');\n process.exit(1);\n }\n try {\n const output = await pullEnv({ service: serviceArg, environment: environmentArg });\n if (output) process.stdout.write(output + '\\n');\n process.exit(0);\n } catch (err: unknown) {\n if (err instanceof PullEnvError) {\n console.error(`Error: ${err.message}`);\n process.exit(err.exitCode);\n }\n throw err;\n }\n }\n\n // --agent mode: standalone agent, no server, no UI\n if (isAgentOnly) {\n const { spawn } = await import('node:child_process');\n const agentBin = join(__dirname, 'agent/index.js');\n const child = spawn(process.execPath, [agentBin], { stdio: 'inherit', windowsHide: true });\n child.on('exit', (code) => process.exit(code ?? 0));\n // SIGINT is already delivered to the child by the terminal (same process group).\n // Intercept it here only to suppress Node's default exit so we stay alive\n // until the child finishes its graceful shutdown.\n process.on('SIGINT', () => { /* wait for child to exit */ });\n process.on('SIGTERM', () => child.kill('SIGTERM'));\n return;\n }\n\n /**\n * A shortcut clicked twice must not fail.\n *\n * Starting a second instance on a port a Runeya already holds ends in\n * EADDRINUSE after ten seconds of retries — and from a launcher there is no\n * terminal to read that in. So the port is asked first: if Runeya answers,\n * the right move is to bring up the window that already exists.\n *\n * Only for launcher starts. From a terminal, `runeya` twice on one port is a\n * mistake worth reporting, not one worth papering over.\n */\n if (isFromDesktop) {\n const port = resolvePort();\n const { probeRuneya } = await import('./free-port.js');\n const existing = await probeRuneya(port);\n if (existing) {\n const url = `http://localhost:${port}`;\n console.log(`[cli] Runeya v${existing.version} déjà en cours sur le port ${port} — ouverture de ${url}`);\n if (!noOpen) await open(url);\n return;\n }\n }\n\n console.log('[cli] Starting Runeya...');\n\n // Create server (automatically spawns local agent)\n const { app, server, wss, shutdown } = await createLocalServer();\n\n // Serve static files from web frontend (embedded in CLI dist during build)\n const webDistPath = join(__dirname, 'web');\n\n /**\n * Les fichiers d'`assets/` portent un hash de leur contenu dans leur nom : une\n * mise à jour produit un NOUVEAU nom, jamais un contenu différent sous le même\n * nom. Ils peuvent donc être gardés indéfiniment, et `immutable` dit au\n * navigateur de ne même pas revalider.\n *\n * Sans cela, `express.static` répond `max-age=0` : chaque rechargement\n * redemande les 295 fichiers pour s'entendre répondre 304. Ce sont des\n * requêtes vides, mais elles occupent les six connexions qu'un navigateur\n * accorde par hôte — pour tous ses onglets à la fois. Avec plusieurs onglets\n * rechargés ensemble, l'ouverture du WebSocket attendait derrière cette file.\n */\n app.use('/assets', express.static(join(webDistPath, 'assets'), {\n immutable: true,\n maxAge: '1y',\n fallthrough: false,\n }));\n\n // Tout le reste (favicon…) : revalidation à chaque fois, ces noms ne changent\n // pas d'une version à l'autre.\n app.use(express.static(webDistPath, {\n index: false,\n setHeaders: (res) => res.setHeader('Cache-Control', 'no-cache'),\n }));\n\n // Fallback to index.html for client-side routing (Vue Router)\n // Express 5 requires explicit path patterns (not '*')\n //\n // JAMAIS mis en cache : c'est lui qui nomme les assets de la version courante.\n // Un index.html périmé rappellerait les fichiers de l'ancienne version — qui,\n // eux, ne sont plus là.\n //\n // `root` + nom relatif, jamais un chemin absolu : `sendFile` refuse tout\n // segment commençant par un point (`dotfiles: 'ignore'` par défaut) et\n // répond 404. Or l'installation la plus courante — `npx @runeya/runeya` —\n // vit sous `~/.npm/_npx/…`. Avec un chemin absolu, la page d'accueil était\n // donc introuvable sur toute machine lancée par npx (ou depuis `~/.nvm`),\n // alors que `/index.html` répondait : `express.static` ne teste, lui, que la\n // partie relative à sa racine.\n app.use((_req: Request, res: Response) => {\n res.setHeader('Cache-Control', 'no-cache');\n res.sendFile('index.html', { root: webDistPath });\n });\n\n const port = resolvePort();\n const host = process.env.RUNEYA_HOST ?? '127.0.0.1';\n\n await listenWithRetry(server, port, host, wss);\n\n // Announce this instance now that the port is really ours, so the settings\n // panel of any Runeya on this machine can list it.\n await registerInstance();\n\n /**\n * L'adresse d'écoute n'est pas une adresse de visite.\n *\n * `0.0.0.0` (et son équivalent IPv6 `::`) dit « toutes les interfaces » à\n * bind ; ce n'est pas une destination. Sous Linux une connexion vers elle\n * retombe sur la boucle locale, ce qui a longtemps masqué le problème — sous\n * Windows elle n'est pas routable du tout, et les navigateurs la bloquent\n * désormais ailleurs aussi. On écoute donc partout, mais on ouvre localhost.\n */\n const browseHost = host === '0.0.0.0' || host === '::' ? 'localhost' : host;\n const appUrl = `http://${browseHost}:${port}`;\n\n if (!noOpen) {\n await open(appUrl);\n }\n\n console.log('\\n🚀 Runeya is running!');\n if (isLanProxy) {\n console.log('🌐 LAN mode: server and service ports exposed on local network');\n }\n printStartupTable(port, appUrl);\n console.log('[cli] Press Ctrl+C to stop');\n\n // Assignée plus bas : l'arrêt doit pouvoir la retirer, et la poser demande\n // de savoir arrêter — les deux se référencent.\n let tray: { stop: () => Promise<void> } | null = null;\n\n let shuttingDown = false;\n const gracefulShutdown = async (signal: string) => {\n if (shuttingDown) {\n console.log(`[cli] Forced exit (second ${signal})`);\n process.exit(1);\n }\n shuttingDown = true;\n console.log(`\\n[cli] Received ${signal}, shutting down gracefully...`);\n\n // L'icône part en premier : elle annonce une instance vivante, et la\n // laisser pendant l'extinction inviterait à cliquer dans le vide.\n await tray?.stop();\n\n // In dev, exit immediately — ports are freed on process death,\n // and the 'exit' handler in agent-spawner SIGKILLs the agent.\n if (process.env.NODE_ENV === 'development') {\n process.exit(0);\n }\n\n await shutdown();\n console.log('[cli] Shutdown complete');\n process.exit(0);\n };\n\n process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));\n process.on('SIGINT', () => gracefulShutdown('SIGINT'));\n\n if (!noTray) {\n const { startInstanceTray } = await import('./tray.js');\n const {\n scheduleSelfRestart,\n listTrayServices,\n onTrayServicesChanged,\n startProcess,\n stopProcess,\n restartProcess,\n networkInfo,\n setLanMode,\n resolveTrayIcon,\n } = await import('@runeya/apps-server');\n\n tray = await startInstanceTray({\n info: { cwd: process.cwd(), port, version, url: appUrl },\n assetsDir: join(__dirname, 'assets'),\n openUrl: (target) => open(target),\n restart: () => scheduleSelfRestart(),\n stop: () => void gracefulShutdown('tray'),\n\n listServices: listTrayServices,\n startService: (id) => startProcess(id),\n // L'arrêt exige l'agent qui le fait tourner : il est dans la vue, et\n // seul un service en cours propose ce geste.\n stopService: async (id) => {\n const service = (await listTrayServices()).find((s) => s.id === id);\n if (!service?.agentId) throw new Error(`Aucun agent pour ${id}`);\n return stopProcess(id, service.agentId);\n },\n restartService: (id) => restartProcess(id),\n onServicesChanged: onTrayServicesChanged,\n // Le logo de l'organisation du projet ouvert, quand il y en a un : c'est ce\n // qui distingue deux Runeya dans la barre système.\n projectIcon: () => resolveTrayIcon(),\n\n lan: {\n read: () => {\n const info = networkInfo();\n // `lanUrls` est déjà ce qu'on voudrait lire au survol : des adresses\n // joignables, pas des IP brutes. Vide hors mode réseau local.\n return { enabled: info.lanEnabled, addresses: info.lanUrls };\n },\n toggle: (enabled) => setLanMode(enabled),\n },\n\n warn: (message) => console.log(message),\n });\n }\n}\n\nmain().catch(async (err) => {\n console.error('[cli] Fatal error:', err);\n\n // With a terminal, the message above is the report. Without one, it goes\n // nowhere: serve it as a page and open it in the browser instead.\n if (startupFailure) {\n try {\n const { diagnose, renderFailurePage, capturedLines, showStartupFailure } = startupFailure;\n const html = renderFailurePage(\n diagnose(err, resolvePort()),\n capturedLines(),\n {\n 'Version': version,\n 'Dossier de travail': process.cwd(),\n 'Node': process.execPath,\n 'Runeya': fileURLToPath(import.meta.url),\n },\n );\n await showStartupFailure(html);\n } catch (reportErr) {\n console.error('[cli] Impossible d\\'afficher le rapport d\\'erreur:', reportErr);\n }\n }\n\n process.exit(1);\n});\n","/**\n * Resolve the HTTP port Runeya should listen on.\n *\n * Only RUNEYA_HTTP_PORT is read (default 4000) — the generic PORT variable is\n * intentionally ignored so it can stay reserved for the user's own services.\n *\n * Throws if the resolved value is not an integer in [1, 65535].\n */\nexport function resolvePort(): number {\n const raw = process.env.RUNEYA_HTTP_PORT;\n if (raw === undefined) return 4000;\n\n const port = Number(raw);\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new Error(\n `Invalid port: ${JSON.stringify(raw)}. Must be an integer between 1 and 65535.`,\n );\n }\n return port;\n}\n"],"mappings":"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","names":["resolve","port"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runeya/runeya",
3
- "version": "2.0.103",
3
+ "version": "2.0.104",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "runeya": "./index.js"
@@ -0,0 +1,9 @@
1
+ import {
2
+ settingsManager
3
+ } from "./chunk-5GYBAMHV.js";
4
+ import "./chunk-QRMG6GMX.js";
5
+ import "./chunk-LTLOVQJQ.js";
6
+ export {
7
+ settingsManager
8
+ };
9
+ //# sourceMappingURL=settings-manager-Y4GNAXOH.js.map