@runeya/runeya 2.0.74 → 2.0.76

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 (208) hide show
  1. package/agent/index.js.map +1 -1
  2. package/agent-manager-DM6C7BTF.js +7 -0
  3. package/{chunk-JRXAQNAC.js → chunk-E2SU5RSO.js} +10 -2
  4. package/{chunk-JRXAQNAC.js.map → chunk-E2SU5RSO.js.map} +1 -1
  5. package/{desktop-launcher-TM7AABMC.js → desktop-launcher-4BVDZ3W4.js} +8 -4
  6. package/desktop-launcher-4BVDZ3W4.js.map +1 -0
  7. package/index.js +8 -3
  8. package/index.js.map +1 -1
  9. package/package.json +1 -1
  10. package/{src-YG67XURV.js → src-MEMRUBM6.js} +6 -6
  11. package/src-MEMRUBM6.js.map +1 -0
  12. package/web/assets/{AgentScalarChatInterface.vue-CHi2dFEc.js → AgentScalarChatInterface.vue-CbsV-wvF.js} +1 -1
  13. package/web/assets/{AgentTerminalPage-BvdfOTep.js → AgentTerminalPage-CFX_cNje.js} +1 -1
  14. package/web/assets/AiChatPage-aNp-79bj.js +1 -0
  15. package/web/assets/AppLayout-C8SJH7E2.js +1 -0
  16. package/web/assets/{AppLayout-Cvn5Nj7U.css → AppLayout-Dvr7plrF.css} +1 -1
  17. package/web/assets/{AuditPage-EqCcRjr9.js → AuditPage-mPkN9IPs.js} +1 -1
  18. package/web/assets/CloudAccountPage--8gMHEov.js +1 -0
  19. package/web/assets/{CloudAccountPage-BUjzLwjW.js → CloudAccountPage-DwfKS8Ui.js} +1 -1
  20. package/web/assets/{CloudMessagingPage-BrZRNxlZ.js → CloudMessagingPage-BZda9W4V.js} +1 -1
  21. package/web/assets/{DashboardPage-B6MhaCCj.js → DashboardPage-BYoHvCSW.js} +1 -1
  22. package/web/assets/{DirectoryPickerDialog-3m0wiBWG.js → DirectoryPickerDialog-GjBksDRF.js} +1 -1
  23. package/web/assets/{EditorIcon-DVd7Gn4R.js → EditorIcon-BGndPLGm.js} +1 -1
  24. package/web/assets/{EnvironmentForm-CbYQ53vB.js → EnvironmentForm-5X5MccdS.js} +1 -1
  25. package/web/assets/{EnvironmentFormPage-mnSwPbUr.js → EnvironmentFormPage-pWcZotB8.js} +1 -1
  26. package/web/assets/{EnvironmentListPage-kFhmundZ.js → EnvironmentListPage-D1u5GOUq.js} +1 -1
  27. package/web/assets/{KanbanBoardPage-cgbSqPnz.js → KanbanBoardPage-B61sIHjE.js} +3 -3
  28. package/web/assets/{KanbanListPage-D4xaJzdt.js → KanbanListPage-Dsg1wA9V.js} +1 -1
  29. package/web/assets/{LaunchProjectPage-Boxl4Dja.js → LaunchProjectPage-BzLfT9xo.js} +1 -1
  30. package/web/assets/{LaunchServicesPage-D-FjI4AR.js → LaunchServicesPage-DxRtzyc-.js} +1 -1
  31. package/web/assets/{LogViewer-Dy7SyJwf.js → LogViewer-DCTx3ncv.js} +1 -1
  32. package/web/assets/{OrgKeyPrompt-Ctjsqp3s.js → OrgKeyPrompt-DGVXqIwV.js} +1 -1
  33. package/web/assets/{ProcessControls-DMG-C-9V.js → ProcessControls-CKHLGdip.js} +1 -1
  34. package/web/assets/{ProcessDetailPage-CroZuFui.js → ProcessDetailPage-BTcbsw0H.js} +1 -1
  35. package/web/assets/{ProcessMetrics-QAK1AZsb.js → ProcessMetrics-B0mOAjpt.js} +1 -1
  36. package/web/assets/{ProjectDetailPage-CvHH1DfL.js → ProjectDetailPage-Do50Toy3.js} +1 -1
  37. package/web/assets/{ProjectListPage-DAXodWJP.js → ProjectListPage-FhR5Gkub.js} +1 -1
  38. package/web/assets/{RandomJobTestPage-DZ_xOlfL.js → RandomJobTestPage-CT1XUQ7l.js} +1 -1
  39. package/web/assets/{ScenarioEditorPage-CODJ_St4.js → ScenarioEditorPage-CAZ18fLj.js} +1 -1
  40. package/web/assets/{SendToChatDialog-DhVM2ESX.js → SendToChatDialog-3VcAeiLB.js} +1 -1
  41. package/web/assets/ServiceControlsBar-DMibK9Gk.js +1 -0
  42. package/web/assets/{ServiceDetailPage-Di9SzpJw.css → ServiceDetailPage-DVOQdgmZ.css} +1 -1
  43. package/web/assets/ServiceDetailPage-DzTdnnmK.js +2 -0
  44. package/web/assets/{ServiceFormPage-MDqY-U7o.js → ServiceFormPage-C3Av0wu_.js} +1 -1
  45. package/web/assets/SettingsPage-Cb4cXWBn.js +2063 -0
  46. package/web/assets/{SettingsPage-CKRCL18-.css → SettingsPage-CeFOjH68.css} +1 -1
  47. package/web/assets/{UnlockPage-Blh0YpJC.js → UnlockPage-Cj9f3u9P.js} +1 -1
  48. package/web/assets/{VariablesTable-BTAp4k6f.js → VariablesTable-_m1LCIc1.js} +1 -1
  49. package/web/assets/{VaultMigrationPage-B7TK6Yjh.js → VaultMigrationPage-4-aYgpPb.js} +1 -1
  50. package/web/assets/{VersionBadge-Buin8AuA.js → VersionBadge-D-5Wk-zP.js} +1 -1
  51. package/web/assets/WikiPage-Dr0BjWqx.js +1 -0
  52. package/web/assets/{WikiView-BgCUaLa6.js → WikiView-Zx8Prvim.js} +1 -1
  53. package/web/assets/{add-scalar-classes-CKwuR5ZQ.js → add-scalar-classes-Bj8wq_Hs.js} +3 -3
  54. package/web/assets/auth-errors-C98TqTeb.js +1 -0
  55. package/web/assets/{autocomplete-0aIbUwlr.js → autocomplete-CGdex9-e.js} +1 -1
  56. package/web/assets/{basic-shape-diamond.svg-BTTsBN8v.js → basic-shape-diamond.svg-qeeRnNFT.js} +1 -1
  57. package/web/assets/{basic-shape-hexagon.svg-CbALgV8W.js → basic-shape-hexagon.svg-CIlKhfGT.js} +1 -1
  58. package/web/assets/{basic-shape-primary-circle-ellipse-round.svg-CM2Rc-Vc.js → basic-shape-primary-circle-ellipse-round.svg-BqolxHsi.js} +1 -1
  59. package/web/assets/{basic-shape-primary-square-rectangle.svg-CQ1KoMjn.js → basic-shape-primary-square-rectangle.svg-CpdZYdXX.js} +1 -1
  60. package/web/assets/{basic-shape-shield.svg-1lqFtlO8.js → basic-shape-shield.svg-Dxhs7gEl.js} +1 -1
  61. package/web/assets/{browser-W4YisEmh.js → browser-DN1U-HwX.js} +1 -1
  62. package/web/assets/{browser-BhYmZa45.js → browser-I2oYlD2i.js} +1 -1
  63. package/web/assets/{card-CLPFpENW.js → card-DtzNVDSZ.js} +1 -1
  64. package/web/assets/{checkbox-xXts-zyO.js → checkbox-GeePBqgX.js} +1 -1
  65. package/web/assets/{chip-BDaJibPj.js → chip-BHIwNcot.js} +1 -1
  66. package/web/assets/{client-B0jAuhqn.js → client-BDHmFNrH.js} +1 -1
  67. package/web/assets/{cloud-chat.store-B4mu3u7F.js → cloud-chat.store-B20ZLeeR.js} +1 -1
  68. package/web/assets/{cloud-session-CPlXmpSe.js → cloud-session-BjfhcCqc.js} +1 -1
  69. package/web/assets/{column-grBnjbWs.js → column-DXHLG_CF.js} +1 -1
  70. package/web/assets/{computer-device-desktop-monitor.svg-BixhDvwl.js → computer-device-desktop-monitor.svg-cgtj7qaG.js} +1 -1
  71. package/web/assets/{computer-device-desktop.svg-ZmA0L2qL.js → computer-device-desktop.svg-CtASuIzj.js} +1 -1
  72. package/web/assets/{computer-device-laptop.svg-BbdJBfg2.js → computer-device-laptop.svg-Bgrj-X1s.js} +1 -1
  73. package/web/assets/{computer-device-mobile-phone-android-samsung-back.svg-BzFWE61G.js → computer-device-mobile-phone-android-samsung-back.svg-BdGuG_w_.js} +1 -1
  74. package/web/assets/{computer-device-mobile-phone-android-samsung.svg-BDtiMsFX.js → computer-device-mobile-phone-android-samsung.svg-BRGfdLz4.js} +1 -1
  75. package/web/assets/{computer-device-mobile-phone-iphone-x-back.svg-DM6YheEO.js → computer-device-mobile-phone-iphone-x-back.svg-AqEKxnYo.js} +1 -1
  76. package/web/assets/{computer-device-mobile-phone-iphone-x.svg-Bp3jERFh.js → computer-device-mobile-phone-iphone-x.svg-DWFt-koa.js} +1 -1
  77. package/web/assets/{computer-device-mobile-tablet-touch.svg-CFlGkb9z.js → computer-device-mobile-tablet-touch.svg-DJ52OpYh.js} +1 -1
  78. package/web/assets/{computer-device-mobile-tablet.svg-BZBxeC6-.js → computer-device-mobile-tablet.svg-Ce_rWOZi.js} +1 -1
  79. package/web/assets/{computer-device-network-ethernet-cat6.svg-Cx3VdpRS.js → computer-device-network-ethernet-cat6.svg-DB9SlCtA.js} +1 -1
  80. package/web/assets/{computer-device-network-lan-www.svg-kpYR7ArK.js → computer-device-network-lan-www.svg-lHja183-.js} +1 -1
  81. package/web/assets/{computer-device-network-wifi-connection.svg-CWV3wPXN.js → computer-device-network-wifi-connection.svg-B1zLcvJN.js} +1 -1
  82. package/web/assets/{computer-device-network-wifi-router.svg-CzE7DHvd.js → computer-device-network-wifi-router.svg-Drrwd9xP.js} +1 -1
  83. package/web/assets/{cssMode-COP0Vc--.js → cssMode-D9jO-uTl.js} +1 -1
  84. package/web/assets/{divider-BgzI-Lls.js → divider-B0vBDWbW.js} +1 -1
  85. package/web/assets/{docx-preview-D9Nq99G-.js → docx-preview-BTpCoAAq.js} +1 -1
  86. package/web/assets/{ecology-science-erlenmeyer-flask.svg-Dvg9Ooy-.js → ecology-science-erlenmeyer-flask.svg--ysD_96O.js} +1 -1
  87. package/web/assets/{fieldset-DkMAzSHT.js → fieldset-BFb-WHon.js} +1 -1
  88. package/web/assets/{freemarker2-BF912KBd.js → freemarker2-DnkPMk4B.js} +1 -1
  89. package/web/assets/{handlebars-CDz6xiAj.js → handlebars-Dsj_qiK6.js} +1 -1
  90. package/web/assets/{html-DdlTee49.js → html-t_OlpWku.js} +1 -1
  91. package/web/assets/{htmlMode-BKPtJJGG.js → htmlMode-DRcQv-pv.js} +1 -1
  92. package/web/assets/{image-flash-lightning.svg-_KHhUck_.js → image-flash-lightning.svg-6f9kbrTL.js} +1 -1
  93. package/web/assets/{image-picture-flower.svg-xYdaJTim.js → image-picture-flower.svg-i7zms3Ho.js} +1 -1
  94. package/web/assets/{index-K7kdEsBo.js → index-GxI3bOA0.js} +73 -73
  95. package/web/assets/{interface-alert-exclamation-diamond.svg-DfMcMOwb.js → interface-alert-exclamation-diamond.svg-DqUMmCtJ.js} +1 -1
  96. package/web/assets/{interface-alert-exclamation-triangle-warning.svg-HFqVNBE9.js → interface-alert-exclamation-triangle-warning.svg-DzDl1xOr.js} +1 -1
  97. package/web/assets/{interface-alert-information-circle.svg-CUOqF7qS.js → interface-alert-information-circle.svg-DmCgkGPM.js} +1 -1
  98. package/web/assets/{interface-award-crown.svg-6s7F0fMR.js → interface-award-crown.svg-C9Fbg_RB.js} +1 -1
  99. package/web/assets/{interface-bookmark.svg-CFJIMfN-.js → interface-bookmark-tag.svg-3gViLsvg.js} +1 -1
  100. package/web/assets/{interface-bookmark-tag.svg-BCyK266t.js → interface-bookmark.svg-MqIoLfKE.js} +1 -1
  101. package/web/assets/{interface-calendar-date-one.svg-DZDWCn7W.js → interface-calendar-date-one.svg-B9sbfbL9.js} +1 -1
  102. package/web/assets/{interface-content-book-open-pages.svg-DV_U01L-.js → interface-content-book-open-pages.svg-1vSNOl7u.js} +1 -1
  103. package/web/assets/{interface-content-book-page.svg-DITAHjsW.js → interface-content-book-page.svg-DIEM6xdS.js} +1 -1
  104. package/web/assets/{interface-content-file.svg-CeQU8wpF.js → interface-content-file.svg-7VSdTCse.js} +1 -1
  105. package/web/assets/{interface-content-folder.svg-CUNjtwrk.js → interface-content-folder.svg-9g1Oeyk0.js} +1 -1
  106. package/web/assets/interface-content-folder.svg-CAHYAOYi.js +1 -0
  107. package/web/assets/{interface-copy-clipboard.svg-Cpw5aWsC.js → interface-copy-clipboard.svg-aMsLLdqD.js} +1 -1
  108. package/web/assets/{interface-edit-attachment.svg-CfC-IGjI.js → interface-edit-attachment.svg-CVDpgAHo.js} +1 -1
  109. package/web/assets/{interface-edit-binocular.svg-CjYGcQSJ.js → interface-edit-binocular.svg-DCXRjTEQ.js} +1 -1
  110. package/web/assets/{interface-edit-magic-wand.svg-Wdc1CXnn.js → interface-edit-magic-wand.svg-CDrPrWdl.js} +1 -1
  111. package/web/assets/{interface-edit-tool-paint-roller.svg-BfODeBzt.js → interface-edit-tool-paint-roller.svg-UvpUIvX7.js} +1 -1
  112. package/web/assets/{interface-edit-tool-pencil.svg-D4KkDVej.js → interface-edit-tool-pencil.svg-vPXMlfGL.js} +1 -1
  113. package/web/assets/{interface-favorite-award.svg-rFwxYUIH.js → interface-favorite-award.svg-CZOrIvmM.js} +1 -1
  114. package/web/assets/{interface-favorite-flag.svg-B3aO74D4.js → interface-favorite-flag.svg-CP5RiVtW.js} +1 -1
  115. package/web/assets/{interface-favorite-heart.svg-DnLWhJhp.js → interface-favorite-heart.svg-B9yhOFXg.js} +1 -1
  116. package/web/assets/{interface-favorite-star.svg-B1bTAfnw.js → interface-favorite-star.svg-B5Iv-JuP.js} +1 -1
  117. package/web/assets/{interface-favorite-stars-sparkles.svg-Ze10JKoz.js → interface-favorite-stars-sparkles.svg-Cipb48vc.js} +1 -1
  118. package/web/assets/{interface-hierarchy-flowchart.svg-DvhnI7vM.js → interface-hierarchy-flowchart.svg-BCEm8EoC.js} +1 -1
  119. package/web/assets/{interface-home-house.svg-TpFO9U15.js → interface-home-house.svg-Bh5-1B_X.js} +1 -1
  120. package/web/assets/{interface-hyperlink.svg-B6PjuMyj.js → interface-hyperlink.svg-DmOAt5ZG.js} +1 -1
  121. package/web/assets/{interface-lighting-brightness.svg-CFNb3F8V.js → interface-lighting-brightness.svg-DhHJhRaa.js} +1 -1
  122. package/web/assets/{interface-lock-closed.svg-CRzdSCj5.js → interface-lock-closed.svg-CDyidwZF.js} +1 -1
  123. package/web/assets/{interface-lock-open-unlock.svg-o1dtCc6U.js → interface-lock-open-unlock.svg-Y-4_5Lj-.js} +1 -1
  124. package/web/assets/{interface-login-key.svg-BCRY7fi7.js → interface-login-key.svg-C8M65861.js} +1 -1
  125. package/web/assets/{interface-search.svg-CSd_UAHp.js → interface-search.svg-gkEckiep.js} +1 -1
  126. package/web/assets/{interface-setting-cog.svg-BiAFMqpv.js → interface-setting-cog.svg-B42Ru0QR.js} +1 -1
  127. package/web/assets/{interface-share-megaphone-bullhorn.svg-Bg6Nrrba.js → interface-share-megaphone-bullhorn.svg-BXgemPpH.js} +1 -1
  128. package/web/assets/{interface-share-rocket.svg-BueJTjIT.js → interface-share-rocket.svg-BpCNXSJv.js} +1 -1
  129. package/web/assets/{interface-share-satellite.svg-BPXIZysE.js → interface-share-satellite.svg-UqTKwPgB.js} +1 -1
  130. package/web/assets/{interface-share-space-ship.svg-Tpmu2ZQs.js → interface-share-space-ship.svg-LjpxJCju.js} +1 -1
  131. package/web/assets/{interface-share.svg-DZ7feWlJ.js → interface-share.svg-aTfbQymz.js} +1 -1
  132. package/web/assets/{interface-signal-square.svg-CHVwe1pi.js → interface-signal-square.svg-BV84IA7I.js} +1 -1
  133. package/web/assets/{interface-time-clock-circle.svg-DtUcGfFi.js → interface-time-clock-circle.svg-B9p8ScHG.js} +1 -1
  134. package/web/assets/{interface-time-hour-glass.svg-BNWEgOHt.js → interface-time-hour-glass.svg-4jjplFkz.js} +1 -1
  135. package/web/assets/{interface-users-multiple.svg-C1Pry5nR.js → interface-users-multiple.svg-D4nN3V4C.js} +1 -1
  136. package/web/assets/{interface-weather-moon.svg-DQx-1A-h.js → interface-weather-moon.svg-DyfDXGyQ.js} +1 -1
  137. package/web/assets/{javascript-CsXL5DT8.js → javascript-DxiQ5ZFe.js} +1 -1
  138. package/web/assets/{jsonMode-DvB3zo30.js → jsonMode-R5AgiRt8.js} +1 -1
  139. package/web/assets/{liquid-DI2z9alR.js → liquid-BPHysTNM.js} +1 -1
  140. package/web/assets/{lspLanguageFeatures-CMc4rLCM.js → lspLanguageFeatures-DVsCw49O.js} +1 -1
  141. package/web/assets/{mail-chat-bubble-square.svg-DN92EruI.js → mail-chat-bubble-square.svg-Bgj_m98i.js} +1 -1
  142. package/web/assets/{mail-send-email-paper-airplane.svg-DOaMqGHu.js → mail-send-email-paper-airplane.svg-Cmgs5A9c.js} +1 -1
  143. package/web/assets/{mail-send-envelope.svg-Co6AFlQX.js → mail-send-envelope.svg-DXtZA2de.js} +1 -1
  144. package/web/assets/{mdx-CGWf38OI.js → mdx-BmXvPH9O.js} +1 -1
  145. package/web/assets/{message-VrL-0XTF.js → message-DUmeTDJC.js} +1 -1
  146. package/web/assets/{minus-BjZ21L72.js → minus-_526hTAz.js} +1 -1
  147. package/web/assets/{modal-C6s7wXuj.js → modal-DWnz3LAY.js} +1 -1
  148. package/web/assets/modal-SaIxK3oE.js +1 -0
  149. package/web/assets/{money-cashier-receipt.svg-8Qup-ZSr.js → money-cashier-receipt.svg-BKLBvJ6k.js} +1 -1
  150. package/web/assets/{money-currency-dollar-pay.svg-CIlSYSGr.js → money-currency-dollar-pay.svg-Dy__wPDu.js} +1 -1
  151. package/web/assets/{money-graph-arrow-increase.svg-CYJyq294.js → money-graph-arrow-increase.svg-CY6efGa2.js} +1 -1
  152. package/web/assets/{money-graph-bar-chart-increase.svg-BV2pC3vV.js → money-graph-bar-chart-increase.svg-DeWwVE-h.js} +1 -1
  153. package/web/assets/{multiselect-CTA4uR0f.js → multiselect-sCEC4UBn.js} +1 -1
  154. package/web/assets/{nature-ecology-leaf.svg-Dqy1XkxJ.js → nature-ecology-leaf.svg-CiA8xWzT.js} +1 -1
  155. package/web/assets/{password-IByxJqSm.js → password-BjWenHiO.js} +1 -1
  156. package/web/assets/{phone-telephone.svg-QvU-I7Ej.js → phone-telephone.svg-DFkp7qtJ.js} +1 -1
  157. package/web/assets/{plus-TqzBK0F-.js → plus-CM2XaJYz.js} +1 -1
  158. package/web/assets/process.store-BdrVU3j7.js +1 -0
  159. package/web/assets/{programming-bug.svg-DEh0hIKm.js → programming-bug.svg-iTd4z5Bn.js} +1 -1
  160. package/web/assets/{programming-cloud.svg-B8v1xLPM.js → programming-cloud.svg-BhZ7wR70.js} +1 -1
  161. package/web/assets/{programming-computer-database-server.svg-B38-gJMV.js → programming-computer-database-server.svg-CNFgEADa.js} +1 -1
  162. package/web/assets/{programming-computer-database.svg-CSc_uTaq.js → programming-computer-database.svg-BLUoB0S3.js} +1 -1
  163. package/web/assets/{programming-module-four-layout.svg-Ct8e9N9z.js → programming-module-four-layout.svg---ShQt1c.js} +1 -1
  164. package/web/assets/{programming-module-three.svg-Cramtamu.js → programming-module-three.svg-Q915QePI.js} +1 -1
  165. package/web/assets/{programming-module.svg-_oZsSiMg.js → programming-module.svg-DGlB0gXU.js} +1 -1
  166. package/web/assets/{programming-script-code.svg-B57Dfv3U.js → programming-script-code.svg-BXqoqM0a.js} +1 -1
  167. package/web/assets/{python-CIgmiyeD.js → python-Bkcdd-GB.js} +1 -1
  168. package/web/assets/{razor-CwnddCBj.js → razor-Dgss4zhv.js} +1 -1
  169. package/web/assets/router-CkyZcpB5.js +1 -0
  170. package/web/assets/settings-scope-UnTi3EI6.js +1 -0
  171. package/web/assets/{settings.store-CPMOmi7H.js → settings.store-Bd6azayI.js} +1 -1
  172. package/web/assets/{shopping-cart.svg-9Veqyy-9.js → shopping-cart.svg-DFzDn0s3.js} +1 -1
  173. package/web/assets/{shopping-gift-present.svg-Dlo3w3e8.js → shopping-gift-present.svg-CzoIs_fz.js} +1 -1
  174. package/web/assets/{shopping-shipping-box-parcel-package.svg-BM0DDqiS.js → shopping-shipping-box-parcel-package.svg-K83gZueW.js} +1 -1
  175. package/web/assets/{src-C-LFb604.js → src-Bn8iaJpP.js} +1 -1
  176. package/web/assets/{src-9tSFXHt7.js → src-CrlKkUl0.js} +1 -1
  177. package/web/assets/{tabpanel-BlB9Tamb.js → tabpanel-B8p6e6cv.js} +1 -1
  178. package/web/assets/{tag-new-circle.svg-A1eYtb-i.js → tag-new-circle.svg-BgOrOZ_K.js} +1 -1
  179. package/web/assets/{toggleswitch-BNzkwtak.js → toggleswitch-BKr-TR6_.js} +1 -1
  180. package/web/assets/{travel-map-earth-globe.svg-DrGjwD_E.js → travel-map-earth-globe.svg-DZQQPdM1.js} +1 -1
  181. package/web/assets/trpc-CPHyoQZL.js +1 -0
  182. package/web/assets/{tsMode-D4XC6YIE.js → tsMode-BO9AVz77.js} +1 -1
  183. package/web/assets/{typescript-Dk_am5Bh.js → typescript-BVxNZ4YH.js} +1 -1
  184. package/web/assets/useAiChatDrawer-tj6s1XKR.js +1 -0
  185. package/web/assets/{useCloudOrg-Dg-9Fo9B.js → useCloudOrg-CXnReqbv.js} +3 -3
  186. package/web/assets/{useProjectCatalog-uQxqbSkg.js → useProjectCatalog-Cw3YywvF.js} +1 -1
  187. package/web/assets/{xml-CzMMYFkm.js → xml-Bv9vIo84.js} +1 -1
  188. package/web/assets/{yaml-U-6eR_c5.js → yaml-Brrhr_WI.js} +1 -1
  189. package/web/index.html +1 -1
  190. package/agent-manager-L35E7FWI.js +0 -7
  191. package/desktop-launcher-TM7AABMC.js.map +0 -1
  192. package/src-YG67XURV.js.map +0 -1
  193. package/web/assets/AiChatPage-DJ03I6Lb.js +0 -1
  194. package/web/assets/AppLayout-DLhk2bQj.js +0 -1
  195. package/web/assets/CloudAccountPage-CNxUzrAO.js +0 -1
  196. package/web/assets/ServiceControlsBar-DdvYd2xI.js +0 -1
  197. package/web/assets/ServiceDetailPage-BJRGB4fq.js +0 -2
  198. package/web/assets/SettingsPage-CeUT68wE.js +0 -2063
  199. package/web/assets/WikiPage-CJ-rNfud.js +0 -1
  200. package/web/assets/auth-errors-BSQODFsD.js +0 -1
  201. package/web/assets/interface-content-folder.svg-BCjROcNE.js +0 -1
  202. package/web/assets/modal-8HVVBuyS.js +0 -1
  203. package/web/assets/process.store-BvO7PchE.js +0 -1
  204. package/web/assets/router-Bh1D7DgU.js +0 -1
  205. package/web/assets/settings-scope-Doez2KD1.js +0 -1
  206. package/web/assets/trpc-sPb5TcJm.js +0 -1
  207. package/web/assets/useAiChatDrawer-CR-1uKnl.js +0 -1
  208. /package/{agent-manager-L35E7FWI.js.map → agent-manager-DM6C7BTF.js.map} +0 -0
