@runeya/runeya 2.0.94 → 2.0.95

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 (261) hide show
  1. package/agent/index.js +22 -1
  2. package/agent/index.js.map +1 -1
  3. package/agent-manager-QQPKKLKY.js +8 -0
  4. package/chat-LPMGV2VS.js +18 -0
  5. package/chat-LPMGV2VS.js.map +1 -0
  6. package/chunk-3MJLS5UY.js +1944 -0
  7. package/chunk-3MJLS5UY.js.map +1 -0
  8. package/chunk-72LQC3YC.js +152 -0
  9. package/chunk-72LQC3YC.js.map +1 -0
  10. package/{chunk-4PQXBTV6.js → chunk-HX3ZIWHM.js} +82 -1959
  11. package/chunk-HX3ZIWHM.js.map +1 -0
  12. package/chunk-MD3VW4HQ.js +160 -0
  13. package/chunk-MD3VW4HQ.js.map +1 -0
  14. package/chunk-R23UUB5R.js +7285 -0
  15. package/chunk-R23UUB5R.js.map +1 -0
  16. package/chunk-WAC56HS4.js +1842 -0
  17. package/chunk-WAC56HS4.js.map +1 -0
  18. package/codex-thread-db-LE5FYDDA.js +27 -0
  19. package/codex-thread-db-LE5FYDDA.js.map +1 -0
  20. package/companion-VPYVGTRU.js +42 -0
  21. package/companion-VPYVGTRU.js.map +1 -0
  22. package/index.js +1 -1
  23. package/package.json +1 -1
  24. package/settings-manager-6FKHBLIV.js +8 -0
  25. package/settings-manager-6FKHBLIV.js.map +1 -0
  26. package/src-NEPDGULO.js +10087 -0
  27. package/src-NEPDGULO.js.map +1 -0
  28. package/web/assets/AgentScalarChatInterface.vue-DCnwgzWk.js +13 -0
  29. package/web/assets/AgentTerminalPage-D6iEzvyz.js +1 -0
  30. package/web/assets/AiChatPage-DDr9XEv8.js +1 -0
  31. package/web/assets/AppLayout-B2mreJVA.js +1 -0
  32. package/web/assets/{AppLayout-Sk3Qnkr-.css → AppLayout-nrP0jOZ1.css} +1 -1
  33. package/web/assets/AuditPage-CSPHdf0m.js +1 -0
  34. package/web/assets/CloudAccountPage-BAkTRH4E.js +1 -0
  35. package/web/assets/CloudAccountPage-C35O8Pcb.js +1 -0
  36. package/web/assets/CloudMessagingPage-5KYELXQI.js +2 -0
  37. package/web/assets/DashboardPage-Dl9Sg1av.js +1 -0
  38. package/web/assets/DirectoryPickerDialog-DLL3-GoW.js +1 -0
  39. package/web/assets/{EditorIcon-CdvuLNAP.js → EditorIcon-CzgSjXLk.js} +2 -2
  40. package/web/assets/{EnvironmentForm-BiWvLVax.js → EnvironmentForm-DmdDIJHv.js} +2 -2
  41. package/web/assets/EnvironmentFormPage-CV7Uq6Ah.js +1 -0
  42. package/web/assets/EnvironmentListPage-Cfo9RA_g.js +1 -0
  43. package/web/assets/KanbanBoardPage-DL1WwMBP.js +4 -0
  44. package/web/assets/KanbanListPage-CSAnUfp3.js +1 -0
  45. package/web/assets/LaunchProjectPage-vNUoulGP.js +1 -0
  46. package/web/assets/LaunchServicesPage-CkWZxZ-v.js +1 -0
  47. package/web/assets/LogViewer-CW-bBjZF.js +3 -0
  48. package/web/assets/OrgKeyPrompt-CHoMbQhn.js +1 -0
  49. package/web/assets/ProcessControls-WS6BjS5H.js +1 -0
  50. package/web/assets/ProcessDetailPage-DEvZSNER.js +1 -0
  51. package/web/assets/{ProcessMetrics-_FGC-0hm.js → ProcessMetrics-DmhwoKrE.js} +2 -2
  52. package/web/assets/ProjectDetailPage-DanRrWb4.js +1 -0
  53. package/web/assets/ProjectListPage--l9HsQ9u.js +1 -0
  54. package/web/assets/RandomJobTestPage-BMatxc2G.js +2 -0
  55. package/web/assets/ScenarioEditorPage-D_rJyudb.js +14 -0
  56. package/web/assets/SendToChatDialog-D-pDvIjD.js +1 -0
  57. package/web/assets/ServiceControlsBar-BSU25sZZ.js +1 -0
  58. package/web/assets/ServiceDetailPage-B1oRlnId.js +2 -0
  59. package/web/assets/ServiceFormPage-D-DmI0fF.js +1 -0
  60. package/web/assets/SettingsPage-Bi72zdhb.js +2063 -0
  61. package/web/assets/{SettingsPage-CX1EAjNK.css → SettingsPage-D6-jpORY.css} +1 -1
  62. package/web/assets/UnlockPage-BtunlGnX.js +1 -0
  63. package/web/assets/VariablesTable-D3HpHlKY.js +1 -0
  64. package/web/assets/VaultMigrationPage-DrrFR1I-.js +1 -0
  65. package/web/assets/VersionBadge-DqcS34oJ.js +1 -0
  66. package/web/assets/WikiPage-BH8A-IB_.js +1 -0
  67. package/web/assets/WikiView-BasNZv2A.js +1 -0
  68. package/web/assets/add-scalar-classes-_PYrgVvq.js +387 -0
  69. package/web/assets/auth-errors-CwswzwYV.js +1 -0
  70. package/web/assets/{autocomplete-tNXsUW-e.js → autocomplete-B-t_B26t.js} +3 -3
  71. package/web/assets/{basic-shape-diamond.svg-BgNul67K.js → basic-shape-diamond.svg-BFWFQIZl.js} +1 -1
  72. package/web/assets/{basic-shape-hexagon.svg-CILNnZwG.js → basic-shape-hexagon.svg-CXsvZPky.js} +1 -1
  73. package/web/assets/{basic-shape-primary-circle-ellipse-round.svg-OXklrBAn.js → basic-shape-primary-circle-ellipse-round.svg-BVg6oDS7.js} +1 -1
  74. package/web/assets/{basic-shape-primary-square-rectangle.svg-DYF4zyUj.js → basic-shape-primary-square-rectangle.svg-jiLWQSQV.js} +1 -1
  75. package/web/assets/{basic-shape-shield.svg-CQbzQswT.js → basic-shape-shield.svg-CEybfnew.js} +1 -1
  76. package/web/assets/{browser-CDtVZzm0.js → browser-BfO6Jws3.js} +1 -1
  77. package/web/assets/{browser-CdTGBSDI.js → browser-C7Qh0u0N.js} +1 -1
  78. package/web/assets/card-CWgnvlKH.js +32 -0
  79. package/web/assets/{checkbox-CTopTVtp.js → checkbox-CKzrAJQv.js} +3 -3
  80. package/web/assets/{chip-Cw38kJ50.js → chip-Bu5HllmO.js} +2 -2
  81. package/web/assets/{client-Bjn9AL4v.js → client-CM-a2QU7.js} +2 -2
  82. package/web/assets/cloud-chat.store-Cjbzzy1s.js +1 -0
  83. package/web/assets/cloud-session-Bs6siQ-Y.js +1 -0
  84. package/web/assets/column-pXrOxKc1.js +907 -0
  85. package/web/assets/{computer-device-desktop-monitor.svg-ByBKx1CQ.js → computer-device-desktop-monitor.svg-DO-9EDqA.js} +1 -1
  86. package/web/assets/{computer-device-desktop.svg-BPvzT4sF.js → computer-device-desktop.svg-U_EIk7jo.js} +1 -1
  87. package/web/assets/{computer-device-laptop.svg-saGCSB2c.js → computer-device-laptop.svg-nvbz6sjk.js} +1 -1
  88. package/web/assets/{computer-device-mobile-phone-android-samsung-back.svg-Bo-eisU4.js → computer-device-mobile-phone-android-samsung-back.svg-Cs34LunN.js} +1 -1
  89. package/web/assets/{computer-device-mobile-phone-android-samsung.svg-Bavaieis.js → computer-device-mobile-phone-android-samsung.svg-CDJgG-4L.js} +1 -1
  90. package/web/assets/{computer-device-mobile-phone-iphone-x-back.svg-BQK9BRXi.js → computer-device-mobile-phone-iphone-x-back.svg-Du0pDh9L.js} +1 -1
  91. package/web/assets/{computer-device-mobile-phone-iphone-x.svg-C24hCDuI.js → computer-device-mobile-phone-iphone-x.svg-CUgXFf2r.js} +1 -1
  92. package/web/assets/{computer-device-mobile-tablet-touch.svg-CUHV3zSo.js → computer-device-mobile-tablet-touch.svg-CKdx-iUf.js} +1 -1
  93. package/web/assets/{computer-device-mobile-tablet.svg-C8SRYMmI.js → computer-device-mobile-tablet.svg-BTvPzs5h.js} +1 -1
  94. package/web/assets/{computer-device-network-ethernet-cat6.svg-Ds4kUid3.js → computer-device-network-ethernet-cat6.svg-Cway8Bfw.js} +1 -1
  95. package/web/assets/{computer-device-network-lan-www.svg-BwIieS6h.js → computer-device-network-lan-www.svg-iuTZVSKE.js} +1 -1
  96. package/web/assets/{computer-device-network-wifi-connection.svg-Q7Mxb3eP.js → computer-device-network-wifi-connection.svg-DEemVGZq.js} +1 -1
  97. package/web/assets/{computer-device-network-wifi-router.svg-B0PMuY1x.js → computer-device-network-wifi-router.svg-BH2ASeRD.js} +1 -1
  98. package/web/assets/{cssMode-8lAGHoa8.js → cssMode-BHBdzmoS.js} +1 -1
  99. package/web/assets/{divider-DRKb8XBY.js → divider-kwmULX2U.js} +2 -2
  100. package/web/assets/{docx-preview-K0JOmyAw.js → docx-preview-CxXKUxi7.js} +1 -1
  101. package/web/assets/{ecology-science-erlenmeyer-flask.svg-D5wbPwU2.js → ecology-science-erlenmeyer-flask.svg-9yLzulSu.js} +1 -1
  102. package/web/assets/{fieldset-jU8x6yyO.js → fieldset-DE0sJS29.js} +2 -2
  103. package/web/assets/{freemarker2-BmTZDOK9.js → freemarker2-CpcoAmNk.js} +1 -1
  104. package/web/assets/{handlebars-DM-mBhq3.js → handlebars-D6DR-MoZ.js} +1 -1
  105. package/web/assets/{html-BohxI4Ke.js → html-Dx3QwrZR.js} +1 -1
  106. package/web/assets/{htmlMode-vqRVK3v5.js → htmlMode-KSJ_gFzK.js} +1 -1
  107. package/web/assets/{image-flash-lightning.svg-s-LoyOp-.js → image-flash-lightning.svg-O9m-H64P.js} +1 -1
  108. package/web/assets/{image-picture-flower.svg-CofKZT5Q.js → image-picture-flower.svg--rWVVuqu.js} +1 -1
  109. package/web/assets/{index-Da38OOd8.css → index-B4UWj2Kz.css} +1 -1
  110. package/web/assets/{index-DHr5P6pq.js → index-pLefgbhx.js} +287 -287
  111. package/web/assets/{interface-alert-exclamation-diamond.svg-C4C4i4oQ.js → interface-alert-exclamation-diamond.svg-CVeV0ecY.js} +1 -1
  112. package/web/assets/{interface-alert-exclamation-triangle-warning.svg-C-ogsTXk.js → interface-alert-exclamation-triangle-warning.svg-MIboYRzH.js} +1 -1
  113. package/web/assets/{interface-alert-information-circle.svg-BFpBDkj5.js → interface-alert-information-circle.svg-BlkHMxfH.js} +1 -1
  114. package/web/assets/{interface-award-crown.svg-DfHdQ8rJ.js → interface-award-crown.svg-C_Z3sLuP.js} +1 -1
  115. package/web/assets/{interface-bookmark.svg-qCQ3v5rM.js → interface-bookmark-tag.svg-ClOZOhfV.js} +1 -1
  116. package/web/assets/{interface-bookmark-tag.svg-DkfXcRMe.js → interface-bookmark.svg-CVpTNe3u.js} +1 -1
  117. package/web/assets/{interface-calendar-date-one.svg-D2ssTK7X.js → interface-calendar-date-one.svg-BvG92AQi.js} +1 -1
  118. package/web/assets/{interface-content-book-open-pages.svg-CH1BmaVm.js → interface-content-book-open-pages.svg-aXXXkj7d.js} +1 -1
  119. package/web/assets/{interface-content-book-page.svg-BU6m1d9-.js → interface-content-book-page.svg-BE0nQJw_.js} +1 -1
  120. package/web/assets/{interface-content-file.svg-DbsUtWTI.js → interface-content-file.svg-DYonyE7J.js} +1 -1
  121. package/web/assets/{interface-content-folder.svg-8IvlkKzB.js → interface-content-folder.svg-DKc7vKrm.js} +1 -1
  122. package/web/assets/interface-content-folder.svg-FcNZvOjy.js +1 -0
  123. package/web/assets/{interface-copy-clipboard.svg-D8ev9OtX.js → interface-copy-clipboard.svg-sAixmHqz.js} +1 -1
  124. package/web/assets/{interface-edit-attachment.svg-dl-nfI3P.js → interface-edit-attachment.svg-DsSzCN6U.js} +1 -1
  125. package/web/assets/{interface-edit-binocular.svg-Box_OuXH.js → interface-edit-binocular.svg-Bheco9Gv.js} +1 -1
  126. package/web/assets/{interface-edit-magic-wand.svg-DIhMw--x.js → interface-edit-magic-wand.svg-C73TY2iI.js} +1 -1
  127. package/web/assets/{interface-edit-tool-paint-roller.svg-COUefijc.js → interface-edit-tool-paint-roller.svg-D2OSqY3g.js} +1 -1
  128. package/web/assets/{interface-edit-tool-pencil.svg-BNmSspcl.js → interface-edit-tool-pencil.svg-CdY316cw.js} +1 -1
  129. package/web/assets/{interface-favorite-award.svg-Cy-XeB8N.js → interface-favorite-award.svg-DfA-EhHI.js} +1 -1
  130. package/web/assets/{interface-favorite-flag.svg-BVBisei8.js → interface-favorite-flag.svg-BnmSaveE.js} +1 -1
  131. package/web/assets/{interface-favorite-heart.svg-BkVO2jBo.js → interface-favorite-heart.svg-28i7lMzG.js} +1 -1
  132. package/web/assets/{interface-favorite-star.svg-Bxe8dqRi.js → interface-favorite-star.svg-u8xOEB4S.js} +1 -1
  133. package/web/assets/{interface-favorite-stars-sparkles.svg-MkrYfhIz.js → interface-favorite-stars-sparkles.svg-D5UHf8ar.js} +1 -1
  134. package/web/assets/{interface-hierarchy-flowchart.svg-De7TQhr3.js → interface-hierarchy-flowchart.svg-BmjWTh4K.js} +1 -1
  135. package/web/assets/{interface-home-house.svg-D_qOil1N.js → interface-home-house.svg-DJ5Ae65N.js} +1 -1
  136. package/web/assets/{interface-hyperlink.svg-5S7ugTcP.js → interface-hyperlink.svg-HdHKY_g6.js} +1 -1
  137. package/web/assets/{interface-lighting-brightness.svg-vJA95mbx.js → interface-lighting-brightness.svg-BDELfqMb.js} +1 -1
  138. package/web/assets/{interface-lock-closed.svg-DVL32yBG.js → interface-lock-closed.svg-BcDwDHkS.js} +1 -1
  139. package/web/assets/{interface-lock-open-unlock.svg-C7DBYFPn.js → interface-lock-open-unlock.svg-DNESCRC1.js} +1 -1
  140. package/web/assets/{interface-login-key.svg-CEq51fI1.js → interface-login-key.svg-BOEot3yk.js} +1 -1
  141. package/web/assets/{interface-search.svg-CkP-JMXm.js → interface-search.svg-CFsy7ant.js} +1 -1
  142. package/web/assets/{interface-setting-cog.svg-CgR9wxJN.js → interface-setting-cog.svg-B7Zk0iyr.js} +1 -1
  143. package/web/assets/{interface-share-megaphone-bullhorn.svg-C_VIGsI0.js → interface-share-megaphone-bullhorn.svg-DvG0IjMM.js} +1 -1
  144. package/web/assets/{interface-share-rocket.svg-aseIyfXq.js → interface-share-rocket.svg-gvaeTB8G.js} +1 -1
  145. package/web/assets/{interface-share-satellite.svg-CzkX6PJ2.js → interface-share-satellite.svg-B5pXJ0kU.js} +1 -1
  146. package/web/assets/{interface-share-space-ship.svg-Df1jdZi5.js → interface-share-space-ship.svg-B0k0J-VQ.js} +1 -1
  147. package/web/assets/{interface-share.svg-CioS2p8V.js → interface-share.svg-ZDsCvjRe.js} +1 -1
  148. package/web/assets/{interface-signal-square.svg-VUtTXd8G.js → interface-signal-square.svg-DBkJ1ire.js} +1 -1
  149. package/web/assets/{interface-time-clock-circle.svg-DWh2OWyC.js → interface-time-clock-circle.svg-BheUirew.js} +1 -1
  150. package/web/assets/{interface-time-hour-glass.svg-BCqCfi9r.js → interface-time-hour-glass.svg-iORrebF8.js} +1 -1
  151. package/web/assets/{interface-users-multiple.svg-Edac3LOs.js → interface-users-multiple.svg-DMqedSUQ.js} +1 -1
  152. package/web/assets/{interface-weather-moon.svg-BrK0lmKX.js → interface-weather-moon.svg-DyPBHRw4.js} +1 -1
  153. package/web/assets/{javascript-ByDc_p54.js → javascript-B1Y6a5s6.js} +1 -1
  154. package/web/assets/{jsonMode-Cm2EOOd4.js → jsonMode-Vj2pUgcF.js} +2 -2
  155. package/web/assets/{liquid-z9Tc1tTM.js → liquid-lb0ImGEW.js} +1 -1
  156. package/web/assets/{lspLanguageFeatures-D6O0oAJj.js → lspLanguageFeatures-sh8ggL5N.js} +3 -3
  157. package/web/assets/{mail-chat-bubble-square.svg-obHuGV3I.js → mail-chat-bubble-square.svg-D_Lx6uBc.js} +1 -1
  158. package/web/assets/{mail-send-email-paper-airplane.svg-I-JVbCkD.js → mail-send-email-paper-airplane.svg-B6FGKBZu.js} +1 -1
  159. package/web/assets/{mail-send-envelope.svg-CcYcXCe5.js → mail-send-envelope.svg-Dtm4h_xw.js} +1 -1
  160. package/web/assets/{mdx-B8bePw34.js → mdx-BbFPcqiD.js} +1 -1
  161. package/web/assets/{minus-k3R4JOtO.js → minus-Bxw18Xk6.js} +2 -2
  162. package/web/assets/modal-D-InjkVP.js +1 -0
  163. package/web/assets/modal-DLY8nKW-.js +5 -0
  164. package/web/assets/{money-cashier-receipt.svg-BIKxMBIH.js → money-cashier-receipt.svg-VpEb8Ewv.js} +1 -1
  165. package/web/assets/{money-currency-dollar-pay.svg-B-HfkTCE.js → money-currency-dollar-pay.svg-vo8FP9z4.js} +1 -1
  166. package/web/assets/{money-graph-arrow-increase.svg-CnXoTtSD.js → money-graph-arrow-increase.svg-CNcLQGOf.js} +1 -1
  167. package/web/assets/{money-graph-bar-chart-increase.svg-Dt7ly9Tz.js → money-graph-bar-chart-increase.svg-BHAccBVA.js} +1 -1
  168. package/web/assets/multiselect-Crs0miOE.js +251 -0
  169. package/web/assets/{nature-ecology-leaf.svg-TjKZfobq.js → nature-ecology-leaf.svg-0y4pBUlD.js} +1 -1
  170. package/web/assets/{password-dyrMCyHO.js → password-TyT4zuky.js} +4 -4
  171. package/web/assets/{phone-telephone.svg-CCMqAIP_.js → phone-telephone.svg-BdWhV2vz.js} +1 -1
  172. package/web/assets/{plus-Dg2E4ggP.js → plus-4Z2iFfO2.js} +6 -6
  173. package/web/assets/process.store-DsGpeQnV.js +1 -0
  174. package/web/assets/{programming-bug.svg-yyshFuq4.js → programming-bug.svg-DXDJVNeQ.js} +1 -1
  175. package/web/assets/{programming-cloud.svg-DPyoJVZM.js → programming-cloud.svg-qWtq6fXG.js} +1 -1
  176. package/web/assets/{programming-computer-database-server.svg-D7pShcvh.js → programming-computer-database-server.svg-DnlJHfH5.js} +1 -1
  177. package/web/assets/{programming-computer-database.svg-CErKDQrw.js → programming-computer-database.svg-Bl73TDXc.js} +1 -1
  178. package/web/assets/{programming-module-four-layout.svg-B26pG3Bb.js → programming-module-four-layout.svg-CGkj0OdH.js} +1 -1
  179. package/web/assets/{programming-module-three.svg-CnoN59HX.js → programming-module-three.svg-Bsk_vaHc.js} +1 -1
  180. package/web/assets/{programming-module.svg-C02rn1I7.js → programming-module.svg-D0Yng9wS.js} +1 -1
  181. package/web/assets/{programming-script-code.svg-D0sPjoPV.js → programming-script-code.svg-DTHMCNnF.js} +1 -1
  182. package/web/assets/{python-1623Ut7s.js → python-HImlMuYG.js} +1 -1
  183. package/web/assets/{razor-CyTiWHYX.js → razor-CTFKddzv.js} +1 -1
  184. package/web/assets/router-DTzqrUba.js +1 -0
  185. package/web/assets/settings-scope-CdxhnRbI.js +1 -0
  186. package/web/assets/{settings.store-BPAoJA_7.js → settings.store-CZ9jrl3S.js} +1 -1
  187. package/web/assets/{shopping-cart.svg-Cusya5ZE.js → shopping-cart.svg-Cx50mrFm.js} +1 -1
  188. package/web/assets/{shopping-gift-present.svg-DuhD1jDX.js → shopping-gift-present.svg-DGOO6qNg.js} +1 -1
  189. package/web/assets/{shopping-shipping-box-parcel-package.svg-mUJnCOxq.js → shopping-shipping-box-parcel-package.svg-C96i4g3q.js} +1 -1
  190. package/web/assets/src-DRjytMUo.js +1 -0
  191. package/web/assets/{src-HsHwQ5rW.js → src-DzMKqnGu.js} +13 -13
  192. package/web/assets/{tabpanel-D-R0gqbm.js → tabpanel-BW8I76pY.js} +3 -3
  193. package/web/assets/{tag-new-circle.svg-DFYYOM3s.js → tag-new-circle.svg-CV5DN0Db.js} +1 -1
  194. package/web/assets/{toggleswitch-Bv2Y60nl.js → toggleswitch-D4Evlg2b.js} +2 -2
  195. package/web/assets/{travel-map-earth-globe.svg-D1KtAG5P.js → travel-map-earth-globe.svg-CWvuO_Hb.js} +1 -1
  196. package/web/assets/trpc-BbC62Ymt.js +1 -0
  197. package/web/assets/{tsMode-DarxEDX3.js → tsMode-BqKPHyIc.js} +6 -6
  198. package/web/assets/{typescript-Bp83QY3R.js → typescript-Bme6ns4u.js} +1 -1
  199. package/web/assets/useAiChatDrawer-BG8t5Thc.js +1 -0
  200. package/web/assets/useCloudOrg-D2LTbk-G.js +572 -0
  201. package/web/assets/{useProjectCatalog-ClgttEEn.js → useProjectCatalog-nlAZuu5X.js} +1 -1
  202. package/web/assets/{xml-CieK61bI.js → xml-zsImRVNc.js} +1 -1
  203. package/web/assets/{yaml-Dd4h-bcV.js → yaml-VubzWJpP.js} +1 -1
  204. package/web/index.html +2 -2
  205. package/agent-manager-3KSS7BHP.js +0 -7
  206. package/chunk-4PQXBTV6.js.map +0 -1
  207. package/src-GGPKDQGD.js +0 -18433
  208. package/src-GGPKDQGD.js.map +0 -1
  209. package/web/assets/AgentScalarChatInterface.vue-CR0iWJNr.js +0 -13
  210. package/web/assets/AgentTerminalPage-DZj9UulV.js +0 -1
  211. package/web/assets/AiChatPage-D4h76hus.js +0 -1
  212. package/web/assets/AppLayout-DusPXiZn.js +0 -1
  213. package/web/assets/AuditPage-BBEa6MYr.js +0 -1
  214. package/web/assets/CloudAccountPage-DKgXvPS1.js +0 -1
  215. package/web/assets/CloudAccountPage-DopITrxL.js +0 -1
  216. package/web/assets/CloudMessagingPage-BNIbysEO.js +0 -2
  217. package/web/assets/DashboardPage-CTGAGY7X.js +0 -1
  218. package/web/assets/DirectoryPickerDialog-BKI9vxkG.js +0 -1
  219. package/web/assets/EnvironmentFormPage-RReX9Ijr.js +0 -1
  220. package/web/assets/EnvironmentListPage-BW5PlOxl.js +0 -1
  221. package/web/assets/KanbanBoardPage-BFYgHGl0.js +0 -4
  222. package/web/assets/KanbanListPage-BAcgRh8Z.js +0 -1
  223. package/web/assets/LaunchProjectPage-CpiyvCBv.js +0 -1
  224. package/web/assets/LaunchServicesPage-ChEXnYIi.js +0 -1
  225. package/web/assets/LogViewer-iTxXl8YQ.js +0 -3
  226. package/web/assets/OrgKeyPrompt-KRyXRMw7.js +0 -1
  227. package/web/assets/ProcessControls-DynA7Ock.js +0 -1
  228. package/web/assets/ProcessDetailPage-BpgGTkXx.js +0 -1
  229. package/web/assets/ProjectDetailPage-B49_-83N.js +0 -1
  230. package/web/assets/ProjectListPage-CFoEPT2F.js +0 -1
  231. package/web/assets/RandomJobTestPage-CALSR3WS.js +0 -2
  232. package/web/assets/ScenarioEditorPage-DxyzCjhy.js +0 -14
  233. package/web/assets/SendToChatDialog-CeFdMciG.js +0 -1
  234. package/web/assets/ServiceControlsBar-CI1_piqu.js +0 -1
  235. package/web/assets/ServiceDetailPage-CVT68kTt.js +0 -2
  236. package/web/assets/ServiceFormPage-nLRxtrOu.js +0 -1
  237. package/web/assets/SettingsPage-DDYegVxd.js +0 -2063
  238. package/web/assets/UnlockPage-D9_ZbMR_.js +0 -1
  239. package/web/assets/VariablesTable-ClL6KuSo.js +0 -1
  240. package/web/assets/VaultMigrationPage-rc5OA9Xt.js +0 -1
  241. package/web/assets/VersionBadge-K5UQnfc6.js +0 -1
  242. package/web/assets/WikiPage-VeQCqO9Z.js +0 -1
  243. package/web/assets/WikiView-XCwSa_R7.js +0 -1
  244. package/web/assets/add-scalar-classes-CvhyJKCs.js +0 -387
  245. package/web/assets/auth-errors-Cmx-4mn3.js +0 -1
  246. package/web/assets/card-BfEdnBhU.js +0 -32
  247. package/web/assets/cloud-chat.store-BPoTzBeD.js +0 -1
  248. package/web/assets/cloud-session-D0ue5Z97.js +0 -1
  249. package/web/assets/column-BtLe8qbf.js +0 -907
  250. package/web/assets/interface-content-folder.svg-nRYFY3NY.js +0 -1
  251. package/web/assets/modal-CVWJd9ZI.js +0 -5
  252. package/web/assets/modal-Ccn3uciU.js +0 -1
  253. package/web/assets/multiselect-BsCXwmy0.js +0 -251
  254. package/web/assets/process.store-CHdSS5Et.js +0 -1
  255. package/web/assets/router-DWhykW-F.js +0 -1
  256. package/web/assets/settings-scope-9i3_Io9Z.js +0 -1
  257. package/web/assets/src-BiD62eGr.js +0 -1
  258. package/web/assets/trpc-4Nls70HO.js +0 -1
  259. package/web/assets/useAiChatDrawer-BYR24v6F.js +0 -1
  260. package/web/assets/useCloudOrg-B1BakNYp.js +0 -572
  261. /package/{agent-manager-3KSS7BHP.js.map → agent-manager-QQPKKLKY.js.map} +0 -0
