@runeya/runeya 2.0.67 → 2.0.68

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 (322) hide show
  1. package/agent/index.js +32 -1
  2. package/agent/index.js.map +1 -1
  3. package/agent-manager-74WZPMVQ.js +7 -0
  4. package/{chunk-OOQ74RCO.js → chunk-YSJ6OJGN.js} +17 -5
  5. package/{chunk-OOQ74RCO.js.map → chunk-YSJ6OJGN.js.map} +1 -1
  6. package/index.js +13 -3
  7. package/index.js.map +1 -1
  8. package/{node-QABM22GF.js → node-B4T3JMM3.js} +32 -2
  9. package/node-B4T3JMM3.js.map +1 -0
  10. package/package.json +1 -1
  11. package/{src-QP5LALGR.js → src-WT7HSY3I.js} +25 -5
  12. package/src-WT7HSY3I.js.map +1 -0
  13. package/web/assets/AgentScalarChatInterface.vue-vU3z8Etw.js +13 -0
  14. package/web/assets/AgentTerminalPage-A8GIX6dZ.css +1 -0
  15. package/web/assets/AgentTerminalPage-DE3GUoXn.js +1 -0
  16. package/web/assets/AiChatPage-BIJczUeS.js +1 -0
  17. package/web/assets/AppLayout-CvkK_Pp3.js +1 -0
  18. package/web/assets/AuditPage-BZuVgUf1.js +1 -0
  19. package/web/assets/CloudAccountPage-B__2SGAw.js +1 -0
  20. package/web/assets/CloudAccountPage-MSWkg9Ke.js +1 -0
  21. package/web/assets/CloudMessagingPage-C5pD6Qsd.js +2 -0
  22. package/web/assets/DashboardPage-66q5K841.js +1 -0
  23. package/web/assets/DirectoryPickerDialog-wZYtGEZ9.js +1 -0
  24. package/web/assets/{EditorIcon-ChiKZey2.js → EditorIcon-DUDLTmUd.js} +2 -2
  25. package/web/assets/{EnvironmentForm-C_Vb13xF.js → EnvironmentForm-C0Q1pRdW.js} +2 -2
  26. package/web/assets/EnvironmentFormPage-LO-mwupn.js +1 -0
  27. package/web/assets/EnvironmentListPage-CvknyN3O.js +1 -0
  28. package/web/assets/KanbanBoardPage-DUsAyowy.js +4 -0
  29. package/web/assets/KanbanBoardPage-JjjS4BfO.css +1 -0
  30. package/web/assets/KanbanListPage-9RBCauSd.js +1 -0
  31. package/web/assets/KanbanListPage-THfBGwd4.css +1 -0
  32. package/web/assets/LaunchProjectPage-obaNCuEY.js +1 -0
  33. package/web/assets/LaunchServicesPage-CiWzQIyC.js +1 -0
  34. package/web/assets/LogViewer-BiSD_TNt.js +3 -0
  35. package/web/assets/OrgKeyPrompt-zhMl_nTd.js +1 -0
  36. package/web/assets/{ProcessControls-DAciBoSD.js → ProcessControls-DMxvJmDe.js} +1 -1
  37. package/web/assets/ProcessDetailPage-CsCqQh2V.js +1 -0
  38. package/web/assets/{ProcessMetrics--iokpCM-.js → ProcessMetrics-DK4Dgdb0.js} +2 -2
  39. package/web/assets/ProjectDetailPage-B0vJySvH.js +1 -0
  40. package/web/assets/ProjectListPage-srxBmrbO.js +1 -0
  41. package/web/assets/RandomJobTestPage-jGfX-6W9.js +2 -0
  42. package/web/assets/ScenarioEditorPage-CxLy6gs7.js +14 -0
  43. package/web/assets/SendToChatDialog-AHkuFQjt.js +1 -0
  44. package/web/assets/ServiceControlsBar-C8P9_qWK.js +1 -0
  45. package/web/assets/ServiceDetailPage-DTBpQegV.js +2 -0
  46. package/web/assets/ServiceFormPage-CsPSMWdD.js +1 -0
  47. package/web/assets/SettingsPage-CmtRn6VJ.js +2063 -0
  48. package/web/assets/UnlockPage-Bkp_hR-F.js +1 -0
  49. package/web/assets/VariablesTable-jo61MhbL.js +1 -0
  50. package/web/assets/VaultMigrationPage-D-Dxg5xH.js +1 -0
  51. package/web/assets/VersionBadge-CwNZLgqN.js +1 -0
  52. package/web/assets/WikiPage-DZLKTPi3.js +1 -0
  53. package/web/assets/WikiView-BpJECJ2Y.js +1 -0
  54. package/web/assets/add-scalar-classes-CqLAxAGv.js +387 -0
  55. package/web/assets/auth-errors-BOjTx5eo.js +1 -0
  56. package/web/assets/{autocomplete-D-6FU1t-.js → autocomplete-CrMQ2sCk.js} +3 -3
  57. package/web/assets/{basic-shape-diamond.svg-DE3LO5SU.js → basic-shape-diamond.svg-CacrbinE.js} +1 -1
  58. package/web/assets/{basic-shape-hexagon.svg-DHCVACA2.js → basic-shape-hexagon.svg-GGJ54oyX.js} +1 -1
  59. package/web/assets/{basic-shape-primary-circle-ellipse-round.svg-BGztJOjy.js → basic-shape-primary-circle-ellipse-round.svg-CuWfwdJM.js} +1 -1
  60. package/web/assets/{basic-shape-primary-square-rectangle.svg-BNvakQwI.js → basic-shape-primary-square-rectangle.svg-C2Bewjip.js} +1 -1
  61. package/web/assets/{basic-shape-shield.svg-D0xk91H_.js → basic-shape-shield.svg-DNtg0KuJ.js} +1 -1
  62. package/web/assets/{browser-BivKTyTv.js → browser-5NN8ieli.js} +1 -1
  63. package/web/assets/{browser-bzX9Nao0.js → browser-XO2fm4BX.js} +1 -1
  64. package/web/assets/card-CjcU4SfX.js +32 -0
  65. package/web/assets/{checkbox-IknS1FQn.js → checkbox-iq9mU5eP.js} +3 -3
  66. package/web/assets/{chip-Boe0Xov3.js → chip-BsccUnHb.js} +2 -2
  67. package/web/assets/client-B9UJRQa-.js +24 -0
  68. package/web/assets/cloud-chat.store-Dw2lzuBY.js +1 -0
  69. package/web/assets/{cloud-session-BwiZNDmW.js → cloud-session-DIhbWyP5.js} +1 -1
  70. package/web/assets/column-BGKYk6b6.js +907 -0
  71. package/web/assets/{computer-device-desktop-monitor.svg-CnYkVG-R.js → computer-device-desktop-monitor.svg-DSwpF_ss.js} +1 -1
  72. package/web/assets/{computer-device-desktop.svg-XlBIDLoz.js → computer-device-desktop.svg-Caj_PZBV.js} +1 -1
  73. package/web/assets/{computer-device-laptop.svg-DaLHuxcg.js → computer-device-laptop.svg-Bv3ienI_.js} +1 -1
  74. package/web/assets/{computer-device-mobile-phone-android-samsung-back.svg-qHWgnNNS.js → computer-device-mobile-phone-android-samsung-back.svg-IWlhEKx_.js} +1 -1
  75. package/web/assets/{computer-device-mobile-phone-android-samsung.svg-CtxJbuqe.js → computer-device-mobile-phone-android-samsung.svg-CglQAFq2.js} +1 -1
  76. package/web/assets/{computer-device-mobile-phone-iphone-x-back.svg-BQiGDxzt.js → computer-device-mobile-phone-iphone-x-back.svg-CgjNnTTw.js} +1 -1
  77. package/web/assets/{computer-device-mobile-phone-iphone-x.svg-CgAytTCm.js → computer-device-mobile-phone-iphone-x.svg-CotZ-4M5.js} +1 -1
  78. package/web/assets/{computer-device-mobile-tablet-touch.svg-CAqOIQYV.js → computer-device-mobile-tablet-touch.svg-B2cemd61.js} +1 -1
  79. package/web/assets/{computer-device-mobile-tablet.svg-DQpw8q67.js → computer-device-mobile-tablet.svg-8nPVs4u_.js} +1 -1
  80. package/web/assets/{computer-device-network-ethernet-cat6.svg-CBRhWnOl.js → computer-device-network-ethernet-cat6.svg-Bl56Qw4v.js} +1 -1
  81. package/web/assets/{computer-device-network-lan-www.svg-Cv-QFYIZ.js → computer-device-network-lan-www.svg-C_x6Rf8N.js} +1 -1
  82. package/web/assets/{computer-device-network-wifi-connection.svg-BBsVDFRE.js → computer-device-network-wifi-connection.svg-oz6dsDQB.js} +1 -1
  83. package/web/assets/{computer-device-network-wifi-router.svg-BK2DsNKU.js → computer-device-network-wifi-router.svg-BciHU6Nj.js} +1 -1
  84. package/web/assets/{cssMode-B4oj4WYQ.js → cssMode-DSX5tYcm.js} +1 -1
  85. package/web/assets/{divider-_mB7RWpZ.js → divider-DnPOdDs3.js} +2 -2
  86. package/web/assets/{ecology-science-erlenmeyer-flask.svg-CA-I1J40.js → ecology-science-erlenmeyer-flask.svg-BzQP6y9L.js} +1 -1
  87. package/web/assets/{fieldset-DxE1RM8v.js → fieldset-D9lkV70l.js} +2 -2
  88. package/web/assets/{freemarker2-DjWzSYtR.js → freemarker2-D9yXX9Vw.js} +1 -1
  89. package/web/assets/{handlebars-CrIRV8P_.js → handlebars-BmcjEksL.js} +1 -1
  90. package/web/assets/{html-FZ2bNZkn.js → html-BQF9vZLL.js} +1 -1
  91. package/web/assets/{htmlMode-C4UY3uXX.js → htmlMode-DxSRpgHE.js} +1 -1
  92. package/web/assets/{image-flash-lightning.svg-BESGut9z.js → image-flash-lightning.svg-DQX09uxo.js} +1 -1
  93. package/web/assets/{image-picture-flower.svg-DFFw77B4.js → image-picture-flower.svg-CUBdrnoc.js} +1 -1
  94. package/web/assets/{index-ChHZJigw.js → index-enuBsJBa.js} +307 -306
  95. package/web/assets/{interface-alert-exclamation-diamond.svg-C0_oVqKd.js → interface-alert-exclamation-diamond.svg-DXQdQSvN.js} +1 -1
  96. package/web/assets/{interface-alert-exclamation-triangle-warning.svg-CT57udnb.js → interface-alert-exclamation-triangle-warning.svg-BoCeNIlU.js} +1 -1
  97. package/web/assets/{interface-alert-information-circle.svg-feXGxf07.js → interface-alert-information-circle.svg-BCA57JL2.js} +1 -1
  98. package/web/assets/{interface-award-crown.svg-Dzcgb2OZ.js → interface-award-crown.svg-B1hTlsb0.js} +1 -1
  99. package/web/assets/{interface-bookmark.svg-D29YXcId.js → interface-bookmark-tag.svg-AosfQ0Ip.js} +1 -1
  100. package/web/assets/{interface-bookmark-tag.svg-DYObw7kI.js → interface-bookmark.svg-zf3cIGKM.js} +1 -1
  101. package/web/assets/{interface-calendar-date-one.svg-B6LAQ50v.js → interface-calendar-date-one.svg-D58WqPie.js} +1 -1
  102. package/web/assets/{interface-content-book-open-pages.svg-BlpLjyAs.js → interface-content-book-open-pages.svg-B74HWMlw.js} +1 -1
  103. package/web/assets/{interface-content-book-page.svg-D8zFMaud.js → interface-content-book-page.svg-C2QWk62-.js} +1 -1
  104. package/web/assets/{interface-content-file.svg-Bu9ZoTup.js → interface-content-file.svg-xKu0qAOQ.js} +1 -1
  105. package/web/assets/interface-content-folder.svg-DjEfXjEF.js +1 -0
  106. package/web/assets/{interface-content-folder.svg-C7xURsse.js → interface-content-folder.svg-ZkrY9WkQ.js} +1 -1
  107. package/web/assets/{interface-copy-clipboard.svg-pk2ijV65.js → interface-copy-clipboard.svg-BEkNG3vO.js} +1 -1
  108. package/web/assets/{interface-edit-attachment.svg-Bcr20hoB.js → interface-edit-attachment.svg-5ztQ3WTq.js} +1 -1
  109. package/web/assets/{interface-edit-binocular.svg-COIP_m1k.js → interface-edit-binocular.svg-CC9U1Gnc.js} +1 -1
  110. package/web/assets/{interface-edit-magic-wand.svg-D_m1zeUL.js → interface-edit-magic-wand.svg-CPl6ZoE9.js} +1 -1
  111. package/web/assets/{interface-edit-tool-paint-roller.svg-BeVeFbeH.js → interface-edit-tool-paint-roller.svg-B85t7jG2.js} +1 -1
  112. package/web/assets/{interface-edit-tool-pencil.svg-dsW53gC1.js → interface-edit-tool-pencil.svg-BSTdqWUg.js} +1 -1
  113. package/web/assets/{interface-favorite-award.svg-3BNGOKWw.js → interface-favorite-award.svg-DbPr_WKt.js} +1 -1
  114. package/web/assets/{interface-favorite-flag.svg-D48-u5Nr.js → interface-favorite-flag.svg-CgKYXc7k.js} +1 -1
  115. package/web/assets/{interface-favorite-heart.svg-CKvRWS8p.js → interface-favorite-heart.svg-DfnXyJMg.js} +1 -1
  116. package/web/assets/{interface-favorite-star.svg-CxMLBraT.js → interface-favorite-star.svg-0sT7jJMK.js} +1 -1
  117. package/web/assets/{interface-favorite-stars-sparkles.svg-Cy14KCtV.js → interface-favorite-stars-sparkles.svg-BcM2EXgn.js} +1 -1
  118. package/web/assets/{interface-hierarchy-flowchart.svg-Lg00w7YV.js → interface-hierarchy-flowchart.svg-BM62WcKt.js} +1 -1
  119. package/web/assets/{interface-home-house.svg-CsvIh8II.js → interface-home-house.svg-KqP7iMC4.js} +1 -1
  120. package/web/assets/{interface-hyperlink.svg-BuFqr9k_.js → interface-hyperlink.svg-DBKFbihR.js} +1 -1
  121. package/web/assets/{interface-lighting-brightness.svg-C1Me4yCs.js → interface-lighting-brightness.svg-DTkCS7PY.js} +1 -1
  122. package/web/assets/{interface-lock-closed.svg-DVhklYLb.js → interface-lock-closed.svg-Div5xlvI.js} +1 -1
  123. package/web/assets/{interface-lock-open-unlock.svg-Day60scV.js → interface-lock-open-unlock.svg-Du5L_iMV.js} +1 -1
  124. package/web/assets/{interface-login-key.svg-DYEI5voM.js → interface-login-key.svg-28TYVVzH.js} +1 -1
  125. package/web/assets/{interface-search.svg-DwsHXg2v.js → interface-search.svg-BS_owhIG.js} +1 -1
  126. package/web/assets/{interface-setting-cog.svg-CeNdjOvF.js → interface-setting-cog.svg-afYc0TQv.js} +1 -1
  127. package/web/assets/{interface-share-megaphone-bullhorn.svg-C8ZC1W-n.js → interface-share-megaphone-bullhorn.svg-BnW8HhjG.js} +1 -1
  128. package/web/assets/{interface-share-rocket.svg-gmRwyR-9.js → interface-share-rocket.svg-DvX_9178.js} +1 -1
  129. package/web/assets/{interface-share-satellite.svg-BfcRjFbw.js → interface-share-satellite.svg-B4nQqv6w.js} +1 -1
  130. package/web/assets/{interface-share-space-ship.svg-CEjN-mXM.js → interface-share-space-ship.svg-Ciol-6JO.js} +1 -1
  131. package/web/assets/{interface-share.svg-CPspWlPa.js → interface-share.svg-COm1OVr8.js} +1 -1
  132. package/web/assets/{interface-signal-square.svg-DxhbfEQv.js → interface-signal-square.svg-DXuF6sqG.js} +1 -1
  133. package/web/assets/{interface-time-clock-circle.svg-Ck0G0rmI.js → interface-time-clock-circle.svg-CWLe4mcs.js} +1 -1
  134. package/web/assets/{interface-time-hour-glass.svg-C-mRKciT.js → interface-time-hour-glass.svg-DXz9wBiv.js} +1 -1
  135. package/web/assets/{interface-users-multiple.svg-DYmB6Rbf.js → interface-users-multiple.svg-CXOw1J5l.js} +1 -1
  136. package/web/assets/{interface-weather-moon.svg-Cvj6_eNh.js → interface-weather-moon.svg-B9H9xib3.js} +1 -1
  137. package/web/assets/{javascript-CY5caZva.js → javascript-BY1URXQK.js} +1 -1
  138. package/web/assets/{jsonMode-rh9HaZkf.js → jsonMode-CxipJdzJ.js} +1 -1
  139. package/web/assets/{liquid-DlLRGYKU.js → liquid-BbqI_ezD.js} +1 -1
  140. package/web/assets/{lspLanguageFeatures-CRnhy4bG.js → lspLanguageFeatures-BrbDxmfl.js} +1 -1
  141. package/web/assets/{mail-chat-bubble-square.svg-BObGty59.js → mail-chat-bubble-square.svg-CAlBGAlW.js} +1 -1
  142. package/web/assets/{mail-send-email-paper-airplane.svg-B5czr-hw.js → mail-send-email-paper-airplane.svg-BoNc-FEY.js} +1 -1
  143. package/web/assets/{mail-send-envelope.svg-C37J2sdc.js → mail-send-envelope.svg-CnMOSib5.js} +1 -1
  144. package/web/assets/{mdx-B3a8uTpN.js → mdx-C4PcQ_oe.js} +1 -1
  145. package/web/assets/{message-CD325uOm.js → message-BWsbEnoG.js} +2 -2
  146. package/web/assets/{minus-Cl1s4nDX.js → minus-BpDIA3FO.js} +2 -2
  147. package/web/assets/modal-DZYAJM4x.js +5 -0
  148. package/web/assets/modal-Fe2dzlxp.js +1 -0
  149. package/web/assets/{money-cashier-receipt.svg-Cc8n6S0T.js → money-cashier-receipt.svg-DZQ9mrBZ.js} +1 -1
  150. package/web/assets/{money-currency-dollar-pay.svg-C0_3kvpL.js → money-currency-dollar-pay.svg-BCaw-GeJ.js} +1 -1
  151. package/web/assets/{money-graph-arrow-increase.svg-woD8qioO.js → money-graph-arrow-increase.svg-DZXh-i2p.js} +1 -1
  152. package/web/assets/{money-graph-bar-chart-increase.svg-CSw1VAAV.js → money-graph-bar-chart-increase.svg-j_1tUlGM.js} +1 -1
  153. package/web/assets/multiselect-CmjxW2sW.js +251 -0
  154. package/web/assets/{nature-ecology-leaf.svg-CQP_HptW.js → nature-ecology-leaf.svg-bajA57tM.js} +1 -1
  155. package/web/assets/{password-CT6KZaXX.js → password-W9W3PSE2.js} +4 -4
  156. package/web/assets/{phone-telephone.svg-DdIEcJda.js → phone-telephone.svg-DD5MGHqV.js} +1 -1
  157. package/web/assets/{plus-CNb4vtRF.js → plus-RuIcofM_.js} +6 -6
  158. package/web/assets/process.store-COWqXNUm.js +1 -0
  159. package/web/assets/{programming-bug.svg-b2e0hwhB.js → programming-bug.svg-CjtqBc8Z.js} +1 -1
  160. package/web/assets/{programming-cloud.svg-2k-_lY2R.js → programming-cloud.svg-BXQ_h3dK.js} +1 -1
  161. package/web/assets/{programming-computer-database-server.svg-CsVPAAB9.js → programming-computer-database-server.svg-D6TzOHsK.js} +1 -1
  162. package/web/assets/{programming-computer-database.svg-CzCJ-cUE.js → programming-computer-database.svg-Dmdh0lIx.js} +1 -1
  163. package/web/assets/{programming-module-four-layout.svg-D3tAGvjg.js → programming-module-four-layout.svg-CtGhpLhO.js} +1 -1
  164. package/web/assets/{programming-module-three.svg-Cgtxdkq9.js → programming-module-three.svg-hz_w8W7I.js} +1 -1
  165. package/web/assets/{programming-module.svg-B1uuFp4W.js → programming-module.svg-oDT_fQLn.js} +1 -1
  166. package/web/assets/{programming-script-code.svg-B4FKnqTv.js → programming-script-code.svg-CxHHTsaU.js} +1 -1
  167. package/web/assets/{python-BObWJ8Hq.js → python-DH-AyaLR.js} +1 -1
  168. package/web/assets/{razor-COigQ7gt.js → razor-BUpT1gRX.js} +1 -1
  169. package/web/assets/router-BIJ4goD-.js +1 -0
  170. package/web/assets/settings-scope-DGzA7Be-.js +1 -0
  171. package/web/assets/settings.store-Dj2nbYYG.js +1 -0
  172. package/web/assets/shared-sse-CTMtESqe.js +1 -0
  173. package/web/assets/{shopping-cart.svg-BuRDYcqM.js → shopping-cart.svg-D1eK38-E.js} +1 -1
  174. package/web/assets/{shopping-gift-present.svg-h10DhCw1.js → shopping-gift-present.svg-CxSfFNAS.js} +1 -1
  175. package/web/assets/{shopping-shipping-box-parcel-package.svg-Cj8fvF6E.js → shopping-shipping-box-parcel-package.svg-M5Njo2qJ.js} +1 -1
  176. package/web/assets/src-BTWvqafq.js +1 -0
  177. package/web/assets/{src-D83niZVs.js → src-CEK4EPEJ.js} +12 -12
  178. package/web/assets/{tabpanel-DguHvr4k.js → tabpanel-CWwOXePg.js} +3 -3
  179. package/web/assets/{tag-new-circle.svg-Zn07CrZt.js → tag-new-circle.svg-v_Go3fcT.js} +1 -1
  180. package/web/assets/{toggleswitch-BGTO0eH4.js → toggleswitch-C4A0_850.js} +2 -2
  181. package/web/assets/{travel-map-earth-globe.svg-B4LvrGwp.js → travel-map-earth-globe.svg-Db2uRb3M.js} +1 -1
  182. package/web/assets/trpc-DfyQNjZd.js +1 -0
  183. package/web/assets/{tsMode-Hh_YkITa.js → tsMode-CXB5XugS.js} +1 -1
  184. package/web/assets/{typescript-C9fyq61g.js → typescript-CHJkC9r6.js} +1 -1
  185. package/web/assets/useAiChatDrawer-Cuhlc2BI.js +1 -0
  186. package/web/assets/useCloudOrg-DYOv1Oak.js +93 -0
  187. package/web/assets/{useCloudOrg-CDe4gvZH.css → useCloudOrg-Dc6yRgro.css} +1 -1
  188. package/web/assets/{useProjectCatalog-BTfFgYwA.js → useProjectCatalog-DDm0I6sX.js} +1 -1
  189. package/web/assets/{xml-DGE9ZlpR.js → xml-DB4EKWC9.js} +1 -1
  190. package/web/assets/{yaml-D4ibnYJa.js → yaml-CqvLyuow.js} +1 -1
  191. package/web/index.html +1 -1
  192. package/agent-manager-5SQNJICJ.js +0 -7
  193. package/node-QABM22GF.js.map +0 -1
  194. package/src-QP5LALGR.js.map +0 -1
  195. package/web/assets/AgentScalarChatInterface.vue-DVn9R6UA.js +0 -13
  196. package/web/assets/AgentTerminalPage-BlQ3k7VX.css +0 -1
  197. package/web/assets/AgentTerminalPage-C66ptjgH.js +0 -1
  198. package/web/assets/AiChatPage-Bh3ugfp4.js +0 -1
  199. package/web/assets/AppLayout-B0n34XKU.js +0 -1
  200. package/web/assets/AuditPage-CbkmlJeq.js +0 -1
  201. package/web/assets/CloudAccountPage-CqMO-gQ1.js +0 -1
  202. package/web/assets/CloudAccountPage-DuTsra7v.js +0 -1
  203. package/web/assets/CloudMessagingPage-D8Y4KWWS.js +0 -2
  204. package/web/assets/DashboardPage-B7BrLHKh.js +0 -1
  205. package/web/assets/DirectoryPickerDialog-DiXqygSc.js +0 -1
  206. package/web/assets/EnvironmentFormPage-BaMwL4YK.js +0 -1
  207. package/web/assets/EnvironmentListPage-DAKszj2p.js +0 -1
  208. package/web/assets/KanbanBoardPage-A-JNWTlH.css +0 -1
  209. package/web/assets/KanbanBoardPage-DVfCJ09e.js +0 -4
  210. package/web/assets/KanbanListPage-BSWy3lH-.css +0 -1
  211. package/web/assets/KanbanListPage-CAUPVG3x.js +0 -1
  212. package/web/assets/LaunchProjectPage-DboQPHhM.js +0 -1
  213. package/web/assets/LaunchServicesPage-CjM0FUsg.js +0 -1
  214. package/web/assets/LogViewer-CV4UKjXg.js +0 -3
  215. package/web/assets/OrgKeyPrompt-B-Ob1wQo.js +0 -1
  216. package/web/assets/ProcessDetailPage-DtFb-qaA.js +0 -1
  217. package/web/assets/ProjectDetailPage-DKwgJnBb.js +0 -1
  218. package/web/assets/ProjectListPage-Dxb9S6la.js +0 -1
  219. package/web/assets/RandomJobTestPage-Rjvqbre2.js +0 -2
  220. package/web/assets/ScenarioEditorPage-Diue0rEv.js +0 -14
  221. package/web/assets/SendToChatDialog-DZm9rbYQ.js +0 -1
  222. package/web/assets/ServiceControlsBar-CqH5T0Bt.js +0 -1
  223. package/web/assets/ServiceDetailPage-yYY05Ofq.js +0 -2
  224. package/web/assets/ServiceFormPage-DLDyDff6.js +0 -1
  225. package/web/assets/SettingsPage-iHIqmfyf.js +0 -2063
  226. package/web/assets/UnlockPage-DQ34l5l1.js +0 -1
  227. package/web/assets/VariablesTable-WVZfP2VG.js +0 -1
  228. package/web/assets/VaultMigrationPage-DqKJ_shK.js +0 -1
  229. package/web/assets/VersionBadge-zIjq4iAX.js +0 -1
  230. package/web/assets/WikiPage-BsY9YXHO.js +0 -1
  231. package/web/assets/WikiView-BnCFtAdF.js +0 -1
  232. package/web/assets/add-scalar-classes-CjgwfCIh.js +0 -387
  233. package/web/assets/auth-errors-DBBrz53D.js +0 -1
  234. package/web/assets/card-wjkfdMj0.js +0 -32
  235. package/web/assets/client-BSU8WE5S.js +0 -24
  236. package/web/assets/cloud-chat.store-XQdrKrub.js +0 -1
  237. package/web/assets/column-B7tQz83B.js +0 -907
  238. package/web/assets/interface-content-folder.svg-ZuNlhEM9.js +0 -1
  239. package/web/assets/modal-CU6Bnd1J.js +0 -5
  240. package/web/assets/modal-DEWMc9tx.js +0 -1
  241. package/web/assets/multiselect-BRGZ5fql.js +0 -251
  242. package/web/assets/process.store-DS0H00M6.js +0 -1
  243. package/web/assets/router-Di7VfiOq.js +0 -1
  244. package/web/assets/settings-scope-D3a6G9-2.js +0 -1
  245. package/web/assets/settings.store-Dxshs2VQ.js +0 -1
  246. package/web/assets/src-CeD-dzB5.js +0 -1
  247. package/web/assets/trpc-B3z_V0Ei.js +0 -1
  248. package/web/assets/useAiChatDrawer-DvkZ7XYr.js +0 -1
  249. package/web/assets/useCloudOrg-Cn9VivVr.js +0 -93
  250. /package/{agent-manager-5SQNJICJ.js.map → agent-manager-74WZPMVQ.js.map} +0 -0
  251. /package/web/assets/{abap-pAHUP4ij.js → abap-Q7FyqTce.js} +0 -0
  252. /package/web/assets/{apex-BlC_AUu4.js → apex-DBNDq2a_.js} +0 -0
  253. /package/web/assets/{azcli-DbowzAON.js → azcli-BHW8ozYN.js} +0 -0
  254. /package/web/assets/{bat-B7Ot2h-l.js → bat-BL-_3Nfo.js} +0 -0
  255. /package/web/assets/{bicep-CYNbZxhZ.js → bicep-DR2vgumW.js} +0 -0
  256. /package/web/assets/{cameligo-k672d15a.js → cameligo-BCjoEAZU.js} +0 -0
  257. /package/web/assets/{clojure-xuOWq34z.js → clojure-zw1Irdul.js} +0 -0
  258. /package/web/assets/{coffee-Dh5Qnmw8.js → coffee-BdEjkiiW.js} +0 -0
  259. /package/web/assets/{cpp-jb4jg9Uk.js → cpp-DKUlBIAG.js} +0 -0
  260. /package/web/assets/{csharp-C3FX5rWX.js → csharp-BsNC4zVq.js} +0 -0
  261. /package/web/assets/{csp-tJzdMmf_.js → csp-X4Chv5_9.js} +0 -0
  262. /package/web/assets/{css-zB4Sehi2.js → css-Dh0Dlycs.js} +0 -0
  263. /package/web/assets/{cypher-COMeemcO.js → cypher-BL_DRjGX.js} +0 -0
  264. /package/web/assets/{dart-Weadv_PU.js → dart-DaM4j487.js} +0 -0
  265. /package/web/assets/{dockerfile-iFO7uBXW.js → dockerfile-Df5WJXAt.js} +0 -0
  266. /package/web/assets/{ecl-ByBPnSNJ.js → ecl-BjUo3uTs.js} +0 -0
  267. /package/web/assets/{elixir-CUuuLhMC.js → elixir-DrLHYSxt.js} +0 -0
  268. /package/web/assets/{flow9-DHgPJYnW.js → flow9-DKiuX7rg.js} +0 -0
  269. /package/web/assets/{fsharp-CsOH3uVl.js → fsharp-CAN78557.js} +0 -0
  270. /package/web/assets/{go-FjpZaNWk.js → go-DGjr9vA5.js} +0 -0
  271. /package/web/assets/{graphql-BZU_cLe2.js → graphql-CcoU3Cj2.js} +0 -0
  272. /package/web/assets/{hcl-B22JqH4g.js → hcl-udfyCcTm.js} +0 -0
  273. /package/web/assets/{ini-Cw9ScvhO.js → ini-BVbXatjh.js} +0 -0
  274. /package/web/assets/{java-BPAfyRNj.js → java-Drpmh61g.js} +0 -0
  275. /package/web/assets/{julia-BRbjfkdM.js → julia-asFGk-ZV.js} +0 -0
  276. /package/web/assets/{kotlin-iJtwF2yj.js → kotlin-HmkKz1TT.js} +0 -0
  277. /package/web/assets/{less-DnqSQZRk.js → less-C5i2m2Dn.js} +0 -0
  278. /package/web/assets/{lexon-UwtyybiL.js → lexon-B3Xh2kL6.js} +0 -0
  279. /package/web/assets/{lua-C7Vxnt0k.js → lua-DnOtgOOu.js} +0 -0
  280. /package/web/assets/{m3-DkilqhMG.js → m3-Brj4HNKq.js} +0 -0
  281. /package/web/assets/{markdown-DG5_GKmn.js → markdown-C3-4Ntpz.js} +0 -0
  282. /package/web/assets/{mips-CZbNXtif.js → mips-vFQKPHzn.js} +0 -0
  283. /package/web/assets/{msdax-ByOBr3GA.js → msdax-D5MYLS2R.js} +0 -0
  284. /package/web/assets/{mysql-BNf3yZG7.js → mysql-CRQHhUON.js} +0 -0
  285. /package/web/assets/{objective-c-CekAT2Hp.js → objective-c-8cZEp0HR.js} +0 -0
  286. /package/web/assets/{pascal-PaCP2kft.js → pascal-BPn_2jro.js} +0 -0
  287. /package/web/assets/{pascaligo-pVN-S8zl.js → pascaligo-L7QnU_8B.js} +0 -0
  288. /package/web/assets/{perl-BrgmAr_c.js → perl-B9zSPnp3.js} +0 -0
  289. /package/web/assets/{pgsql-DXarcsuV.js → pgsql-DiRJukCJ.js} +0 -0
  290. /package/web/assets/{php-pTuNcPEb.js → php-Dv4g8Lhr.js} +0 -0
  291. /package/web/assets/{pla-D8gY3b39.js → pla-CKAoz6vp.js} +0 -0
  292. /package/web/assets/{postiats-BiEOKgdF.js → postiats-B_PYgUTS.js} +0 -0
  293. /package/web/assets/{powerquery-0qhoXxWG.js → powerquery-CAagSyo-.js} +0 -0
  294. /package/web/assets/{powershell-DmAj7k9Y.js → powershell-Cj9BzLhS.js} +0 -0
  295. /package/web/assets/{protobuf-4nlCKMEm.js → protobuf-DTRY4FFo.js} +0 -0
  296. /package/web/assets/{pug-C9VnVJ-l.js → pug-qADGmCS8.js} +0 -0
  297. /package/web/assets/{qsharp-BBrnSEmg.js → qsharp-xkZT0ZOm.js} +0 -0
  298. /package/web/assets/{r-3a6NbDoK.js → r-C7wfNC2Z.js} +0 -0
  299. /package/web/assets/{redis-CT6FZ_VD.js → redis-BoccK80D.js} +0 -0
  300. /package/web/assets/{redshift-ByL_rc1e.js → redshift-EL8PjTts.js} +0 -0
  301. /package/web/assets/{restructuredtext-BEB80A1j.js → restructuredtext-CA6rgR7C.js} +0 -0
  302. /package/web/assets/{ruby-CFHcKnWa.js → ruby-BymrInur.js} +0 -0
  303. /package/web/assets/{rust-Dom84VId.js → rust-BTbPL-fg.js} +0 -0
  304. /package/web/assets/{sb-DcgyDR9B.js → sb-BTkOICcb.js} +0 -0
  305. /package/web/assets/{scala-B_oferCh.js → scala-CzaUHeQF.js} +0 -0
  306. /package/web/assets/{scheme-BD3ba5Ao.js → scheme-DZe2DRuY.js} +0 -0
  307. /package/web/assets/{scss-Ni06KrSO.js → scss-D5oFt9cg.js} +0 -0
  308. /package/web/assets/{shell-BfWn1eBI.js → shell-DCkIF5jZ.js} +0 -0
  309. /package/web/assets/{solidity-Gey9uue3.js → solidity-CfOO4gXi.js} +0 -0
  310. /package/web/assets/{sophia-B8U6Ufav.js → sophia-0-sROOHR.js} +0 -0
  311. /package/web/assets/{sparql-3LaSujLm.js → sparql-Dzzr9hol.js} +0 -0
  312. /package/web/assets/{sql-B16v0VMC.js → sql-DbXHiHh_.js} +0 -0
  313. /package/web/assets/{st-B_-Ysz08.js → st-DEaYV8xH.js} +0 -0
  314. /package/web/assets/{swift-Cwd6kBdY.js → swift-BQItveav.js} +0 -0
  315. /package/web/assets/{systemverilog-CX5F_zdk.js → systemverilog-nE6YfGlx.js} +0 -0
  316. /package/web/assets/{tcl-O3T9sATk.js → tcl-Do7Q0SM0.js} +0 -0
  317. /package/web/assets/{twig-bKsxXKz3.js → twig-B2CLZN2j.js} +0 -0
  318. /package/web/assets/{typespec-DEhlmAIg.js → typespec-r9R1AgVi.js} +0 -0
  319. /package/web/assets/{uuid-BsA29kWk.js → uuid-CXjA27vZ.js} +0 -0
  320. /package/web/assets/{vb-CShugoE2.js → vb-DGnD02qr.js} +0 -0
  321. /package/web/assets/{w3c-keyname-9KQ-4XZl.js → w3c-keyname-2TLn3EjF.js} +0 -0
  322. /package/web/assets/{wgsl-BgF6PaUo.js → wgsl-C2fD4koY.js} +0 -0