@@ -21,6 +21,9 @@ function idFromName(name) {
21
21
  const slug = slugify(name);
22
22
  return slug.startsWith("runeya") ? slug : `runeya-${slug}`;
23
23
  }
24
+ function launcherWorkingDir(workingDir) {
25
+ return workingDir ?? homedir();
26
+ }
24
27
  function deriveIdentity(explicitName, workingDir) {
25
28
  const name = explicitName ?? (workingDir ? `Runeya \u2014 ${basename(workingDir)}` : "Runeya");
26
29
  return { name, id: idFromName(name) };
@@ -87,7 +90,7 @@ async function installLinux(opts) {
87
90
  // Marker used by uninstall-desktop to refuse deleting a hand-written entry
88
91
  "X-Runeya-Managed=true"
89
92
  ];
90
- if (opts.workingDir) lines.push(`Path=${desktopValue(opts.workingDir)}`);
93
+ lines.push(`Path=${desktopValue(launcherWorkingDir(opts.workingDir))}`);
91
94
  await mkdir(p.appsDir, { recursive: true });
92
95
  await writeFile(p.entry, lines.join("\n") + "\n", { mode: 493 });
93
96
  paths.push(p.entry);
@@ -127,7 +130,7 @@ async function installMac(opts) {
127
130
  const stub = [
128
131
  "#!/bin/sh",
129
132
  "# Generated by `runeya install-desktop` \u2014 safe to delete.",
130
- opts.workingDir ? `cd ${shQuote(opts.workingDir)} || exit 1` : "",
133
+ `cd ${shQuote(launcherWorkingDir(opts.workingDir))} || exit 1`,
131
134
  `exec ${[opts.nodePath, opts.cliEntry, ...launcherArgs(opts)].map(shQuote).join(" ")} "$@"`,
132
135
  ""
133
136
  ].filter(Boolean).join("\n");
@@ -197,7 +200,7 @@ async function installWindows(opts) {
197
200
  `$sc = $ws.CreateShortcut(${psQuote(lnk)})`,
198
201
  `$sc.TargetPath = ${psQuote(opts.nodePath)}`,
199
202
  `$sc.Arguments = ${psQuote([`"${opts.cliEntry}"`, ...launcherArgs(opts)].join(" "))}`,
200
- opts.workingDir ? `$sc.WorkingDirectory = ${psQuote(opts.workingDir)}` : "",
203
+ `$sc.WorkingDirectory = ${psQuote(launcherWorkingDir(opts.workingDir))}`,
201
204
  `$sc.Description = 'Runeya \u2014 process and service manager'`,
202
205
  iconPath ? `$sc.IconLocation = ${psQuote(iconPath)}` : "",
203
206
  // WindowStyle 7 = minimized: the console still exists (Node needs one) but
@@ -249,8 +252,9 @@ export {
249
252
  idFromName,
250
253
  installDesktopLauncher,
251
254
  launcherArgs,
255
+ launcherWorkingDir,
252
256
  psQuote,
253
257
  slugify,
254
258
  uninstallDesktopLauncher
255
259
  };
256
- //# sourceMappingURL=desktop-launcher-TM7AABMC.js.map
260
+ //# sourceMappingURL=desktop-launcher-4BVDZ3W4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/desktop-launcher.ts"],"sourcesContent":["/**\n * Cross-platform desktop launcher (`runeya install-desktop`).\n *\n * Deliberately an explicit sub-command rather than a postinstall hook: npm 12\n * blocks lifecycle scripts by default, so a launcher created that way would be\n * silently missing. Here the user asks for it, and gets the paths back.\n *\n * Nothing is embedded — the launcher points at the Node binary and the CLI\n * entry point currently in use. If the user switches Node version manager,\n * re-running the command re-pins the paths.\n */\nimport { mkdir, writeFile, rm, copyFile, access } from 'node:fs/promises';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { homedir } from 'node:os';\nimport { join, basename, dirname } from 'node:path';\n\nconst exec = promisify(execFile);\n\nexport type InstallOptions = {\n /** Absolute path to the Node binary the launcher must use. */\n nodePath: string;\n /** Absolute path to the CLI entry point (dist/index.js). */\n cliEntry: string;\n /** Directory holding the CLI dist — used to find the bundled icons in assets/. */\n distDir: string;\n /** Working directory to pin, or null to let the desktop decide. */\n workingDir: string | null;\n /** Display name, e.g. \"Runeya\" or \"Runeya — my-stack\". */\n name: string;\n /** Filesystem-safe id derived from the name, e.g. \"runeya-my-stack\". */\n id: string;\n /** Port baked into the launcher, or null to follow Runeya's default. */\n port: number | null;\n /** Agent port, or null to let Runeya derive it from `port + 1`. */\n agentPort: number | null;\n};\n\n/**\n * Arguments the launcher passes to the CLI.\n *\n * `--agent-port` is omitted when it is exactly what Runeya would derive on its\n * own, so the command line stays readable and keeps following the derivation\n * if it ever changes.\n */\nexport function launcherArgs(opts: Pick<InstallOptions, 'port' | 'agentPort'>): string[] {\n const args = ['--from-desktop'];\n if (opts.port !== null) args.push('--port', String(opts.port));\n if (opts.agentPort !== null && opts.agentPort !== (opts.port ?? 4000) + 1) {\n args.push('--agent-port', String(opts.agentPort));\n }\n return args;\n}\n\nexport type LauncherResult = {\n /** Files created or removed, for reporting back to the user. */\n paths: string[];\n /** Non-fatal problems (missing icon, desktop database refresh failed…). */\n warnings: string[];\n};\n\n/** Turn a display name into a filesystem- and desktop-id-safe slug. */\nexport function slugify(name: string): string {\n const slug = name\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return slug || 'runeya';\n}\n\n/**\n * The id is a pure function of the display name, so `uninstall-desktop --name`\n * always resolves to the launcher that `install-desktop` created. Names that\n * already slug to something starting with \"runeya\" are not prefixed again —\n * without that, the default \"Runeya — my-stack\" would yield the unreachable\n * id \"runeya-runeya-my-stack\".\n */\nexport function idFromName(name: string): string {\n const slug = slugify(name);\n return slug.startsWith('runeya') ? slug : `runeya-${slug}`;\n}\n\n/**\n * Derive the display name and id for a launcher.\n * Pinning a directory yields \"Runeya — <folder>\" so several stacks can each\n * have their own entry without colliding.\n */\n/**\n * Le dossier de travail d'un lanceur, avec un repli qui n'est jamais la racine.\n *\n * Sans dossier épinglé, un lanceur hérite du cwd du système — `/` pour le\n * Finder comme pour systemd — et Runeya y placerait son `.runeya`. La racine\n * est en lecture seule sous macOS et interdite d'écriture sous Linux : le home\n * est le seul repli toujours disponible. Le CLI applique la même garde à\n * l'exécution, pour les lanceurs posés avant ce correctif.\n */\nexport function launcherWorkingDir(workingDir: string | null): string {\n return workingDir ?? homedir();\n}\n\nexport function deriveIdentity(explicitName: string | undefined, workingDir: string | null): { name: string; id: string } {\n const name = explicitName ?? (workingDir ? `Runeya — ${basename(workingDir)}` : 'Runeya');\n return { name, id: idFromName(name) };\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Best-effort command: never fails the install, just reports a warning. */\nasync function tryExec(file: string, args: string[], warnings: string[]): Promise<void> {\n try {\n await exec(file, args);\n } catch {\n warnings.push(`Commande optionnelle échouée : ${file} (le lanceur est créé, le menu peut mettre un instant à l'afficher)`);\n }\n}\n\n// ─── Linux ───────────────────────────────────────────────────────────────────\n\n/**\n * Quote a value for the `Exec=` key of a .desktop file.\n * Per the Desktop Entry spec, inside a quoted argument the characters\n * `\"`, backtick, `$` and `\\` must each be preceded by a backslash.\n */\nexport function desktopExecQuote(value: string): string {\n return `\"${value.replace(/[\"`$\\\\]/g, (c) => `\\\\${c}`)}\"`;\n}\n\n/** Escape a value for a non-Exec .desktop key (only backslashes are special). */\nfunction desktopValue(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\\n/g, ' ');\n}\n\nfunction xdgDataHome(): string {\n return process.env['XDG_DATA_HOME'] || join(homedir(), '.local/share');\n}\n\nfunction linuxPaths(id: string) {\n const dataHome = xdgDataHome();\n const appsDir = join(dataHome, 'applications');\n return {\n appsDir,\n entry: join(appsDir, `${id}.desktop`),\n iconDir: join(dataHome, 'icons/hicolor/scalable/apps'),\n icon: join(dataHome, `icons/hicolor/scalable/apps/${id}.svg`),\n };\n}\n\nasync function installLinux(opts: InstallOptions): Promise<LauncherResult> {\n const paths: string[] = [];\n const warnings: string[] = [];\n const p = linuxPaths(opts.id);\n\n // The icon is an SVG, which the scalable hicolor directory takes as-is.\n const sourceIcon = join(opts.distDir, 'assets/icon.svg');\n let iconName = 'application-x-executable';\n if (await exists(sourceIcon)) {\n await mkdir(p.iconDir, { recursive: true });\n await copyFile(sourceIcon, p.icon);\n paths.push(p.icon);\n iconName = opts.id;\n } else {\n warnings.push(`Icône introuvable (${sourceIcon}), icône générique utilisée`);\n }\n\n // --from-desktop: nobody is watching a terminal, so startup failures must be\n // reported in a browser window rather than written to a discarded stderr.\n const exec_ = [opts.nodePath, opts.cliEntry, ...launcherArgs(opts)]\n .map(desktopExecQuote)\n .join(' ');\n const lines = [\n '[Desktop Entry]',\n 'Type=Application',\n `Name=${desktopValue(opts.name)}`,\n 'Comment=Process and service manager',\n `Exec=${exec_}`,\n `Icon=${iconName}`,\n 'Terminal=false',\n 'Categories=Development;',\n 'StartupNotify=true',\n // Marker used by uninstall-desktop to refuse deleting a hand-written entry\n 'X-Runeya-Managed=true',\n ];\n lines.push(`Path=${desktopValue(launcherWorkingDir(opts.workingDir))}`);\n\n await mkdir(p.appsDir, { recursive: true });\n await writeFile(p.entry, lines.join('\\n') + '\\n', { mode: 0o755 });\n paths.push(p.entry);\n\n await tryExec('update-desktop-database', [p.appsDir], warnings);\n\n return { paths, warnings };\n}\n\nasync function uninstallLinux(id: string): Promise<LauncherResult> {\n const paths: string[] = [];\n const warnings: string[] = [];\n const p = linuxPaths(id);\n for (const target of [p.entry, p.icon]) {\n if (await exists(target)) {\n await rm(target, { force: true });\n paths.push(target);\n }\n }\n if (paths.length) await tryExec('update-desktop-database', [p.appsDir], warnings);\n return { paths, warnings };\n}\n\n// ─── macOS ───────────────────────────────────────────────────────────────────\n\n/** Escape a value destined for a <string> node of an Info.plist. */\nfunction plistString(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n}\n\n/** Single-quote a value for the POSIX shell inside the .app stub script. */\nfunction shQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction macAppPath(name: string): string {\n return join(homedir(), 'Applications', `${name}.app`);\n}\n\nasync function installMac(opts: InstallOptions): Promise<LauncherResult> {\n const warnings: string[] = [];\n const appPath = macAppPath(opts.name);\n const macosDir = join(appPath, 'Contents/MacOS');\n const resourcesDir = join(appPath, 'Contents/Resources');\n const execName = opts.id;\n\n await mkdir(macosDir, { recursive: true });\n await mkdir(resourcesDir, { recursive: true });\n\n // The bundle executable is a shell stub: no compiled code, no signing needed.\n // A locally generated .app carries no quarantine attribute, so Gatekeeper\n // lets it run even unsigned.\n const stub = [\n '#!/bin/sh',\n '# Generated by `runeya install-desktop` — safe to delete.',\n `cd ${shQuote(launcherWorkingDir(opts.workingDir))} || exit 1`,\n `exec ${[opts.nodePath, opts.cliEntry, ...launcherArgs(opts)].map(shQuote).join(' ')} \"$@\"`,\n '',\n ].filter(Boolean).join('\\n');\n await writeFile(join(macosDir, execName), stub, { mode: 0o755 });\n\n // CFBundleIconFile is only emitted when the .icns actually made it into the\n // bundle — a key pointing at a missing file makes Finder fall back silently,\n // which is harder to diagnose than no key at all.\n const sourceIcns = join(opts.distDir, 'assets/icon.icns');\n let iconKey = '';\n if (await exists(sourceIcns)) {\n await copyFile(sourceIcns, join(resourcesDir, `${execName}.icns`));\n iconKey = `\\n <key>CFBundleIconFile</key><string>${plistString(execName)}</string>`;\n } else {\n warnings.push(`Icône introuvable (${sourceIcns}), icône générique utilisée`);\n }\n\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>CFBundleName</key><string>${plistString(opts.name)}</string>\n <key>CFBundleDisplayName</key><string>${plistString(opts.name)}</string>\n <key>CFBundleExecutable</key><string>${plistString(execName)}</string>\n <key>CFBundleIdentifier</key><string>dev.runeya.launcher.${plistString(opts.id)}</string>\n <key>CFBundlePackageType</key><string>APPL</string>${iconKey}\n <key>CFBundleInfoDictionaryVersion</key><string>6.0</string>\n <key>CFBundleShortVersionString</key><string>1.0</string>\n <key>NSHighResolutionCapable</key><true/>\n</dict>\n</plist>\n`;\n await writeFile(join(appPath, 'Contents/Info.plist'), plist);\n\n // Ask LaunchServices to notice the new bundle so Spotlight finds it right away.\n await tryExec(\n '/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister',\n ['-f', appPath],\n warnings,\n );\n\n return { paths: [appPath], warnings };\n}\n\nasync function uninstallMac(name: string): Promise<LauncherResult> {\n const appPath = macAppPath(name);\n if (!(await exists(appPath))) return { paths: [], warnings: [] };\n await rm(appPath, { recursive: true, force: true });\n return { paths: [appPath], warnings: [] };\n}\n\n// ─── Windows ─────────────────────────────────────────────────────────────────\n\n/** Single-quote a value for a PowerShell literal string. */\nexport function psQuote(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\nfunction windowsLnkPath(name: string): string {\n const appData = process.env['APPDATA'] || join(homedir(), 'AppData/Roaming');\n return join(appData, 'Microsoft/Windows/Start Menu/Programs', `${name}.lnk`);\n}\n\nasync function runPowerShell(script: string, warnings: string[]): Promise<void> {\n // -EncodedCommand avoids every layer of cmd.exe quoting.\n const encoded = Buffer.from(script, 'utf16le').toString('base64');\n try {\n await exec('powershell.exe', ['-NoProfile', '-NonInteractive', '-EncodedCommand', encoded]);\n } catch (err) {\n warnings.push(`PowerShell a échoué : ${(err as Error).message}`);\n throw err;\n }\n}\n\nasync function installWindows(opts: InstallOptions): Promise<LauncherResult> {\n const warnings: string[] = [];\n const lnk = windowsLnkPath(opts.name);\n\n // The .ico is referenced in place inside the installed dist rather than\n // copied: the shortcut already breaks if that dist moves, so a second copy\n // would only add a file to leave behind.\n const icoPath = join(opts.distDir, 'assets/icon.ico');\n const iconPath = (await exists(icoPath)) ? icoPath : null;\n if (!iconPath) warnings.push(`Icône introuvable (${icoPath}), icône de Node utilisée`);\n\n const script = [\n `$ws = New-Object -ComObject WScript.Shell`,\n `$sc = $ws.CreateShortcut(${psQuote(lnk)})`,\n `$sc.TargetPath = ${psQuote(opts.nodePath)}`,\n `$sc.Arguments = ${psQuote([`\"${opts.cliEntry}\"`, ...launcherArgs(opts)].join(' '))}`,\n `$sc.WorkingDirectory = ${psQuote(launcherWorkingDir(opts.workingDir))}`,\n `$sc.Description = 'Runeya — process and service manager'`,\n iconPath ? `$sc.IconLocation = ${psQuote(iconPath)}` : '',\n // WindowStyle 7 = minimized: the console still exists (Node needs one) but\n // stays out of the way while the browser opens.\n `$sc.WindowStyle = 7`,\n `$sc.Save()`,\n ].filter(Boolean).join('\\n');\n\n await mkdir(dirname(lnk), { recursive: true });\n await runPowerShell(script, warnings);\n\n return { paths: [lnk], warnings };\n}\n\nasync function uninstallWindows(name: string): Promise<LauncherResult> {\n const lnk = windowsLnkPath(name);\n if (!(await exists(lnk))) return { paths: [], warnings: [] };\n await rm(lnk, { force: true });\n return { paths: [lnk], warnings: [] };\n}\n\n// ─── Entry points ────────────────────────────────────────────────────────────\n\nexport async function installDesktopLauncher(opts: InstallOptions): Promise<LauncherResult> {\n switch (process.platform) {\n case 'linux':\n case 'freebsd':\n case 'openbsd':\n return installLinux(opts);\n case 'darwin':\n return installMac(opts);\n case 'win32':\n return installWindows(opts);\n default:\n throw new Error(`Plateforme non supportée : ${process.platform}`);\n }\n}\n\nexport async function uninstallDesktopLauncher(name: string, id: string): Promise<LauncherResult> {\n switch (process.platform) {\n case 'linux':\n case 'freebsd':\n case 'openbsd':\n return uninstallLinux(id);\n case 'darwin':\n return uninstallMac(name);\n case 'win32':\n return uninstallWindows(name);\n default:\n throw new Error(`Plateforme non supportée : ${process.platform}`);\n }\n}\n"],"mappings":"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","names":[]}
package/index.js CHANGED
@@ -4,6 +4,7 @@
4
4
  import { fileURLToPath, URL as NodeURL } from "url";
5
5
  import { dirname, join, resolve } from "path";
6
6
  import { readFileSync } from "fs";
7
+ import { homedir } from "os";
7
8
  import express from "express";
8
9
  import dotenv from "dotenv";
9
10
  import open from "open";
@@ -83,7 +84,7 @@ for (const { flag, env: key } of ENV_FLAGS) {
83
84
  if (args.includes("--debug")) process.env["RUNEYA_DEBUG"] = "1";
84
85
  var subCommand = args[0];
85
86
  if (subCommand === "install-desktop" || subCommand === "uninstall-desktop") {
86
- const { installDesktopLauncher, uninstallDesktopLauncher, deriveIdentity } = await import("./desktop-launcher-TM7AABMC.js");
87
+ const { installDesktopLauncher, uninstallDesktopLauncher, deriveIdentity } = await import("./desktop-launcher-4BVDZ3W4.js");
87
88
  const { shouldRunWizard, runInstallWizard, printInstallReport, printUninstallReport } = await import("./desktop-wizard-4CYANX2O.js");
88
89
  const { parsePort } = await import("./free-port-565NMFIZ.js");
89
90
  const rest = args.slice(1);
@@ -142,6 +143,10 @@ if (targetDir) {
142
143
  const resolved = resolve(process.env["RUNEYA_DATA_DIR"], "..");
143
144
  process.chdir(resolved);
144
145
  console.log(`[cli] Working directory: ${resolved} (from RUNEYA_DATA_DIR)`);
146
+ } else if (process.cwd() === "/") {
147
+ const home = homedir();
148
+ process.chdir(home);
149
+ console.log(`[cli] Working directory: ${home} (lanceur sans dossier \xE9pingl\xE9)`);
145
150
  }
146
151
  dotenv.config({ quiet: true });
147
152
  if (args.includes("--help") || args.includes("-h")) {
@@ -274,7 +279,7 @@ async function main() {
274
279
  ensureNodeBinOnPath();
275
280
  await ensureUserBinsOnPath();
276
281
  if (!isPullEnv) stampConsole();
277
- const { createLocalServer, pullEnv, PullEnvError, registerInstance } = await import("./src-YG67XURV.js");
282
+ const { createLocalServer, pullEnv, PullEnvError, registerInstance } = await import("./src-MEMRUBM6.js");
278
283
  if (isPullEnv) {
279
284
  if (!serviceArg) {
280
285
  console.error("Error: --service (-s) is required with --pull-env");
@@ -331,7 +336,7 @@ async function main() {
331
336
  }));
332
337
  app.use((_req, res) => {
333
338
  res.setHeader("Cache-Control", "no-cache");
334
- res.sendFile(join(webDistPath, "index.html"));
339
+ res.sendFile("index.html", { root: webDistPath });
335
340
  });
336
341
  const port = resolvePort();
337
342
  const host = process.env.RUNEYA_HOST ?? "127.0.0.1";
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 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// 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}\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 --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 --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\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 } = await import('@runeya/apps-server');\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' });\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 app.use((_req: Request, res: Response) => {\n res.setHeader('Cache-Control', 'no-cache');\n res.sendFile(join(webDistPath, 'index.html'));\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 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 // 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\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// 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 --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 --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\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 } = await import('@runeya/apps-server');\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' });\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 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 // 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\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.74",
3
+ "version": "2.0.76",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "runeya": "./index.js"
@@ -60,7 +60,6 @@ import {
60
60
  isCiMode,
61
61
  isEncryptedValue,
62
62
  isVaultLocked,
63
- isWildcardHost,
64
63
  keyRoot,
65
64
  keyedFilePath,
66
65
  killInstance,
@@ -105,12 +104,13 @@ import {
105
104
  stampOrgCloud,
106
105
  traefikManager,
107
106
  unregisterInstance,
107
+ urlHostFor,
108
108
  vaultFor,
109
109
  vaultIdOfRoot,
110
110
  wasRead,
111
111
  withDeprecatedAliases,
112
112
  writeEntity
113
- } from "./chunk-JRXAQNAC.js";
113
+ } from "./chunk-E2SU5RSO.js";
114
114
 
115
115
  // ../server/src/create-server.ts
116
116
  import express from "express";
@@ -2572,7 +2572,7 @@ var settingsManager = new SettingsManager();
2572
2572
  // ../server/src/services/service-builtins.ts
2573
2573
  function buildServerBuiltins(input) {
2574
2574
  const { service, siblings, projectName, environmentName, agentName, host } = input;
2575
- const urlHost = isWildcardHost(host) ? "{{agent.HOST_LAN}}" : host;
2575
+ const urlHost = urlHostFor(host) ?? "{{agent.HOST_LAN}}";
2576
2576
  const values = {
2577
2577
  "service.NAME": service.name,
2578
2578
  "service.ID": service.id,
@@ -8169,7 +8169,7 @@ function tailTranscript(opts) {
8169
8169
 
8170
8170
  // ../server/src/services/ai-runners/claude-pty-runner.ts
8171
8171
  async function getAgentManager() {
8172
- const { agentManager: agentManager2 } = await import("./agent-manager-L35E7FWI.js");
8172
+ const { agentManager: agentManager2 } = await import("./agent-manager-DM6C7BTF.js");
8173
8173
  return agentManager2;
8174
8174
  }
8175
8175
  function buildPtyArgs(params, sessionId, opts) {
@@ -8910,7 +8910,7 @@ async function shutdownCodexAppServer() {
8910
8910
  }
8911
8911
  }
8912
8912
  async function getAgentManager2() {
8913
- const { agentManager: agentManager2 } = await import("./agent-manager-L35E7FWI.js");
8913
+ const { agentManager: agentManager2 } = await import("./agent-manager-DM6C7BTF.js");
8914
8914
  return agentManager2;
8915
8915
  }
8916
8916
  function parseRuneyaCurlCommand(command) {
@@ -17761,4 +17761,4 @@ export {
17761
17761
  pullEnv,
17762
17762
  registerInstance
17763
17763
  };
17764
- //# sourceMappingURL=src-YG67XURV.js.map
17764
+ //# sourceMappingURL=src-MEMRUBM6.js.map