@@ -0,0 +1,1944 @@
1
+ // ../server/src/config/env.ts
2
+ import { z } from "zod";
3
+ import { resolve as resolvePath } from "path";
4
+ var serverPort = z.coerce.number().int().min(1).max(65535).default(4e3).parse(process.env.RUNEYA_HTTP_PORT);
5
+ var defaultAgentPort = process.env.RUNEYA_AGENT_PORT ? z.coerce.number().int().min(1).max(65535).parse(process.env.RUNEYA_AGENT_PORT) : serverPort + 1;
6
+ var EnvSchema = z.object({
7
+ RUNEYA_HTTP_PORT: z.coerce.number().int().min(1).max(65535).default(4e3),
8
+ RUNEYA_HOST: z.string().default("127.0.0.1"),
9
+ RUNEYA_AGENT_PORT: z.coerce.number().int().min(1).max(65535).default(defaultAgentPort),
10
+ RUNEYA_AGENT_HOST: z.string().default("127.0.0.1"),
11
+ RUNEYA_AGENT_BINARY_PATH: z.string().nullable().default(null),
12
+ RUNEYA_DATA_DIR: z.preprocess((v) => typeof v === "string" && v.length > 0 ? v : void 0, z.string().default(".runeya")),
13
+ // Home holding the cloud vaults (`<home>/.runeya/orgs/...`). Defaults to the
14
+ // user's home directory; overridden by tests so they never write to the real
15
+ // one, and usable to relocate the vaults on a shared machine.
16
+ RUNEYA_HOME: z.preprocess((v) => typeof v === "string" && v.length > 0 ? v : void 0, z.string().nullable().default(null)),
17
+ RUNEYA_CLOUD_URL: z.string().url().nullable().default(null),
18
+ // Cloud front-end (landing) URL — used by the web app for the registration /
19
+ // onboarding flow. Configured on the server at launch; the web fetches it.
20
+ RUNEYA_CLOUD_APP_URL: z.string().url().nullable().default(null),
21
+ RUNEYA_MODE: z.enum(["local-simple", "cloud"]).default("local-simple"),
22
+ RUNEYA_CORS_ORIGIN: z.string().nullable().default(null),
23
+ RUNEYA_LAN_PROXY: z.preprocess((v) => v === "true" || v === "1", z.boolean()).default(false),
24
+ // Set by the CLI when it was started from a desktop launcher rather than a
25
+ // terminal. The web app surfaces it so the user knows which Runeya they are
26
+ // looking at when several are running.
27
+ RUNEYA_FROM_DESKTOP: z.preprocess((v) => v === "true" || v === "1", z.boolean()).default(false),
28
+ // Label shown for this machine in the cloud's "linked machines" screen.
29
+ // Defaults to the hostname (see `getDeviceName`); set it explicitly when a
30
+ // single host runs several instances and you want to tell them apart.
31
+ RUNEYA_DEVICE_NAME: z.preprocess(
32
+ (v) => typeof v === "string" && v.trim().length > 0 ? v.trim() : void 0,
33
+ z.string().max(64).nullable().default(null)
34
+ )
35
+ }).transform((data) => ({
36
+ ...data,
37
+ // Short aliases used throughout the server code
38
+ PORT: data.RUNEYA_HTTP_PORT,
39
+ HOST: data.RUNEYA_HOST,
40
+ MODE: data.RUNEYA_MODE,
41
+ /**
42
+ * Absolute from the start, resolved once against the launch directory.
43
+ *
44
+ * It defaults to a relative `.runeya`, and every caller used to re-resolve it
45
+ * against whatever the process's cwd happened to be. A vault that moves when
46
+ * the process changes directory is a vault that can be silently written to the
47
+ * wrong place — so the answer is fixed here, at boot, and never recomputed.
48
+ */
49
+ DATA_DIR: resolvePath(data.RUNEYA_DATA_DIR),
50
+ HOME_DIR: data.RUNEYA_HOME,
51
+ CLOUD_URL: data.RUNEYA_CLOUD_URL,
52
+ CLOUD_APP_URL: data.RUNEYA_CLOUD_APP_URL,
53
+ CORS_ORIGIN: data.RUNEYA_CORS_ORIGIN,
54
+ AGENT_BINARY_PATH: data.RUNEYA_AGENT_BINARY_PATH,
55
+ DEVICE_NAME: data.RUNEYA_DEVICE_NAME,
56
+ FROM_DESKTOP: data.RUNEYA_FROM_DESKTOP
57
+ }));
58
+ var env = EnvSchema.parse(process.env);
59
+
60
+ // ../server/src/services/vault-resolver.ts
61
+ import { join, sep } from "path";
62
+ import { homedir } from "os";
63
+ import { readdir, mkdir, access, readFile, writeFile, unlink } from "fs/promises";
64
+ import { existsSync } from "fs";
65
+ var SAFE_ID = /^[A-Za-z0-9._-]{1,128}$/;
66
+ function assertSafeId(kind, id) {
67
+ if (!SAFE_ID.test(id) || id === "." || id === "..") {
68
+ throw new Error(`Invalid ${kind} id for a vault path: ${JSON.stringify(id)}`);
69
+ }
70
+ }
71
+ function machineRoot() {
72
+ const override = process.env["RUNEYA_HOME"];
73
+ return join(override && override.length > 0 ? override : homedir(), ".runeya");
74
+ }
75
+ function localVaultRoot() {
76
+ return env.DATA_DIR;
77
+ }
78
+ function orgVaultRoot(orgId) {
79
+ assertSafeId("organization", orgId);
80
+ return join(machineRoot(), "orgs", orgId);
81
+ }
82
+ function projectVaultRoot(orgId, projectId) {
83
+ assertSafeId("project", projectId);
84
+ return join(orgVaultRoot(orgId), "projects", projectId);
85
+ }
86
+ function orgIdOfRoot(root) {
87
+ const marker = join(machineRoot(), "orgs") + sep;
88
+ if (!root.startsWith(marker)) return null;
89
+ const [orgId] = root.slice(marker.length).split(sep);
90
+ return orgId && SAFE_ID.test(orgId) ? orgId : null;
91
+ }
92
+ function vaultIdOfRoot(root) {
93
+ return orgIdOfRoot(root) ?? void 0;
94
+ }
95
+ function vaultFor(target) {
96
+ if (!target.orgId) return { root: localVaultRoot() };
97
+ return { root: projectVaultRoot(target.orgId, target.id) };
98
+ }
99
+ var ORG_CLOUD_FILE = "cloud.json";
100
+ async function stampOrgCloud(orgId, cloudUrl, name) {
101
+ const root = orgVaultRoot(orgId);
102
+ await mkdir(root, { recursive: true });
103
+ const known = name ?? (await readOrgNames())[orgId];
104
+ const stamp = known ? { cloudUrl, name: known } : { cloudUrl };
105
+ await writeFile(join(root, ORG_CLOUD_FILE), JSON.stringify(stamp, null, 2), "utf-8");
106
+ }
107
+ async function rememberOrgName(orgId, name) {
108
+ const root = orgVaultRoot(orgId);
109
+ if (!existsSync(root)) return;
110
+ const file = join(root, ORG_CLOUD_FILE);
111
+ let stamp = {};
112
+ try {
113
+ stamp = JSON.parse(await readFile(file, "utf-8"));
114
+ } catch {
115
+ }
116
+ if (stamp["name"] === name) return;
117
+ await writeFile(file, JSON.stringify({ ...stamp, name }, null, 2), "utf-8");
118
+ }
119
+ async function readOrgNames() {
120
+ const out = {};
121
+ for (const orgId of await listOrgVaults()) {
122
+ try {
123
+ const raw = await readFile(join(orgVaultRoot(orgId), ORG_CLOUD_FILE), "utf-8");
124
+ const name = JSON.parse(raw).name;
125
+ if (typeof name === "string" && name) out[orgId] = name;
126
+ } catch {
127
+ }
128
+ }
129
+ return out;
130
+ }
131
+ var ORG_LOGO_FILE = "logo.json";
132
+ var LOGO_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp", "image/gif"]);
133
+ async function rememberOrgLogo(orgId, contentType, base64) {
134
+ if (!LOGO_TYPES.has(contentType)) return;
135
+ const root = orgVaultRoot(orgId);
136
+ const stored = { contentType, base64, fetchedAt: (/* @__PURE__ */ new Date()).toISOString() };
137
+ await mkdir(root, { recursive: true });
138
+ await writeFile(join(root, ORG_LOGO_FILE), JSON.stringify(stored), "utf-8");
139
+ }
140
+ async function forgetOrgLogo(orgId) {
141
+ try {
142
+ await unlink(join(orgVaultRoot(orgId), ORG_LOGO_FILE));
143
+ } catch {
144
+ }
145
+ }
146
+ async function readOrgLogos() {
147
+ const out = {};
148
+ for (const orgId of await listOrgVaults()) {
149
+ try {
150
+ const raw = await readFile(join(orgVaultRoot(orgId), ORG_LOGO_FILE), "utf-8");
151
+ const { contentType, base64 } = JSON.parse(raw);
152
+ if (typeof contentType !== "string" || !LOGO_TYPES.has(contentType)) continue;
153
+ if (typeof base64 !== "string" || !base64) continue;
154
+ out[orgId] = `data:${contentType};base64,${base64}`;
155
+ } catch {
156
+ }
157
+ }
158
+ return out;
159
+ }
160
+ async function readOrgClouds() {
161
+ const orgsDir = join(machineRoot(), "orgs");
162
+ const out = {};
163
+ let orgIds;
164
+ try {
165
+ orgIds = (await readdir(orgsDir, { withFileTypes: true })).filter((e) => e.isDirectory() && SAFE_ID.test(e.name)).map((e) => e.name);
166
+ } catch {
167
+ return out;
168
+ }
169
+ for (const orgId of orgIds) {
170
+ try {
171
+ const raw = await readFile(join(orgsDir, orgId, ORG_CLOUD_FILE), "utf-8");
172
+ const url = JSON.parse(raw).cloudUrl;
173
+ if (typeof url === "string" && url) out[orgId] = url;
174
+ } catch {
175
+ }
176
+ }
177
+ return out;
178
+ }
179
+ async function listOrgVaults() {
180
+ const orgsDir = join(machineRoot(), "orgs");
181
+ try {
182
+ return (await readdir(orgsDir, { withFileTypes: true })).filter((e) => e.isDirectory() && SAFE_ID.test(e.name)).map((e) => e.name);
183
+ } catch {
184
+ return [];
185
+ }
186
+ }
187
+ async function listCloudVaults() {
188
+ const orgsDir = join(machineRoot(), "orgs");
189
+ const found = [];
190
+ let orgIds;
191
+ try {
192
+ orgIds = (await readdir(orgsDir, { withFileTypes: true })).filter((e) => e.isDirectory() && SAFE_ID.test(e.name)).map((e) => e.name);
193
+ } catch {
194
+ return found;
195
+ }
196
+ for (const orgId of orgIds) {
197
+ const projectsDir = join(orgsDir, orgId, "projects");
198
+ try {
199
+ for (const entry of await readdir(projectsDir, { withFileTypes: true })) {
200
+ if (!entry.isDirectory() || !SAFE_ID.test(entry.name)) continue;
201
+ const root = join(projectsDir, entry.name);
202
+ if (!await access(join(root, "project.json")).then(() => true, () => false)) continue;
203
+ found.push({ orgId, projectId: entry.name, root });
204
+ }
205
+ } catch {
206
+ }
207
+ }
208
+ return found;
209
+ }
210
+ async function allVaultRoots() {
211
+ const cloud = await listCloudVaults();
212
+ return [localVaultRoot(), ...cloud.map((v) => v.root)];
213
+ }
214
+ function machineFilePath(filename) {
215
+ return join(machineRoot(), filename);
216
+ }
217
+ async function keyedFilePath(filename) {
218
+ return join(await keyRoot(), filename);
219
+ }
220
+ function legacyMachineFilePath(filename) {
221
+ return join(localVaultRoot(), filename);
222
+ }
223
+ async function ensureLocalVault() {
224
+ const root = localVaultRoot();
225
+ await mkdir(root, { recursive: true });
226
+ return root;
227
+ }
228
+ var KEY_FILES = [".encryption.key.enc", ".runeya-verify"];
229
+ var keyRootPromise = null;
230
+ async function holdsKey(root) {
231
+ for (const filename of KEY_FILES) {
232
+ try {
233
+ await access(join(root, filename));
234
+ return true;
235
+ } catch {
236
+ }
237
+ }
238
+ return false;
239
+ }
240
+ function keyRoot() {
241
+ keyRootPromise ??= (async () => {
242
+ if (await holdsKey(machineRoot())) return machineRoot();
243
+ return await holdsKey(localVaultRoot()) ? localVaultRoot() : machineRoot();
244
+ })();
245
+ return keyRootPromise;
246
+ }
247
+ async function legacyVaultRoot() {
248
+ const local = localVaultRoot();
249
+ if (await keyRoot() === local) return null;
250
+ return await holdsKey(local) ? local : null;
251
+ }
252
+
253
+ // ../../packages/shared/src/schemas/settings.schema.ts
254
+ import { z as z3 } from "zod";
255
+
256
+ // ../../packages/shared/src/schemas/scenario.schema.ts
257
+ import { z as z2 } from "zod";
258
+ var PositionSchema = z2.object({
259
+ x: z2.number(),
260
+ y: z2.number()
261
+ });
262
+ var ScenarioGroupSchema = z2.object({
263
+ id: z2.string().min(1).max(128),
264
+ name: z2.string().min(1).max(200),
265
+ description: z2.string().max(1e3).optional(),
266
+ color: z2.string().max(32).optional(),
267
+ position: PositionSchema.default({ x: 0, y: 0 }),
268
+ width: z2.number().default(300),
269
+ height: z2.number().default(200)
270
+ });
271
+ var ScenarioPresetRoleSchema = z2.object({
272
+ id: z2.string().min(1).max(64),
273
+ name: z2.string().min(1).max(200),
274
+ systemPrompt: z2.string().max(1e4).default(""),
275
+ prompt: z2.string().max(1e4).default("")
276
+ });
277
+ var ScenarioPresetInitialDataSchema = z2.object({
278
+ leaderId: z2.string().min(1).max(128),
279
+ groups: z2.array(z2.object({
280
+ id: z2.string().min(1).max(128),
281
+ name: z2.string().min(1).max(200),
282
+ description: z2.string().max(1e3).optional(),
283
+ color: z2.string().max(32).optional(),
284
+ position: z2.object({ x: z2.number(), y: z2.number() }).default({ x: 0, y: 0 }),
285
+ width: z2.number().default(300),
286
+ height: z2.number().default(200)
287
+ })).max(100).default([]),
288
+ nodes: z2.array(z2.object({
289
+ id: z2.string().min(1).max(128),
290
+ type: z2.enum(["ai", "ask"]).default("ai"),
291
+ parentIds: z2.array(z2.string().max(128)).default([]),
292
+ groupId: z2.string().max(128).nullable().default(null),
293
+ label: z2.string().max(240).default(""),
294
+ role: z2.string().max(64).default("other"),
295
+ prompt: z2.string().max(5e4).default(""),
296
+ question: z2.string().max(2e3).default(""),
297
+ autoGenerated: z2.boolean().default(true),
298
+ canAddNode: z2.boolean().default(false),
299
+ aiCli: z2.enum(["claude-code", "codex"]).default("claude-code"),
300
+ model: z2.string().max(128).default("sonnet"),
301
+ position: z2.object({ x: z2.number(), y: z2.number() }).default({ x: 0, y: 0 })
302
+ })).min(1).max(500)
303
+ });
304
+ var LocalizedStringSchema = z2.record(z2.string(), z2.string().max(100));
305
+ var ScenarioPresetLabelsSchema = z2.object({
306
+ group: LocalizedStringSchema.optional(),
307
+ node: LocalizedStringSchema.optional(),
308
+ role: LocalizedStringSchema.optional(),
309
+ leader: LocalizedStringSchema.optional()
310
+ });
311
+ var ScenarioPresetSchema = z2.object({
312
+ id: z2.string().min(1).max(128),
313
+ name: z2.string().min(1).max(200),
314
+ icon: z2.string().max(64).optional(),
315
+ defaultTraversalMode: z2.enum(["hierarchical", "topological"]).optional(),
316
+ canChangeTraversalMode: z2.boolean().default(true),
317
+ roles: z2.array(ScenarioPresetRoleSchema).min(1).max(100),
318
+ initialData: ScenarioPresetInitialDataSchema.optional(),
319
+ labels: ScenarioPresetLabelsSchema.optional()
320
+ });
321
+ var ScenarioNodeSchema = z2.object({
322
+ id: z2.string().min(1).max(128),
323
+ type: z2.enum(["ai", "ask"]).default("ai"),
324
+ parentIds: z2.array(z2.string().max(128)).default([]),
325
+ groupId: z2.string().max(128).nullable().default(null),
326
+ label: z2.string().max(240).default(""),
327
+ role: z2.string().max(64).default("other"),
328
+ prompt: z2.string().max(5e4).default(""),
329
+ question: z2.string().max(2e3).default(""),
330
+ autoGenerated: z2.boolean().default(true),
331
+ canAddNode: z2.boolean().default(false),
332
+ aiCli: z2.enum(["claude-code", "codex"]).default("claude-code"),
333
+ model: z2.string().max(128).default("sonnet"),
334
+ position: PositionSchema.default({ x: 0, y: 0 }),
335
+ injectParentOutputs: z2.boolean().default(false),
336
+ injectedAncestorIds: z2.array(z2.string().max(128)).default([])
337
+ });
338
+ var ScenarioSchema = z2.object({
339
+ id: z2.string().min(1).max(128),
340
+ name: z2.string().min(1).max(200),
341
+ icon: z2.string().max(64).optional(),
342
+ description: z2.string().max(2e3).optional(),
343
+ leaderId: z2.string().min(1).max(128),
344
+ groups: z2.array(ScenarioGroupSchema).max(100).default([]),
345
+ nodes: z2.array(ScenarioNodeSchema).min(1).max(500),
346
+ traversalMode: z2.enum(["hierarchical", "topological"]).default("hierarchical"),
347
+ presetId: z2.string().max(128).optional(),
348
+ isPublished: z2.boolean().default(false),
349
+ createdAt: z2.number(),
350
+ updatedAt: z2.number()
351
+ });
352
+
353
+ // ../../packages/shared/src/schemas/settings.schema.ts
354
+ var AI_PROVIDERS = ["anthropic", "openai", "mistral", "groq", "ollama"];
355
+ var AIProviderSchema = z3.object({
356
+ id: z3.string().min(1).max(128),
357
+ name: z3.string().min(1).max(200),
358
+ provider: z3.enum(AI_PROVIDERS),
359
+ encryptedApiKey: z3.string().max(2e3).default(""),
360
+ model: z3.string().max(200).optional(),
361
+ active: z3.boolean().default(false),
362
+ createdAt: z3.coerce.date(),
363
+ updatedAt: z3.coerce.date()
364
+ });
365
+ var JSLogParserSchema = z3.object({
366
+ id: z3.string().min(1).max(128),
367
+ name: z3.string().min(1).max(200),
368
+ description: z3.string().max(2e3).optional(),
369
+ code: z3.string().min(1).max(5e4).refine(
370
+ (s) => !s.includes("require(") && !s.includes("import ") && !s.includes("eval("),
371
+ { message: "Code must not contain require, import, or eval patterns" }
372
+ ),
373
+ enabled: z3.boolean().default(true),
374
+ builtin: z3.boolean().optional(),
375
+ createdAt: z3.coerce.date(),
376
+ updatedAt: z3.coerce.date()
377
+ });
378
+ var NotificationPreferencesSchema = z3.object({
379
+ scenario_waiting_input: z3.boolean().default(true),
380
+ ai_conversation_complete: z3.boolean().default(true),
381
+ ai_conversation_error: z3.boolean().default(true),
382
+ service_error_log: z3.boolean().default(true),
383
+ service_status_changed: z3.boolean().default(true),
384
+ service_health_changed: z3.boolean().default(true),
385
+ /** Service IDs excluded from error-log notifications */
386
+ service_error_log_excluded: z3.array(z3.string().max(100)).max(500).default([]),
387
+ /** Service IDs excluded from status-change notifications */
388
+ service_status_changed_excluded: z3.array(z3.string().max(100)).max(500).default([]),
389
+ /** Service IDs excluded from health-change notifications */
390
+ service_health_changed_excluded: z3.array(z3.string().max(100)).max(500).default([])
391
+ });
392
+ var CompanionSettingsSchema = z3.object({
393
+ /** Activer le compagnon d'office sur les conversations créées ensuite. */
394
+ enabledByDefault: z3.boolean().default(false),
395
+ /**
396
+ * Consignes envoyées au compagnon, à la place des nôtres.
397
+ *
398
+ * Vide — l'absence — signifie « celles de Runeya ». On ne recopie pas le
399
+ * texte par défaut dans le réglage : figé le jour où il est enregistré, il ne
400
+ * profiterait plus jamais des corrections apportées au nôtre.
401
+ *
402
+ * Rejeté au-delà de la borne plutôt que tronqué (§1) : un prompt coupé en
403
+ * plein milieu produirait des relectures incohérentes sans rien signaler.
404
+ */
405
+ prompt: z3.string().max(2e4).optional()
406
+ });
407
+ var SettingsSchema = z3.object({
408
+ mode: z3.enum(["local-simple", "cloud"]),
409
+ cloudUrl: z3.string().url().max(2048).nullable().optional(),
410
+ logParsers: z3.array(JSLogParserSchema).max(100).default([]),
411
+ scenarios: z3.array(ScenarioSchema).max(100).default([]),
412
+ /** Absolute path to the folder where the global wiki/docs markdown files live. Optional. */
413
+ globalDocsPath: z3.string().max(4096).optional(),
414
+ /**
415
+ * Optionnel plutôt que défauté : un réglage absent est un réglage jamais
416
+ * touché, et le rendre obligatoire dans le type forcerait chaque appelant qui
417
+ * construit un objet de réglages à inventer une valeur.
418
+ */
419
+ companion: CompanionSettingsSchema.optional()
420
+ });
421
+ var TraefikConfigSchema = z3.object({
422
+ enabled: z3.boolean().default(false),
423
+ acmeEmail: z3.string().email().max(256).optional(),
424
+ wildcardDomain: z3.string().max(253).optional(),
425
+ httpPort: z3.number().int().min(1).max(65535).default(80),
426
+ httpsPort: z3.number().int().min(1).max(65535).default(443),
427
+ dnsProvider: z3.string().max(64).optional(),
428
+ dnsCredentials: z3.record(z3.string().max(64), z3.string().max(2048)).default({}),
429
+ acmeStaging: z3.boolean().default(false),
430
+ encryptedCert: z3.string().max(65536).optional(),
431
+ encryptedCertKey: z3.string().max(65536).optional()
432
+ });
433
+ var SettingsPrivateSchema = z3.object({
434
+ aiProviders: z3.array(AIProviderSchema).max(50).default([]),
435
+ scenarios: z3.array(ScenarioSchema).max(100).default([]),
436
+ notifications: NotificationPreferencesSchema.default(() => ({
437
+ scenario_waiting_input: true,
438
+ ai_conversation_complete: true,
439
+ ai_conversation_error: true,
440
+ service_error_log: true,
441
+ service_status_changed: true,
442
+ service_health_changed: true,
443
+ service_error_log_excluded: [],
444
+ service_status_changed_excluded: [],
445
+ service_health_changed_excluded: []
446
+ })),
447
+ traefikConfig: TraefikConfigSchema.optional()
448
+ });
449
+ var SchemaVersionSchema = z3.object({
450
+ version: z3.number().int().positive(),
451
+ migratedAt: z3.coerce.date()
452
+ });
453
+
454
+ // ../../packages/shared/src/utils/companion-markers.ts
455
+ var COMPANION_RELAY_OPEN = "[RUNEYA_COMPAGNON_RESPONSE]";
456
+ var COMPANION_RELAY_CLOSE = "[/RUNEYA_COMPAGNON_RESPONSE]";
457
+ function extractCompanionRelay(raw) {
458
+ const text = (raw ?? "").trim();
459
+ const open = text.lastIndexOf(COMPANION_RELAY_OPEN);
460
+ if (open === -1) return null;
461
+ const after = text.slice(open + COMPANION_RELAY_OPEN.length);
462
+ const close = after.indexOf(COMPANION_RELAY_CLOSE);
463
+ const inner = (close === -1 ? after : after.slice(0, close)).trim();
464
+ return inner || null;
465
+ }
466
+
467
+ // ../../packages/shared/src/constants/intervals.ts
468
+ var AGENT_HEALTH_POLL_INTERVAL = 15e3;
469
+
470
+ // ../../packages/shared/src/constants/timeouts.ts
471
+ var GRACE_PERIOD = 1e4;
472
+ var AGENT_FETCH_TIMEOUT = 1e4;
473
+ var AGENT_LONG_FETCH_TIMEOUT = 6e5;
474
+ var AGENT_STOP_FETCH_TIMEOUT = GRACE_PERIOD + 15e3;
475
+ var PASSPHRASE_TIMEOUT = 3e4;
476
+ var WS_RECONNECT_MIN = 1e3;
477
+ var WS_RECONNECT_MAX = 15e3;
478
+
479
+ // ../../packages/shared/src/schemas/user.schema.ts
480
+ import { z as z4 } from "zod";
481
+ var UserSchema = z4.object({
482
+ id: z4.string().max(128),
483
+ email: z4.string().email().max(320),
484
+ name: z4.string().min(1).max(500),
485
+ avatar: z4.string().url().max(2048).nullable().optional()
486
+ });
487
+
488
+ // ../../packages/shared/src/schemas/org.schema.ts
489
+ import { z as z5 } from "zod";
490
+ var OrgSchema = z5.object({
491
+ id: z5.string().max(128),
492
+ name: z5.string().min(1).max(100),
493
+ slug: z5.string().min(1).max(100).regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/),
494
+ ownerId: z5.string().max(128)
495
+ });
496
+ var OrgMemberSchema = z5.object({
497
+ id: z5.string().max(128),
498
+ orgId: z5.string().max(128),
499
+ userId: z5.string().max(128),
500
+ globalRole: z5.enum(["owner", "admin", "member"]),
501
+ invitedAt: z5.coerce.date(),
502
+ joinedAt: z5.coerce.date().nullable().optional()
503
+ });
504
+
505
+ // ../../packages/shared/src/schemas/project.schema.ts
506
+ import { z as z6 } from "zod";
507
+ var ProjectSchema = z6.object({
508
+ id: z6.string().max(128),
509
+ orgId: z6.string().max(128).nullable().optional(),
510
+ name: z6.string().min(1).max(200),
511
+ description: z6.string().max(1e4).optional().default(""),
512
+ serviceIds: z6.array(z6.string().max(128)).max(1e4).default([]),
513
+ // Environment support
514
+ // NOTE: activeEnvironmentId is runtime-only (not persisted to JSON)
515
+ // It's initialized to 'local' by default at load time
516
+ activeEnvironmentId: z6.string().max(128).optional(),
517
+ environmentIds: z6.array(z6.string().max(128)).max(100).default([]),
518
+ // Ordre d'affichage des groupes de services dans la sidebar (noms de groupes).
519
+ // Les groupes absents de cette liste sont affichés après, par ordre alphabétique.
520
+ groupOrder: z6.array(z6.string().max(200)).max(100).default([])
521
+ });
522
+ var CreateProjectSchema = ProjectSchema.omit({ id: true }).partial().required({ name: true });
523
+ var UpdateProjectSchema = ProjectSchema.partial().required({ id: true });
524
+
525
+ // ../../packages/shared/src/schemas/service.schema.ts
526
+ import { z as z8 } from "zod";
527
+
528
+ // ../../packages/shared/src/schemas/log-source.schema.ts
529
+ import { z as z7 } from "zod";
530
+ var safePath = z7.string().min(1).max(4096).refine(
531
+ (p) => !p.includes("\0"),
532
+ { message: "path must not contain null bytes" }
533
+ ).refine(
534
+ (p) => !/(^|[/\\])\.\.([/\\]|$)/.test(p),
535
+ { message: "path must not contain path-traversal sequences (..)" }
536
+ );
537
+ var ConsoleLogSourceSchema = z7.object({
538
+ type: z7.literal("console")
539
+ });
540
+ var FileLogSourceSchema = z7.object({
541
+ type: z7.literal("file"),
542
+ path: safePath,
543
+ encoding: z7.string().max(32).default("utf-8"),
544
+ startFromEnd: z7.boolean().default(true),
545
+ createIfNotExists: z7.boolean().default(false)
546
+ });
547
+ var MongoLogSourceSchema = z7.object({
548
+ type: z7.literal("mongo"),
549
+ /** @sensitive — stored encrypted (AES-256-GCM) on disk */
550
+ connectionString: z7.string().min(1).max(2048),
551
+ database: z7.string().min(1).max(256),
552
+ collection: z7.string().min(1).max(256),
553
+ filter: z7.record(z7.string(), z7.unknown()).optional(),
554
+ timestampField: z7.string().max(128).default("timestamp"),
555
+ messageField: z7.string().max(128).default("message"),
556
+ levelField: z7.string().max(128).optional()
557
+ });
558
+ var MySQLLogSourceSchema = z7.object({
559
+ type: z7.literal("mysql"),
560
+ host: z7.string().min(1).max(253),
561
+ port: z7.number().int().min(1).max(65535).default(3306),
562
+ user: z7.string().min(1).max(256),
563
+ /** @sensitive — stored encrypted (AES-256-GCM) on disk */
564
+ password: z7.string().max(2048),
565
+ database: z7.string().min(1).max(256),
566
+ table: z7.string().min(1).max(256),
567
+ query: z7.string().max(8192).optional(),
568
+ timestampColumn: z7.string().max(128).default("created_at"),
569
+ messageColumn: z7.string().max(128).default("message"),
570
+ levelColumn: z7.string().max(128).optional(),
571
+ pollIntervalMs: z7.number().int().min(500).max(6e4).default(2e3)
572
+ });
573
+ var LogSourceConfigSchema = z7.discriminatedUnion("type", [
574
+ ConsoleLogSourceSchema,
575
+ FileLogSourceSchema,
576
+ MongoLogSourceSchema,
577
+ MySQLLogSourceSchema
578
+ ]);
579
+
580
+ // ../../packages/shared/src/schemas/service.schema.ts
581
+ var HealthCheckSchema = z8.object({
582
+ type: z8.enum(["http", "command"]).default("http"),
583
+ // HTTP-specific (required when type=http)
584
+ path: z8.string().min(1).max(500).startsWith("/").optional(),
585
+ method: z8.enum(["GET", "HEAD", "POST", "PUT"]).optional().default("GET"),
586
+ expectedStatus: z8.number().int().min(100).max(599).optional().default(200),
587
+ // Command-specific (required when type=command)
588
+ command: z8.string().min(1).max(4096).optional(),
589
+ // Shared
590
+ interval: z8.number().int().positive().default(1e3),
591
+ timeout: z8.number().int().positive().default(1e3),
592
+ retries: z8.number().int().nonnegative().default(3),
593
+ initialDelay: z8.number().int().nonnegative().optional().default(0)
594
+ }).refine(
595
+ (data) => data.type === "http" ? !!data.path : !!data.command,
596
+ { message: "HTTP type requires path; command type requires command" }
597
+ );
598
+ var BootstrapCommandSchema = z8.object({
599
+ id: z8.string().min(1).max(64),
600
+ label: z8.string().max(200).default(""),
601
+ entrypoint: z8.string().max(4096).optional(),
602
+ command: z8.string().max(4096).default(""),
603
+ user: z8.string().max(256).optional()
604
+ });
605
+ var DockerConfigSchema = z8.object({
606
+ // Image mode (pull from registry) — mutually exclusive with build mode in UI
607
+ image: z8.string().min(1).max(1024).optional(),
608
+ // Build mode — Dockerfile stored inline in services.json
609
+ dockerfile: z8.string().max(65536).optional(),
610
+ buildContext: z8.string().max(4096).optional(),
611
+ buildArgs: z8.record(z8.string().max(256), z8.string().max(4096)).default({}).refine(
612
+ (obj) => Object.keys(obj).length <= 50,
613
+ { message: "Max 50 build args" }
614
+ ),
615
+ targetStage: z8.string().max(256).optional(),
616
+ // Runtime config
617
+ networkMode: z8.enum(["host", "bridge"]).default("host"),
618
+ ports: z8.array(z8.string().max(64)).max(100).default([]),
619
+ volumes: z8.array(z8.string().max(1024)).max(100).default([]),
620
+ mountRootpath: z8.boolean().default(false),
621
+ entrypoint: z8.string().max(4096).optional(),
622
+ command: z8.string().max(4096).optional(),
623
+ user: z8.string().max(256).optional(),
624
+ useNativeCommand: z8.boolean().default(false),
625
+ nativeCommandMode: z8.enum(["shared", "isolated"]).default("isolated"),
626
+ nativeShell: z8.string().max(256).default("sh"),
627
+ bootstrapCommands: z8.array(BootstrapCommandSchema).max(20).default([])
628
+ });
629
+ var RestartStrategySchema = z8.enum(["none", "on-failure", "always", "unless-stopped"]).default("none");
630
+ var ServiceShortcutSchema = z8.object({
631
+ id: z8.string().min(1).max(64),
632
+ label: z8.string().max(200).default(""),
633
+ command: z8.string().max(4096).default(""),
634
+ cwd: z8.string().max(4096).optional()
635
+ });
636
+ var ServiceCommandSchema = z8.object({
637
+ id: z8.string().min(1).max(64),
638
+ label: z8.string().max(200).default(""),
639
+ command: z8.string().max(4096).default(""),
640
+ cwd: z8.string().max(4096).optional(),
641
+ shell: z8.boolean().optional().default(true)
642
+ });
643
+ var VariableSlotSchema = z8.object({
644
+ value: z8.string().max(8192).default(""),
645
+ pre: z8.string().max(8192).default(""),
646
+ post: z8.string().max(8192).default(""),
647
+ isSecret: z8.boolean().default(false),
648
+ // When true, this variable is injected into the process environment of AI
649
+ // agents (Claude Code, Codex, …) spawned while this environment is active.
650
+ // Opt-in: defaults to false so secrets are never leaked to AI agents by default.
651
+ injectIntoAi: z8.boolean().default(false)
652
+ });
653
+ var VariableSchema = z8.object({
654
+ key: z8.string().min(1).max(256),
655
+ value: VariableSlotSchema
656
+ });
657
+ var VariablesRecordSchema = z8.record(
658
+ z8.string().max(128),
659
+ VariableSchema
660
+ ).refine(
661
+ (obj) => Object.keys(obj).length <= 200,
662
+ { message: "Max 200 variables" }
663
+ );
664
+ var VariableSlotsRecordSchema = z8.record(
665
+ z8.string().max(256),
666
+ VariableSlotSchema
667
+ ).refine(
668
+ (obj) => Object.keys(obj).length <= 200,
669
+ { message: "Max 200 variable slots" }
670
+ );
671
+ var ServiceConfigSchema = z8.object({
672
+ id: z8.string().max(128),
673
+ orgId: z8.string().max(128).nullable().optional(),
674
+ agentId: z8.string().max(128).optional(),
675
+ // Optional: if absent, inherited from active environment's agentId
676
+ name: z8.string().min(1).max(200),
677
+ commands: z8.array(ServiceCommandSchema).max(50).optional().default([]),
678
+ cwd: z8.string().max(4096).optional(),
679
+ ports: z8.array(z8.number().int().positive().max(65535)).max(20).optional().default([]),
680
+ // Metadata fields (migration from old Runeya)
681
+ groups: z8.array(z8.string().max(200)).max(20).optional().default([]),
682
+ description: z8.string().max(2e3).optional(),
683
+ /** Path (relative to service.cwd or absolute) where the service's docs/wiki markdown files live. Optional — defaults to service.cwd. */
684
+ docsPath: z8.string().max(4096).optional(),
685
+ url: z8.string().max(2048).optional(),
686
+ localUrls: z8.array(z8.object({
687
+ url: z8.string().max(253).regex(/^([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$/),
688
+ port: z8.number().int().min(1).max(65535)
689
+ })).max(20).optional().default([]),
690
+ openapiUrl: z8.string().max(2048).optional(),
691
+ git: z8.object({
692
+ remote: z8.string().max(2048).optional(),
693
+ home: z8.string().max(2048).optional()
694
+ }).optional(),
695
+ meta: z8.record(z8.string().max(256), z8.string().max(2e3)).optional().refine((obj) => !obj || Object.keys(obj).length <= 100, { message: "Too many meta keys (max 100)" }),
696
+ // Transient env dict (resolved by server before deployment, used directly by agent runner — NOT persisted)
697
+ env: z8.record(z8.string().max(256), z8.string().max(8192)).default({}).refine(
698
+ (obj) => Object.keys(obj).length <= 200,
699
+ { message: "Too many env vars (max 200)" }
700
+ ),
701
+ envSecrets: z8.array(z8.string().max(256)).max(200).default([]),
702
+ // Transient: resolved JS log parsers (from parserIds, resolved by server before deployment — NOT persisted)
703
+ resolvedLogParsers: z8.array(JSLogParserSchema).default([]).optional(),
704
+ // Transient: resolved working directory (cwd with env vars expanded — NOT persisted)
705
+ resolvedCwd: z8.string().optional(),
706
+ runner: z8.enum(["native", "docker"]).optional().default("native"),
707
+ dockerConfig: DockerConfigSchema.optional(),
708
+ healthCheck: HealthCheckSchema.optional(),
709
+ parserIds: z8.array(z8.string().max(128)).max(50).default([]),
710
+ shortcuts: z8.array(ServiceShortcutSchema).max(50).optional().default([]),
711
+ autoRestart: z8.boolean().optional().default(false),
712
+ clearLogsOnStart: z8.boolean().optional().default(false),
713
+ restartStrategy: RestartStrategySchema.optional(),
714
+ maxRestarts: z8.number().int().nonnegative().optional(),
715
+ restartBackoffMs: z8.number().int().positive().optional().default(1e3),
716
+ // Log sources additionnelles (au-delà du stdout/stderr console par défaut)
717
+ logSources: z8.array(LogSourceConfigSchema).max(20).optional().default([])
718
+ });
719
+ var CreateServiceSchema = ServiceConfigSchema.omit({ id: true }).partial().required({ name: true });
720
+ var UpdateServiceSchema = ServiceConfigSchema.partial().required({ id: true }).extend({
721
+ agentId: z8.string().max(128).nullable().optional(),
722
+ // null = clear (inherit from env), undefined = no change
723
+ cwd: z8.string().max(4096).nullable().optional(),
724
+ git: z8.object({ remote: z8.string().max(2048).optional(), home: z8.string().max(2048).optional() }).nullable().optional(),
725
+ meta: z8.record(z8.string().max(256), z8.string().max(2e3)).nullable().optional().refine((obj) => !obj || Object.keys(obj).length <= 100, { message: "Too many meta keys (max 100)" }),
726
+ healthCheck: HealthCheckSchema.nullable().optional()
727
+ });
728
+
729
+ // ../../packages/shared/src/schemas/process.schema.ts
730
+ import { z as z9 } from "zod";
731
+ var ProcessStateSchema = z9.enum(["starting", "running", "stopped", "errored"]);
732
+ var HealthStatusSchema = z9.enum(["healthy", "unhealthy", "unknown"]);
733
+ var ProcessStatusSchema = z9.object({
734
+ id: z9.string().max(128),
735
+ serviceId: z9.string().max(128),
736
+ agentId: z9.string().max(128),
737
+ state: ProcessStateSchema,
738
+ pid: z9.number().int().nullable().optional(),
739
+ pids: z9.array(z9.number().int()).optional().default([]),
740
+ exitCode: z9.number().int().nullable().optional(),
741
+ startedAt: z9.coerce.date().nullable().optional(),
742
+ restartCount: z9.number().int().nonnegative().default(0),
743
+ uptime: z9.number().nonnegative().default(0),
744
+ healthStatus: HealthStatusSchema.default("unknown"),
745
+ /**
746
+ * Le répertoire où le processus s'exécute VRAIMENT, absolutisé par l'agent.
747
+ *
748
+ * Rapporté par l'agent plutôt que déduit de la config : entre le `cwd` de la
749
+ * commande, celui du service, l'ancrage sur le projet et les variables que
750
+ * l'agent étend lui-même, la valeur affichée n'aurait rien prouvé. Ce qui
751
+ * intéresse quand un service tourne contre le mauvais dépôt, c'est le chemin
752
+ * final — y compris quand il retombe sur le répertoire de l'agent.
753
+ */
754
+ cwd: z9.string().max(4096).nullable().optional()
755
+ });
756
+
757
+ // ../../packages/shared/src/schemas/log.schema.ts
758
+ import { z as z10 } from "zod";
759
+ var LogLevelSchema = z10.enum(["debug", "info", "warn", "error", "fatal"]);
760
+ var LogLineSchema = z10.object({
761
+ /** Raw log line as received from the process (immutable context) */
762
+ raw: z10.string(),
763
+ /** Source stream (immutable context) */
764
+ stream: z10.enum(["stdout", "stderr"]),
765
+ /** Severity level */
766
+ level: LogLevelSchema,
767
+ /** Parsed/enriched message to display */
768
+ message: z10.string(),
769
+ /** When true, the line is hidden from the log view */
770
+ hidden: z10.boolean(),
771
+ /** Arbitrary key/value pairs shown in the detail panel */
772
+ metadata: z10.record(z10.string().max(256), z10.unknown()).refine(
773
+ (obj) => Object.keys(obj).length <= 100,
774
+ { message: "Too many metadata keys (max 100)" }
775
+ ),
776
+ /** Full parsed JSON object when the line is JSON */
777
+ json: z10.record(z10.string(), z10.unknown()).optional(),
778
+ /** Custom header for the JSON log card (supports HTML, sanitized before display) */
779
+ jsonHeader: z10.string().max(256).optional()
780
+ });
781
+ var LogCardDirectiveSchema = z10.object({
782
+ id: z10.string().max(128),
783
+ type: z10.string().max(64),
784
+ header: z10.string().max(256),
785
+ collapsable: z10.boolean().optional(),
786
+ collapsed: z10.boolean().optional(),
787
+ state: z10.enum(["open", "append", "close", "self"])
788
+ });
789
+ var ParsedLogSchema = z10.object({
790
+ id: z10.string().max(128),
791
+ processId: z10.string().max(128),
792
+ pid: z10.number().int().nullable().optional(),
793
+ timestamp: z10.coerce.date(),
794
+ level: LogLevelSchema.default("info"),
795
+ message: z10.string().max(16384),
796
+ raw: z10.string().max(16384),
797
+ stream: z10.enum(["stdout", "stderr"]).default("stdout"),
798
+ hidden: z10.boolean().optional().default(false),
799
+ metadata: z10.record(z10.string().max(256), z10.unknown()).optional().refine(
800
+ (obj) => !obj || Object.keys(obj).length <= 100,
801
+ { message: "Too many metadata keys (max 100)" }
802
+ ),
803
+ json: z10.record(z10.string(), z10.unknown()).optional(),
804
+ logCard: LogCardDirectiveSchema.optional(),
805
+ sourceType: z10.enum(["console", "file", "mongo", "mysql"]).optional(),
806
+ sourcePath: z10.string().max(4096).optional()
807
+ });
808
+
809
+ // ../../packages/shared/src/schemas/agent.schema.ts
810
+ import { z as z11 } from "zod";
811
+ var ENV_VAR_NAME_REGEX = /^[A-Za-z_][A-Za-z0-9_]*$/;
812
+ var AgentConfigSchema = z11.object({
813
+ id: z11.string().max(128),
814
+ name: z11.string().min(1).max(100),
815
+ url: z11.string().url().max(2048),
816
+ passphrase: z11.string().min(1).max(1024),
817
+ passthroughEnv: z11.array(
818
+ z11.string().regex(ENV_VAR_NAME_REGEX).max(256)
819
+ ).max(100).default([])
820
+ });
821
+ var AgentStatusSchema = z11.object({
822
+ connected: z11.boolean(),
823
+ lastSeen: z11.string().nullable().optional(),
824
+ uptime: z11.number().nonnegative().default(0),
825
+ runnersAvailable: z11.array(z11.enum(["native", "docker"])).default(["native"]),
826
+ lanIp: z11.string().optional(),
827
+ /**
828
+ * Ce que la machine de l'agent vaut pour les builtins de portée `agent`.
829
+ * Sert à PRÉVISUALISER — la valeur injectée reste calculée au lancement, par
830
+ * l'agent lui-même : une IP change, un agent se déconnecte, et un statut
831
+ * n'est qu'un cliché.
832
+ */
833
+ os: z11.string().max(64).optional(),
834
+ home: z11.string().max(4096).optional(),
835
+ cwd: z11.string().max(4096).optional()
836
+ });
837
+
838
+ // ../../packages/shared/src/schemas/permission.schema.ts
839
+ import { z as z12 } from "zod";
840
+ var GlobalRoleSchema = z12.enum(["owner", "admin", "member"]);
841
+ var ProjectRoleSchema = z12.enum(["admin", "editor", "viewer"]);
842
+ var ProjectMemberRoleSchema = z12.object({
843
+ id: z12.string().max(128),
844
+ projectId: z12.string().max(128),
845
+ userId: z12.string().max(128),
846
+ role: ProjectRoleSchema
847
+ });
848
+
849
+ // ../../packages/shared/src/schemas/sync.schema.ts
850
+ import { z as z13 } from "zod";
851
+ var ConfigVersionSchema = z13.object({
852
+ id: z13.string().max(128),
853
+ entityType: z13.enum(["project", "service"]),
854
+ entityId: z13.string().max(128),
855
+ version: z13.string().max(128),
856
+ parentVersion: z13.string().max(128),
857
+ data: z13.record(z13.string(), z13.unknown()).refine(
858
+ (obj) => Object.keys(obj).length <= 1e3,
859
+ "Too many data keys (max 1000)"
860
+ ),
861
+ patch: z13.array(z13.record(z13.string(), z13.unknown())).max(1e3),
862
+ userId: z13.string().max(128),
863
+ timestamp: z13.coerce.date(),
864
+ resolved: z13.boolean().default(false)
865
+ });
866
+ var ConfigChangeSchema = z13.object({
867
+ entityType: z13.enum(["project", "service"]),
868
+ entityId: z13.string().max(128),
869
+ version: z13.string().max(128),
870
+ parentVersion: z13.string().max(128),
871
+ data: z13.record(z13.string(), z13.unknown()).refine(
872
+ (obj) => Object.keys(obj).length <= 1e3,
873
+ "Too many data keys (max 1000)"
874
+ ),
875
+ patch: z13.array(z13.record(z13.string(), z13.unknown())).max(1e3)
876
+ });
877
+ var SyncStatusSchema = z13.object({
878
+ connected: z13.boolean(),
879
+ lastSync: z13.coerce.date().nullable().optional(),
880
+ pendingChanges: z13.number().int().nonnegative().default(0),
881
+ conflicts: z13.number().int().nonnegative().default(0)
882
+ });
883
+
884
+ // ../../packages/shared/src/schemas/audit.schema.ts
885
+ import { z as z14 } from "zod";
886
+ var AuditActionSchema = z14.enum([
887
+ "create",
888
+ "update",
889
+ "delete",
890
+ "invite",
891
+ "remove",
892
+ "deploy",
893
+ "start",
894
+ "stop",
895
+ "roleChange"
896
+ ]);
897
+ var AuditEntityTypeSchema = z14.enum([
898
+ "org",
899
+ "project",
900
+ "service",
901
+ "member",
902
+ "permission"
903
+ ]);
904
+ var AuditLogSchema = z14.object({
905
+ id: z14.string().max(128),
906
+ orgId: z14.string().max(128),
907
+ userId: z14.string().max(128),
908
+ action: AuditActionSchema,
909
+ entityType: AuditEntityTypeSchema,
910
+ entityId: z14.string().max(128),
911
+ metadata: z14.record(z14.string().max(256), z14.unknown()).default({}).refine(
912
+ (obj) => Object.keys(obj).length <= 100,
913
+ { message: "Too many metadata keys (max 100)" }
914
+ ),
915
+ timestamp: z14.coerce.date()
916
+ });
917
+
918
+ // ../../packages/shared/src/schemas/metrics.schema.ts
919
+ import { z as z15 } from "zod";
920
+ var ProcessMetricsSchema = z15.object({
921
+ processId: z15.string().max(128),
922
+ cpu: z15.number().nonnegative(),
923
+ memory: z15.number().int().nonnegative(),
924
+ timestamp: z15.string()
925
+ });
926
+
927
+ // ../../packages/shared/src/schemas/environment.schema.ts
928
+ import { z as z16 } from "zod";
929
+ var EnvironmentVariablesSchema = z16.record(
930
+ z16.string().max(256),
931
+ VariableSchema
932
+ ).refine(
933
+ (obj) => Object.keys(obj).length <= 200,
934
+ { message: "Max 200 variables" }
935
+ );
936
+ var EnvironmentSchema = z16.object({
937
+ id: z16.string().max(128),
938
+ projectId: z16.string().max(128),
939
+ name: z16.string().min(1).max(200),
940
+ description: z16.string().max(2e3).optional().default(""),
941
+ parentIds: z16.array(z16.string().max(128)).max(10).default([]),
942
+ variables: EnvironmentVariablesSchema.default({}),
943
+ // Scope: 'global' = project-level env, 'service' = per-service env
944
+ scope: z16.enum(["global", "service"]).default("global"),
945
+ // When scope='service': the serviceId this env belongs to
946
+ reference: z16.string().max(128).optional(),
947
+ // When scope='service': the globalEnvId this env activates on
948
+ activateOn: z16.string().max(128).optional(),
949
+ immutable: z16.boolean().default(false),
950
+ default: z16.boolean().optional().default(false),
951
+ color: z16.string().max(20).optional(),
952
+ bgColor: z16.string().max(20).optional(),
953
+ // When scope='global': the default agent used by services that don't have an explicit agentId
954
+ agentId: z16.string().max(128).optional()
955
+ });
956
+ var ResolvedEnvironmentSchema = z16.object({
957
+ variables: z16.record(z16.string().max(256), VariableSchema).refine((obj) => Object.keys(obj).length <= 500, { message: "Max 500 resolved variables" }),
958
+ env: z16.record(z16.string().max(256), z16.string().max(8192)).refine((obj) => Object.keys(obj).length <= 500, { message: "Max 500 resolved env vars" }),
959
+ envSecrets: z16.array(z16.string().max(256)).max(500),
960
+ sources: z16.record(z16.string().max(256), z16.object({
961
+ environmentId: z16.string().max(128),
962
+ environmentName: z16.string().max(200),
963
+ overridden: z16.boolean(),
964
+ resolvedFrom: z16.object({
965
+ environmentId: z16.string().max(128),
966
+ environmentName: z16.string().max(200)
967
+ }).optional(),
968
+ // Set when a machine-local override was applied to this variable, pointing
969
+ // at the environment that carries the winning override. Distinct from
970
+ // `overridden`, which also covers "shadows an inherited variable".
971
+ overriddenBy: z16.object({
972
+ environmentId: z16.string().max(128),
973
+ environmentName: z16.string().max(200)
974
+ }).optional()
975
+ })).refine((obj) => Object.keys(obj).length <= 500, { message: "Max 500 source entries" })
976
+ });
977
+ var CreateEnvironmentSchema = EnvironmentSchema.omit({ id: true }).extend({
978
+ description: z16.string().max(2e3).optional().default(""),
979
+ parentIds: z16.array(z16.string().max(128)).max(10).optional().default([]),
980
+ variables: EnvironmentVariablesSchema.optional().default({}),
981
+ scope: z16.enum(["global", "service"]).optional().default("global"),
982
+ reference: z16.string().max(128).optional(),
983
+ activateOn: z16.string().max(128).optional(),
984
+ immutable: z16.boolean().optional().default(false)
985
+ });
986
+ var UpdateEnvironmentSchema = EnvironmentSchema.partial().required({ id: true }).extend({
987
+ description: z16.string().max(2e3).optional(),
988
+ parentIds: z16.array(z16.string().max(128)).max(10).optional(),
989
+ variables: EnvironmentVariablesSchema.optional(),
990
+ scope: z16.enum(["global", "service"]).optional(),
991
+ immutable: z16.boolean().optional(),
992
+ default: z16.boolean().optional(),
993
+ agentId: z16.string().max(128).nullable().optional()
994
+ // null = clear (no default agent)
995
+ });
996
+
997
+ // ../../packages/shared/src/schemas/environment-overrides.schema.ts
998
+ import { z as z17 } from "zod";
999
+ var VariableOverrideSchema = z17.object({
1000
+ value: VariableSlotSchema
1001
+ });
1002
+ var EnvironmentOverridesSchema = z17.record(
1003
+ z17.string().max(128),
1004
+ VariableOverrideSchema
1005
+ ).refine(
1006
+ (obj) => Object.keys(obj).length <= 5e3,
1007
+ { message: "Max 5000 overrides" }
1008
+ );
1009
+
1010
+ // ../../packages/shared/src/schemas/api-key.schema.ts
1011
+ import { z as z18 } from "zod";
1012
+ var ApiServiceActionSchema = z18.enum([
1013
+ "service:read",
1014
+ "service:start",
1015
+ "service:stop",
1016
+ "service:restart",
1017
+ "service:healthcheck",
1018
+ "service:status",
1019
+ "logs:read"
1020
+ ]);
1021
+ var ApiEnvActionSchema = z18.enum(["env:read", "env:write"]);
1022
+ var ApiEnvPermSchema = z18.object({
1023
+ environmentId: z18.string().max(128),
1024
+ actions: z18.array(ApiEnvActionSchema).max(10).default(["env:read"]),
1025
+ includeSecrets: z18.boolean().default(false)
1026
+ });
1027
+ var ApiServicePermSchema = z18.object({
1028
+ serviceId: z18.string().max(128),
1029
+ actions: z18.array(ApiServiceActionSchema).max(10).default(["service:read"]),
1030
+ environments: z18.array(ApiEnvPermSchema).max(100).default([])
1031
+ });
1032
+ var ApiKeyScopeSchema = z18.object({
1033
+ services: z18.array(ApiServicePermSchema).max(500).default([])
1034
+ });
1035
+ var ApiKeySchema = z18.object({
1036
+ id: z18.string().max(128),
1037
+ name: z18.string().min(1).max(200),
1038
+ key: z18.string().regex(/^[0-9a-f]{64}$/i),
1039
+ scopes: ApiKeyScopeSchema,
1040
+ createdAt: z18.string().max(64),
1041
+ isPublic: z18.boolean().default(false)
1042
+ });
1043
+ var PersistedApiKeySchema = ApiKeySchema.extend({
1044
+ key: z18.string().min(1).max(4096)
1045
+ });
1046
+ var ApiKeysFileSchema = z18.object({
1047
+ keys: z18.array(PersistedApiKeySchema).max(100)
1048
+ });
1049
+ var MaskedApiKeySchema = ApiKeySchema.omit({ key: true }).extend({
1050
+ /** Last 4 characters of the secret, for recognising a key in a list. */
1051
+ keyPreview: z18.string().max(8)
1052
+ });
1053
+
1054
+ // ../../packages/shared/src/schemas/image.schema.ts
1055
+ import { z as z19 } from "zod";
1056
+ var ALLOWED_IMAGE_MIME_TYPES = ["image/png", "image/jpeg", "image/webp", "image/gif"];
1057
+ var ImagePartSchema = z19.object({
1058
+ type: z19.literal("image"),
1059
+ imageId: z19.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "Must be a valid UUID"),
1060
+ url: z19.string().min(1),
1061
+ mimeType: z19.enum(ALLOWED_IMAGE_MIME_TYPES),
1062
+ altText: z19.string().max(500).optional()
1063
+ });
1064
+ var ImageUploadResponseSchema = z19.object({
1065
+ imageId: z19.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "Must be a valid UUID"),
1066
+ url: z19.string().min(1),
1067
+ mimeType: z19.enum(ALLOWED_IMAGE_MIME_TYPES),
1068
+ originalName: z19.string()
1069
+ });
1070
+ var ImageMetaSchema = z19.object({
1071
+ imageId: z19.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "Must be a valid UUID"),
1072
+ filePath: z19.string().min(1),
1073
+ mimeType: z19.enum(ALLOWED_IMAGE_MIME_TYPES),
1074
+ originalName: z19.string().min(1),
1075
+ createdAt: z19.number().positive(),
1076
+ size: z19.number().positive().optional()
1077
+ });
1078
+
1079
+ // ../../packages/shared/src/schemas/kanban.schema.ts
1080
+ import { z as z20 } from "zod";
1081
+ var KanbanAttachmentSchema = z20.object({
1082
+ /** Server-issued id, also the storage key. */
1083
+ id: z20.string().max(128),
1084
+ name: z20.string().max(255),
1085
+ size: z20.number().int().nonnegative(),
1086
+ contentType: z20.string().max(128)
1087
+ });
1088
+ var KanbanCardEventSchema = z20.object({
1089
+ type: z20.enum(["created", "edited", "moved", "image_added", "image_removed", "title_changed", "conversation_started", "scenario_started", "comment", "archived", "unarchived"]),
1090
+ timestamp: z20.string(),
1091
+ /** Extra context: old/new column name, old/new title, comment text, etc. */
1092
+ /**
1093
+ * Le texte de l'entrée : le corps d'un commentaire, ou le contexte du geste.
1094
+ *
1095
+ * Borné comme le corps d'une carte (100 000), et non plus à 5 000 : un
1096
+ * commentaire est de la prose comme une description, et rien de technique ne
1097
+ * justifiait un écart de vingt fois. La borne étroite s'est vue à l'import
1098
+ * d'un Kanbanize, où des commentaires de 12 000 caractères passaient par
1099
+ * l'API publique — bornée, elle, à 20 000 — pour écrire en base une donnée que
1100
+ * ce schéma déclarait invalide, et qu'aucune reprise depuis l'interface
1101
+ * n'aurait ensuite pu enregistrer.
1102
+ */
1103
+ detail: z20.string().max(1e5).optional(),
1104
+ /**
1105
+ * Stable identity of the event, used to tell an edit from an insertion when a
1106
+ * whole history is written back. Absent on events recorded before the field
1107
+ * existed; those fall back to (type, timestamp).
1108
+ */
1109
+ id: z20.string().max(128).optional(),
1110
+ /** Who authored this event — 'ai' or 'user'. Only set for comment events. */
1111
+ author: z20.enum(["ai", "user"]).optional(),
1112
+ /**
1113
+ * Qui est derrière l'événement, estampillé par le serveur — jamais pris du
1114
+ * client, sans quoi n'importe qui pourrait signer au nom d'un autre.
1115
+ *
1116
+ * Posé sur les commentaires (c'est ce qui rend « mon propre commentaire »
1117
+ * répondable ; `author` ne sépare que l'IA de l'humain) et sur les
1118
+ * déplacements. Absent des événements écrits avant qu'on l'estampille : un
1119
+ * lecteur doit donc afficher « on ne sait pas », pas un nom vide.
1120
+ *
1121
+ * Pour une clé d'API, c'est le nom de la clé et non son porteur : la clé
1122
+ * emprunte les droits de son créateur, pas son identité — personne ne doit
1123
+ * croire qu'un humain a déplacé ce qu'un robot de CI a déplacé.
1124
+ */
1125
+ authorUser: z20.object({ id: z20.string().max(128), name: z20.string().max(200) }).optional(),
1126
+ /** Set when the author amended their comment, so the UI can say so. */
1127
+ editedAt: z20.string().optional(),
1128
+ /** Files attached to a comment — same storage as a card's own attachments. */
1129
+ attachments: z20.array(KanbanAttachmentSchema).max(20).optional(),
1130
+ /** Conversation that produced this event (comments only). Used to navigate back to the conversation. */
1131
+ conversationId: z20.string().optional()
1132
+ });
1133
+ var KanbanCardSchema = z20.object({
1134
+ id: z20.string(),
1135
+ title: z20.string().min(1).max(500),
1136
+ markdown: z20.string().max(1e5).default(""),
1137
+ /**
1138
+ * Legacy inline images, kept so boards written before object storage still
1139
+ * render. New uploads go to `attachments` instead.
1140
+ */
1141
+ images: z20.array(z20.string()).default([]),
1142
+ /** Files attached to the card — stored out of band, referenced here. */
1143
+ attachments: z20.array(KanbanAttachmentSchema).max(50).default([]),
1144
+ order: z20.number().int(),
1145
+ /**
1146
+ * La priorité de la carte, de 1 à 10 — 10 étant le plus urgent.
1147
+ *
1148
+ * Facultative, et absente veut dire « pas de priorité », pas « la plus
1149
+ * basse » : une carte qu'on n'a pas encore arbitrée ne doit pas se ranger
1150
+ * d'office au fond de la pile.
1151
+ */
1152
+ priority: z20.number().int().min(1).max(10).optional(),
1153
+ /**
1154
+ * Les groupes de la carte — des étiquettes libres, posées par l'équipe.
1155
+ *
1156
+ * Rien ne les déclare ailleurs : un groupe existe parce qu'une carte le
1157
+ * porte, et disparaît avec la dernière qui le portait. C'est ce qui permet
1158
+ * d'en créer un en le tapant, sans passer par un écran d'administration.
1159
+ */
1160
+ groups: z20.array(z20.string().min(1).max(60)).max(30).optional(),
1161
+ /**
1162
+ * L'échéance de la carte : le jour où elle est attendue, `AAAA-MM-JJ`.
1163
+ *
1164
+ * Un jour, pas un instant, et c'est une décision : une équipe se dit « pour
1165
+ * vendredi », jamais « pour vendredi 23:59:59 UTC ». Stocker un instant
1166
+ * ferait afficher une échéance au 4 mars comme le 3 mars à qui travaille à
1167
+ * l'ouest de Greenwich — la carte serait en retard d'un jour pour la moitié
1168
+ * de l'équipe, et personne ne saurait pourquoi.
1169
+ *
1170
+ * Facultative, et absente veut dire « pas d'échéance », pas « en retard » :
1171
+ * une carte qu'on n'a pas datée ne doit pas s'annoncer comme urgente.
1172
+ */
1173
+ deadline: z20.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
1174
+ /**
1175
+ * La couleur de la carte, en hexadécimal (`#RRGGBB`) — un liseré en haut de
1176
+ * la carte, et rien d'autre : ce qu'elle veut dire appartient à l'équipe.
1177
+ *
1178
+ * Bornée à une notation stricte plutôt qu'à une chaîne libre : cette valeur
1179
+ * finit dans un attribut `style`, et une couleur ne doit pouvoir contenir
1180
+ * qu'une couleur. Absente sur les cartes sans couleur.
1181
+ */
1182
+ color: z20.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
1183
+ /**
1184
+ * Le journal de la carte — commentaires compris.
1185
+ *
1186
+ * Optionnel, et c'est tout l'intérêt : c'est la partie qui grossit sans fin
1187
+ * (une IA bavarde y écrit des pages), alors les lectures de tableau ne le
1188
+ * transportent plus. `undefined` veut dire « pas chargé », et une écriture
1189
+ * qui l'omet laisse au serveur celui qu'il a en base — à ne pas confondre
1190
+ * avec `[]`, qui demanderait bel et bien de le vider.
1191
+ */
1192
+ history: z20.array(KanbanCardEventSchema).optional(),
1193
+ /**
1194
+ * Ce que le journal absent laisse quand même dire : combien de commentaires,
1195
+ * et quand fut le dernier. Posés par le serveur en lecture, ignorés en
1196
+ * écriture — la carte ne les stocke pas, ils se déduisent de `history`.
1197
+ */
1198
+ commentCount: z20.number().int().nonnegative().optional(),
1199
+ lastCommentAt: z20.string().optional(),
1200
+ /**
1201
+ * Les entrées de journal qui ouvrent une conversation IA. Elles restent dans
1202
+ * la lecture allégée — il y en a une poignée par carte, et l'hôte s'en sert
1203
+ * pour dire, sans ouvrir la carte, qu'une IA y travaille.
1204
+ */
1205
+ conversationEvents: z20.array(KanbanCardEventSchema).optional(),
1206
+ createdAt: z20.string(),
1207
+ updatedAt: z20.string(),
1208
+ /**
1209
+ * Quand la carte a été archivée — absente tant qu'elle est au tableau.
1210
+ *
1211
+ * Une carte archivée reste dans sa colonne en base : c'est la lecture qui la
1212
+ * retire du tableau, jamais une écriture qui la déplace. Rien à recoller donc
1213
+ * au désarchivage, et aucun cimetière où une carte pourrait se perdre.
1214
+ */
1215
+ archivedAt: z20.string().optional(),
1216
+ /**
1217
+ * La colonne d'où la carte a été archivée, telle qu'elle s'appelait alors.
1218
+ *
1219
+ * L'identifiant sert à l'y remettre, le titre à le dire dans l'archive même
1220
+ * quand la colonne a disparu depuis — auquel cas le désarchivage repose la
1221
+ * carte dans la première colonne, sans se taire sur son origine.
1222
+ */
1223
+ archivedFrom: z20.object({ columnId: z20.string().max(128), columnTitle: z20.string().max(200) }).optional(),
1224
+ /**
1225
+ * Quand la carte a été supprimée. Rien n'est effacé : la carte reste en base,
1226
+ * et toutes les lectures l'écartent.
1227
+ *
1228
+ * Une suppression est le seul geste que rien ne rattrape — sauf à ne pas
1229
+ * l'exécuter vraiment. La colonne et le tableau portent le même champ, pour
1230
+ * que supprimer l'un n'emporte jamais les cartes de l'autre.
1231
+ */
1232
+ deletedAt: z20.string().optional(),
1233
+ /**
1234
+ * People assigned to the card. Names are denormalized for display; the server
1235
+ * keeps only members of the owning organization, and notifies newcomers.
1236
+ */
1237
+ assignees: z20.array(z20.object({ id: z20.string().max(128), name: z20.string().max(200) })).max(20).default([]),
1238
+ /**
1239
+ * Who first created the card. Stamped by the server the first time a card id
1240
+ * appears in a board write, never taken from the client — a member could
1241
+ * otherwise claim any authorship. Absent on cards created before this field
1242
+ * existed, so readers must treat it as unknown rather than assume.
1243
+ */
1244
+ createdBy: z20.object({ id: z20.string().max(128), name: z20.string().max(200) }).optional()
1245
+ });
1246
+ var KanbanColumnSchema = z20.object({
1247
+ id: z20.string(),
1248
+ title: z20.string().min(1).max(200),
1249
+ order: z20.number().int(),
1250
+ cards: z20.array(KanbanCardSchema).default([]),
1251
+ /**
1252
+ * Le regroupement auquel la colonne appartient, s'il y en a un.
1253
+ *
1254
+ * Un pointeur vers le parent, et rien dans l'autre sens : le groupe ne tient
1255
+ * pas la liste de ses membres. Deux listes qui prétendent dire qui contient
1256
+ * quoi finissent par se contredire, et un déplacement devient alors deux
1257
+ * écritures au lieu d'une.
1258
+ */
1259
+ groupId: z20.string().optional(),
1260
+ /** Supprimée, mais conservée — voir `deletedAt` sur la carte. */
1261
+ deletedAt: z20.string().optional()
1262
+ });
1263
+ var KanbanColumnGroupSchema = z20.object({
1264
+ id: z20.string(),
1265
+ title: z20.string().min(1).max(200),
1266
+ /** La couleur du bandeau, en hexadécimal — l'interface décide du défaut. */
1267
+ color: z20.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
1268
+ /** Le groupe parent, pour les regroupements imbriqués. */
1269
+ parentId: z20.string().optional(),
1270
+ /** Supprimé, mais conservé — comme une colonne. */
1271
+ deletedAt: z20.string().optional()
1272
+ });
1273
+ var KanbanBoardSchema = z20.object({
1274
+ id: z20.string(),
1275
+ name: z20.string().min(1).max(200),
1276
+ description: z20.string().max(1e4).default(""),
1277
+ /**
1278
+ * Le mode d'emploi du tableau, en texte libre : ce que veulent dire ses
1279
+ * colonnes, quand une carte a le droit d'avancer, les conventions de
1280
+ * l'équipe. Écrit par les humains, lu surtout par l'IA — il est injecté dans
1281
+ * le prompt des agents pour qu'ils travaillent selon les règles du tableau
1282
+ * plutôt que selon les leurs.
1283
+ */
1284
+ instructions: z20.string().max(2e4).default(""),
1285
+ columns: z20.array(KanbanColumnSchema).default([]),
1286
+ /** Les regroupements de colonnes — vide sur un tableau qui n'en a jamais eu. */
1287
+ columnGroups: z20.array(KanbanColumnGroupSchema).default([]),
1288
+ archived: z20.boolean().default(false),
1289
+ /** Supprimé, mais conservé avec ses cartes — voir `deletedAt` sur la carte. */
1290
+ deletedAt: z20.string().optional(),
1291
+ createdAt: z20.string(),
1292
+ updatedAt: z20.string()
1293
+ });
1294
+ var CreateKanbanBoardInput = z20.object({
1295
+ name: z20.string().min(1).max(200),
1296
+ description: z20.string().max(1e4).optional(),
1297
+ instructions: z20.string().max(2e4).optional()
1298
+ });
1299
+ var UpdateKanbanBoardInput = z20.object({
1300
+ id: z20.string(),
1301
+ name: z20.string().min(1).max(200).optional(),
1302
+ description: z20.string().max(1e4).optional(),
1303
+ instructions: z20.string().max(2e4).optional(),
1304
+ columns: z20.array(KanbanColumnSchema).optional(),
1305
+ archived: z20.boolean().optional()
1306
+ });
1307
+ var KanbanCardLinkSchema = z20.object({
1308
+ id: z20.string().max(128),
1309
+ /** Le tableau et la carte qui *dépendent* de l'autre. */
1310
+ childBoardId: z20.string().max(64),
1311
+ childCardId: z20.string().max(128),
1312
+ /** Le tableau et la carte *dont* on dépend. */
1313
+ parentBoardId: z20.string().max(64),
1314
+ parentCardId: z20.string().max(128),
1315
+ createdAt: z20.string(),
1316
+ createdBy: z20.object({ id: z20.string().max(128), name: z20.string().max(200) }).optional()
1317
+ });
1318
+ var KanbanCardRefSchema = z20.object({
1319
+ cardId: z20.string().max(128),
1320
+ boardId: z20.string().max(64),
1321
+ boardName: z20.string().max(200),
1322
+ columnId: z20.string().max(128),
1323
+ columnTitle: z20.string().max(200),
1324
+ title: z20.string().max(500),
1325
+ /** Les mêmes informations qu'une ligne de tableau montre d'une carte d'ici. */
1326
+ assignees: z20.array(z20.object({ id: z20.string().max(128), name: z20.string().max(200) })).default([]),
1327
+ commentCount: z20.number().int().nonnegative().default(0)
1328
+ });
1329
+
1330
+ // ../../packages/shared/src/schemas/cloud-api-key.schema.ts
1331
+ import { z as z21 } from "zod";
1332
+ var CloudApiScopeSchema = z21.enum([
1333
+ "kanban:read",
1334
+ "kanban:write",
1335
+ "kanban:comment",
1336
+ "kanban:delete"
1337
+ ]);
1338
+ var CloudApiKeySecretSchema = z21.string().regex(/^rk_[0-9a-f]{64}$/);
1339
+ var CloudApiKeySchema = z21.object({
1340
+ id: z21.string().max(128),
1341
+ organizationId: z21.string().max(128),
1342
+ name: z21.string().min(1).max(200),
1343
+ scopes: z21.array(CloudApiScopeSchema).min(1).max(10),
1344
+ /**
1345
+ * Les tableaux que la clé peut atteindre, ou `null` pour « tous ceux de
1346
+ * l'organisation ».
1347
+ *
1348
+ * `null` et `[]` ne sont pas la même chose : la liste vide n'ouvre rien, et
1349
+ * c'est délibéré — un tableau supprimé ne doit pas élargir une clé qui ne le
1350
+ * nommait plus que lui.
1351
+ */
1352
+ boards: z21.array(z21.string().max(64)).max(200).nullable(),
1353
+ createdAt: z21.string().max(64),
1354
+ /** Dernier usage constaté, pour reconnaître une clé oubliée. */
1355
+ lastUsedAt: z21.string().max(64).nullable(),
1356
+ /** Qui l'a émise — une clé sans visage ne se révoque jamais sereinement. */
1357
+ createdBy: z21.object({ id: z21.string().max(128), name: z21.string().max(200) }),
1358
+ /** Les 4 derniers caractères du secret, pour reconnaître une clé dans une liste. */
1359
+ keyPreview: z21.string().max(8)
1360
+ });
1361
+ var CreatedCloudApiKeySchema = z21.object({
1362
+ key: CloudApiKeySchema,
1363
+ secret: CloudApiKeySecretSchema
1364
+ });
1365
+ var CreateCloudApiKeyInput = z21.object({
1366
+ organizationId: z21.string().min(1).max(128),
1367
+ name: z21.string().min(1).max(200),
1368
+ scopes: z21.array(CloudApiScopeSchema).min(1).max(10),
1369
+ boards: z21.array(z21.string().max(64)).max(200).nullable().default(null)
1370
+ });
1371
+ var UpdateCloudApiKeyInput = z21.object({
1372
+ id: z21.string().min(1).max(128),
1373
+ name: z21.string().min(1).max(200).optional(),
1374
+ scopes: z21.array(CloudApiScopeSchema).min(1).max(10).optional(),
1375
+ boards: z21.array(z21.string().max(64)).max(200).nullable().optional()
1376
+ });
1377
+
1378
+ // ../../packages/shared/src/schemas/changelog.schema.ts
1379
+ import { z as z22 } from "zod";
1380
+ var ChangelogSurfaceSchema = z22.enum(["app", "cloud"]);
1381
+ var ChangelogChangeKindSchema = z22.enum(["feature", "improvement", "fix", "breaking"]);
1382
+ var ChangelogTextSchema = z22.object({
1383
+ fr: z22.string().min(1).max(500),
1384
+ en: z22.string().min(1).max(500)
1385
+ });
1386
+ var ChangelogChangeSchema = z22.object({
1387
+ kind: ChangelogChangeKindSchema,
1388
+ text: ChangelogTextSchema
1389
+ });
1390
+ var ChangelogDraftSchema = ChangelogChangeSchema.extend({
1391
+ date: z22.string().regex(/^\d{4}-\d{2}-\d{2}$/),
1392
+ title: ChangelogTextSchema.optional()
1393
+ });
1394
+ var ChangelogReleaseSchema = z22.object({
1395
+ surface: ChangelogSurfaceSchema,
1396
+ /** `1.4.2` pour l'app (version npm publiée), `2026-09-03` — ou `2026-09-03.2` — pour le cloud. */
1397
+ version: z22.string().min(1).max(32).regex(/^[0-9][0-9.-]*$/),
1398
+ /** Date de publication, `YYYY-MM-DD`. */
1399
+ date: z22.string().regex(/^\d{4}-\d{2}-\d{2}$/),
1400
+ /** Facultatif : une version peut s'annoncer par son seul numéro. */
1401
+ title: ChangelogTextSchema.optional(),
1402
+ /** Une version sans changement n'a rien à annoncer : elle n'a pas sa place ici. */
1403
+ changes: z22.array(ChangelogChangeSchema).min(1).max(50)
1404
+ });
1405
+ var ChangelogIndexItemSchema = ChangelogReleaseSchema.omit({ changes: true }).extend({
1406
+ changeCount: z22.number().int().nonnegative()
1407
+ });
1408
+
1409
+ // ../../packages/shared/src/utils/crypto.ts
1410
+ import { createCipheriv, createDecipheriv, randomBytes, pbkdf2Sync } from "crypto";
1411
+
1412
+ // ../../packages/shared/src/native-parsers.ts
1413
+ var epoch = /* @__PURE__ */ new Date("2025-01-01T00:00:00Z");
1414
+ var nativeParsers = [
1415
+ {
1416
+ id: "native:json",
1417
+ name: "JSON Log Parser",
1418
+ description: "Parses JSON log lines and extracts level, message, timestamp, metadata, and the full parsed object.",
1419
+ code: `(line) => {
1420
+ var trimmed = line.message.trim();
1421
+ if (!trimmed.startsWith('{')) return line;
1422
+ try {
1423
+ var obj = JSON.parse(trimmed);
1424
+ var level = (obj.level || obj.severity || obj.loglevel || '').toString().toLowerCase();
1425
+ var levelMap = { trace: 'debug', debug: 'debug', info: 'info', warn: 'warn', warning: 'warn', error: 'error', fatal: 'fatal', err: 'error' };
1426
+ var mappedLevel = levelMap[level] || line.level;
1427
+ var message = obj.message || obj.msg || obj.text || trimmed;
1428
+ var metadata = {};
1429
+ for (var k in obj) {
1430
+ if (['level','severity','loglevel','message','msg','text','timestamp','time','ts'].indexOf(k) !== -1) continue;
1431
+ metadata[k] = typeof obj[k] === 'string' ? obj[k] : JSON.stringify(obj[k]);
1432
+ }
1433
+ var merged = {};
1434
+ for (var mk in line.metadata) merged[mk] = line.metadata[mk];
1435
+ for (var nk in metadata) merged[nk] = metadata[nk];
1436
+ return { raw: line.raw, stream: line.stream, level: mappedLevel, message: String(message).slice(0, 16384), hidden: line.hidden, metadata: merged, json: obj, jsonHeader: line.jsonHeader };
1437
+ } catch (e) { return line; }
1438
+ }`,
1439
+ enabled: true,
1440
+ builtin: true,
1441
+ createdAt: epoch,
1442
+ updatedAt: epoch
1443
+ },
1444
+ {
1445
+ id: "native:debug",
1446
+ name: "Runeya Debug Parser",
1447
+ description: 'Detects Runeya internal debug logs emitted as JSON arrays: ["runeya", payload]. Marks them as debug level.',
1448
+ code: `(line) => {
1449
+ var trimmed = line.message.trim();
1450
+ if (!trimmed.startsWith('[')) return line;
1451
+ try {
1452
+ var parsed = JSON.parse(trimmed);
1453
+ if (!Array.isArray(parsed) || parsed[0] !== 'runeya') return line;
1454
+ var debug = parsed.length === 2 ? parsed[1] : parsed.slice(1);
1455
+ var message = typeof debug === 'string' ? debug : JSON.stringify(debug);
1456
+ var merged = {};
1457
+ for (var k in line.metadata) merged[k] = line.metadata[k];
1458
+ merged.runeya_debug = JSON.stringify(debug);
1459
+ return { raw: line.raw, stream: line.stream, level: 'debug', message: message, hidden: line.hidden, metadata: merged, jsonHeader: line.jsonHeader };
1460
+ } catch (e) { return line; }
1461
+ }`,
1462
+ enabled: true,
1463
+ builtin: true,
1464
+ createdAt: epoch,
1465
+ updatedAt: epoch
1466
+ },
1467
+ {
1468
+ id: "native:links",
1469
+ name: "Link Detector",
1470
+ description: "Detects URLs in plain-text log lines and exposes them in metadata.links for frontend rendering.",
1471
+ code: `(line) => {
1472
+ var urlRegex = /(https?|ftp):\\/\\/[\\w_-]+(?:\\.[\\w_-]+)+([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?/gi;
1473
+ var urls = line.message.match(urlRegex);
1474
+ if (!urls || urls.length === 0) return line;
1475
+ var merged = {};
1476
+ for (var k in line.metadata) merged[k] = line.metadata[k];
1477
+ merged.links = urls.join(' ');
1478
+ return { raw: line.raw, stream: line.stream, level: line.level, message: line.message, hidden: line.hidden, metadata: merged, jsonHeader: line.jsonHeader };
1479
+ }`,
1480
+ enabled: true,
1481
+ builtin: true,
1482
+ createdAt: epoch,
1483
+ updatedAt: epoch
1484
+ }
1485
+ ];
1486
+
1487
+ // ../../packages/shared/src/js-log-parser.ts
1488
+ import vm from "vm";
1489
+ var VALID_LEVELS = /* @__PURE__ */ new Set(["debug", "info", "warn", "error", "fatal"]);
1490
+ var PARSE_TIMEOUT_MS = 50;
1491
+ var MAX_CONSECUTIVE_TIMEOUTS = 10;
1492
+ var JSLogParser = class {
1493
+ parsers = [];
1494
+ constructor(definitions = []) {
1495
+ this.setParsers(definitions);
1496
+ }
1497
+ setParsers(definitions) {
1498
+ this.parsers = [];
1499
+ for (const def of definitions) {
1500
+ if (!def.enabled) continue;
1501
+ try {
1502
+ const compiled = this.compileParser(def);
1503
+ this.parsers.push({
1504
+ id: def.id,
1505
+ name: def.name,
1506
+ enabled: true,
1507
+ fn: compiled
1508
+ });
1509
+ } catch (err) {
1510
+ console.warn(
1511
+ `[js-log-parser] Failed to compile parser "${def.name}" (${def.id}): ${err instanceof Error ? err.message : String(err)}`
1512
+ );
1513
+ }
1514
+ }
1515
+ }
1516
+ parse(line) {
1517
+ let current = line;
1518
+ for (const parser of this.parsers) {
1519
+ try {
1520
+ current = parser.fn(current);
1521
+ } catch (err) {
1522
+ console.warn(
1523
+ `[js-log-parser] Parser "${parser.name}" threw error: ${err instanceof Error ? err.message : String(err)}`
1524
+ );
1525
+ }
1526
+ }
1527
+ return this.sanitize(current);
1528
+ }
1529
+ /**
1530
+ * Compile le code utilisateur en une fonction bornée en temps.
1531
+ *
1532
+ * Le `timeout` de `runInNewContext` ne couvre que l'évaluation de la factory :
1533
+ * la closure retournée s'exécutait ensuite ligne par ligne directement sur
1534
+ * l'event loop, sans aucune borne. Une regex à backtracking exponentiel
1535
+ * fournie par l'utilisateur figeait donc l'agent entier — logs, statuts et
1536
+ * métriques de *tous* les services. Chaque invocation repasse maintenant par
1537
+ * la vm, avec son propre budget.
1538
+ */
1539
+ compileParser(def) {
1540
+ const forbidden = ["require(", "import ", "eval("];
1541
+ for (const pat of forbidden) {
1542
+ if (def.code.includes(pat)) {
1543
+ throw new Error("Code contains forbidden patterns (require, import, eval)");
1544
+ }
1545
+ }
1546
+ const sandbox = {
1547
+ RegExp,
1548
+ String,
1549
+ Object,
1550
+ Array,
1551
+ JSON,
1552
+ Math,
1553
+ Date,
1554
+ undefined: void 0,
1555
+ null: null
1556
+ };
1557
+ let script;
1558
+ try {
1559
+ script = new vm.Script(`(${def.code})`, { filename: `parser-${def.id}.js` });
1560
+ } catch (err) {
1561
+ throw new Error(`Compilation failed: ${err instanceof Error ? err.message : String(err)}`);
1562
+ }
1563
+ const context = vm.createContext({ ...sandbox, __line: null, __result: null });
1564
+ let parserFn;
1565
+ try {
1566
+ parserFn = script.runInContext(context, { timeout: 100 });
1567
+ } catch (err) {
1568
+ throw new Error(`Execution failed: ${err instanceof Error ? err.message : String(err)}`);
1569
+ }
1570
+ if (typeof parserFn !== "function") {
1571
+ throw new Error("Parser code must export a function");
1572
+ }
1573
+ context["__parserFn"] = parserFn;
1574
+ const callScript = new vm.Script("__result = __parserFn(__line);", {
1575
+ filename: `parser-${def.id}-call.js`
1576
+ });
1577
+ let consecutiveTimeouts = 0;
1578
+ let disabled = false;
1579
+ return (line) => {
1580
+ if (disabled) return line;
1581
+ const ctx = context;
1582
+ ctx["__line"] = line;
1583
+ ctx["__result"] = null;
1584
+ try {
1585
+ callScript.runInContext(context, { timeout: PARSE_TIMEOUT_MS });
1586
+ consecutiveTimeouts = 0;
1587
+ } catch (err) {
1588
+ const e = err;
1589
+ const timedOut = !!e && (e.code === "ERR_SCRIPT_EXECUTION_TIMEOUT" || typeof e.message === "string" && /execution timed out/i.test(e.message));
1590
+ if (!timedOut) throw err;
1591
+ consecutiveTimeouts += 1;
1592
+ if (consecutiveTimeouts >= MAX_CONSECUTIVE_TIMEOUTS) {
1593
+ disabled = true;
1594
+ console.warn(
1595
+ `[js-log-parser] Parser "${def.name}" (${def.id}) disabled after ${MAX_CONSECUTIVE_TIMEOUTS} consecutive timeouts`
1596
+ );
1597
+ }
1598
+ return line;
1599
+ }
1600
+ const result = ctx["__result"];
1601
+ if (result === null || result === void 0 || typeof result !== "object") {
1602
+ return line;
1603
+ }
1604
+ return result;
1605
+ };
1606
+ }
1607
+ /** Sanitize the final LogLine: truncate message, limit metadata, validate level */
1608
+ sanitize(line) {
1609
+ let { message, metadata, level } = line;
1610
+ if (message.length > 16384) {
1611
+ message = message.substring(0, 16384) + "...[truncated]";
1612
+ }
1613
+ metadata = metadata ?? {};
1614
+ const metaKeys = Object.keys(metadata);
1615
+ if (metaKeys.length > 100) {
1616
+ const limited = {};
1617
+ for (let i = 0; i < 100; i++) {
1618
+ limited[metaKeys[i]] = metadata[metaKeys[i]];
1619
+ }
1620
+ metadata = limited;
1621
+ }
1622
+ if (!VALID_LEVELS.has(level)) {
1623
+ level = "info";
1624
+ }
1625
+ if (message !== line.message || metadata !== line.metadata || level !== line.level) {
1626
+ return { ...line, message, metadata, level };
1627
+ }
1628
+ return line;
1629
+ }
1630
+ };
1631
+
1632
+ // ../../packages/shared/src/builtins.ts
1633
+ var BUILTIN_VARIABLES = [
1634
+ // ── Le service ───────────────────────────────────────────────────────────
1635
+ { name: "service.NAME", scope: "server", descriptionKey: "serviceName" },
1636
+ { name: "service.ID", scope: "server", descriptionKey: "serviceId" },
1637
+ { name: "service.PORT", scope: "server", descriptionKey: "servicePort" },
1638
+ { name: "service.URL", scope: "server", descriptionKey: "serviceUrl" },
1639
+ { name: "service.BASE_URL", scope: "server", descriptionKey: "serviceBaseUrl" },
1640
+ { name: "service.CWD", scope: "agent", descriptionKey: "serviceCwd" },
1641
+ // ── Le projet et l'environnement actif ───────────────────────────────────
1642
+ { name: "project.NAME", scope: "server", descriptionKey: "projectName" },
1643
+ { name: "runeya.ENV_NAME", scope: "server", descriptionKey: "envName" },
1644
+ // ── Le serveur Runeya ────────────────────────────────────────────────────
1645
+ // `service.HOST` a toujours désigné l'adresse d'écoute du SERVEUR, pas une
1646
+ // propriété du service : le nom trompait, il devient un alias.
1647
+ { name: "runeya.HOST", scope: "server", descriptionKey: "runeyaHost", deprecatedAlias: "service.HOST" },
1648
+ // ── La machine qui exécute ───────────────────────────────────────────────
1649
+ { name: "agent.HOST_LAN", scope: "agent", descriptionKey: "agentHostLan", deprecatedAlias: "service.HOST_LAN" },
1650
+ // Le NOM de l'agent est une étiquette de la configuration du serveur, pas
1651
+ // une propriété de la machine : c'est le serveur qui le connaît et le résout.
1652
+ { name: "agent.NAME", scope: "server", descriptionKey: "agentName" },
1653
+ { name: "agent.OS", scope: "agent", descriptionKey: "agentOs" },
1654
+ { name: "agent.HOME", scope: "agent", descriptionKey: "agentHome" }
1655
+ ];
1656
+ var BUILTIN_REFERENCE_RE = /\{\{([A-Za-z][A-Za-z0-9_.-]*)\}\}/g;
1657
+ var ENVIRONMENT_NAMESPACE = "environment.";
1658
+ function interpolateBuiltins(text, values) {
1659
+ return text.replace(BUILTIN_REFERENCE_RE, (match, name) => {
1660
+ if (name.startsWith(ENVIRONMENT_NAMESPACE)) return match;
1661
+ return values[name] ?? match;
1662
+ });
1663
+ }
1664
+ function interpolateBuiltinsInEnv(env2, values) {
1665
+ const out = {};
1666
+ for (const [key, value] of Object.entries(env2)) {
1667
+ out[key] = interpolateBuiltins(value, values);
1668
+ }
1669
+ return out;
1670
+ }
1671
+ function withDeprecatedAliases(values) {
1672
+ const out = { ...values };
1673
+ for (const builtin of BUILTIN_VARIABLES) {
1674
+ if (builtin.deprecatedAlias && out[builtin.name] !== void 0) {
1675
+ out[builtin.deprecatedAlias] = out[builtin.name];
1676
+ }
1677
+ }
1678
+ return out;
1679
+ }
1680
+ function serviceSlug(name) {
1681
+ return name.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
1682
+ }
1683
+ function servicePortValues(ports, prefix = "service") {
1684
+ const values = {};
1685
+ (ports ?? []).forEach((port, i) => {
1686
+ values[i === 0 ? `${prefix}.PORT` : `${prefix}.PORT_${i + 1}`] = String(port);
1687
+ });
1688
+ return values;
1689
+ }
1690
+ function isWildcardHost(host) {
1691
+ const h = host.trim();
1692
+ return h === "" || h === "0.0.0.0" || h === "::" || h === "[::]";
1693
+ }
1694
+ function isLoopbackHost(host) {
1695
+ const h = host.trim();
1696
+ return h === "127.0.0.1" || h === "::1" || h === "[::1]";
1697
+ }
1698
+ function urlHostFor(host) {
1699
+ if (isWildcardHost(host)) return null;
1700
+ return isLoopbackHost(host) ? "localhost" : host.trim();
1701
+ }
1702
+ function serviceUrlValues(service, host, prefix = "service") {
1703
+ const domainByPort = new Map((service.localUrls ?? []).map((lu) => [lu.port, lu.url]));
1704
+ const ports = [...service.ports ?? []];
1705
+ for (const local of service.localUrls ?? []) {
1706
+ if (!ports.includes(local.port)) ports.push(local.port);
1707
+ }
1708
+ const values = {};
1709
+ ports.forEach((port, i) => {
1710
+ const domain = domainByPort.get(port);
1711
+ values[i === 0 ? `${prefix}.URL` : `${prefix}.URL_${i + 1}`] = domain ? `http://${domain}` : `http://${host}:${port}`;
1712
+ });
1713
+ return values;
1714
+ }
1715
+ function crossServiceValues(service, host) {
1716
+ const slug = serviceSlug(service.name);
1717
+ if (!slug) return {};
1718
+ return {
1719
+ [`services.${slug}.NAME`]: service.name,
1720
+ [`services.${slug}.ID`]: service.id,
1721
+ ...servicePortValues(service.ports, `services.${slug}`),
1722
+ ...serviceUrlValues(service, host, `services.${slug}`),
1723
+ ...service.url ? { [`services.${slug}.BASE_URL`]: service.url } : {}
1724
+ };
1725
+ }
1726
+
1727
+ // ../../packages/shared/src/constants/buffers.ts
1728
+ var LOG_BUFFER_SIZE = 5e3;
1729
+
1730
+ // ../../packages/shared/src/constants/editors.ts
1731
+ var SUPPORTED_EDITORS = [
1732
+ { key: "vscode", name: "Visual Studio Code", command: "code" },
1733
+ { key: "cursor", name: "Cursor", command: "cursor" },
1734
+ { key: "windsurf", name: "Windsurf", command: "windsurf" },
1735
+ { key: "sublime", name: "Sublime Text", command: "subl" },
1736
+ { key: "atom", name: "Atom", command: "atom" },
1737
+ { key: "antigravity", name: "Antigravity", command: "antigravity" },
1738
+ { key: "intellij", name: "IntelliJ IDEA", command: "idea" },
1739
+ { key: "android-studio", name: "Android Studio", command: "studio" },
1740
+ { key: "webstorm", name: "WebStorm", command: "webstorm" },
1741
+ { key: "zed", name: "Zed", command: "zed" },
1742
+ { key: "neovim", name: "Neovim", command: "nvim" },
1743
+ { key: "vim", name: "Vim", command: "vim" },
1744
+ { key: "emacs", name: "Emacs", command: "emacs" },
1745
+ { key: "fleet", name: "Fleet", command: "fleet" }
1746
+ ];
1747
+ var EDITOR_BY_KEY = new Map(
1748
+ SUPPORTED_EDITORS.map((e) => [e.key, e])
1749
+ );
1750
+
1751
+ // ../../packages/shared/src/sync/json-crdt.ts
1752
+ import * as Y from "yjs";
1753
+ function normalize(value) {
1754
+ return JSON.parse(JSON.stringify(value ?? null));
1755
+ }
1756
+ function isPlainObject(v) {
1757
+ return typeof v === "object" && v !== null && !Array.isArray(v);
1758
+ }
1759
+ function toPlain(value) {
1760
+ if (value instanceof Y.Map) {
1761
+ const out = {};
1762
+ for (const [k, v] of value.entries()) out[k] = toPlain(v);
1763
+ return out;
1764
+ }
1765
+ if (value instanceof Y.Array) return value.toArray().map(toPlain);
1766
+ return value ?? null;
1767
+ }
1768
+ function identityOf(value) {
1769
+ if (isPlainObject(value) && typeof value["id"] === "string") return `id:${value["id"]}`;
1770
+ return `v:${JSON.stringify(value)}`;
1771
+ }
1772
+ function identityOfY(value) {
1773
+ if (value instanceof Y.Map) {
1774
+ const id = value.get("id");
1775
+ if (typeof id === "string") return `id:${id}`;
1776
+ }
1777
+ return `v:${JSON.stringify(toPlain(value))}`;
1778
+ }
1779
+ function toY(value) {
1780
+ if (Array.isArray(value)) {
1781
+ const arr = new Y.Array();
1782
+ if (value.length > 0) arr.insert(0, value.map(toY));
1783
+ return arr;
1784
+ }
1785
+ if (isPlainObject(value)) {
1786
+ const map = new Y.Map();
1787
+ for (const [k, v] of Object.entries(value)) map.set(k, toY(v));
1788
+ return map;
1789
+ }
1790
+ return value;
1791
+ }
1792
+ function applyToMap(map, next) {
1793
+ for (const key of Array.from(map.keys())) {
1794
+ if (!(key in next)) map.delete(key);
1795
+ }
1796
+ for (const [key, value] of Object.entries(next)) {
1797
+ const current = map.get(key);
1798
+ if (Array.isArray(value)) {
1799
+ if (!(current instanceof Y.Array)) map.set(key, toY(value));
1800
+ else applyToArray(current, value);
1801
+ } else if (isPlainObject(value)) {
1802
+ if (!(current instanceof Y.Map)) map.set(key, toY(value));
1803
+ else applyToMap(current, value);
1804
+ } else if (current instanceof Y.Map || current instanceof Y.Array || current !== value) {
1805
+ map.set(key, value);
1806
+ }
1807
+ }
1808
+ }
1809
+ function applyToArray(arr, next) {
1810
+ const wanted = next.map(identityOf);
1811
+ const wantedCount = /* @__PURE__ */ new Map();
1812
+ for (const k of wanted) wantedCount.set(k, (wantedCount.get(k) ?? 0) + 1);
1813
+ const seen = /* @__PURE__ */ new Map();
1814
+ for (let i = arr.length - 1; i >= 0; i--) {
1815
+ const key = identityOfY(arr.get(i));
1816
+ const used = seen.get(key) ?? 0;
1817
+ if (used >= (wantedCount.get(key) ?? 0)) arr.delete(i, 1);
1818
+ else seen.set(key, used + 1);
1819
+ }
1820
+ for (let j = 0; j < next.length; j++) {
1821
+ const key = wanted[j];
1822
+ if (j < arr.length && identityOfY(arr.get(j)) === key) {
1823
+ const current = arr.get(j);
1824
+ const value = next[j];
1825
+ if (current instanceof Y.Map && isPlainObject(value)) applyToMap(current, value);
1826
+ else if (current instanceof Y.Array && Array.isArray(value)) applyToArray(current, value);
1827
+ continue;
1828
+ }
1829
+ let found = -1;
1830
+ for (let k = j + 1; k < arr.length; k++) {
1831
+ if (identityOfY(arr.get(k)) === key) {
1832
+ found = k;
1833
+ break;
1834
+ }
1835
+ }
1836
+ if (found !== -1) {
1837
+ const moved = toPlain(arr.get(found));
1838
+ arr.delete(found, 1);
1839
+ arr.insert(j, [toY(moved)]);
1840
+ } else {
1841
+ arr.insert(j, [toY(next[j])]);
1842
+ }
1843
+ }
1844
+ }
1845
+ function getCollection(doc, name) {
1846
+ return doc.getMap(name);
1847
+ }
1848
+ function readEntity(collection, id) {
1849
+ const entity = collection.get(id);
1850
+ if (!(entity instanceof Y.Map)) return null;
1851
+ const plain = toPlain(entity);
1852
+ return isPlainObject(plain) ? plain : null;
1853
+ }
1854
+ function writeEntity(collection, id, entity) {
1855
+ const next = normalize(entity);
1856
+ if (!isPlainObject(next)) return;
1857
+ const current = collection.get(id);
1858
+ if (!(current instanceof Y.Map)) {
1859
+ collection.set(id, toY(next));
1860
+ return;
1861
+ }
1862
+ applyToMap(current, next);
1863
+ }
1864
+
1865
+ export {
1866
+ env,
1867
+ machineRoot,
1868
+ localVaultRoot,
1869
+ orgVaultRoot,
1870
+ projectVaultRoot,
1871
+ orgIdOfRoot,
1872
+ vaultIdOfRoot,
1873
+ vaultFor,
1874
+ stampOrgCloud,
1875
+ rememberOrgName,
1876
+ readOrgNames,
1877
+ rememberOrgLogo,
1878
+ forgetOrgLogo,
1879
+ readOrgLogos,
1880
+ readOrgClouds,
1881
+ listOrgVaults,
1882
+ listCloudVaults,
1883
+ allVaultRoots,
1884
+ machineFilePath,
1885
+ keyedFilePath,
1886
+ legacyMachineFilePath,
1887
+ ensureLocalVault,
1888
+ keyRoot,
1889
+ legacyVaultRoot,
1890
+ ProjectSchema,
1891
+ ScenarioGroupSchema,
1892
+ ScenarioNodeSchema,
1893
+ ScenarioSchema,
1894
+ AIProviderSchema,
1895
+ JSLogParserSchema,
1896
+ NotificationPreferencesSchema,
1897
+ SettingsSchema,
1898
+ TraefikConfigSchema,
1899
+ SettingsPrivateSchema,
1900
+ SchemaVersionSchema,
1901
+ LogSourceConfigSchema,
1902
+ HealthCheckSchema,
1903
+ DockerConfigSchema,
1904
+ RestartStrategySchema,
1905
+ ServiceShortcutSchema,
1906
+ ServiceCommandSchema,
1907
+ VariableSchema,
1908
+ ServiceConfigSchema,
1909
+ EnvironmentSchema,
1910
+ CreateEnvironmentSchema,
1911
+ UpdateEnvironmentSchema,
1912
+ VariableOverrideSchema,
1913
+ ApiKeyScopeSchema,
1914
+ ApiKeysFileSchema,
1915
+ ChangelogSurfaceSchema,
1916
+ ChangelogReleaseSchema,
1917
+ ChangelogIndexItemSchema,
1918
+ COMPANION_RELAY_OPEN,
1919
+ COMPANION_RELAY_CLOSE,
1920
+ extractCompanionRelay,
1921
+ nativeParsers,
1922
+ JSLogParser,
1923
+ interpolateBuiltinsInEnv,
1924
+ withDeprecatedAliases,
1925
+ serviceSlug,
1926
+ servicePortValues,
1927
+ urlHostFor,
1928
+ serviceUrlValues,
1929
+ crossServiceValues,
1930
+ AGENT_HEALTH_POLL_INTERVAL,
1931
+ LOG_BUFFER_SIZE,
1932
+ AGENT_FETCH_TIMEOUT,
1933
+ AGENT_LONG_FETCH_TIMEOUT,
1934
+ AGENT_STOP_FETCH_TIMEOUT,
1935
+ PASSPHRASE_TIMEOUT,
1936
+ WS_RECONNECT_MIN,
1937
+ WS_RECONNECT_MAX,
1938
+ SUPPORTED_EDITORS,
1939
+ EDITOR_BY_KEY,
1940
+ getCollection,
1941
+ readEntity,
1942
+ writeEntity
1943
+ };
1944
+ //# sourceMappingURL=chunk-3MJLS5UY.js.map