package/index.js CHANGED
@@ -270,10 +270,11 @@ function listenWithRetry(server, port, host, wss, maxRetries = 20, delay = 500)
270
270
  });
271
271
  }
272
272
  async function main() {
273
- const { ensureNodeBinOnPath, ensureUserBinsOnPath } = await import("./node-QABM22GF.js");
273
+ const { ensureNodeBinOnPath, ensureUserBinsOnPath, stampConsole } = await import("./node-B4T3JMM3.js");
274
274
  ensureNodeBinOnPath();
275
275
  await ensureUserBinsOnPath();
276
- const { createLocalServer, pullEnv, PullEnvError, registerInstance } = await import("./src-QP5LALGR.js");
276
+ if (!isPullEnv) stampConsole();
277
+ const { createLocalServer, pullEnv, PullEnvError, registerInstance } = await import("./src-WT7HSY3I.js");
277
278
  if (isPullEnv) {
278
279
  if (!serviceArg) {
279
280
  console.error("Error: --service (-s) is required with --pull-env");
@@ -319,8 +320,17 @@ async function main() {
319
320
  console.log("[cli] Starting Runeya...");
320
321
  const { app, server, wss, shutdown } = await createLocalServer();
321
322
  const webDistPath = join(__dirname, "web");
322
- app.use(express.static(webDistPath));
323
+ app.use("/assets", express.static(join(webDistPath, "assets"), {
324
+ immutable: true,
325
+ maxAge: "1y",
326
+ fallthrough: false
327
+ }));
328
+ app.use(express.static(webDistPath, {
329
+ index: false,
330
+ setHeaders: (res) => res.setHeader("Cache-Control", "no-cache")
331
+ }));
323
332
  app.use((_req, res) => {
333
+ res.setHeader("Cache-Control", "no-cache");
324
334
  res.sendFile(join(webDistPath, "index.html"));
325
335
  });
326
336
  const port = resolvePort();
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 } = await import('@runeya/packages-shared/node');\n ensureNodeBinOnPath();\n await ensureUserBinsOnPath();\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 app.use(express.static(webDistPath));\n\n // Fallback to index.html for client-side routing (Vue Router)\n // Express 5 requires explicit path patterns (not '*')\n app.use((_req: Request, res: Response) => {\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 const appUrl = `http://${host}:${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 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 const appUrl = `http://${host}:${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"]}
@@ -69,10 +69,40 @@ function isDirectory(path) {
69
69
  return false;
70
70
  }
71
71
  }
72
+
73
+ // ../../packages/shared/src/node/log-timestamps.ts
74
+ function isDecorative(args) {
75
+ if (args.length === 0) return true;
76
+ const first = args[0];
77
+ if (typeof first !== "string") return false;
78
+ const trimmed = first.trim();
79
+ return trimmed === "" || /^[┌│└├┬┴┼─┐┘┤]/.test(trimmed);
80
+ }
81
+ var LEVELS = ["log", "info", "warn", "error", "debug"];
82
+ function formatElapsed(startedAt, now) {
83
+ const seconds = (now - startedAt) / 1e3;
84
+ return `+${seconds.toFixed(3)}s`.padStart(10);
85
+ }
86
+ function stampConsole(startedAt = Date.now()) {
87
+ const target = console;
88
+ if (target.__runeyaStamped) return () => {
89
+ };
90
+ target.__runeyaStamped = true;
91
+ const originals = LEVELS.map((level) => {
92
+ const original = console[level].bind(console);
93
+ console[level] = (...args) => isDecorative(args) ? original(...args) : original(formatElapsed(startedAt, Date.now()), ...args);
94
+ return [level, original];
95
+ });
96
+ return () => {
97
+ for (const [level, original] of originals) console[level] = original;
98
+ target.__runeyaStamped = false;
99
+ };
100
+ }
72
101
  export {
73
102
  appendToPath,
74
103
  ensureNodeBinOnPath,
75
104
  ensureUserBinsOnPath,
76
- readLoginShellPath
105
+ readLoginShellPath,
106
+ stampConsole
77
107
  };
78
- //# sourceMappingURL=node-QABM22GF.js.map
108
+ //# sourceMappingURL=node-B4T3JMM3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../packages/shared/src/node/node-path.ts","../../../packages/shared/src/node/user-path.ts","../../../packages/shared/src/node/log-timestamps.ts"],"sourcesContent":["import { dirname, delimiter } from 'node:path';\n\n/**\n * Garantit que le répertoire du binaire Node est dans le `PATH` des services.\n *\n * Un raccourci de bureau n'hérite pas du `PATH` d'un shell de connexion : il\n * reçoit celui de la session graphique, où les gestionnaires de version (n, nvm,\n * fnm, volta, brew) ne figurent pas. Node, lui, est lancé par chemin absolu et\n * démarre très bien — mais `npm`, `npx`, `yarn` et `corepack`, qui vivent à côté\n * de lui, deviennent introuvables. Un service échoue alors sur un message qui ne\n * dit rien de sa cause : « cannot find package manager binary ».\n *\n * Le répertoire est ajouté en QUEUE : ce que la machine a déjà choisi de mettre\n * devant garde la main, et un `PATH` déjà complet ne change pas.\n */\nexport function ensureNodeBinOnPath(environment: NodeJS.ProcessEnv = process.env): void {\n appendToPath(dirname(process.execPath), environment);\n}\n\n/**\n * Ajoute un répertoire en queue du `PATH`, sans doublon ni séparateur vide.\n */\nexport function appendToPath(dir: string, environment: NodeJS.ProcessEnv = process.env): void {\n if (!dir) return;\n const current = environment['PATH'] ?? '';\n const entries = current.split(delimiter).filter(Boolean);\n if (entries.includes(dir)) return;\n environment['PATH'] = entries.length > 0 ? `${current}${delimiter}${dir}` : dir;\n}\n","import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { homedir } from 'node:os';\nimport { existsSync, statSync } from 'node:fs';\nimport { join, delimiter } from 'node:path';\nimport { appendToPath } from './node-path.js';\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Marqueur : un `.zshrc` interactif écrit volontiers sur stdout (bannières,\n * gestionnaires de version, `motd`). Sans balise, on ne sait pas quelle ligne\n * est le `PATH`.\n */\nconst MARKER = '__RUNEYA_PATH__';\n\n/** Le profil de l'utilisateur peut être long à charger — mais pas éternel. */\nconst SHELL_TIMEOUT_MS = 3000;\n\n/**\n * Emplacements où un CLI utilisateur s'installe sans passer par le système.\n * Filet de sécurité quand le shell de connexion n'a rien donné : on ne devine\n * pas les gestionnaires de version (chemins versionnés), seulement le banal.\n */\nfunction commonUserBins(home: string): string[] {\n return [\n join(home, '.local', 'bin'),\n join(home, 'bin'),\n join(home, '.npm-global', 'bin'),\n join(home, '.bun', 'bin'),\n join(home, '.cargo', 'bin'),\n '/opt/homebrew/bin',\n '/usr/local/bin',\n ];\n}\n\n/**\n * Demande son `PATH` au shell de connexion de l'utilisateur.\n *\n * Un raccourci de bureau reçoit le `PATH` de la session graphique, pas celui du\n * shell : `~/.local/bin`, nvm, fnm, volta, mise, asdf… n'y figurent pas. Le CLI\n * installé par l'utilisateur devient alors introuvable, et l'agent le déclare\n * simplement « non disponible ».\n *\n * Renvoie `null` en cas d'échec (Windows, pas de `SHELL`, timeout, profil qui\n * plante) : l'absence de réponse ne doit jamais empêcher l'agent de démarrer.\n */\nexport async function readLoginShellPath(): Promise<string | null> {\n if (process.platform === 'win32') return null;\n\n const shell = process.env['SHELL'];\n if (!shell || !existsSync(shell)) return null;\n\n try {\n // `-l -i` : le `PATH` d'un utilisateur vit aussi bien dans le profil de\n // connexion que dans le fichier interactif (`.zshrc`, `.bashrc`).\n // `shell: false` : le shell EST le programme lancé, pas l'interpréteur.\n const { stdout } = await execFileAsync(shell, ['-l', '-i', '-c', `echo \"${MARKER}$PATH\"`], {\n timeout: SHELL_TIMEOUT_MS,\n shell: false,\n encoding: 'utf8',\n maxBuffer: 1024 * 1024,\n env: { ...process.env, TERM: 'dumb' },\n });\n\n const line = stdout.split('\\n').find(l => l.includes(MARKER));\n if (!line) return null;\n\n const value = line.slice(line.indexOf(MARKER) + MARKER.length).trim();\n return value.length > 0 ? value : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Complète le `PATH` de l'agent avec ce que le shell de connexion connaît, puis\n * avec les emplacements utilisateur usuels qui existent réellement sur disque.\n *\n * Tout est ajouté EN QUEUE, comme pour Node : ce que la machine a déjà mis\n * devant garde la main, et un `PATH` déjà complet ne change pas.\n */\nexport async function ensureUserBinsOnPath(\n environment: NodeJS.ProcessEnv = process.env,\n home: string = homedir(),\n): Promise<void> {\n const shellPath = await readLoginShellPath();\n if (shellPath) {\n for (const entry of shellPath.split(delimiter).filter(Boolean)) {\n appendToPath(entry, environment);\n }\n }\n\n for (const dir of commonUserBins(home)) {\n if (isDirectory(dir)) appendToPath(dir, environment);\n }\n}\n\nfunction isDirectory(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n","/**\n * Horodate ce que le process écrit sur la console, en temps écoulé depuis son\n * démarrage.\n *\n * Les 300 et quelques appels à `console.log` du serveur, de l'agent et du CLI\n * n'ont pas à être réécrits : on enveloppe `console` une fois, au démarrage, et\n * tout ce qui passe par lui est daté — jusqu'aux bibliothèques tierces.\n *\n * Le delta plutôt que l'heure : ces journaux servent surtout à comprendre ce qui\n * prend du temps au sein d'un même lancement, et « +1.204s » se lit sans\n * soustraction mentale. L'heure absolue reste disponible dans le journal\n * d'audit, qui, lui, sert à recouper avec le cloud.\n */\n\n/**\n * Une ligne qui ne dit rien à dater : une ligne vide, ou un morceau d'encadré.\n *\n * La bannière de démarrage est dessinée ligne à ligne ; un horodatage devant\n * chacune casse l'alignement des colonnes et n'apprend rien — elles sont toutes\n * écrites dans la même milliseconde.\n */\nfunction isDecorative(args: unknown[]): boolean {\n if (args.length === 0) return true;\n const first = args[0];\n if (typeof first !== 'string') return false;\n const trimmed = first.trim();\n return trimmed === '' || /^[┌│└├┬┴┼─┐┘┤]/.test(trimmed);\n}\n\nconst LEVELS = ['log', 'info', 'warn', 'error', 'debug'] as const;\n\n/** Le temps écoulé, cadré pour que les lignes s'alignent en colonne. */\nfunction formatElapsed(startedAt: number, now: number): string {\n const seconds = (now - startedAt) / 1000;\n return `+${seconds.toFixed(3)}s`.padStart(10);\n}\n\n/**\n * Enveloppe `console`. Rend une fonction qui remet l'original en place — les\n * tests en ont besoin, et un mode dont la sortie est lue par un script aussi.\n *\n * Appelé deux fois, le second appel ne fait rien : sans cette garde, deux\n * horodatages se cumuleraient sur chaque ligne.\n */\nexport function stampConsole(startedAt: number = Date.now()): () => void {\n const target = console as unknown as Record<string, unknown> & { __runeyaStamped?: boolean };\n if (target.__runeyaStamped) return () => {};\n target.__runeyaStamped = true;\n\n const originals = LEVELS.map((level) => {\n const original = console[level].bind(console);\n console[level] = (...args: unknown[]) => (\n isDecorative(args)\n ? original(...args)\n : original(formatElapsed(startedAt, Date.now()), ...args)\n );\n return [level, original] as const;\n });\n\n return () => {\n for (const [level, original] of originals) console[level] = original;\n target.__runeyaStamped = false;\n };\n}\n"],"mappings":"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","names":["delimiter","delimiter"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runeya/runeya",
3
- "version": "2.0.67",
3
+ "version": "2.0.68",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "runeya": "./index.js"
@@ -97,7 +97,7 @@ import {
97
97
  vaultIdOfRoot,
98
98
  wasRead,
99
99
  writeEntity
100
- } from "./chunk-OOQ74RCO.js";
100
+ } from "./chunk-YSJ6OJGN.js";
101
101
 
102
102
  // ../server/src/create-server.ts
103
103
  import express from "express";
@@ -7951,7 +7951,7 @@ function tailTranscript(opts) {
7951
7951
 
7952
7952
  // ../server/src/services/ai-runners/claude-pty-runner.ts
7953
7953
  async function getAgentManager() {
7954
- const { agentManager: agentManager2 } = await import("./agent-manager-5SQNJICJ.js");
7954
+ const { agentManager: agentManager2 } = await import("./agent-manager-74WZPMVQ.js");
7955
7955
  return agentManager2;
7956
7956
  }
7957
7957
  function buildPtyArgs(params, sessionId, opts) {
@@ -8673,7 +8673,7 @@ async function shutdownCodexAppServer() {
8673
8673
  }
8674
8674
  }
8675
8675
  async function getAgentManager2() {
8676
- const { agentManager: agentManager2 } = await import("./agent-manager-5SQNJICJ.js");
8676
+ const { agentManager: agentManager2 } = await import("./agent-manager-74WZPMVQ.js");
8677
8677
  return agentManager2;
8678
8678
  }
8679
8679
  function parseRuneyaCurlCommand(command) {
@@ -16712,6 +16712,22 @@ async function createLocalServer() {
16712
16712
  await ensureFilePermissions();
16713
16713
  auditService.cleanup().catch((err) => console.error("[server] Audit cleanup failed:", err));
16714
16714
  const app = express();
16715
+ let inFlight = 0;
16716
+ app.use((req, res, next) => {
16717
+ const startedAt2 = Date.now();
16718
+ inFlight++;
16719
+ const label = `${req.method} ${req.originalUrl.split("?")[0]}`;
16720
+ const slow = setTimeout(() => {
16721
+ console.warn(`[http] LENTE (>1s, toujours en cours) ${label} \u2014 ${inFlight} requ\xEAte(s) en vol`);
16722
+ }, 1e3);
16723
+ res.on("close", () => {
16724
+ clearTimeout(slow);
16725
+ inFlight--;
16726
+ const ms = Date.now() - startedAt2;
16727
+ if (ms >= 1e3) console.warn(`[http] ${label} a tenu une connexion ${(ms / 1e3).toFixed(1)}s`);
16728
+ });
16729
+ next();
16730
+ });
16715
16731
  const corsOrigin = env.CORS_ORIGIN ?? (env.RUNEYA_LAN_PROXY ? (origin, cb) => {
16716
16732
  if (!origin) {
16717
16733
  cb(null, false);
@@ -17302,6 +17318,7 @@ async function createLocalServer() {
17302
17318
  });
17303
17319
  const wsConnRegistry = /* @__PURE__ */ new Map();
17304
17320
  server.on("upgrade", async (req, socket, head) => {
17321
+ if (process.env["RUNEYA_DEBUG"]) console.log("[ws-upgrade] demande re\xE7ue");
17305
17322
  const auth = req.headers["authorization"];
17306
17323
  const headerToken = auth?.startsWith("Bearer ") ? auth.slice(7) : null;
17307
17324
  const urlObj = new URL(req.url ?? "/", `http://localhost:${env.PORT}`);
@@ -17309,6 +17326,7 @@ async function createLocalServer() {
17309
17326
  const token = headerToken ?? queryToken;
17310
17327
  if (!hasEncryptionKey()) {
17311
17328
  if (!token) {
17329
+ console.warn("[ws-upgrade] refus\xE9e : serveur verrouill\xE9 et aucun jeton fourni");
17312
17330
  socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
17313
17331
  socket.destroy();
17314
17332
  return;
@@ -17316,12 +17334,14 @@ async function createLocalServer() {
17316
17334
  try {
17317
17335
  await verifyJwt(token);
17318
17336
  } catch {
17337
+ console.warn("[ws-upgrade] refus\xE9e : jeton invalide ou expir\xE9");
17319
17338
  socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
17320
17339
  socket.destroy();
17321
17340
  return;
17322
17341
  }
17323
17342
  }
17324
17343
  wss.handleUpgrade(req, socket, head, (ws) => {
17344
+ if (process.env["RUNEYA_DEBUG"]) console.log("[ws-upgrade] accept\xE9e \u2014 WebSocket \xE9tabli");
17325
17345
  wss.emit("connection", ws, req);
17326
17346
  });
17327
17347
  });
@@ -17491,7 +17511,7 @@ function listenWithRetry(server, port, host, wss, maxRetries = 20, delay = 500)
17491
17511
  });
17492
17512
  }
17493
17513
  async function main() {
17494
- const { ensureNodeBinOnPath, ensureUserBinsOnPath } = await import("./node-QABM22GF.js");
17514
+ const { ensureNodeBinOnPath, ensureUserBinsOnPath } = await import("./node-B4T3JMM3.js");
17495
17515
  ensureNodeBinOnPath();
17496
17516
  await ensureUserBinsOnPath();
17497
17517
  console.log("Hello World 2");
@@ -17535,4 +17555,4 @@ export {
17535
17555
  pullEnv,
17536
17556
  registerInstance
17537
17557
  };
17538
- //# sourceMappingURL=src-QP5LALGR.js.map
17558
+ //# sourceMappingURL=src-WT7HSY3I.js.map