@runeya/runeya 2.0.125 → 2.0.127

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 (281) hide show
  1. package/agent/index.js.map +1 -1
  2. package/agent-manager-FN6M6CLD.js +10 -0
  3. package/{chat-JIJQ7IJS.js → chat-VCHK77CW.js} +7 -7
  4. package/{chunk-HK5QNU6P.js → chunk-BDQOBEZ3.js} +18 -2
  5. package/chunk-BDQOBEZ3.js.map +1 -0
  6. package/{chunk-GKK3ACWB.js → chunk-LHVTBWM7.js} +599 -267
  7. package/chunk-LHVTBWM7.js.map +1 -0
  8. package/{chunk-N3ZI35SC.js → chunk-QPII36FL.js} +3 -3
  9. package/{chunk-T2BV5WZE.js → chunk-TTPL2M74.js} +87 -1
  10. package/chunk-TTPL2M74.js.map +1 -0
  11. package/{chunk-H22YLVQE.js → chunk-UKLNK5YA.js} +44 -20
  12. package/chunk-UKLNK5YA.js.map +1 -0
  13. package/{chunk-4PN7QBNM.js → chunk-WQWRTPPJ.js} +10 -5
  14. package/chunk-WQWRTPPJ.js.map +1 -0
  15. package/{companion-OZODV5BR.js → companion-YB3SDDTU.js} +7 -5
  16. package/{desktop-launcher-EGGVXXKV.js → desktop-launcher-J2BCSSGZ.js} +2 -2
  17. package/index.js +4 -4
  18. package/mcp-server/index.js +1469 -20
  19. package/mcp-server/index.js.map +1 -1
  20. package/package.json +1 -1
  21. package/settings-manager-4EDX7NIB.js +10 -0
  22. package/{src-SGSG2RSF.js → src-J3RBNMRJ.js} +268 -76
  23. package/src-J3RBNMRJ.js.map +1 -0
  24. package/web/assets/AgentScalarChatInterface.vue-86061Tlh.js +13 -0
  25. package/web/assets/AgentTerminalPage-DxGLu5uT.js +1 -0
  26. package/web/assets/AiChatPage-DmQKv6pr.js +1 -0
  27. package/web/assets/{AppLayout-vWoE_P8T.css → AppLayout-Do2CLgOr.css} +1 -1
  28. package/web/assets/AppLayout-DtK_nr-e.js +1 -0
  29. package/web/assets/AuditPage-CX5VJGlF.js +1 -0
  30. package/web/assets/CloudAccountPage-B_sjXlfl.js +1 -0
  31. package/web/assets/CloudAccountPage-ocHdrVEm.js +1 -0
  32. package/web/assets/CloudMessagingPage-BTfGWio6.js +2 -0
  33. package/web/assets/DashboardPage-7sATlyhd.js +164 -0
  34. package/web/assets/DashboardPage-DWA-1xgl.css +1 -0
  35. package/web/assets/DirectoryPickerDialog-DAJGNiRV.js +1 -0
  36. package/web/assets/{EditorIcon-BZyy2C12.js → EditorIcon-lzF8hPtZ.js} +2 -2
  37. package/web/assets/EnvironmentForm-DVWdFsE1.js +108 -0
  38. package/web/assets/EnvironmentFormPage-DoKBTKCU.js +1 -0
  39. package/web/assets/EnvironmentListPage-C9wGFZWU.js +1 -0
  40. package/web/assets/KanbanBoardPage-CoiDga7h.js +4 -0
  41. package/web/assets/KanbanListPage-xWYUu1P0.js +1 -0
  42. package/web/assets/LaunchProjectPage-DVXgnUYk.js +1 -0
  43. package/web/assets/LaunchServicesPage-CPN3Z3m5.css +1 -0
  44. package/web/assets/LaunchServicesPage-DM6keva3.js +1 -0
  45. package/web/assets/LogViewer-CMtuP1rB.js +3 -0
  46. package/web/assets/OrgKeyPrompt-BqVugrV1.js +1 -0
  47. package/web/assets/{ProcessControls-neMxqIY_.js → ProcessControls-DkaiMo0H.js} +1 -1
  48. package/web/assets/ProcessDetailPage-DJacy1ZE.js +1 -0
  49. package/web/assets/{ProcessMetrics-Bb7yNIVd.js → ProcessMetrics-D2lP9cEF.js} +2 -2
  50. package/web/assets/RandomJobTestPage-BOsChnPH.js +2 -0
  51. package/web/assets/ScenarioEditorPage-8XSWtwA5.js +14 -0
  52. package/web/assets/SendToChatDialog-DqPVoUgN.js +1 -0
  53. package/web/assets/ServiceControlsBar-QwLQLGFP.js +1 -0
  54. package/web/assets/ServiceControlsBar-lhuSKZqO.css +1 -0
  55. package/web/assets/ServiceDetailPage-DUw-ZZyD.js +2 -0
  56. package/web/assets/{ServiceDetailPage-BcFOlsU9.css → ServiceDetailPage-cQNK1uWq.css} +1 -1
  57. package/web/assets/ServiceFormPage-OYBr0pY4.js +1 -0
  58. package/web/assets/SettingsPage-BFoWbWhq.js +2063 -0
  59. package/web/assets/UnlockPage-DgLCLMkg.js +1 -0
  60. package/web/assets/VaultMigrationPage-C93bZgWb.js +1 -0
  61. package/web/assets/VersionBadge-2JJyjyFh.js +1 -0
  62. package/web/assets/WikiPage-DBinkJlt.js +1 -0
  63. package/web/assets/WikiView-DMyRUz16.js +1 -0
  64. package/web/assets/add-scalar-classes-C1s53GSo.js +387 -0
  65. package/web/assets/{autocomplete-BTMTTAk9.js → autocomplete-qVwP27uM.js} +3 -3
  66. package/web/assets/{basic-shape-diamond.svg-CZQG7mdB.js → basic-shape-diamond.svg-BwZ1Enqo.js} +1 -1
  67. package/web/assets/{basic-shape-hexagon.svg-BnLoXUmj.js → basic-shape-hexagon.svg-Cyko19l-.js} +1 -1
  68. package/web/assets/{basic-shape-primary-circle-ellipse-round.svg-DDU6pRYe.js → basic-shape-primary-circle-ellipse-round.svg-CWaxr-XS.js} +1 -1
  69. package/web/assets/{basic-shape-primary-square-rectangle.svg-Dq_Zdck2.js → basic-shape-primary-square-rectangle.svg-BueTJIhO.js} +1 -1
  70. package/web/assets/{basic-shape-shield.svg-DbFCxPmO.js → basic-shape-shield.svg-DiYXMUMt.js} +1 -1
  71. package/web/assets/{browser-CTYk99RA.js → browser-72mztbYe.js} +1 -1
  72. package/web/assets/{browser-DowFjZcI.js → browser-B8wHMk1o.js} +1 -1
  73. package/web/assets/{card-R4Q2Qr9t.js → card-CRMlmWrt.js} +2 -2
  74. package/web/assets/{checkbox-CfoV-T17.js → checkbox-BiDvmfqK.js} +3 -3
  75. package/web/assets/{chip-V3vhLdcF.js → chip-Cb6eK00K.js} +2 -2
  76. package/web/assets/client-3Q_o9QCm.js +24 -0
  77. package/web/assets/cloud-chat.store-DIxQd2ew.js +1 -0
  78. package/web/assets/cloud-client-Idzdbhu6.js +1 -0
  79. package/web/assets/cloud-session-CIGp7324.js +2 -0
  80. package/web/assets/cloud-session-Cj_Q0hKS.js +1 -0
  81. package/web/assets/column-4DnT4nYp.js +763 -0
  82. package/web/assets/{computer-device-desktop-monitor.svg-CRLfD7-U.js → computer-device-desktop-monitor.svg-DkL4R6oe.js} +1 -1
  83. package/web/assets/{computer-device-desktop.svg-CGKq4iih.js → computer-device-desktop.svg-DXRQ2Wl4.js} +1 -1
  84. package/web/assets/{computer-device-laptop.svg-bmeM_RDO.js → computer-device-laptop.svg-BwdMHvul.js} +1 -1
  85. package/web/assets/{computer-device-mobile-phone-android-samsung-back.svg-CFwMSjoP.js → computer-device-mobile-phone-android-samsung-back.svg-CzfVICvS.js} +1 -1
  86. package/web/assets/{computer-device-mobile-phone-android-samsung.svg-iIOhGZVY.js → computer-device-mobile-phone-android-samsung.svg-5mcZzPvQ.js} +1 -1
  87. package/web/assets/{computer-device-mobile-phone-iphone-x-back.svg-CLqnsMnT.js → computer-device-mobile-phone-iphone-x-back.svg-CovJE-GH.js} +1 -1
  88. package/web/assets/{computer-device-mobile-phone-iphone-x.svg-XECS9ZDX.js → computer-device-mobile-phone-iphone-x.svg-PgDuCiQq.js} +1 -1
  89. package/web/assets/{computer-device-mobile-tablet-touch.svg-CUR9IhGB.js → computer-device-mobile-tablet-touch.svg-1xFu6tBt.js} +1 -1
  90. package/web/assets/{computer-device-mobile-tablet.svg-BJGisjBt.js → computer-device-mobile-tablet.svg-lvKpoZnh.js} +1 -1
  91. package/web/assets/{computer-device-network-ethernet-cat6.svg-DzgiswAZ.js → computer-device-network-ethernet-cat6.svg-BJ6jNe-4.js} +1 -1
  92. package/web/assets/{computer-device-network-lan-www.svg-Dr1frFpv.js → computer-device-network-lan-www.svg-D2V9EO5w.js} +1 -1
  93. package/web/assets/{computer-device-network-wifi-connection.svg-DSj6qxT1.js → computer-device-network-wifi-connection.svg-DhFLYNK0.js} +1 -1
  94. package/web/assets/{computer-device-network-wifi-router.svg-8lGzw_-s.js → computer-device-network-wifi-router.svg-BGWV2N2B.js} +1 -1
  95. package/web/assets/{cssMode-sBjZEJAf.js → cssMode-Q_UQl6r1.js} +1 -1
  96. package/web/assets/{divider-p4BForJk.js → divider-D2zmU0b9.js} +2 -2
  97. package/web/assets/{docx-preview-D-bfEEBT.js → docx-preview-CAEo0pZg.js} +1 -1
  98. package/web/assets/{ecology-science-erlenmeyer-flask.svg-DhxVJRJ1.js → ecology-science-erlenmeyer-flask.svg-D4Cb7DOj.js} +1 -1
  99. package/web/assets/{fieldset-CCZ1tJUm.js → fieldset-CvPPXvgb.js} +2 -2
  100. package/web/assets/{freemarker2-C8iPD1fo.js → freemarker2-CCRi9jHA.js} +1 -1
  101. package/web/assets/{handlebars-BbBZAhwL.js → handlebars-4FU6Ze_N.js} +1 -1
  102. package/web/assets/{html-BQ_SV3Jd.js → html-1I40tTPC.js} +1 -1
  103. package/web/assets/{htmlMode-DReHoZFB.js → htmlMode-DQrNrxvx.js} +1 -1
  104. package/web/assets/{image-flash-lightning.svg-DbKHX2c2.js → image-flash-lightning.svg-Bh48o-tL.js} +1 -1
  105. package/web/assets/{image-picture-flower.svg-CEpqP8le.js → image-picture-flower.svg-CE0C3oid.js} +1 -1
  106. package/web/assets/{index-PMr5ScNs.js → index-SrQFBx_K.js} +36 -36
  107. package/web/assets/{interface-alert-exclamation-diamond.svg-CoNNtahD.js → interface-alert-exclamation-diamond.svg-Dzt9JrNZ.js} +1 -1
  108. package/web/assets/{interface-alert-exclamation-triangle-warning.svg-BHa7AW0u.js → interface-alert-exclamation-triangle-warning.svg-CET5JCIK.js} +1 -1
  109. package/web/assets/{interface-alert-information-circle.svg-CpRzO-l8.js → interface-alert-information-circle.svg-GX_R0hCS.js} +1 -1
  110. package/web/assets/{interface-award-crown.svg-BFOXAZFu.js → interface-award-crown.svg-BUS_3snr.js} +1 -1
  111. package/web/assets/{interface-bookmark.svg-DulnuoPg.js → interface-bookmark-tag.svg-GOtO3ous.js} +1 -1
  112. package/web/assets/{interface-bookmark-tag.svg-DpZGlSV4.js → interface-bookmark.svg-B1HfpZ9v.js} +1 -1
  113. package/web/assets/{interface-calendar-date-one.svg-CWQHbXWQ.js → interface-calendar-date-one.svg-W8G2NQFL.js} +1 -1
  114. package/web/assets/{interface-content-book-open-pages.svg-BH97UDUJ.js → interface-content-book-open-pages.svg-0dUMuEJV.js} +1 -1
  115. package/web/assets/{interface-content-book-page.svg-DmnJkpeN.js → interface-content-book-page.svg-BZ9dLtQQ.js} +1 -1
  116. package/web/assets/{interface-content-file.svg-DkouOQzj.js → interface-content-file.svg-C5JU1QaC.js} +1 -1
  117. package/web/assets/interface-content-folder.svg-BZAP22kT.js +1 -0
  118. package/web/assets/{interface-content-folder.svg-DK2esxIw.js → interface-content-folder.svg-DeWnODx9.js} +1 -1
  119. package/web/assets/{interface-copy-clipboard.svg-DuwyZprv.js → interface-copy-clipboard.svg-DneOONZN.js} +1 -1
  120. package/web/assets/{interface-edit-attachment.svg-C4lXPh7a.js → interface-edit-attachment.svg-BUDutqFa.js} +1 -1
  121. package/web/assets/{interface-edit-binocular.svg-CuA4f4ED.js → interface-edit-binocular.svg-DQ_sVWUa.js} +1 -1
  122. package/web/assets/{interface-edit-magic-wand.svg-D-Cc4zpI.js → interface-edit-magic-wand.svg-BqDEUbja.js} +1 -1
  123. package/web/assets/{interface-edit-tool-paint-roller.svg-MtAeMQ6k.js → interface-edit-tool-paint-roller.svg-CcbJr-sE.js} +1 -1
  124. package/web/assets/{interface-edit-tool-pencil.svg-ZAP8C3Sw.js → interface-edit-tool-pencil.svg-Dlmq9sMb.js} +1 -1
  125. package/web/assets/{interface-favorite-award.svg-DRZh5var.js → interface-favorite-award.svg-CfRf16yB.js} +1 -1
  126. package/web/assets/{interface-favorite-flag.svg-Dy0qBZak.js → interface-favorite-flag.svg-BeXa9l_o.js} +1 -1
  127. package/web/assets/{interface-favorite-heart.svg-Cjxi5AEp.js → interface-favorite-heart.svg-DWDXtfc-.js} +1 -1
  128. package/web/assets/{interface-favorite-star.svg-B1OPbNTd.js → interface-favorite-star.svg-D0my2O2z.js} +1 -1
  129. package/web/assets/{interface-favorite-stars-sparkles.svg-CvnZTUkf.js → interface-favorite-stars-sparkles.svg-DwnkpORM.js} +1 -1
  130. package/web/assets/{interface-hierarchy-flowchart.svg-GGCH0pvQ.js → interface-hierarchy-flowchart.svg-BS1qAEvQ.js} +1 -1
  131. package/web/assets/{interface-home-house.svg-DB_dC7eo.js → interface-home-house.svg-ByCGOgtp.js} +1 -1
  132. package/web/assets/{interface-hyperlink.svg-LlMqAHmb.js → interface-hyperlink.svg-D0RP2diO.js} +1 -1
  133. package/web/assets/{interface-lighting-brightness.svg-DutEgNfQ.js → interface-lighting-brightness.svg-B7Wir9fI.js} +1 -1
  134. package/web/assets/{interface-lock-closed.svg-DteyBWrL.js → interface-lock-closed.svg-D93wzWGY.js} +1 -1
  135. package/web/assets/{interface-lock-open-unlock.svg-D2g-W1Mn.js → interface-lock-open-unlock.svg-CEbreK15.js} +1 -1
  136. package/web/assets/{interface-login-key.svg-Dk1JjhYH.js → interface-login-key.svg-a_CUiiRx.js} +1 -1
  137. package/web/assets/{interface-search.svg-CDHAdhLc.js → interface-search.svg-CP6bN80a.js} +1 -1
  138. package/web/assets/{interface-setting-cog.svg-BXKxgm-B.js → interface-setting-cog.svg-C1yqB1H3.js} +1 -1
  139. package/web/assets/{interface-share-megaphone-bullhorn.svg-Fq3c3_sE.js → interface-share-megaphone-bullhorn.svg-BpEzN7dc.js} +1 -1
  140. package/web/assets/{interface-share-rocket.svg-BBIuiQ8_.js → interface-share-rocket.svg-CZTpH2do.js} +1 -1
  141. package/web/assets/{interface-share-satellite.svg-LZRzoY-Y.js → interface-share-satellite.svg-CDpvXyTq.js} +1 -1
  142. package/web/assets/{interface-share-space-ship.svg-C6EewxDh.js → interface-share-space-ship.svg-QXv4WQWa.js} +1 -1
  143. package/web/assets/{interface-share.svg-Bj60UW_t.js → interface-share.svg-DO9f8_w3.js} +1 -1
  144. package/web/assets/{interface-signal-square.svg-wJGg3ZJ7.js → interface-signal-square.svg-Dpbb94dT.js} +1 -1
  145. package/web/assets/{interface-time-clock-circle.svg-C2Ki_bgh.js → interface-time-clock-circle.svg-BOM8J4p-.js} +1 -1
  146. package/web/assets/{interface-time-hour-glass.svg-BeaTe2YW.js → interface-time-hour-glass.svg-B4wmuGrS.js} +1 -1
  147. package/web/assets/{interface-users-multiple.svg-ZNPhOLEJ.js → interface-users-multiple.svg-CX6Z1IAw.js} +1 -1
  148. package/web/assets/{interface-weather-moon.svg-CzOxK1E2.js → interface-weather-moon.svg-VjaROepI.js} +1 -1
  149. package/web/assets/{javascript-CV2jmATe.js → javascript-dnJjMqJl.js} +1 -1
  150. package/web/assets/{jsonMode-BpNATOZn.js → jsonMode-DIklAZzl.js} +2 -2
  151. package/web/assets/{liquid-Bkbhlfu6.js → liquid-DM3-T0fg.js} +1 -1
  152. package/web/assets/{lspLanguageFeatures-BIiCr6WR.js → lspLanguageFeatures-DtduOI48.js} +3 -3
  153. package/web/assets/{mail-chat-bubble-square.svg-B-R9ItyG.js → mail-chat-bubble-square.svg-BtQmLgyl.js} +1 -1
  154. package/web/assets/{mail-send-email-paper-airplane.svg-F4sC3JuQ.js → mail-send-email-paper-airplane.svg-DBzfHbzK.js} +1 -1
  155. package/web/assets/{mail-send-envelope.svg-BaE9bGol.js → mail-send-envelope.svg-ByoaJJai.js} +1 -1
  156. package/web/assets/{mdx-CsTzsRLc.js → mdx-COmjqkAf.js} +1 -1
  157. package/web/assets/{minus-CsIPqtIl.js → minus-CLTSMcUf.js} +2 -2
  158. package/web/assets/modal-BaVGcm8s.js +1 -0
  159. package/web/assets/modal-Cl434j6P.js +5 -0
  160. package/web/assets/{money-cashier-receipt.svg-C8rqn3qa.js → money-cashier-receipt.svg-D3I5UkrO.js} +1 -1
  161. package/web/assets/{money-currency-dollar-pay.svg-BW5dnMxx.js → money-currency-dollar-pay.svg-BEt_zoFT.js} +1 -1
  162. package/web/assets/{money-graph-arrow-increase.svg-fHNc8kor.js → money-graph-arrow-increase.svg-BFgo8Syp.js} +1 -1
  163. package/web/assets/{money-graph-bar-chart-increase.svg-65H_xZ15.js → money-graph-bar-chart-increase.svg-BPBRyqtM.js} +1 -1
  164. package/web/assets/{multiselect-Z0owdrkn.js → multiselect-Bd1n3-4t.js} +3 -3
  165. package/web/assets/{nature-ecology-leaf.svg-BIZVZEYz.js → nature-ecology-leaf.svg-DCIaflet.js} +1 -1
  166. package/web/assets/{password-Be5EVCzq.js → password-kxqyN9bC.js} +4 -4
  167. package/web/assets/{phone-telephone.svg-B1dHjXge.js → phone-telephone.svg-_P3X_Fym.js} +1 -1
  168. package/web/assets/{plus-BY4yX4ZS.js → plus-Cs39ICwL.js} +6 -6
  169. package/web/assets/process.store-m5afcW9w.js +1 -0
  170. package/web/assets/{programming-bug.svg-DJHBIgCF.js → programming-bug.svg-BGbIcZnS.js} +1 -1
  171. package/web/assets/{programming-cloud.svg-26MWe8cC.js → programming-cloud.svg-8TyU38aV.js} +1 -1
  172. package/web/assets/{programming-computer-database-server.svg-Dy7gdMab.js → programming-computer-database-server.svg-DBxTrFCn.js} +1 -1
  173. package/web/assets/{programming-computer-database.svg-3HsFit56.js → programming-computer-database.svg-Bi3RBUmB.js} +1 -1
  174. package/web/assets/{programming-module-four-layout.svg-CLumiwsC.js → programming-module-four-layout.svg-BicMHalL.js} +1 -1
  175. package/web/assets/{programming-module-three.svg-3DvVSvY_.js → programming-module-three.svg-D13tfKhT.js} +1 -1
  176. package/web/assets/{programming-module.svg-CgtgW8TW.js → programming-module.svg-HJDv8jeZ.js} +1 -1
  177. package/web/assets/{programming-script-code.svg-DdeXzy2-.js → programming-script-code.svg-oXFzvCKr.js} +1 -1
  178. package/web/assets/project-launch.store-Cgu622KX.js +1 -0
  179. package/web/assets/project.store-CM-kT9-z.js +1 -0
  180. package/web/assets/{python-YqWM3LFr.js → python-ejRXAr81.js} +1 -1
  181. package/web/assets/{radiobutton-Pm1c37Fw.js → radiobutton-BWBirQno.js} +2 -2
  182. package/web/assets/{razor-BtNiyC__.js → razor-CbzUoARP.js} +1 -1
  183. package/web/assets/router-o5ycRaEE.js +1 -0
  184. package/web/assets/settings-scope-CSLK3J2k.js +1 -0
  185. package/web/assets/settings.store-DDQmm1ig.js +1 -0
  186. package/web/assets/{shopping-cart.svg-ejbEU5yG.js → shopping-cart.svg-DL2Mf0BX.js} +1 -1
  187. package/web/assets/{shopping-gift-present.svg-RLuyvmga.js → shopping-gift-present.svg-keqzudV3.js} +1 -1
  188. package/web/assets/{shopping-shipping-box-parcel-package.svg-0GduEUbl.js → shopping-shipping-box-parcel-package.svg-BZ0Ri9AV.js} +1 -1
  189. package/web/assets/src-C1fYy9Ht.js +572 -0
  190. package/web/assets/src-DnhPQBBB.js +1 -0
  191. package/web/assets/{tabpanel-CssLXh-h.js → tabpanel-Bdw_XASI.js} +3 -3
  192. package/web/assets/{tag-new-circle.svg-CEdgH15R.js → tag-new-circle.svg-7tUBDDe7.js} +1 -1
  193. package/web/assets/theme-COzp71lh.js +1 -0
  194. package/web/assets/{toggleswitch-CEiGEBl3.js → toggleswitch-BhJmSx1t.js} +2 -2
  195. package/web/assets/{travel-map-earth-globe.svg-Dmwx1Lus.js → travel-map-earth-globe.svg-CfJb5_3k.js} +1 -1
  196. package/web/assets/trpc-Bn_6G8HK.js +1 -0
  197. package/web/assets/{tsMode-DpPT4F6s.js → tsMode-D5Gulgwd.js} +5 -5
  198. package/web/assets/{typescript-DoO0syM1.js → typescript-B73-3GtI.js} +1 -1
  199. package/web/assets/useAiChatDrawer-QOflawaX.js +1 -0
  200. package/web/assets/useCloudOrg-BZNmQ2Ek.js +1 -0
  201. package/web/assets/useEnvVarAutocomplete-DAxcV0jl.js +1 -0
  202. package/web/assets/useProjectCatalog-8u5wFtf-.js +1 -0
  203. package/web/assets/{useProjectCloudOrg-CG7seJKu.js → useProjectCloudOrg-Bkja4sed.js} +1 -1
  204. package/web/assets/useServiceUrlHost-biHEzQVv.js +1 -0
  205. package/web/assets/{xml-FoCdWVvH.js → xml-Mkua9fdo.js} +1 -1
  206. package/web/assets/{yaml-CgRsanOy.js → yaml-BP9pkdmT.js} +1 -1
  207. package/web/index.html +1 -1
  208. package/agent-manager-FZFFWISA.js +0 -10
  209. package/chunk-4PN7QBNM.js.map +0 -1
  210. package/chunk-GKK3ACWB.js.map +0 -1
  211. package/chunk-H22YLVQE.js.map +0 -1
  212. package/chunk-HK5QNU6P.js.map +0 -1
  213. package/chunk-T2BV5WZE.js.map +0 -1
  214. package/settings-manager-MAVD4GAS.js +0 -10
  215. package/src-SGSG2RSF.js.map +0 -1
  216. package/web/assets/AgentScalarChatInterface.vue-Bv7WQetq.js +0 -13
  217. package/web/assets/AgentTerminalPage-CMA5oI2T.js +0 -1
  218. package/web/assets/AiChatPage-C0Ho1rG3.js +0 -1
  219. package/web/assets/AppLayout-DBKRAp0R.js +0 -1
  220. package/web/assets/AuditPage-fZVhSJlE.js +0 -1
  221. package/web/assets/CloudAccountPage-2LiTQCKr.js +0 -1
  222. package/web/assets/CloudAccountPage-CunPTy1b.js +0 -1
  223. package/web/assets/CloudMessagingPage-DWciFn32.js +0 -2
  224. package/web/assets/DashboardPage-3psdQljM.js +0 -164
  225. package/web/assets/DashboardPage-DFaiJ4c-.css +0 -1
  226. package/web/assets/DirectoryPickerDialog-DiiAUQKg.js +0 -1
  227. package/web/assets/EnvironmentForm-MRC8U5op.js +0 -108
  228. package/web/assets/EnvironmentFormPage-gd8fGS8P.js +0 -1
  229. package/web/assets/EnvironmentListPage-DgbclvZs.js +0 -1
  230. package/web/assets/KanbanBoardPage-BBT0gqjT.js +0 -4
  231. package/web/assets/KanbanListPage-CidIQgAq.js +0 -1
  232. package/web/assets/LaunchProjectPage-DBtkrI-A.js +0 -1
  233. package/web/assets/LaunchServicesPage-DdmfVxYL.js +0 -1
  234. package/web/assets/LaunchServicesPage-zR9FoF4q.css +0 -1
  235. package/web/assets/LogViewer-CvDPgFjq.js +0 -3
  236. package/web/assets/OrgKeyPrompt-D3RmJEtb.js +0 -1
  237. package/web/assets/ProcessDetailPage-Dj0L8Jz0.js +0 -1
  238. package/web/assets/RandomJobTestPage-ohHAOaio.js +0 -2
  239. package/web/assets/ScenarioEditorPage-BIcmG3wo.js +0 -14
  240. package/web/assets/SendToChatDialog-oi4KFAVq.js +0 -1
  241. package/web/assets/ServiceControlsBar-BtnWYJmp.css +0 -1
  242. package/web/assets/ServiceControlsBar-GgoPszoH.js +0 -1
  243. package/web/assets/ServiceDetailPage-CIDlO0iu.js +0 -2
  244. package/web/assets/ServiceFormPage-p3AUhHLN.js +0 -1
  245. package/web/assets/SettingsPage-B_heumvd.js +0 -2063
  246. package/web/assets/UnlockPage-nz_1VQWy.js +0 -1
  247. package/web/assets/VaultMigrationPage-B_nZC8Cc.js +0 -1
  248. package/web/assets/VersionBadge-DJJK7bgD.js +0 -1
  249. package/web/assets/WikiPage-DiCUjWEu.js +0 -1
  250. package/web/assets/WikiView-vYMnLt41.js +0 -1
  251. package/web/assets/add-scalar-classes-_7NDhIUO.js +0 -387
  252. package/web/assets/client-DHQNUKOx.js +0 -24
  253. package/web/assets/cloud-chat.store-CaSRn8Mg.js +0 -1
  254. package/web/assets/cloud-client-CzGojtBl.js +0 -1
  255. package/web/assets/cloud-session-D71P4F3g.js +0 -2
  256. package/web/assets/cloud-session-DlLnrwVQ.js +0 -1
  257. package/web/assets/column-CjJa3tsz.js +0 -763
  258. package/web/assets/interface-content-folder.svg-BLBb2W1v.js +0 -1
  259. package/web/assets/modal-B_0-h4nC.js +0 -1
  260. package/web/assets/modal-KwmdNF_4.js +0 -5
  261. package/web/assets/process.store-B-PvNJQb.js +0 -1
  262. package/web/assets/project-launch.store-DtFeb4vv.js +0 -1
  263. package/web/assets/project.store-DcaBpnnB.js +0 -1
  264. package/web/assets/router-DnVYXVMw.js +0 -1
  265. package/web/assets/settings-scope-DR8NUZr5.js +0 -1
  266. package/web/assets/settings.store-CniuNQ3t.js +0 -1
  267. package/web/assets/src-BS3JGGS_.js +0 -1
  268. package/web/assets/src-BzZzroPd.js +0 -572
  269. package/web/assets/theme-C7HVmgEO.js +0 -1
  270. package/web/assets/trpc-C6zILEMh.js +0 -1
  271. package/web/assets/useAiChatDrawer-CnrYG1GW.js +0 -1
  272. package/web/assets/useCloudOrg-DWmP9gqs.js +0 -1
  273. package/web/assets/useEnvVarAutocomplete-Dkx7Cn9l.js +0 -1
  274. package/web/assets/useProjectCatalog-Cu3VZu2F.js +0 -1
  275. package/web/assets/useServiceUrlHost-ADKWqhx0.js +0 -1
  276. /package/{agent-manager-FZFFWISA.js.map → agent-manager-FN6M6CLD.js.map} +0 -0
  277. /package/{chat-JIJQ7IJS.js.map → chat-VCHK77CW.js.map} +0 -0
  278. /package/{chunk-N3ZI35SC.js.map → chunk-QPII36FL.js.map} +0 -0
  279. /package/{companion-OZODV5BR.js.map → companion-YB3SDDTU.js.map} +0 -0
  280. /package/{desktop-launcher-EGGVXXKV.js.map → desktop-launcher-J2BCSSGZ.js.map} +0 -0
  281. /package/{settings-manager-MAVD4GAS.js.map → settings-manager-4EDX7NIB.js.map} +0 -0
@@ -31,7 +31,7 @@ import {
31
31
  runCompanionNow,
32
32
  syncConversationFromClaudeTranscript,
33
33
  verifyJwt
34
- } from "./chunk-H22YLVQE.js";
34
+ } from "./chunk-UKLNK5YA.js";
35
35
  import {
36
36
  StoreDiskCoordinator,
37
37
  agentManager,
@@ -50,10 +50,10 @@ import {
50
50
  recordLocalRemoval,
51
51
  refsOfProjectId,
52
52
  serviceStore
53
- } from "./chunk-4PN7QBNM.js";
53
+ } from "./chunk-WQWRTPPJ.js";
54
54
  import {
55
55
  settingsManager
56
- } from "./chunk-N3ZI35SC.js";
56
+ } from "./chunk-QPII36FL.js";
57
57
  import {
58
58
  atomicWriteJsonSecure,
59
59
  atomicWriteSecure,
@@ -61,32 +61,40 @@ import {
61
61
  hasChangedSinceRead,
62
62
  readJsonFileSafe,
63
63
  rememberFile,
64
+ renameWithRetry,
64
65
  resolveConversationRunDir,
65
66
  wasRead
66
- } from "./chunk-HK5QNU6P.js";
67
+ } from "./chunk-BDQOBEZ3.js";
67
68
  import {
68
69
  AGENT_STOP_FETCH_TIMEOUT,
69
70
  ApiKeysFileSchema,
71
+ BUILTIN_VARIABLES,
72
+ BootstrapCommandSchema,
70
73
  DockerConfigSchema,
71
74
  HealthCheckSchema,
72
75
  JSLogParserSchema,
73
76
  LogSourceConfigSchema,
77
+ MASKED_VALUE,
74
78
  MissingVariableSchema,
75
79
  RestartStrategySchema,
76
80
  ScenarioSchema,
77
81
  ServiceCommandSchema,
82
+ ServiceConfigSchema,
78
83
  ServiceShortcutSchema,
79
84
  ambiguousServiceSlugs,
80
85
  crossServiceValues,
86
+ findUnresolvedReferences,
81
87
  interpolateBuiltinsInEnv,
82
88
  isSharedWithAi,
89
+ maskLogSourceSecrets,
83
90
  nativeParsers,
91
+ restoreLogSourceSecrets,
84
92
  servicePortValues,
85
93
  serviceSlug,
86
94
  serviceUrlValues,
87
95
  urlHostFor,
88
96
  withDeprecatedAliases
89
- } from "./chunk-T2BV5WZE.js";
97
+ } from "./chunk-TTPL2M74.js";
90
98
  import {
91
99
  allVaultRoots,
92
100
  env,
@@ -101,7 +109,7 @@ import {
101
109
  } from "./chunk-ZFELQG4B.js";
102
110
 
103
111
  // ../server/src/trpc/routers/chat.ts
104
- import { z as z6 } from "zod";
112
+ import { z as z9 } from "zod";
105
113
  import Anthropic2 from "@anthropic-ai/sdk";
106
114
  import OpenAI2 from "openai";
107
115
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -635,7 +643,7 @@ async function resolveConversationCwd(conversationId) {
635
643
  }
636
644
 
637
645
  // ../server/src/services/environment-overrides-store.ts
638
- import { readFile as readFile2, writeFile, rename, mkdir, chmod } from "fs/promises";
646
+ import { readFile as readFile2, writeFile, mkdir, chmod } from "fs/promises";
639
647
  import { dirname as dirname2, join as join4 } from "path";
640
648
  var FILENAME = "environment-overrides.json";
641
649
  var EnvironmentOverridesStore = class {
@@ -750,7 +758,7 @@ var EnvironmentOverridesStore = class {
750
758
  const path = join4(root, FILENAME);
751
759
  const tmpPath = path + ".tmp";
752
760
  await writeFile(tmpPath, JSON.stringify(encrypted, null, 2), "utf-8");
753
- await rename(tmpPath, path);
761
+ await renameWithRetry(tmpPath, path);
754
762
  await chmod(path, 384);
755
763
  }
756
764
  }
@@ -824,7 +832,6 @@ function slotReferenceText(variable) {
824
832
  ${slot.value}
825
833
  ${slot.post}`;
826
834
  }
827
- var MASKED_VALUE = "***";
828
835
  var HIDDEN_VALUES_NOTICE = `Values shown as ${MASKED_VALUE} are secrets their author did not share with AI. The service does receive them: never treat such a key as missing, and never pass ${MASKED_VALUE} as its value.`;
829
836
  function filterEnvForAi(resolved, sharedKeys) {
830
837
  const secret = new Set(resolved.envSecrets);
@@ -1169,8 +1176,8 @@ var EnvironmentResolver = class {
1169
1176
  return secretKeys;
1170
1177
  }
1171
1178
  interpolatesSecretKey(rawValue, ctxSecretKeys) {
1172
- const refs = [...rawValue.matchAll(/\{\{environment\.([^}]+)\}\}/g)].map((m) => m[1]);
1173
- return refs.some((ref) => ctxSecretKeys.has(ref));
1179
+ const refs2 = [...rawValue.matchAll(/\{\{environment\.([^}]+)\}\}/g)].map((m) => m[1]);
1180
+ return refs2.some((ref) => ctxSecretKeys.has(ref));
1174
1181
  }
1175
1182
  /**
1176
1183
  * Build the interpolation context for an environment.
@@ -1374,6 +1381,7 @@ var EnvironmentResolver = class {
1374
1381
  var environmentResolver = new EnvironmentResolver();
1375
1382
 
1376
1383
  // ../../packages/ai-capabilities/src/capabilities.ts
1384
+ import { z as z3 } from "zod";
1377
1385
  function toList(raw) {
1378
1386
  if (!raw) return [];
1379
1387
  const text = raw.trim();
@@ -1400,9 +1408,107 @@ function gitTarget(p) {
1400
1408
  ...p.orgId ? { orgId: p.orgId } : {}
1401
1409
  };
1402
1410
  }
1411
+ var toBool = (raw) => raw.trim().toLowerCase() === "true";
1412
+ var newId = () => globalThis.crypto.randomUUID();
1413
+ function listItem(raw) {
1414
+ try {
1415
+ return JSON.parse(raw);
1416
+ } catch {
1417
+ return raw;
1418
+ }
1419
+ }
1420
+ function parseTyped(name, schema, raw) {
1421
+ if (raw === void 0) return void 0;
1422
+ let result = raw.trim() === "null" ? schema.safeParse(null) : schema.safeParse(raw);
1423
+ if (!result.success && raw.trim() === "null") result = schema.safeParse(raw);
1424
+ if (!result.success) {
1425
+ const text = raw.trim();
1426
+ const json = listItem(text);
1427
+ if (json !== text) result = schema.safeParse(json);
1428
+ if (!result.success && !/^[[{]/.test(text)) {
1429
+ const list = schema.safeParse(toList(text).map(listItem));
1430
+ if (list.success) result = list;
1431
+ }
1432
+ }
1433
+ if (!result.success) throw new Error(`${name}: ${z3.prettifyError(result.error)}`);
1434
+ return result.data;
1435
+ }
1436
+ function withIds(items) {
1437
+ return items.map((item) => ({ ...item, id: item.id || newId() }));
1438
+ }
1439
+ var optionalId = (schema) => schema.extend({ id: z3.string().min(1).max(64).optional() });
1440
+ var DockerConfigInput = DockerConfigSchema.extend({
1441
+ bootstrapCommands: z3.array(optionalId(BootstrapCommandSchema)).max(20).default([])
1442
+ }).refine((c) => !!c.image !== !!c.dockerfile, {
1443
+ message: 'dockerConfig needs exactly one of "image" (an image to pull) or "dockerfile" (a Dockerfile to build)'
1444
+ });
1445
+ var SERVICE_FIELDS = [
1446
+ { name: "description", description: "What the service is, in a sentence" },
1447
+ { name: "agentId", description: "The agent that runs it, from list_agents. Omit to inherit from the environment.", clearable: true },
1448
+ { name: "cwd", description: `Working directory, RELATIVE to the project root (e.g. "apps/web", or omit for the root). The project is synced between machines and lives in a different folder on each: Runeya resolves a relative cwd against each machine's own project folder, while an absolute path (/home/you/\u2026) breaks on every other machine. Use an absolute path only for something outside the project, written with ~ or an environment variable ($NAME) rather than a literal home directory.`, clearable: true },
1449
+ { name: "command", description: 'Shortcut for a single command line (e.g. "npm run dev"). Replaces every existing command. Use commands for several.' },
1450
+ { name: "commands", description: 'The processes of the service. They all start AT THE SAME TIME, in parallel, and the service runs while they run \u2014 not one after another. Use several for processes that live side by side (a web server and a worker). Steps that must follow each other (build, then install, then launch) go in ONE command chained with &&. A one-off action the user triggers by hand (build, deploy, read logs) is a shortcut, not a command. Each command runs in the service cwd, or its own "cwd", relative to the project root. No absolute paths of this machine: the service is synced to other machines. Replaces every existing command. "id" is generated when omitted; "shell" runs the line through a shell (default true).', schema: z3.array(optionalId(ServiceCommandSchema)).max(50) },
1451
+ { name: "ports", description: "Ports the service listens on. Declare them: they become {{service.PORT}}, {{service.URL}} and {{services.<slug>.URL}} for the other services, which environment variables should reference instead of repeating the numbers.", schema: ServiceConfigSchema.shape.ports.unwrap().unwrap() },
1452
+ { name: "groups", description: "Groups the service belongs to. Replaces the current ones.", schema: ServiceConfigSchema.shape.groups.unwrap().unwrap() },
1453
+ { name: "url", description: "URL where the service is reached" },
1454
+ { name: "localUrls", description: 'Local domain names routed to a port of the service (e.g. {"url":"api.localhost.dev","port":3000})', schema: ServiceConfigSchema.shape.localUrls.unwrap().unwrap() },
1455
+ { name: "openapiUrl", description: "URL of its OpenAPI document" },
1456
+ { name: "docsPath", description: "Where its markdown docs live, relative to cwd or absolute. Defaults to cwd." },
1457
+ { name: "git", description: 'Its git repository: "remote" URL and "home" page', schema: ServiceConfigSchema.shape.git.unwrap(), clearable: true },
1458
+ { name: "meta", description: "Free key/value metadata (strings)", schema: ServiceConfigSchema.shape.meta.unwrap(), clearable: true },
1459
+ { name: "runner", description: '"native" runs the commands on the machine; "docker" runs the service in a container and then needs dockerConfig', schema: ServiceConfigSchema.shape.runner.unwrap().unwrap() },
1460
+ { name: "dockerConfig", description: 'With runner "docker": the container. Exactly one of "image" (pull) or "dockerfile" (inline Dockerfile, built with "buildContext", "buildArgs", "targetStage"). Ports and volumes use Docker syntax ("8080:80", "./data:/data"); host paths in volumes relative to the service directory, never an absolute path of this machine. "useNativeCommand" runs the service commands inside the container instead of its CMD ("nativeCommandMode": one shared container or one per command). "bootstrapCommands" run once when the container starts. Replaces the whole Docker configuration: read it first with get_service to keep what you do not change.', schema: DockerConfigInput },
1461
+ { name: "healthCheck", description: 'How to tell the service is ready: an HTTP "path" to call, or a "command" that must succeed', schema: HealthCheckSchema, clearable: true },
1462
+ { name: "autoRestart", description: "Restart the service when it crashes", schema: z3.boolean() },
1463
+ { name: "restartStrategy", description: "When to restart it", schema: RestartStrategySchema.unwrap() },
1464
+ { name: "maxRestarts", description: "Give up after this many restarts", schema: ServiceConfigSchema.shape.maxRestarts.unwrap() },
1465
+ { name: "restartBackoffMs", description: "Delay before a restart, in milliseconds", schema: ServiceConfigSchema.shape.restartBackoffMs.unwrap().unwrap() },
1466
+ { name: "clearLogsOnStart", description: "Clear the logs each time the service starts", schema: z3.boolean() },
1467
+ { name: "shortcuts", description: 'One-click actions shown on the service, run on demand and independently of the running commands (build, deploy, migrate, read logs). Same path rules as commands: relative to the project root, never an absolute path of this machine. Replaces the current ones. "id" is generated when omitted.', schema: z3.array(optionalId(ServiceShortcutSchema)).max(50) },
1468
+ { name: "parserIds", description: "Log parsers applied to its output, by id", schema: ServiceConfigSchema.shape.parserIds.unwrap() },
1469
+ { name: "logSources", description: 'Extra log sources beyond the console output (files, databases\u2026). Replaces the current ones. Credentials (mongo connectionString, mysql password) read as "***": send "***" back to keep the stored value, or the real value to change it.', schema: ServiceConfigSchema.shape.logSources.unwrap().unwrap() }
1470
+ ];
1471
+ function serviceParams(clearable2) {
1472
+ return SERVICE_FIELDS.map((f) => {
1473
+ const nullable = clearable2 && f.clearable;
1474
+ const base = f.schema ?? (nullable ? z3.string() : void 0);
1475
+ return {
1476
+ name: f.name,
1477
+ description: nullable ? `${f.description} null clears it.` : f.description,
1478
+ required: false,
1479
+ ...base ? { schema: nullable ? base.nullable() : base } : {}
1480
+ };
1481
+ });
1482
+ }
1483
+ function serviceFields(p, params) {
1484
+ const out = {};
1485
+ for (const param of params) {
1486
+ if (p[param.name] === void 0 || param.name === "command") continue;
1487
+ out[param.name] = param.schema ? parseTyped(param.name, param.schema, p[param.name]) : p[param.name];
1488
+ }
1489
+ if (p.command !== void 0 && p.commands === void 0) out["commands"] = [{ label: "", command: p.command, shell: true }];
1490
+ if (Array.isArray(out["commands"])) out["commands"] = withIds(out["commands"]);
1491
+ if (Array.isArray(out["shortcuts"])) out["shortcuts"] = withIds(out["shortcuts"]);
1492
+ const docker = out["dockerConfig"];
1493
+ if (docker?.bootstrapCommands) out["dockerConfig"] = { ...docker, bootstrapCommands: withIds(docker.bootstrapCommands) };
1494
+ return out;
1495
+ }
1496
+ function maskServices(result) {
1497
+ if (Array.isArray(result)) return result.map(maskServices);
1498
+ if (result && typeof result === "object" && Array.isArray(result.logSources)) {
1499
+ const service = result;
1500
+ return { ...service, logSources: maskLogSourceSecrets(service.logSources) };
1501
+ }
1502
+ return result;
1503
+ }
1504
+ var refs = (scope) => BUILTIN_VARIABLES.filter((b) => b.scope === scope).map((b) => `{{${b.name}}}`).join(", ");
1505
+ var BUILTINS_HELP = `Built-in references Runeya fills itself \u2014 filled when the service is deployed, from the service that receives the variable: ${refs("server")}, the numbered {{service.PORT_2}} / {{service.URL_2}}\u2026 for its other ports, and {{services.<slug>.PORT}}, .URL, .BASE_URL, .NAME, .ID for a sibling service of the project (slug = its name in lowercase-dashes). Filled on the machine when the service starts: ${refs("agent")}.`;
1506
+ var CREATE_SERVICE_PARAMS = serviceParams(false);
1507
+ var UPDATE_SERVICE_PARAMS = serviceParams(true);
1403
1508
  var RUNEYA_CAPABILITIES = [
1404
1509
  {
1405
1510
  name: "list_services",
1511
+ transformOutput: maskServices,
1406
1512
  description: "List services, with the serviceId and agentId to use in other calls. Pass the projectId your context names to stay on the project the user is looking at, or another one from list_projects to look elsewhere. Called with no project, this can answer for every project of every organization on the machine \u2014 far more than the interface shows.",
1407
1513
  route: "service.list",
1408
1514
  method: "GET",
@@ -1688,8 +1794,8 @@ var RUNEYA_CAPABILITIES = [
1688
1794
  },
1689
1795
  // ─── Lecture seule ───────────────────────────────────────────────────────
1690
1796
  //
1691
- // Tout ce qui se consulte sans rien changer. La création, la mise à jour et
1692
- // la suppression restent hors MCP : elles s'ajouteront au cas par cas.
1797
+ // Tout ce qui se consulte sans rien changer. Les écritures s'ajoutent au cas
1798
+ // par cas : aujourd'hui les services et leurs variables, plus bas.
1693
1799
  //
1694
1800
  // Volontairement absentes, et à ne pas ajouter sans y regarder à deux fois,
1695
1801
  // parce qu'elles rendent un secret : `environment.list` / `get` / `resolve` /
@@ -1716,6 +1822,7 @@ var RUNEYA_CAPABILITIES = [
1716
1822
  },
1717
1823
  {
1718
1824
  name: "get_service",
1825
+ transformOutput: maskServices,
1719
1826
  description: "Read the full configuration of one service: its commands, ports, groups, runner, log sources and restart policy. list_services gives the ids.",
1720
1827
  route: "service.get",
1721
1828
  method: "GET",
@@ -1726,13 +1833,145 @@ var RUNEYA_CAPABILITIES = [
1726
1833
  },
1727
1834
  {
1728
1835
  name: "get_service_env",
1729
- description: 'Read the environment variables a service runs with, and the project\'s variable inventory. `env` lists every key the service receives; a value reads "***" when it is a secret whose author did not share it with AI (sharing = ticking "AI read", or injecting it into the agents\' environment, which grants reading too). `envSecrets` says which keys are secret, `hiddenKeys` which ones are masked. A masked key is set on the service: never treat it as missing, never suggest adding it, and never pass "***" as a value \u2014 ask the user for it. `variables` describes every variable of the project \u2014 which environment defines it and its scope, its description, its flags, whether this machine overrides it, and `inService: false` for the ones this service does not receive. Use it to say where a variable must be changed instead of guessing. On an overridden variable, `sharedValue` is what the machine-local override replaces (the team\'s value, masked as "***" when unreadable); no other value appears there.',
1836
+ description: 'Read the environment variables a service runs with, and the project\'s variable inventory. `env` lists every key the service receives; a value reads "***" when it is a secret whose author did not share it with AI (sharing = ticking "AI read", or injecting it into the agents\' environment, which grants reading too). `envSecrets` says which keys are secret, `hiddenKeys` which ones are masked. A masked key is set on the service: never treat it as missing, never suggest adding it, and never pass "***" as a value \u2014 ask the user for it. `variables` describes every variable of the project \u2014 which environment defines it and its scope, its description, its flags, whether this machine overrides it, and `inService: false` for the ones this service does not receive. Use it to say where a variable must be changed instead of guessing. On an overridden variable, `sharedValue` is what the machine-local override replaces (the team\'s value, masked as "***" when unreadable); no other value appears there. This is the resolver: the values are what the service would receive \u2014 inheritance, {{environment.KEY}} references, this machine\'s overrides and server built-ins applied; agent built-ins stay as written until the service starts. Use it to check a variable you just composed. `unresolvedReferences` lists references nothing will fill (a typo, a variable that does not exist): fix them.',
1730
1837
  route: "service.getEnv",
1731
1838
  method: "GET",
1732
1839
  params: [
1733
- { name: "serviceId", description: "The service ID", required: true }
1840
+ { name: "serviceId", description: "The service ID", required: true },
1841
+ { name: "environmentId", description: "A global environment of the project to resolve in instead of the active one, without activating it (from list_environments). Omit for the active one.", required: false }
1734
1842
  ],
1735
- buildInput: (p) => ({ id: p.serviceId })
1843
+ buildInput: (p) => ({ id: p.serviceId, ...p.environmentId ? { environmentId: p.environmentId } : {} })
1844
+ },
1845
+ // ─── Écrire un service et ses variables ────────────────────────────────────
1846
+ //
1847
+ // Les variables s'écrivent à l'aveugle (`environment.setVariableBlind`) : une
1848
+ // IA remplace la valeur d'un secret sans la lire, et ne peut ni le rendre
1849
+ // public, ni le partager avec les IA. La règle tient côté serveur, dans la
1850
+ // route ; ces outils ne passent jamais par une route qui renvoie des valeurs
1851
+ // (`upsertVariable`, `removeVariable`, `update` rendent l'environnement entier).
1852
+ {
1853
+ name: "create_service",
1854
+ transformOutput: maskServices,
1855
+ description: "Create a service, native or Docker, in a project: it joins the project and gets its environments in the same call. Pass the projectId your context names. Projects are synced between machines, so write paths relative to the project root and put machine-specific values (a device serial, a local token) in environment variables, referenced as $NAME in commands \u2014 see the cwd, commands and shortcuts parameters. Then set its variables with set_environment_variable.",
1856
+ route: "service.create",
1857
+ method: "POST",
1858
+ params: [
1859
+ { name: "name", description: "The service name", required: true },
1860
+ { name: "projectId", description: "The project it joins: the one your context names, or another from list_projects. Without it, the service belongs to no project.", required: false },
1861
+ { name: "orgId", description: "Its organization. Needed only when the same project id exists in several.", required: false },
1862
+ ...CREATE_SERVICE_PARAMS
1863
+ ],
1864
+ buildInput: (p) => {
1865
+ const fields = serviceFields(p, CREATE_SERVICE_PARAMS);
1866
+ if (fields["runner"] === "docker" && !fields["dockerConfig"]) {
1867
+ throw new Error('dockerConfig: required with runner "docker" \u2014 give an "image" or a "dockerfile"');
1868
+ }
1869
+ return {
1870
+ name: p.name,
1871
+ ...fields,
1872
+ ...p.projectId ? { projectId: p.projectId } : {},
1873
+ ...p.orgId ? { orgId: p.orgId } : {}
1874
+ };
1875
+ }
1876
+ },
1877
+ {
1878
+ name: "add_service_to_project",
1879
+ description: "Add an existing service to a project, and create its environments \u2014 one for each of the project's environments, where its own variables go. Not needed after create_service, which already does it; calling it again changes nothing.",
1880
+ route: "project.addService",
1881
+ method: "POST",
1882
+ params: [
1883
+ { name: "projectId", description: "The project ID, from list_projects", required: true },
1884
+ { name: "serviceId", description: "The service ID", required: true },
1885
+ { name: "orgId", description: "Its organization. Needed only when the same project id exists in several.", required: false }
1886
+ ],
1887
+ buildInput: (p) => ({ projectId: p.projectId, serviceId: p.serviceId, ...p.orgId ? { orgId: p.orgId } : {} })
1888
+ },
1889
+ {
1890
+ name: "update_service",
1891
+ transformOutput: maskServices,
1892
+ description: "Change any part of a service configuration \u2014 commands, ports, health check, restart policy, shortcuts, log sources, whether it runs natively or in Docker (runner, dockerConfig)\u2026 Only the fields you pass change; a list or an object you pass replaces the current one whole. Read the service first with get_service.",
1893
+ route: "service.update",
1894
+ method: "POST",
1895
+ params: [
1896
+ { name: "serviceId", description: "The service ID", required: true },
1897
+ { name: "name", description: "New name", required: false },
1898
+ { name: "orgId", description: "Move the service to this organization vault. Leave unset unless asked.", required: false, schema: z3.string().max(128).nullable() },
1899
+ ...UPDATE_SERVICE_PARAMS
1900
+ ],
1901
+ buildInput: (p) => ({
1902
+ id: p.serviceId,
1903
+ ...p.name ? { name: p.name } : {},
1904
+ ...p.orgId !== void 0 ? { orgId: parseTyped("orgId", z3.string().max(128).nullable(), p.orgId) } : {},
1905
+ ...serviceFields(p, UPDATE_SERVICE_PARAMS)
1906
+ })
1907
+ },
1908
+ {
1909
+ name: "list_environments",
1910
+ description: "List the environments of a project, with no value: each one's id, name and scope (global = shared by the whole project, service = one service's own variables), which global environment is active, which service a service environment belongs to and which global environment activates it, its parents (it inherits their variables), `isolated` when a service environment does not inherit from its global one, and the variables it defines with their flags. Empty environments are listed too \u2014 a service you just created has one per global environment, where its own variables go. Use it to find the environmentId before set_environment_variable.",
1911
+ route: "environment.listForAi",
1912
+ method: "GET",
1913
+ params: [
1914
+ { name: "projectId", description: "The project ID: the one your context names, or another from list_projects", required: true },
1915
+ { name: "orgId", description: "Its organization. Needed only when the same project id exists in several.", required: false }
1916
+ ],
1917
+ buildInput: (p) => ({ projectId: p.projectId, ...p.orgId ? { orgId: p.orgId } : {} })
1918
+ },
1919
+ {
1920
+ name: "resolve_environment",
1921
+ description: "Resolve one environment alone \u2014 its variables with those inherited from its parents and this machine's overrides \u2014 as an AI may read it: secrets not shared with AI read \"***\". Built-in references ({{service.*}}, {{services.*}}, {{agent.*}}\u2026) are NOT filled, since they depend on the service that receives the variable; use get_service_env for a service's final values. `unresolvedReferences` lists references nothing will fill: a misspelled {{environment.KEY}}, or a name that is no built-in.",
1922
+ route: "environment.resolveForAi",
1923
+ method: "GET",
1924
+ params: [
1925
+ { name: "environmentId", description: "The environment, from list_environments", required: true }
1926
+ ],
1927
+ buildInput: (p) => ({ environmentId: p.environmentId })
1928
+ },
1929
+ {
1930
+ name: "set_environment_variable",
1931
+ description: `Create or change an environment variable, by name, in one environment \u2014 global or service, same rules for both. Find the environmentId with list_environments. Where it belongs: a value shared by several services (a database host, an API base URL) goes ONCE in the active global environment; services inherit it. A value only one service needs goes in that service's environment (scope service, activated by the active global one), where it also overrides a global variable of the same name. Never hardcode what Runeya already knows: a service's own port is {{service.PORT}}, its own URL {{service.URL}}, another service's address {{services.<slug>.URL}} \u2014 a copied "3210" or "http://localhost:3211" breaks as soon as a port changes or the project runs on another machine. If the port a variable needs is not declared on its service, declare it there (update_service, ports) instead of writing the number. When a written value contains a port or URL of a project service, the response lists \`suggestions\`: rewrite the value with those references. Compose instead of copying: a value can reference another variable of the resolved environment as {{environment.KEY}} (e.g. "postgres://{{environment.DB_USER}}@{{environment.DB_HOST}}:5432"). ${BUILTINS_HELP} After writing, check the result with get_service_env (a service, optionally in another global environment) or resolve_environment (an environment alone). References are substituted in one pass: a reference to a variable whose own value is only a reference may stay unexpanded, so point at the variable that holds the actual value. $NAME is not a reference here: it only expands inside a shell command. pre and post are concatenated around the value, each resolved separately. You can replace a secret's value without reading it, and create a variable as secret. You cannot make a secret public nor make it readable by AI: that stays the user's decision. Never pass "***" as a value. The response never contains the value.`,
1932
+ route: "environment.setVariableBlind",
1933
+ method: "POST",
1934
+ params: [
1935
+ { name: "environmentId", description: "The environment that holds the variable, from list_environments", required: true },
1936
+ { name: "key", description: "The variable name, e.g. DATABASE_URL", required: true },
1937
+ { name: "value", description: "The new value, possibly with {{environment.KEY}} references. Omit to leave it unchanged.", required: false },
1938
+ { name: "pre", description: 'Text put before the value (e.g. "https://"). Omit to leave it unchanged.', required: false },
1939
+ { name: "post", description: 'Text put after the value (e.g. "/api"). Omit to leave it unchanged.', required: false },
1940
+ { name: "isSecret", description: '"true" to store it as a secret. On an existing public variable, makes it secret.', required: false },
1941
+ { name: "description", description: "What the variable is for, in markdown", required: false }
1942
+ ],
1943
+ buildInput: (p) => ({
1944
+ environmentId: p.environmentId,
1945
+ key: p.key,
1946
+ ...p.value !== void 0 ? { value: p.value } : {},
1947
+ ...p.pre !== void 0 ? { pre: p.pre } : {},
1948
+ ...p.post !== void 0 ? { post: p.post } : {},
1949
+ ...p.isSecret !== void 0 ? { isSecret: toBool(p.isSecret) } : {},
1950
+ ...p.description !== void 0 ? { description: p.description } : {}
1951
+ })
1952
+ },
1953
+ {
1954
+ name: "set_environment_inheritance",
1955
+ description: "Switch whether a service environment inherits the variables of the global environment that activates it (the default), or is isolated from it and receives only its own variables. list_environments shows this as `isolated`. Isolating a service is unusual: it loses every shared variable of the project. Do it only when the user asks, and never to work around a variable \u2014 override it in the service environment instead.",
1956
+ route: "environment.setInheritanceBlind",
1957
+ method: "POST",
1958
+ params: [
1959
+ { name: "environmentId", description: "A service environment (scope service), from list_environments", required: true },
1960
+ { name: "inherit", description: '"true" to inherit from the global environment, "false" to isolate', required: true, schema: z3.boolean() }
1961
+ ],
1962
+ buildInput: (p) => ({ environmentId: p.environmentId, inherit: toBool(p.inherit ?? "true") })
1963
+ },
1964
+ {
1965
+ name: "remove_environment_variable",
1966
+ description: "Delete an environment variable, by name, from one environment. Its value is lost.",
1967
+ route: "environment.removeVariableBlind",
1968
+ method: "POST",
1969
+ params: [
1970
+ { name: "environmentId", description: "The environment that holds the variable", required: true },
1971
+ { name: "key", description: "The variable name", required: true }
1972
+ ],
1973
+ buildInput: (p) => ({ environmentId: p.environmentId, key: p.key }),
1974
+ destructive: true
1736
1975
  },
1737
1976
  {
1738
1977
  name: "get_service_metrics",
@@ -1959,6 +2198,14 @@ var RUNEYA_CAPABILITIES = [
1959
2198
  }
1960
2199
  ];
1961
2200
 
2201
+ // ../../packages/ai-capabilities/src/adapters/json-schema.ts
2202
+ import { z as z4 } from "zod";
2203
+ function paramJsonSchema(param) {
2204
+ if (!param.schema) return { type: "string", description: param.description };
2205
+ const { $schema: _ignored, ...schema } = z4.toJSONSchema(param.schema, { io: "input", unrepresentable: "any" });
2206
+ return { ...schema, description: param.description };
2207
+ }
2208
+
1962
2209
  // ../../packages/ai-capabilities/src/adapters/anthropic.ts
1963
2210
  function buildAnthropicTools(capabilities) {
1964
2211
  return capabilities.map((cap) => ({
@@ -1967,7 +2214,7 @@ function buildAnthropicTools(capabilities) {
1967
2214
  input_schema: {
1968
2215
  type: "object",
1969
2216
  properties: Object.fromEntries(
1970
- cap.params.map((p) => [p.name, { type: "string", description: p.description }])
2217
+ cap.params.map((p) => [p.name, paramJsonSchema(p)])
1971
2218
  ),
1972
2219
  required: cap.params.filter((p) => p.required).map((p) => p.name)
1973
2220
  }
@@ -1984,7 +2231,7 @@ function buildOpenAITools(capabilities) {
1984
2231
  parameters: {
1985
2232
  type: "object",
1986
2233
  properties: Object.fromEntries(
1987
- cap.params.map((p) => [p.name, { type: "string", description: p.description }])
2234
+ cap.params.map((p) => [p.name, paramJsonSchema(p)])
1988
2235
  ),
1989
2236
  required: cap.params.filter((p) => p.required).map((p) => p.name)
1990
2237
  }
@@ -2011,14 +2258,24 @@ function buildToolSafetyInstruction(capabilities) {
2011
2258
  return lines.join("\n");
2012
2259
  }
2013
2260
 
2261
+ // ../../packages/ai-capabilities/src/adapters/mcp.ts
2262
+ import { z as z5 } from "zod";
2263
+ function toRawParams(input, cap) {
2264
+ const typed = new Set(cap?.params.filter((p) => p.schema).map((p) => p.name));
2265
+ return Object.fromEntries(Object.entries(input).map(([k, v]) => [
2266
+ k,
2267
+ v === null && typed.has(k) ? "null" : v == null ? void 0 : typeof v === "object" ? JSON.stringify(v) : String(v)
2268
+ ]));
2269
+ }
2270
+
2014
2271
  // ../../packages/ai-capabilities/src/trpc-caller.ts
2015
- async function callTrpc(baseUrl, route, method, input, authToken) {
2272
+ async function callTrpc(baseUrl, route, method, input, authToken, fetchImpl = fetch) {
2016
2273
  const headers = {
2017
2274
  "Content-Type": "application/json",
2018
2275
  "Authorization": `Bearer ${authToken}`
2019
2276
  };
2020
2277
  const url = method === "GET" && input ? `${baseUrl}/api/trpc/${route}?input=${encodeURIComponent(JSON.stringify(input))}` : `${baseUrl}/api/trpc/${route}`;
2021
- const res = await fetch(url, {
2278
+ const res = await fetchImpl(url, {
2022
2279
  method,
2023
2280
  headers,
2024
2281
  ...method === "POST" ? { body: JSON.stringify(input ?? {}) } : {},
@@ -2029,6 +2286,24 @@ async function callTrpc(baseUrl, route, method, input, authToken) {
2029
2286
  const result = json["result"];
2030
2287
  return result?.["data"] ?? result ?? json;
2031
2288
  }
2289
+ async function runCapability(cap, baseUrl, params, authToken, fetchImpl = fetch) {
2290
+ const result = await callTrpc(baseUrl, cap.route, cap.method, cap.buildInput(params), authToken, fetchImpl);
2291
+ return cap.transformOutput ? cap.transformOutput(result) : result;
2292
+ }
2293
+
2294
+ // ../../packages/ai-capabilities/src/project-anchor.ts
2295
+ function applyProjectAnchor(cap, params, anchor2) {
2296
+ if (!anchor2.projectId) return params;
2297
+ const accepts = (name) => cap.params.some((p) => p.name === name);
2298
+ if (!accepts("projectId") || params["projectId"]) return params;
2299
+ return {
2300
+ ...params,
2301
+ projectId: anchor2.projectId,
2302
+ // L'organisation n'accompagne le projet que si la capability la comprend :
2303
+ // ailleurs, ce serait un champ de trop, refusé par le schéma de la route.
2304
+ ...anchor2.orgId && accepts("orgId") && !params["orgId"] ? { orgId: anchor2.orgId } : {}
2305
+ };
2306
+ }
2032
2307
 
2033
2308
  // ../server/src/services/llms-txt-generator.ts
2034
2309
  function generateAdminLlmsTxt(services, jwt, project) {
@@ -2215,7 +2490,7 @@ function normalizeToolName(raw) {
2215
2490
  const match = KNOWN_TOOL_NAMES.find((t2) => raw.startsWith(t2));
2216
2491
  return match ?? raw;
2217
2492
  }
2218
- async function executeTool(rawName, input, apiKey, authToken) {
2493
+ async function executeTool(rawName, input, apiKey, authToken, anchor2 = {}) {
2219
2494
  const name = normalizeToolName(rawName);
2220
2495
  const cap = RUNEYA_CAPABILITIES.find((c) => c.name === name);
2221
2496
  if (!cap) throw new Error(`Unknown tool: ${name}`);
@@ -2233,22 +2508,17 @@ async function executeTool(rawName, input, apiKey, authToken) {
2233
2508
  throw new Error(`No '${action}' permission for service ${serviceId}`);
2234
2509
  }
2235
2510
  }
2236
- const params = Object.fromEntries(
2237
- Object.entries(input).map(([k, v]) => [
2238
- k,
2239
- v != null ? typeof v === "object" ? JSON.stringify(v) : String(v) : void 0
2240
- ])
2241
- );
2511
+ const params = applyProjectAnchor(cap, toRawParams(input, cap), anchor2);
2242
2512
  const baseUrl = `http://localhost:${env.PORT}`;
2243
- return callTrpc(baseUrl, cap.route, cap.method, cap.buildInput(params), authToken);
2513
+ return runCapability(cap, baseUrl, params, authToken);
2244
2514
  }
2245
2515
 
2246
2516
  // ../server/src/trpc/routers/service.ts
2247
- import { z as z3 } from "zod";
2517
+ import { z as z6 } from "zod";
2248
2518
  import { TRPCError as TRPCError2 } from "@trpc/server";
2249
2519
 
2250
2520
  // ../server/src/services/audit-service.ts
2251
- import { appendFile, readFile as readFile3, stat, rename as rename2, unlink, readdir as readdir2, mkdir as mkdir2 } from "fs/promises";
2521
+ import { appendFile, readFile as readFile3, stat, rename, unlink, readdir as readdir2, mkdir as mkdir2 } from "fs/promises";
2252
2522
  var AUDIT_FILENAME = "audit.log";
2253
2523
  var MAX_FILE_SIZE = 10 * 1024 * 1024;
2254
2524
  var MAX_AGE_DAYS = 30;
@@ -2314,7 +2584,7 @@ var AuditService = class {
2314
2584
  try {
2315
2585
  const stats = await stat(filepath);
2316
2586
  if (stats.size > MAX_FILE_SIZE) {
2317
- await rename2(filepath, this.getRotatedPath());
2587
+ await rename(filepath, this.getRotatedPath());
2318
2588
  }
2319
2589
  } catch {
2320
2590
  }
@@ -2538,6 +2808,39 @@ function buildServerBuiltins(input) {
2538
2808
 
2539
2809
  // ../server/src/trpc/routers/service.ts
2540
2810
  import { isAbsolute as isAbsolute2 } from "path";
2811
+
2812
+ // ../server/src/services/attach-service.ts
2813
+ async function attachServiceToProject(target, serviceId) {
2814
+ const project = await projectStore.addService(target, serviceId);
2815
+ if (!project) return null;
2816
+ const service = await serviceStore.get(serviceId);
2817
+ if (!service) return project;
2818
+ const globalEnvs = await environmentStore.listByScope(target.id, "global", target.orgId);
2819
+ for (const globalEnv of globalEnvs) {
2820
+ if (await environmentStore.findServiceEnvironment(serviceId, globalEnv.id)) continue;
2821
+ const svcEnv = await environmentStore.create({
2822
+ projectId: target.id,
2823
+ name: `${service.name} (${globalEnv.name})`,
2824
+ scope: "service",
2825
+ reference: serviceId,
2826
+ activateOn: globalEnv.id,
2827
+ parentIds: [globalEnv.id],
2828
+ variables: {}
2829
+ }, target.orgId);
2830
+ await projectStore.addEnvironment(target, svcEnv.id);
2831
+ }
2832
+ return project;
2833
+ }
2834
+
2835
+ // ../server/src/trpc/routers/service.ts
2836
+ function withRestoredLogSecrets(incoming, existing) {
2837
+ if (!incoming) return void 0;
2838
+ try {
2839
+ return restoreLogSourceSecrets(incoming, existing);
2840
+ } catch (err) {
2841
+ throw new TRPCError2({ code: "BAD_REQUEST", message: err.message });
2842
+ }
2843
+ }
2541
2844
  async function resolveEffectiveAgentId(service) {
2542
2845
  const known = /* @__PURE__ */ new Set([
2543
2846
  ...agentManager.listAgents().map((a) => a.config.id),
@@ -2552,7 +2855,7 @@ async function resolveEffectiveAgentId(service) {
2552
2855
  }
2553
2856
  return agentManager.getDefaultAgentId();
2554
2857
  }
2555
- async function resolveServiceVariables(service) {
2858
+ async function resolveServiceVariables(service, opts = {}) {
2556
2859
  const projects = await projectStore.list();
2557
2860
  const project = projects.find((p) => p.serviceIds.includes(service.id));
2558
2861
  let resolvedService = service;
@@ -2571,16 +2874,17 @@ async function resolveServiceVariables(service) {
2571
2874
  } catch (err) {
2572
2875
  console.error("[service-router] Failed to resolve parsers for service", service.id + ":", err.message);
2573
2876
  }
2574
- if (!project || !project.activeEnvironmentId) {
2877
+ const environmentId = opts.environmentId ?? project?.activeEnvironmentId;
2878
+ if (!project || !environmentId) {
2575
2879
  return resolvedService;
2576
2880
  }
2577
2881
  try {
2578
2882
  const resolved = await environmentResolver.resolveForService({
2579
2883
  serviceId: service.id,
2580
- activeEnvironmentId: project.activeEnvironmentId
2884
+ activeEnvironmentId: environmentId
2581
2885
  });
2582
2886
  const [environment, agentId, siblings] = await Promise.all([
2583
- environmentStore.get(project.activeEnvironmentId),
2887
+ environmentStore.get(environmentId),
2584
2888
  resolveEffectiveAgentId(service),
2585
2889
  Promise.all(project.serviceIds.filter((id) => id !== service.id).map((id) => serviceStore.get(id)))
2586
2890
  ]);
@@ -2603,7 +2907,7 @@ async function resolveServiceVariables(service) {
2603
2907
  }
2604
2908
  return resolvedService;
2605
2909
  }
2606
- var DockerConfigInput = DockerConfigSchema;
2910
+ var DockerConfigInput2 = DockerConfigSchema;
2607
2911
  var serviceRouter = router({
2608
2912
  /**
2609
2913
  * Sans filtre, la réponse couvre TOUT le poste : `serviceStore.list()` rend
@@ -2620,10 +2924,10 @@ var serviceRouter = router({
2620
2924
  * silencieux ferait croire au filtrage tout en rendant les services des
2621
2925
  * autres organisations.
2622
2926
  */
2623
- list: protectedProcedure.meta({ openapi: { method: "GET", path: "/services", tags: ["services"], summary: "List services (every project of the machine unless narrowed by project or organization)", protect: true } }).input(z3.object({
2624
- projectId: z3.string().max(128).optional(),
2625
- orgId: z3.string().max(128).nullable().optional()
2626
- }).optional()).output(z3.any()).query(async ({ input, ctx }) => {
2927
+ list: protectedProcedure.meta({ openapi: { method: "GET", path: "/services", tags: ["services"], summary: "List services (every project of the machine unless narrowed by project or organization)", protect: true } }).input(z6.object({
2928
+ projectId: z6.string().max(128).optional(),
2929
+ orgId: z6.string().max(128).nullable().optional()
2930
+ }).optional()).output(z6.any()).query(async ({ input, ctx }) => {
2627
2931
  const all = await serviceStore.list();
2628
2932
  const allowedIds = getAllowedServiceIds(ctx);
2629
2933
  let filtered = allowedIds ? all.filter((s) => allowedIds.has(s.id)) : all;
@@ -2643,7 +2947,7 @@ var serviceRouter = router({
2643
2947
  effectiveAgentId: await resolveEffectiveAgentId(s)
2644
2948
  })));
2645
2949
  }),
2646
- get: protectedProcedure.meta({ openapi: { method: "GET", path: "/services/{id}", tags: ["services"], summary: "Get a service by ID", protect: true } }).input(z3.object({ id: z3.string().max(128) })).output(z3.any()).query(async ({ input, ctx }) => {
2950
+ get: protectedProcedure.meta({ openapi: { method: "GET", path: "/services/{id}", tags: ["services"], summary: "Get a service by ID", protect: true } }).input(z6.object({ id: z6.string().max(128) })).output(z6.any()).query(async ({ input, ctx }) => {
2647
2951
  requireServiceAction(ctx, input.id, "service:read");
2648
2952
  const service = await serviceStore.get(input.id);
2649
2953
  if (!service) {
@@ -2669,17 +2973,28 @@ var serviceRouter = router({
2669
2973
  * valeurs** — où chacune est définie, ce que ses cases disent, et si ce
2670
2974
  * service la reçoit. Sans lui, un agent lisait l'effet sans la cause.
2671
2975
  */
2672
- getEnv: protectedProcedure.meta({ openapi: { method: "GET", path: "/services/{id}/env", tags: ["services"], summary: "Get a service's environment variables (unshared secrets masked) plus the project's value-free variable inventory", protect: true } }).input(z3.object({ id: z3.string().max(128) })).output(z3.any()).query(async ({ input, ctx }) => {
2976
+ getEnv: protectedProcedure.meta({ openapi: { method: "GET", path: "/services/{id}/env", tags: ["services"], summary: "Get a service's environment variables (unshared secrets masked) plus the project's value-free variable inventory", protect: true } }).input(z6.object({
2977
+ id: z6.string().max(128),
2978
+ // Un environnement global du projet où résoudre, sans l'activer. Absent : l'actif.
2979
+ environmentId: z6.string().max(128).optional()
2980
+ })).output(z6.any()).query(async ({ input, ctx }) => {
2673
2981
  requireServiceAction(ctx, input.id, "service:read");
2674
2982
  const service = await serviceStore.get(input.id);
2675
2983
  if (!service) {
2676
2984
  throw new TRPCError2({ code: "NOT_FOUND", message: `Service ${input.id} not found` });
2677
2985
  }
2678
- const resolved = await resolveServiceVariables(service);
2679
2986
  const project = await projectStore.ofService(service.id);
2680
- const shared = project?.activeEnvironmentId ? await environmentResolver.resolveAiSharedKeysForService({
2987
+ if (input.environmentId) {
2988
+ const target = await environmentStore.get(input.environmentId);
2989
+ if (!target || !project || target.projectId !== project.id || (target.scope ?? "global") !== "global") {
2990
+ throw new TRPCError2({ code: "BAD_REQUEST", message: `Environment ${input.environmentId} is not a global environment of this service's project` });
2991
+ }
2992
+ }
2993
+ const environmentId = input.environmentId ?? project?.activeEnvironmentId ?? null;
2994
+ const resolved = await resolveServiceVariables(service, input.environmentId ? { environmentId: input.environmentId } : {});
2995
+ const shared = environmentId ? await environmentResolver.resolveAiSharedKeysForService({
2681
2996
  serviceId: service.id,
2682
- activeEnvironmentId: project.activeEnvironmentId
2997
+ activeEnvironmentId: environmentId
2683
2998
  }) : /* @__PURE__ */ new Set();
2684
2999
  const filtered = filterEnvForAi(
2685
3000
  { env: resolved.env ?? {}, envSecrets: resolved.envSecrets ?? [] },
@@ -2688,8 +3003,8 @@ var serviceRouter = router({
2688
3003
  const [environments, overrides, sharedResolved] = project ? await Promise.all([
2689
3004
  environmentStore.getByProjectId(project.id, project.orgId ?? null),
2690
3005
  environmentOverridesStore.getAll(),
2691
- project.activeEnvironmentId ? environmentResolver.resolveForService(
2692
- { serviceId: service.id, activeEnvironmentId: project.activeEnvironmentId },
3006
+ environmentId ? environmentResolver.resolveForService(
3007
+ { serviceId: service.id, activeEnvironmentId: environmentId },
2693
3008
  { applyOverrides: false }
2694
3009
  ) : Promise.resolve({ env: {}, envSecrets: [] })
2695
3010
  ]) : [[], {}, { env: {}, envSecrets: [] }];
@@ -2700,38 +3015,47 @@ var serviceRouter = router({
2700
3015
  resolvedSecretKeys: new Set(resolved.envSecrets ?? []),
2701
3016
  maskedKeys: new Set(filtered.hiddenKeys)
2702
3017
  });
2703
- return { ...filtered, variables };
3018
+ return {
3019
+ ...filtered,
3020
+ environmentId,
3021
+ // Ce qui arrivera tel quel au process. Les valeurs masquées n'y sont pas
3022
+ // inspectées : leurs références diraient la forme du secret.
3023
+ unresolvedReferences: findUnresolvedReferences(resolved.env ?? {}, { serverResolved: true, skipKeys: filtered.hiddenKeys }),
3024
+ variables
3025
+ };
2704
3026
  }),
2705
- create: protectedProcedure.meta({ openapi: { method: "POST", path: "/services", tags: ["services"], summary: "Create a new service", protect: true } }).output(z3.any()).input(
2706
- z3.object({
2707
- agentId: z3.string().max(128).optional(),
2708
- name: z3.string().min(1).max(200),
2709
- commands: z3.array(ServiceCommandSchema).max(50).optional(),
2710
- cwd: z3.string().max(4096).optional(),
2711
- ports: z3.array(z3.number().int().min(1).max(65535)).max(20).optional(),
2712
- groups: z3.array(z3.string().max(200)).max(20).optional(),
2713
- description: z3.string().max(2e3).optional(),
2714
- docsPath: z3.string().max(4096).optional(),
2715
- url: z3.string().max(2048).optional(),
2716
- localUrls: z3.array(z3.object({
2717
- url: z3.string().max(253),
2718
- port: z3.number().int().min(1).max(65535)
3027
+ create: protectedProcedure.meta({ openapi: { method: "POST", path: "/services", tags: ["services"], summary: "Create a new service", protect: true } }).output(z6.any()).input(
3028
+ z6.object({
3029
+ agentId: z6.string().max(128).optional(),
3030
+ name: z6.string().min(1).max(200),
3031
+ commands: z6.array(ServiceCommandSchema).max(50).optional(),
3032
+ cwd: z6.string().max(4096).optional(),
3033
+ ports: z6.array(z6.number().int().min(1).max(65535)).max(20).optional(),
3034
+ groups: z6.array(z6.string().max(200)).max(20).optional(),
3035
+ description: z6.string().max(2e3).optional(),
3036
+ docsPath: z6.string().max(4096).optional(),
3037
+ url: z6.string().max(2048).optional(),
3038
+ localUrls: z6.array(z6.object({
3039
+ url: z6.string().max(253),
3040
+ port: z6.number().int().min(1).max(65535)
2719
3041
  })).max(20).optional(),
2720
- openapiUrl: z3.string().max(2048).optional(),
2721
- git: z3.object({ remote: z3.string().max(2048).optional(), home: z3.string().max(2048).optional() }).optional(),
2722
- meta: z3.record(z3.string().max(256), z3.string().max(2e3)).optional().refine((obj) => !obj || Object.keys(obj).length <= 100, { message: "Too many meta keys (max 100)" }),
2723
- runner: z3.enum(["native", "docker"]).optional().default("native"),
2724
- dockerConfig: DockerConfigInput.optional(),
3042
+ openapiUrl: z6.string().max(2048).optional(),
3043
+ git: z6.object({ remote: z6.string().max(2048).optional(), home: z6.string().max(2048).optional() }).optional(),
3044
+ meta: z6.record(z6.string().max(256), z6.string().max(2e3)).optional().refine((obj) => !obj || Object.keys(obj).length <= 100, { message: "Too many meta keys (max 100)" }),
3045
+ runner: z6.enum(["native", "docker"]).optional().default("native"),
3046
+ dockerConfig: DockerConfigInput2.optional(),
2725
3047
  healthCheck: HealthCheckSchema.optional(),
2726
- autoRestart: z3.boolean().optional().default(false),
3048
+ autoRestart: z6.boolean().optional().default(false),
3049
+ clearLogsOnStart: z6.boolean().optional(),
2727
3050
  restartStrategy: RestartStrategySchema.optional(),
2728
- maxRestarts: z3.number().int().nonnegative().optional(),
2729
- restartBackoffMs: z3.number().int().positive().optional().default(1e3),
2730
- orgId: z3.string().max(128).nullable().optional(),
3051
+ maxRestarts: z6.number().int().nonnegative().optional(),
3052
+ restartBackoffMs: z6.number().int().positive().optional().default(1e3),
3053
+ orgId: z6.string().max(128).nullable().optional(),
3054
+ logSources: z6.array(LogSourceConfigSchema).max(20).optional(),
2731
3055
  // Le projet qui va l'adopter : le service naît dans son coffre.
2732
- projectId: z3.string().max(128).optional(),
2733
- shortcuts: z3.array(ServiceShortcutSchema).max(50).optional(),
2734
- parserIds: z3.array(z3.string().max(128)).max(50).optional()
3056
+ projectId: z6.string().max(128).optional(),
3057
+ shortcuts: z6.array(ServiceShortcutSchema).max(50).optional(),
3058
+ parserIds: z6.array(z6.string().max(128)).max(50).optional()
2735
3059
  })
2736
3060
  ).mutation(async ({ input }) => {
2737
3061
  if (input.agentId) {
@@ -2743,55 +3067,59 @@ var serviceRouter = router({
2743
3067
  });
2744
3068
  }
2745
3069
  }
2746
- if (input.runner === "docker") {
2747
- throw new TRPCError2({ code: "BAD_REQUEST", message: 'Docker runner is not yet supported. Use "native" runner.' });
2748
- }
2749
3070
  const { projectId, ...fields } = input;
3071
+ const logSources = withRestoredLogSecrets(input.logSources, []);
3072
+ const target = projectId ? { id: projectId, ...input.orgId !== void 0 ? { orgId: input.orgId } : {} } : void 0;
3073
+ if (target && !await projectStore.get(target)) {
3074
+ throw new TRPCError2({ code: "NOT_FOUND", message: `Project ${projectId} not found` });
3075
+ }
2750
3076
  const service = await serviceStore.create(
2751
- { ...fields, agentId: input.agentId },
3077
+ { ...fields, agentId: input.agentId, ...logSources ? { logSources } : {} },
2752
3078
  projectId ? { id: projectId, orgId: input.orgId } : void 0
2753
3079
  );
3080
+ if (target) await attachServiceToProject(target, service.id);
2754
3081
  await auditService.log({ userId: "local", action: "create", entityType: "service", entityId: service.id, metadata: { name: input.name } });
2755
3082
  return service;
2756
3083
  }),
2757
- update: protectedProcedure.meta({ openapi: { method: "PATCH", path: "/services/{id}", tags: ["services"], summary: "Update a service", protect: true } }).output(z3.any()).input(
2758
- z3.object({
2759
- id: z3.string().max(128),
2760
- agentId: z3.string().max(128).nullable().optional(),
3084
+ update: protectedProcedure.meta({ openapi: { method: "PATCH", path: "/services/{id}", tags: ["services"], summary: "Update a service", protect: true } }).output(z6.any()).input(
3085
+ z6.object({
3086
+ id: z6.string().max(128),
3087
+ agentId: z6.string().max(128).nullable().optional(),
2761
3088
  // null = clear (inherit from env)
2762
- name: z3.string().min(1).max(200).optional(),
2763
- commands: z3.array(ServiceCommandSchema).max(50).optional(),
2764
- cwd: z3.string().max(4096).nullable().optional(),
2765
- ports: z3.array(z3.number().int().min(1).max(65535)).max(20).optional(),
2766
- groups: z3.array(z3.string().max(200)).max(20).optional(),
2767
- description: z3.string().max(2e3).optional(),
2768
- docsPath: z3.string().max(4096).optional(),
2769
- url: z3.string().max(2048).optional(),
2770
- localUrls: z3.array(z3.object({
2771
- url: z3.string().max(253),
2772
- port: z3.number().int().min(1).max(65535)
3089
+ name: z6.string().min(1).max(200).optional(),
3090
+ commands: z6.array(ServiceCommandSchema).max(50).optional(),
3091
+ cwd: z6.string().max(4096).nullable().optional(),
3092
+ ports: z6.array(z6.number().int().min(1).max(65535)).max(20).optional(),
3093
+ groups: z6.array(z6.string().max(200)).max(20).optional(),
3094
+ description: z6.string().max(2e3).optional(),
3095
+ docsPath: z6.string().max(4096).optional(),
3096
+ url: z6.string().max(2048).optional(),
3097
+ localUrls: z6.array(z6.object({
3098
+ url: z6.string().max(253),
3099
+ port: z6.number().int().min(1).max(65535)
2773
3100
  })).max(20).optional(),
2774
- openapiUrl: z3.string().max(2048).optional(),
2775
- git: z3.object({ remote: z3.string().max(2048).optional(), home: z3.string().max(2048).optional() }).nullable().optional(),
2776
- meta: z3.record(z3.string().max(256), z3.string().max(2e3)).nullable().optional().refine((obj) => !obj || Object.keys(obj).length <= 100, { message: "Too many meta keys (max 100)" }),
2777
- runner: z3.enum(["native", "docker"]).optional(),
2778
- dockerConfig: DockerConfigInput.optional(),
3101
+ openapiUrl: z6.string().max(2048).optional(),
3102
+ git: z6.object({ remote: z6.string().max(2048).optional(), home: z6.string().max(2048).optional() }).nullable().optional(),
3103
+ meta: z6.record(z6.string().max(256), z6.string().max(2e3)).nullable().optional().refine((obj) => !obj || Object.keys(obj).length <= 100, { message: "Too many meta keys (max 100)" }),
3104
+ runner: z6.enum(["native", "docker"]).optional(),
3105
+ dockerConfig: DockerConfigInput2.optional(),
2779
3106
  healthCheck: HealthCheckSchema.nullable().optional(),
2780
- autoRestart: z3.boolean().optional(),
2781
- clearLogsOnStart: z3.boolean().optional(),
3107
+ autoRestart: z6.boolean().optional(),
3108
+ clearLogsOnStart: z6.boolean().optional(),
2782
3109
  restartStrategy: RestartStrategySchema.optional(),
2783
- maxRestarts: z3.number().int().nonnegative().optional(),
2784
- restartBackoffMs: z3.number().int().positive().optional(),
2785
- orgId: z3.string().max(128).nullable().optional(),
2786
- shortcuts: z3.array(ServiceShortcutSchema).max(50).optional(),
2787
- parserIds: z3.array(z3.string().max(128)).max(50).optional(),
2788
- logSources: z3.array(LogSourceConfigSchema).max(20).optional()
3110
+ maxRestarts: z6.number().int().nonnegative().optional(),
3111
+ restartBackoffMs: z6.number().int().positive().optional(),
3112
+ orgId: z6.string().max(128).nullable().optional(),
3113
+ shortcuts: z6.array(ServiceShortcutSchema).max(50).optional(),
3114
+ parserIds: z6.array(z6.string().max(128)).max(50).optional(),
3115
+ logSources: z6.array(LogSourceConfigSchema).max(20).optional()
2789
3116
  })
2790
3117
  ).mutation(async ({ input }) => {
2791
3118
  const existing = await serviceStore.get(input.id);
2792
3119
  if (!existing) {
2793
3120
  throw new TRPCError2({ code: "NOT_FOUND", message: `Service ${input.id} not found` });
2794
3121
  }
3122
+ const logSources = withRestoredLogSecrets(input.logSources, existing.logSources ?? []);
2795
3123
  let stoppedForAgentChange = false;
2796
3124
  if (input.agentId !== void 0 && input.agentId !== existing.agentId && existing.agentId) {
2797
3125
  const oldAgentStatus = agentManager.getStatus(existing.agentId);
@@ -2816,7 +3144,7 @@ var serviceRouter = router({
2816
3144
  }
2817
3145
  }
2818
3146
  }
2819
- const service = await serviceStore.update(input);
3147
+ const service = await serviceStore.update({ ...input, ...logSources ? { logSources } : {} });
2820
3148
  if (!service) {
2821
3149
  throw new TRPCError2({ code: "NOT_FOUND", message: `Service ${input.id} not found` });
2822
3150
  }
@@ -2840,7 +3168,7 @@ var serviceRouter = router({
2840
3168
  await auditService.log({ userId: "local", action: "update", entityType: "service", entityId: input.id });
2841
3169
  return { ...service, effectiveAgentId: await resolveEffectiveAgentId(service), stoppedForAgentChange };
2842
3170
  }),
2843
- delete: protectedProcedure.meta({ openapi: { method: "DELETE", path: "/services/{id}", tags: ["services"], summary: "Delete a service", protect: true } }).input(z3.object({ id: z3.string().max(128) })).output(z3.object({ success: z3.literal(true) })).mutation(async ({ input }) => {
3171
+ delete: protectedProcedure.meta({ openapi: { method: "DELETE", path: "/services/{id}", tags: ["services"], summary: "Delete a service", protect: true } }).input(z6.object({ id: z6.string().max(128) })).output(z6.object({ success: z6.literal(true) })).mutation(async ({ input }) => {
2844
3172
  const deleted = await serviceStore.delete(input.id);
2845
3173
  if (!deleted) {
2846
3174
  throw new TRPCError2({ code: "NOT_FOUND", message: `Service ${input.id} not found` });
@@ -2848,7 +3176,7 @@ var serviceRouter = router({
2848
3176
  await auditService.log({ userId: "local", action: "delete", entityType: "service", entityId: input.id });
2849
3177
  return { success: true };
2850
3178
  }),
2851
- checkCwd: protectedProcedure.input(z3.object({ id: z3.string().max(128), checkReachability: z3.boolean().optional() })).query(async ({ input }) => {
3179
+ checkCwd: protectedProcedure.input(z6.object({ id: z6.string().max(128), checkReachability: z6.boolean().optional() })).query(async ({ input }) => {
2852
3180
  const service = await serviceStore.get(input.id);
2853
3181
  if (!service) {
2854
3182
  throw new TRPCError2({ code: "NOT_FOUND", message: `Service ${input.id} not found` });
@@ -2881,7 +3209,7 @@ var serviceRouter = router({
2881
3209
  }
2882
3210
  return { exists, canClone, unresolvedVars: [], resolvedCwd, gitMismatch };
2883
3211
  }),
2884
- cloneRepository: protectedProcedure.input(z3.object({ id: z3.string().max(128) })).mutation(async ({ input }) => {
3212
+ cloneRepository: protectedProcedure.input(z6.object({ id: z6.string().max(128) })).mutation(async ({ input }) => {
2885
3213
  const service = await serviceStore.get(input.id);
2886
3214
  if (!service) {
2887
3215
  throw new TRPCError2({ code: "NOT_FOUND", message: `Service ${input.id} not found` });
@@ -3639,9 +3967,9 @@ async function fetchProviderModels(provider, plaintextKey) {
3639
3967
  async function vaultOfProject(projectId) {
3640
3968
  if (!projectId) return void 0;
3641
3969
  await ensureProjectsLoaded();
3642
- const refs = refsOfProjectId(projectId);
3643
- if (refs.length !== 1) return void 0;
3644
- return refs[0]?.orgId ?? void 0;
3970
+ const refs2 = refsOfProjectId(projectId);
3971
+ if (refs2.length !== 1) return void 0;
3972
+ return refs2[0]?.orgId ?? void 0;
3645
3973
  }
3646
3974
 
3647
3975
  // ../server/src/services/image-storage.service.ts
@@ -3830,13 +4158,13 @@ async function resolveImagesToBase64(images, contextId) {
3830
4158
  }
3831
4159
 
3832
4160
  // ../server/src/trpc/routers/cloud-auth.ts
3833
- import { z as z5 } from "zod";
4161
+ import { z as z8 } from "zod";
3834
4162
  import { hostname } from "os";
3835
4163
  import { basename } from "path";
3836
4164
  import { TRPCError as TRPCError3 } from "@trpc/server";
3837
4165
 
3838
4166
  // ../server/src/services/cloud-session-store.ts
3839
- import { readFile as readFile6, writeFile as writeFile3, rename as rename3, mkdir as mkdir5, chmod as chmod2, unlink as unlink3 } from "fs/promises";
4167
+ import { readFile as readFile6, writeFile as writeFile3, mkdir as mkdir5, chmod as chmod2, unlink as unlink3 } from "fs/promises";
3840
4168
  import { dirname as dirname3 } from "path";
3841
4169
  import { randomBytes as randomBytes2, createHash, timingSafeEqual as timingSafeEqual2 } from "crypto";
3842
4170
  var FILENAME2 = "cloud-session.json";
@@ -3948,7 +4276,7 @@ var CloudSessionStore = class {
3948
4276
  const payload = { version: 2, accounts: this.accounts };
3949
4277
  const tmpPath = filePath + ".tmp";
3950
4278
  await writeFile3(tmpPath, JSON.stringify(payload, null, 2), "utf-8");
3951
- await rename3(tmpPath, filePath);
4279
+ await renameWithRetry(tmpPath, filePath);
3952
4280
  await chmod2(filePath, 384);
3953
4281
  }
3954
4282
  /**
@@ -4085,14 +4413,14 @@ var cloudSessionStore = new CloudSessionStore();
4085
4413
 
4086
4414
  // ../server/src/services/lan-mode.ts
4087
4415
  import { networkInterfaces } from "os";
4088
- import { readFile as readFile7, writeFile as writeFile4, rename as rename4, mkdir as mkdir6 } from "fs/promises";
4416
+ import { readFile as readFile7, writeFile as writeFile4, mkdir as mkdir6 } from "fs/promises";
4089
4417
  import { join as join7 } from "path";
4090
- import { z as z4 } from "zod";
4418
+ import { z as z7 } from "zod";
4091
4419
  var LOOPBACK2 = "127.0.0.1";
4092
4420
  var ANY = "0.0.0.0";
4093
4421
  var NETWORK_FILE = "network.json";
4094
- var NetworkFileSchema = z4.object({
4095
- instances: z4.record(z4.string(), z4.object({ lanEnabled: z4.boolean().default(false) })).default({})
4422
+ var NetworkFileSchema = z7.object({
4423
+ instances: z7.record(z7.string(), z7.object({ lanEnabled: z7.boolean().default(false) })).default({})
4096
4424
  });
4097
4425
  var httpServer = null;
4098
4426
  function instanceKey() {
@@ -4120,7 +4448,7 @@ async function writePersisted(lanEnabled) {
4120
4448
  const filePath = networkFilePath();
4121
4449
  const tmpPath = filePath + ".tmp";
4122
4450
  await writeFile4(tmpPath, JSON.stringify(state, null, 2), "utf-8");
4123
- await rename4(tmpPath, filePath);
4451
+ await renameWithRetry(tmpPath, filePath);
4124
4452
  }
4125
4453
  function registerHttpServer(server) {
4126
4454
  httpServer = server;
@@ -4360,15 +4688,15 @@ function isAllowedProxyPath(path) {
4360
4688
  const [pathname] = path.split("?");
4361
4689
  return PROXY_PREFIXES.some((p) => pathname === p || pathname.startsWith(p));
4362
4690
  }
4363
- var ScopeSchema = z5.object({
4364
- accountId: z5.string().min(1).max(64)
4691
+ var ScopeSchema = z8.object({
4692
+ accountId: z8.string().min(1).max(64)
4365
4693
  });
4366
4694
  function scopeOf(input) {
4367
4695
  return { accountId: input.accountId };
4368
4696
  }
4369
4697
  var cloudAuthRouter = router({
4370
4698
  /** Build the cloud authorization URL to open in the browser. */
4371
- startLogin: protectedProcedure.input(z5.object({ returnTo: z5.string().url().max(2048) })).mutation(async ({ input }) => {
4699
+ startLogin: protectedProcedure.input(z8.object({ returnTo: z8.string().url().max(2048) })).mutation(async ({ input }) => {
4372
4700
  const callback = callbackForReturnTo(input.returnTo);
4373
4701
  if (!callback) {
4374
4702
  throw new TRPCError3({
@@ -4406,7 +4734,7 @@ var cloudAuthRouter = router({
4406
4734
  * `null` quand rien ne rattache cette organisation à un compte de ce poste :
4407
4735
  * l'interface l'affiche comme déconnectée, ce qu'elle est.
4408
4736
  */
4409
- accountForOrg: protectedProcedure.input(z5.object({ orgId: z5.string().min(1).max(128) })).query(async ({ input }) => ({ accountId: await accountForOrg(input.orgId) })),
4737
+ accountForOrg: protectedProcedure.input(z8.object({ orgId: z8.string().min(1).max(128) })).query(async ({ input }) => ({ accountId: await accountForOrg(input.orgId) })),
4410
4738
  /**
4411
4739
  * Les comptes liés à ce poste, et l'organisation dont chacun répond.
4412
4740
  *
@@ -4462,7 +4790,7 @@ var cloudAuthRouter = router({
4462
4790
  * drops the session, and the local token is dropped here too, so nothing is
4463
4791
  * left holding a dead credential.
4464
4792
  */
4465
- revokeDevice: protectedProcedure.input(ScopeSchema.extend({ id: z5.string().min(1).max(128) })).mutation(async ({ input }) => {
4793
+ revokeDevice: protectedProcedure.input(ScopeSchema.extend({ id: z8.string().min(1).max(128) })).mutation(async ({ input }) => {
4466
4794
  const { accountId } = input;
4467
4795
  if (!accountId) throw new TRPCError3({ code: "PRECONDITION_FAILED", message: "No cloud account for this scope." });
4468
4796
  const res = await cloudFetch2("/api/auth/device/revoke", {
@@ -4485,17 +4813,17 @@ var cloudAuthRouter = router({
4485
4813
  * the cloud: the web UI asks its own server, which holds the credential.
4486
4814
  */
4487
4815
  proxy: protectedProcedure.input(
4488
- z5.object({
4489
- path: z5.string().min(1).max(512),
4490
- method: z5.enum(["GET", "POST"]).default("GET"),
4491
- query: z5.record(z5.string().max(128), z5.string().max(2048)).optional(),
4492
- body: z5.unknown().optional(),
4816
+ z8.object({
4817
+ path: z8.string().min(1).max(512),
4818
+ method: z8.enum(["GET", "POST"]).default("GET"),
4819
+ query: z8.record(z8.string().max(128), z8.string().max(2048)).optional(),
4820
+ body: z8.unknown().optional(),
4493
4821
  // Obligatoire, et seul : c'est la porte par laquelle passent tous les
4494
4822
  // appels cloud de l'interface. La laisser optionnelle est ce qui a
4495
4823
  // permis aux composables partagées de n'envoyer aucune portée pendant
4496
4824
  // trente routes, et au serveur de retomber sur « le compte unique du
4497
4825
  // poste » — muet dès qu'il y en a eu deux.
4498
- accountId: z5.string().min(1).max(64)
4826
+ accountId: z8.string().min(1).max(64)
4499
4827
  })
4500
4828
  ).mutation(async ({ input }) => {
4501
4829
  if (!isAllowedProxyPath(input.path)) {
@@ -5277,7 +5605,7 @@ function tailTranscript(opts) {
5277
5605
 
5278
5606
  // ../server/src/services/ai-runners/claude-pty-runner.ts
5279
5607
  async function getAgentManager() {
5280
- const { agentManager: agentManager2 } = await import("./agent-manager-FZFFWISA.js");
5608
+ const { agentManager: agentManager2 } = await import("./agent-manager-FN6M6CLD.js");
5281
5609
  return agentManager2;
5282
5610
  }
5283
5611
  function buildPtyArgs(params, sessionId, opts) {
@@ -5969,7 +6297,7 @@ async function shutdownCodexAppServer() {
5969
6297
  }
5970
6298
  }
5971
6299
  async function getAgentManager2() {
5972
- const { agentManager: agentManager2 } = await import("./agent-manager-FZFFWISA.js");
6300
+ const { agentManager: agentManager2 } = await import("./agent-manager-FN6M6CLD.js");
5973
6301
  return agentManager2;
5974
6302
  }
5975
6303
  function parseRuneyaCurlCommand(command) {
@@ -6407,22 +6735,22 @@ ${prompt}`;
6407
6735
  };
6408
6736
 
6409
6737
  // ../server/src/trpc/routers/chat.ts
6410
- var MessageSchema = z6.object({
6411
- role: z6.enum(["user", "assistant"]),
6412
- content: z6.string().max(1e5)
6738
+ var MessageSchema = z9.object({
6739
+ role: z9.enum(["user", "assistant"]),
6740
+ content: z9.string().max(1e5)
6413
6741
  });
6414
- var ImagePartSchema = z6.object({
6415
- type: z6.literal("image"),
6416
- imageId: z6.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
6417
- url: z6.string().max(500),
6418
- mimeType: z6.string().max(100),
6419
- altText: z6.string().max(500).optional()
6742
+ var ImagePartSchema = z9.object({
6743
+ type: z9.literal("image"),
6744
+ imageId: z9.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
6745
+ url: z9.string().max(500),
6746
+ mimeType: z9.string().max(100),
6747
+ altText: z9.string().max(500).optional()
6420
6748
  });
6421
- var ImagePartsSchema = z6.array(ImagePartSchema).max(5).optional();
6749
+ var ImagePartsSchema = z9.array(ImagePartSchema).max(5).optional();
6422
6750
  var LANGUAGE_INSTRUCTION = "Always respond in the same language the user writes in.";
6423
6751
  async function buildSystemPrompt(apiKey) {
6424
6752
  const allServices = await serviceStore.list();
6425
- const resolvedServices = await Promise.all(allServices.map(resolveServiceVariables));
6753
+ const resolvedServices = await Promise.all(allServices.map((s) => resolveServiceVariables(s)));
6426
6754
  const context = apiKey ? generateLlmsTxt(apiKey, resolvedServices.filter((s) => apiKey.scopes.services.some((p) => p.serviceId === s.id))) : generateAdminLlmsTxt(resolvedServices);
6427
6755
  const runeya_ai_vars = Object.entries(process.env).filter(([k]) => k.startsWith("RUNEYA_AI_")).map(([k, v]) => `${k}=${v}`).join("\n");
6428
6756
  const envSection = runeya_ai_vars ? `
@@ -6434,7 +6762,7 @@ ${runeya_ai_vars}` : "";
6434
6762
 
6435
6763
  ${context}${envSection}`;
6436
6764
  }
6437
- async function* runAnthropic(client, model, system, initialMessages, apiKey, authToken, signal) {
6765
+ async function* runAnthropic(client, model, system, initialMessages, apiKey, authToken, signal, anchor2 = {}) {
6438
6766
  const messages = [...initialMessages];
6439
6767
  const MAX_TOOL_ROUNDS = 10;
6440
6768
  for (let round = 0; round < MAX_TOOL_ROUNDS; round++) {
@@ -6491,7 +6819,7 @@ async function* runAnthropic(client, model, system, initialMessages, apiKey, aut
6491
6819
  let result;
6492
6820
  let isError = false;
6493
6821
  try {
6494
- result = await executeTool(block.name, block.input, apiKey, authToken);
6822
+ result = await executeTool(block.name, block.input, apiKey, authToken, anchor2);
6495
6823
  } catch (err) {
6496
6824
  result = err.message;
6497
6825
  isError = true;
@@ -6508,7 +6836,7 @@ async function* runAnthropic(client, model, system, initialMessages, apiKey, aut
6508
6836
  }
6509
6837
  yield { type: "done", text: "" };
6510
6838
  }
6511
- async function* runOpenAI(client, model, initialMessages, apiKey, authToken, signal) {
6839
+ async function* runOpenAI(client, model, initialMessages, apiKey, authToken, signal, anchor2 = {}) {
6512
6840
  const messages = [...initialMessages];
6513
6841
  const MAX_TOOL_ROUNDS = 10;
6514
6842
  for (let round = 0; round < MAX_TOOL_ROUNDS; round++) {
@@ -6559,7 +6887,7 @@ async function* runOpenAI(client, model, initialMessages, apiKey, authToken, sig
6559
6887
  let result;
6560
6888
  let isError = false;
6561
6889
  try {
6562
- result = await executeTool(tc.name, input, apiKey, authToken);
6890
+ result = await executeTool(tc.name, input, apiKey, authToken, anchor2);
6563
6891
  } catch (err) {
6564
6892
  result = err.message;
6565
6893
  isError = true;
@@ -6661,7 +6989,7 @@ async function buildCliSystemContext(conv, jwt) {
6661
6989
  const ref = conv ? await conversationStore.projectRefOf(conv) : null;
6662
6990
  const project = ref ? await projectStore.get(ref) : null;
6663
6991
  const ownServices = project ? allServices.filter((svc) => project.serviceIds.includes(svc.id)) : allServices;
6664
- const resolvedServices = await Promise.all(ownServices.map(resolveServiceVariables));
6992
+ const resolvedServices = await Promise.all(ownServices.map((s) => resolveServiceVariables(s)));
6665
6993
  let systemContext = generateAdminLlmsTxt(resolvedServices, jwt, project);
6666
6994
  if (!conv?.isCompanion) systemContext += "\n\n" + companionSystemNote();
6667
6995
  systemContext += await kanbanContextFor(conv);
@@ -6806,24 +7134,24 @@ async function startCodexSession(convId, prompt, opts = {}) {
6806
7134
  });
6807
7135
  return { session, done };
6808
7136
  }
6809
- var MessagePartSchema = z6.discriminatedUnion("type", [
6810
- z6.object({ type: z6.literal("thinking"), text: z6.string().max(1e5) }),
6811
- z6.object({ type: z6.literal("text"), text: z6.string().max(1e5) }),
6812
- z6.object({
6813
- type: z6.literal("tool"),
7137
+ var MessagePartSchema = z9.discriminatedUnion("type", [
7138
+ z9.object({ type: z9.literal("thinking"), text: z9.string().max(1e5) }),
7139
+ z9.object({ type: z9.literal("text"), text: z9.string().max(1e5) }),
7140
+ z9.object({
7141
+ type: z9.literal("tool"),
6814
7142
  id: Id128Schema,
6815
7143
  name: Id128Schema,
6816
- input: z6.record(z6.string(), z6.unknown()).optional(),
6817
- rawInput: z6.string().max(1e4).optional(),
6818
- result: z6.unknown().optional(),
6819
- isError: z6.boolean().optional(),
6820
- pending: z6.boolean()
7144
+ input: z9.record(z9.string(), z9.unknown()).optional(),
7145
+ rawInput: z9.string().max(1e4).optional(),
7146
+ result: z9.unknown().optional(),
7147
+ isError: z9.boolean().optional(),
7148
+ pending: z9.boolean()
6821
7149
  })
6822
7150
  ]);
6823
- var StoredMessageSchema = z6.object({
6824
- role: z6.enum(["user", "assistant"]),
6825
- content: z6.string().max(1e5),
6826
- parts: z6.array(MessagePartSchema).max(200).optional()
7151
+ var StoredMessageSchema = z9.object({
7152
+ role: z9.enum(["user", "assistant"]),
7153
+ content: z9.string().max(1e5),
7154
+ parts: z9.array(MessagePartSchema).max(200).optional()
6827
7155
  });
6828
7156
  async function conversationCwd(conv) {
6829
7157
  return resolveConversationCwd(conv.id);
@@ -6840,7 +7168,7 @@ var chatRouter = router({
6840
7168
  * et sans le même filtre il y reversait toutes les conversations de la
6841
7169
  * machine, une seconde après un chargement pourtant filtré.
6842
7170
  */
6843
- onChanged: protectedProcedure.input(z6.object({
7171
+ onChanged: protectedProcedure.input(z9.object({
6844
7172
  projectId: Id128Schema.optional(),
6845
7173
  orgId: Id128Schema.nullable().optional()
6846
7174
  }).optional()).subscription(async function* ({ input }) {
@@ -6888,7 +7216,7 @@ var chatRouter = router({
6888
7216
  * reachable where they were written, without leaking into every other
6889
7217
  * organization's projects.
6890
7218
  */
6891
- list: protectedProcedure.input(z6.object({
7219
+ list: protectedProcedure.input(z9.object({
6892
7220
  projectId: Id128Schema.optional(),
6893
7221
  orgId: Id128Schema.nullable().optional()
6894
7222
  }).optional()).query(async ({ input }) => {
@@ -6896,24 +7224,24 @@ var chatRouter = router({
6896
7224
  if (!projectId) return conversationStore.list();
6897
7225
  return conversationStore.listForProject({ id: projectId, orgId: input?.orgId });
6898
7226
  }),
6899
- get: protectedProcedure.input(z6.object({ id: Id128Schema })).query(async ({ input }) => {
7227
+ get: protectedProcedure.input(z9.object({ id: Id128Schema })).query(async ({ input }) => {
6900
7228
  const conv = await conversationStore.get(input.id);
6901
7229
  if (!conv) throw new TRPCError4({ code: "NOT_FOUND", message: "Conversation not found" });
6902
7230
  return conv;
6903
7231
  }),
6904
- create: protectedProcedure.input(z6.object({
7232
+ create: protectedProcedure.input(z9.object({
6905
7233
  title: ShortString200Schema.optional(),
6906
- isCli: z6.boolean().optional(),
6907
- runner: z6.enum(["claude-code", "codex"]).optional(),
7234
+ isCli: z9.boolean().optional(),
7235
+ runner: z9.enum(["claude-code", "codex"]).optional(),
6908
7236
  providerId: Id128Schema.optional(),
6909
7237
  scenarioId: Id128Schema.optional(),
6910
- scenarioInput: z6.string().max(1e5).optional(),
7238
+ scenarioInput: z9.string().max(1e5).optional(),
6911
7239
  kanbanBoardId: Id128Schema.optional(),
6912
7240
  kanbanCardId: Id128Schema.optional(),
6913
7241
  // The project the conversation is about: only the caller knows which
6914
7242
  // one it is looking at.
6915
7243
  projectId: Id128Schema.optional(),
6916
- orgId: z6.string().max(128).nullable().optional()
7244
+ orgId: z9.string().max(128).nullable().optional()
6917
7245
  })).mutation(async ({ input }) => {
6918
7246
  let scenario = null;
6919
7247
  if (input.scenarioId) {
@@ -6947,13 +7275,13 @@ var chatRouter = router({
6947
7275
  }
6948
7276
  return conv;
6949
7277
  }),
6950
- update: protectedProcedure.input(z6.object({
7278
+ update: protectedProcedure.input(z9.object({
6951
7279
  id: Id128Schema,
6952
7280
  title: ShortString200Schema.optional(),
6953
- messages: z6.array(StoredMessageSchema).max(500).optional(),
6954
- contextUsage: z6.object({
6955
- inputTokens: z6.number().int().nonnegative(),
6956
- contextWindow: z6.number().int().positive()
7281
+ messages: z9.array(StoredMessageSchema).max(500).optional(),
7282
+ contextUsage: z9.object({
7283
+ inputTokens: z9.number().int().nonnegative(),
7284
+ contextWindow: z9.number().int().positive()
6957
7285
  }).optional()
6958
7286
  })).mutation(async ({ input }) => {
6959
7287
  const conv = await conversationStore.update(input.id, { title: input.title, messages: input.messages, contextUsage: input.contextUsage });
@@ -6967,10 +7295,10 @@ var chatRouter = router({
6967
7295
  * messages, et un réglage qui voyage avec 500 messages se perdrait dans un
6968
7296
  * patch dont ce n'est pas le sujet.
6969
7297
  */
6970
- setCompanion: protectedProcedure.input(z6.object({
7298
+ setCompanion: protectedProcedure.input(z9.object({
6971
7299
  id: Id128Schema,
6972
- enabled: z6.boolean(),
6973
- runner: z6.enum(["claude-code", "codex"]).optional()
7300
+ enabled: z9.boolean(),
7301
+ runner: z9.enum(["claude-code", "codex"]).optional()
6974
7302
  })).mutation(async ({ input }) => {
6975
7303
  const existing = await conversationStore.get(input.id);
6976
7304
  if (!existing) throw new TRPCError4({ code: "NOT_FOUND", message: "Conversation not found" });
@@ -6993,7 +7321,7 @@ var chatRouter = router({
6993
7321
  * compagnon silencieux parce qu'il n'avait rien à dire et un message qui
6994
7322
  * n'a pas pu être transmis se ressemblent parfaitement sans cette trace.
6995
7323
  */
6996
- companionDelivery: protectedProcedure.input(z6.object({ id: Id128Schema })).query(async ({ input }) => {
7324
+ companionDelivery: protectedProcedure.input(z9.object({ id: Id128Schema })).query(async ({ input }) => {
6997
7325
  const conv = await conversationStore.get(input.id);
6998
7326
  const companionId = conv?.companionConversationId;
6999
7327
  const running = isCompanionThinking(input.id) || (companionId ? activeSessionRegistry.get(companionId)?.status === "running" : false);
@@ -7043,7 +7371,7 @@ var chatRouter = router({
7043
7371
  * route emprunte exactement le chemin de livraison, sans le jugement, et
7044
7372
  * rend PAR OÙ le message est passé.
7045
7373
  */
7046
- testCompanionBridge: protectedProcedure.input(z6.object({ id: Id128Schema })).mutation(async ({ input }) => {
7374
+ testCompanionBridge: protectedProcedure.input(z9.object({ id: Id128Schema })).mutation(async ({ input }) => {
7047
7375
  const conv = await conversationStore.get(input.id);
7048
7376
  if (!conv) throw new TRPCError4({ code: "NOT_FOUND", message: "Conversation not found" });
7049
7377
  const route = await deliverToMainConversation(
@@ -7064,7 +7392,7 @@ var chatRouter = router({
7064
7392
  * entier, bien plus qu'une requête ne doit rester ouverte. L'interface suit
7065
7393
  * l'avancement par l'état poussé « il relit », déjà en place.
7066
7394
  */
7067
- runCompanionNow: protectedProcedure.input(z6.object({ id: Id128Schema })).mutation(async ({ input }) => {
7395
+ runCompanionNow: protectedProcedure.input(z9.object({ id: Id128Schema })).mutation(async ({ input }) => {
7068
7396
  const conv = await conversationStore.get(input.id);
7069
7397
  if (!conv) throw new TRPCError4({ code: "NOT_FOUND", message: "Conversation not found" });
7070
7398
  if (conv.isCompanion) {
@@ -7081,7 +7409,7 @@ var chatRouter = router({
7081
7409
  });
7082
7410
  return { started: true };
7083
7411
  }),
7084
- delete: protectedProcedure.input(z6.object({ id: Id128Schema })).mutation(async ({ input }) => {
7412
+ delete: protectedProcedure.input(z9.object({ id: Id128Schema })).mutation(async ({ input }) => {
7085
7413
  const existing = await conversationStore.get(input.id);
7086
7414
  if (!existing) throw new TRPCError4({ code: "NOT_FOUND", message: "Conversation not found" });
7087
7415
  resetRelaunches(input.id);
@@ -7109,12 +7437,12 @@ var chatRouter = router({
7109
7437
  (err) => console.error("[chat.delete] Image cleanup error:", err)
7110
7438
  );
7111
7439
  }),
7112
- archive: protectedProcedure.input(z6.object({ id: Id128Schema, archived: z6.boolean() })).mutation(async ({ input }) => {
7440
+ archive: protectedProcedure.input(z9.object({ id: Id128Schema, archived: z9.boolean() })).mutation(async ({ input }) => {
7113
7441
  const conv = await conversationStore.update(input.id, { archived: input.archived });
7114
7442
  if (!conv) throw new TRPCError4({ code: "NOT_FOUND", message: "Conversation not found" });
7115
7443
  return conv;
7116
7444
  }),
7117
- pin: protectedProcedure.input(z6.object({ id: Id128Schema, pinned: z6.boolean() })).mutation(async ({ input }) => {
7445
+ pin: protectedProcedure.input(z9.object({ id: Id128Schema, pinned: z9.boolean() })).mutation(async ({ input }) => {
7118
7446
  const conv = await conversationStore.setPinned(input.id, input.pinned);
7119
7447
  if (!conv) throw new TRPCError4({ code: "NOT_FOUND", message: "Conversation not found" });
7120
7448
  return conv;
@@ -7122,16 +7450,16 @@ var chatRouter = router({
7122
7450
  // L'ordre ne vaut que pour les ids donnés : l'écran ne connaît que les
7123
7451
  // conversations du projet courant, et les épinglées des autres projets
7124
7452
  // n'ont pas à bouger parce qu'on a rangé celles-ci.
7125
- reorderPinned: protectedProcedure.input(z6.object({ ids: z6.array(Id128Schema).max(500) })).mutation(async ({ input }) => {
7453
+ reorderPinned: protectedProcedure.input(z9.object({ ids: z9.array(Id128Schema).max(500) })).mutation(async ({ input }) => {
7126
7454
  await conversationStore.reorderPinned(input.ids);
7127
7455
  })
7128
7456
  }),
7129
- listModels: protectedProcedure.input(z6.object({
7457
+ listModels: protectedProcedure.input(z9.object({
7130
7458
  providerId: Id128Schema.optional(),
7131
7459
  // Le projet dit de quelle organisation lire les fournisseurs ; absent,
7132
7460
  // ce sont ceux du poste.
7133
7461
  projectId: Id128Schema.optional(),
7134
- orgId: z6.string().max(128).nullable().optional()
7462
+ orgId: z9.string().max(128).nullable().optional()
7135
7463
  }).optional()).query(async ({ input }) => {
7136
7464
  const active = await getActiveProvider(
7137
7465
  input?.providerId,
@@ -7144,7 +7472,7 @@ var chatRouter = router({
7144
7472
  return [];
7145
7473
  }
7146
7474
  }),
7147
- checkCliAvailability: protectedProcedure.input(z6.object({ agentId: Id128Schema.optional() }).optional()).query(async ({ input }) => {
7475
+ checkCliAvailability: protectedProcedure.input(z9.object({ agentId: Id128Schema.optional() }).optional()).query(async ({ input }) => {
7148
7476
  if (input?.agentId) {
7149
7477
  try {
7150
7478
  const res = await agentManager.agentQuery(
@@ -7162,12 +7490,12 @@ var chatRouter = router({
7162
7490
  ]);
7163
7491
  return { available: claudeOk, codexAvailable: codexOk };
7164
7492
  }),
7165
- enhanceScenarioPrompt: protectedProcedure.input(z6.object({
7166
- text: z6.string().max(1e4),
7493
+ enhanceScenarioPrompt: protectedProcedure.input(z9.object({
7494
+ text: z9.string().max(1e4),
7167
7495
  providerId: Id128Schema.optional(),
7168
- model: z6.string().max(200).optional(),
7496
+ model: z9.string().max(200).optional(),
7169
7497
  projectId: Id128Schema.optional(),
7170
- orgId: z6.string().max(128).nullable().optional()
7498
+ orgId: z9.string().max(128).nullable().optional()
7171
7499
  })).mutation(async ({ input }) => {
7172
7500
  const active = await getActiveProvider(
7173
7501
  input.providerId,
@@ -7224,22 +7552,22 @@ Return ONLY the improved text, no explanation, no preamble.`;
7224
7552
  }
7225
7553
  }),
7226
7554
  getStreamingStatus: protectedProcedure.query(() => activeSessionRegistry.listActive()),
7227
- stopSession: protectedProcedure.input(z6.object({ conversationId: ConversationIdSchema })).mutation(({ input }) => {
7555
+ stopSession: protectedProcedure.input(z9.object({ conversationId: ConversationIdSchema })).mutation(({ input }) => {
7228
7556
  if (process.env.RUNEYA_DEBUG) console.log("[chat]: stopSession");
7229
7557
  const killed = activeSessionRegistry.kill(input.conversationId);
7230
7558
  if (!killed) throw new TRPCError4({ code: "NOT_FOUND", message: "No active session for this conversation" });
7231
7559
  return { ok: true };
7232
7560
  }),
7233
- streamViaClaudeCode: protectedProcedure.input(z6.object({
7561
+ streamViaClaudeCode: protectedProcedure.input(z9.object({
7234
7562
  conversationId: ConversationIdSchema,
7235
- prompt: z6.string().max(1e5),
7236
- contextNote: z6.string().max(2e5).optional(),
7563
+ prompt: z9.string().max(1e5),
7564
+ contextNote: z9.string().max(2e5).optional(),
7237
7565
  model: ShortString200Schema.optional(),
7238
- effort: z6.enum(["low", "medium", "high"]).optional(),
7239
- reconnect: z6.boolean().optional(),
7566
+ effort: z9.enum(["low", "medium", "high"]).optional(),
7567
+ reconnect: z9.boolean().optional(),
7240
7568
  agentId: Id128Schema.optional(),
7241
- environmentId: z6.string().max(128).optional(),
7242
- imageIds: z6.array(z6.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)).max(5).optional(),
7569
+ environmentId: z9.string().max(128).optional(),
7570
+ imageIds: z9.array(z9.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)).max(5).optional(),
7243
7571
  imageParts: ImagePartsSchema
7244
7572
  })).subscription(async function* ({ input, ctx, signal }) {
7245
7573
  if (process.env.RUNEYA_DEBUG) console.log("[chat]: Reconnect");
@@ -7341,15 +7669,15 @@ ${imagePaths.map((p) => `Image: ${p}`).join("\n")}` : cliPrompt;
7341
7669
  if (process.env.RUNEYA_DEBUG) console.log("[chat]: drainSession...");
7342
7670
  yield* drainSession(session, signal, false);
7343
7671
  }),
7344
- streamViaCodex: protectedProcedure.input(z6.object({
7672
+ streamViaCodex: protectedProcedure.input(z9.object({
7345
7673
  conversationId: ConversationIdSchema,
7346
- prompt: z6.string().max(1e5),
7347
- contextNote: z6.string().max(2e5).optional(),
7674
+ prompt: z9.string().max(1e5),
7675
+ contextNote: z9.string().max(2e5).optional(),
7348
7676
  model: ShortString200Schema.optional(),
7349
- reconnect: z6.boolean().optional(),
7677
+ reconnect: z9.boolean().optional(),
7350
7678
  agentId: Id128Schema.optional(),
7351
- environmentId: z6.string().max(128).optional(),
7352
- imageIds: z6.array(z6.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)).max(5).optional(),
7679
+ environmentId: z9.string().max(128).optional(),
7680
+ imageIds: z9.array(z9.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)).max(5).optional(),
7353
7681
  imageParts: ImagePartsSchema
7354
7682
  })).subscription(async function* ({ input, ctx, signal }) {
7355
7683
  const existingSession = activeSessionRegistry.get(input.conversationId);
@@ -7419,13 +7747,13 @@ ${input.prompt}` : input.prompt;
7419
7747
  });
7420
7748
  yield* drainSession(session, signal, false);
7421
7749
  }),
7422
- send: protectedProcedure.input(z6.object({
7750
+ send: protectedProcedure.input(z9.object({
7423
7751
  conversationId: ConversationIdSchema,
7424
- messages: z6.array(MessageSchema).min(0).max(100),
7752
+ messages: z9.array(MessageSchema).min(0).max(100),
7425
7753
  model: ShortString200Schema.optional(),
7426
- contextNote: z6.string().max(2e5).optional(),
7427
- reconnect: z6.boolean().optional(),
7428
- imageIds: z6.array(z6.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)).max(5).optional(),
7754
+ contextNote: z9.string().max(2e5).optional(),
7755
+ reconnect: z9.boolean().optional(),
7756
+ imageIds: z9.array(z9.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)).max(5).optional(),
7429
7757
  imageParts: ImagePartsSchema
7430
7758
  })).subscription(async function* ({ input, ctx, signal }) {
7431
7759
  const existingSession = activeSessionRegistry.get(input.conversationId);
@@ -7438,6 +7766,7 @@ ${input.prompt}` : input.prompt;
7438
7766
  }
7439
7767
  const conv = await conversationStore.get(input.conversationId);
7440
7768
  const convRef = conv ? await conversationStore.projectRefOf(conv) : null;
7769
+ const anchor2 = { projectId: convRef?.id, orgId: convRef?.orgId ?? void 0 };
7441
7770
  const active = await getActiveProvider(conv?.providerId, convRef?.orgId ?? void 0);
7442
7771
  if (!active) {
7443
7772
  throw new TRPCError4({
@@ -7486,7 +7815,7 @@ ${input.prompt}` : input.prompt;
7486
7815
  }
7487
7816
  return { role: m.role, content: m.content };
7488
7817
  });
7489
- gen = runAnthropic(client, model, system, msgs, apiKey, authToken, apiSignal);
7818
+ gen = runAnthropic(client, model, system, msgs, apiKey, authToken, apiSignal, anchor2);
7490
7819
  } else if (provider.provider in OPENAI_COMPAT_BASE_URLS) {
7491
7820
  const baseURL = OPENAI_COMPAT_BASE_URLS[provider.provider];
7492
7821
  const client = new OpenAI2({ apiKey: plaintextKey || "ollama", baseURL });
@@ -7505,7 +7834,7 @@ ${input.prompt}` : input.prompt;
7505
7834
  return { role: m.role, content: m.content };
7506
7835
  })
7507
7836
  ];
7508
- gen = runOpenAI(client, model, msgs, apiKey, authToken, apiSignal);
7837
+ gen = runOpenAI(client, model, msgs, apiKey, authToken, apiSignal, anchor2);
7509
7838
  } else {
7510
7839
  activeSessionRegistry.pushEvent(input.conversationId, { type: "error", message: `Provider "${provider.provider}" is not supported.` });
7511
7840
  activeSessionRegistry.pushEvent(input.conversationId, { type: "done", text: "" });
@@ -7538,25 +7867,25 @@ ${input.prompt}` : input.prompt;
7538
7867
  // ── PTY passthrough (interactive Claude Code session) ────────────────────
7539
7868
  pty: router({
7540
7869
  /** Start a PTY session running `claude --resume <sessionId>` (or fresh). */
7541
- start: protectedProcedure.input(z6.object({
7542
- agentId: z6.string().max(128).optional(),
7543
- sessionId: z6.string().max(128).optional(),
7544
- runner: z6.enum(["claude-code", "codex"]).default("claude-code"),
7545
- resume: z6.boolean().default(false),
7546
- model: z6.string().max(128).optional(),
7547
- cwd: z6.string().max(4096).optional(),
7870
+ start: protectedProcedure.input(z9.object({
7871
+ agentId: z9.string().max(128).optional(),
7872
+ sessionId: z9.string().max(128).optional(),
7873
+ runner: z9.enum(["claude-code", "codex"]).default("claude-code"),
7874
+ resume: z9.boolean().default(false),
7875
+ model: z9.string().max(128).optional(),
7876
+ cwd: z9.string().max(4096).optional(),
7548
7877
  /** Anchors the session when no explicit cwd is given. */
7549
- serviceId: z6.string().max(128).optional(),
7878
+ serviceId: z9.string().max(128).optional(),
7550
7879
  projectId: Id128Schema.optional(),
7551
- orgId: z6.string().max(128).nullable().optional(),
7552
- cols: z6.number().int().min(1).max(1e3).default(120),
7553
- rows: z6.number().int().min(1).max(1e3).default(30),
7554
- enableMcp: z6.boolean().default(false),
7555
- apiBaseUrl: z6.string().max(512).optional(),
7556
- environmentId: z6.string().max(128).optional(),
7557
- attachedContexts: z6.array(z6.object({
7558
- label: z6.string().max(200),
7559
- text: z6.string().max(1e6)
7880
+ orgId: z9.string().max(128).nullable().optional(),
7881
+ cols: z9.number().int().min(1).max(1e3).default(120),
7882
+ rows: z9.number().int().min(1).max(1e3).default(30),
7883
+ enableMcp: z9.boolean().default(false),
7884
+ apiBaseUrl: z9.string().max(512).optional(),
7885
+ environmentId: z9.string().max(128).optional(),
7886
+ attachedContexts: z9.array(z9.object({
7887
+ label: z9.string().max(200),
7888
+ text: z9.string().max(1e6)
7560
7889
  })).max(20).optional()
7561
7890
  })).mutation(async ({ input, ctx }) => {
7562
7891
  const t0 = Date.now();
@@ -7714,10 +8043,10 @@ Context:
7714
8043
  return { spawnId: res.spawnId, agentId, reattached: false };
7715
8044
  }),
7716
8045
  /** Subscribe to PTY output stream (raw text with ANSI). */
7717
- stream: protectedProcedure.input(z6.object({
7718
- agentId: z6.string().max(128).optional(),
7719
- spawnId: z6.string().max(128),
7720
- fromOffset: z6.number().int().min(0).default(0)
8046
+ stream: protectedProcedure.input(z9.object({
8047
+ agentId: z9.string().max(128).optional(),
8048
+ spawnId: z9.string().max(128),
8049
+ fromOffset: z9.number().int().min(0).default(0)
7721
8050
  })).subscription(async function* ({ input, signal }) {
7722
8051
  const agentId = input.agentId ?? agentManager.getDefaultAgentId();
7723
8052
  if (!agentId) throw new TRPCError4({ code: "PRECONDITION_FAILED", message: "No agent available" });
@@ -7772,10 +8101,10 @@ Context:
7772
8101
  }
7773
8102
  }),
7774
8103
  /** Write input to a PTY session (keystrokes from xterm). */
7775
- write: protectedProcedure.input(z6.object({
7776
- agentId: z6.string().max(128).optional(),
7777
- spawnId: z6.string().max(128),
7778
- data: z6.string().max(1e6)
8104
+ write: protectedProcedure.input(z9.object({
8105
+ agentId: z9.string().max(128).optional(),
8106
+ spawnId: z9.string().max(128),
8107
+ data: z9.string().max(1e6)
7779
8108
  })).mutation(async ({ input }) => {
7780
8109
  const agentId = input.agentId ?? agentManager.getDefaultAgentId();
7781
8110
  if (!agentId) throw new TRPCError4({ code: "PRECONDITION_FAILED", message: "No agent available" });
@@ -7785,11 +8114,11 @@ Context:
7785
8114
  });
7786
8115
  }),
7787
8116
  /** Resize a PTY session. */
7788
- resize: protectedProcedure.input(z6.object({
7789
- agentId: z6.string().max(128).optional(),
7790
- spawnId: z6.string().max(128),
7791
- cols: z6.number().int().min(1).max(1e3),
7792
- rows: z6.number().int().min(1).max(1e3)
8117
+ resize: protectedProcedure.input(z9.object({
8118
+ agentId: z9.string().max(128).optional(),
8119
+ spawnId: z9.string().max(128),
8120
+ cols: z9.number().int().min(1).max(1e3),
8121
+ rows: z9.number().int().min(1).max(1e3)
7793
8122
  })).mutation(async ({ input }) => {
7794
8123
  const agentId = input.agentId ?? agentManager.getDefaultAgentId();
7795
8124
  if (!agentId) throw new TRPCError4({ code: "PRECONDITION_FAILED", message: "No agent available" });
@@ -7805,11 +8134,11 @@ Context:
7805
8134
  * picks it up. Returns the tmp path and which clipboard method succeeded
7806
8135
  * (null if none — caller should inject `@<path>` instead of Ctrl+V).
7807
8136
  */
7808
- pasteImage: protectedProcedure.input(z6.object({
7809
- agentId: z6.string().max(128).optional(),
7810
- sessionId: z6.string().max(128).optional(),
7811
- mimeType: z6.string().max(64),
7812
- base64: z6.string().max(15e6)
8137
+ pasteImage: protectedProcedure.input(z9.object({
8138
+ agentId: z9.string().max(128).optional(),
8139
+ sessionId: z9.string().max(128).optional(),
8140
+ mimeType: z9.string().max(64),
8141
+ base64: z9.string().max(15e6)
7813
8142
  })).mutation(async ({ input }) => {
7814
8143
  const agentId = input.agentId ?? agentManager.getDefaultAgentId();
7815
8144
  if (!agentId) throw new TRPCError4({ code: "PRECONDITION_FAILED", message: "No agent available" });
@@ -7827,7 +8156,7 @@ Context:
7827
8156
  * Read the transcript Claude Code stores on disk for a given session.
7828
8157
  * Returns parsed JSONL entries (user / assistant messages, tool uses, etc.).
7829
8158
  */
7830
- transcript: protectedProcedure.input(z6.object({ sessionId: z6.string().max(128) })).query(async ({ input }) => {
8159
+ transcript: protectedProcedure.input(z9.object({ sessionId: z9.string().max(128) })).query(async ({ input }) => {
7831
8160
  return readClaudeTranscript(input.sessionId);
7832
8161
  }),
7833
8162
  /**
@@ -7835,9 +8164,9 @@ Context:
7835
8164
  * when was the transcript JSONL last touched? Used by the non-PTY view
7836
8165
  * to show a "Claude is thinking…" indicator while output streams.
7837
8166
  */
7838
- activity: protectedProcedure.input(z6.object({
7839
- agentId: z6.string().max(128).optional(),
7840
- sessionId: z6.string().max(128)
8167
+ activity: protectedProcedure.input(z9.object({
8168
+ agentId: z9.string().max(128).optional(),
8169
+ sessionId: z9.string().max(128)
7841
8170
  })).query(async ({ input }) => {
7842
8171
  const agentId = input.agentId ?? agentManager.getDefaultAgentId();
7843
8172
  let running = false;
@@ -7863,7 +8192,7 @@ Context:
7863
8192
  * them on the conversation, so the non-PTY chat view stays in sync.
7864
8193
  * Uses the conversation id as session id (PTY sessions are spawned that way).
7865
8194
  */
7866
- syncTranscript: protectedProcedure.input(z6.object({ conversationId: ConversationIdSchema })).mutation(async ({ input }) => {
8195
+ syncTranscript: protectedProcedure.input(z9.object({ conversationId: ConversationIdSchema })).mutation(async ({ input }) => {
7867
8196
  const conv = await conversationStore.get(input.conversationId);
7868
8197
  if (!conv) {
7869
8198
  throw new TRPCError4({ code: "NOT_FOUND", message: `Conversation ${input.conversationId} not found` });
@@ -7877,14 +8206,14 @@ Context:
7877
8206
  * with the given sessionId. Used to benchmark the PTY → tRPC → xterm.js
7878
8207
  * pipeline. Open the conversation in PTY mode to attach to it.
7879
8208
  */
7880
- debugStress: protectedProcedure.input(z6.object({
7881
- sessionId: z6.string().max(128),
7882
- agentId: z6.string().max(128).optional(),
7883
- bytesPerSec: z6.number().int().min(100).max(1e7).default(5e4),
7884
- chunkSize: z6.number().int().min(1).max(65536).default(256),
7885
- durationMs: z6.number().int().min(0).max(36e5).default(0),
7886
- cols: z6.number().int().min(1).max(1e3).default(120),
7887
- rows: z6.number().int().min(1).max(1e3).default(30)
8209
+ debugStress: protectedProcedure.input(z9.object({
8210
+ sessionId: z9.string().max(128),
8211
+ agentId: z9.string().max(128).optional(),
8212
+ bytesPerSec: z9.number().int().min(100).max(1e7).default(5e4),
8213
+ chunkSize: z9.number().int().min(1).max(65536).default(256),
8214
+ durationMs: z9.number().int().min(0).max(36e5).default(0),
8215
+ cols: z9.number().int().min(1).max(1e3).default(120),
8216
+ rows: z9.number().int().min(1).max(1e3).default(30)
7888
8217
  })).mutation(async ({ input }) => {
7889
8218
  const agentId = input.agentId ?? agentManager.getDefaultAgentId();
7890
8219
  if (!agentId) throw new TRPCError4({ code: "PRECONDITION_FAILED", message: "No agent available" });
@@ -7931,9 +8260,9 @@ Context:
7931
8260
  return { spawnId: res.spawnId, agentId, stressSessionId };
7932
8261
  }),
7933
8262
  /** Kill a PTY session. */
7934
- kill: protectedProcedure.input(z6.object({
7935
- agentId: z6.string().max(128).optional(),
7936
- spawnId: z6.string().max(128)
8263
+ kill: protectedProcedure.input(z9.object({
8264
+ agentId: z9.string().max(128).optional(),
8265
+ spawnId: z9.string().max(128)
7937
8266
  })).mutation(async ({ input }) => {
7938
8267
  const agentId = input.agentId ?? agentManager.getDefaultAgentId();
7939
8268
  if (!agentId) throw new TRPCError4({ code: "PRECONDITION_FAILED", message: "No agent available" });
@@ -7965,11 +8294,14 @@ export {
7965
8294
  accountForOrgOrThrow,
7966
8295
  cloudFetch,
7967
8296
  readCloudIdentity,
8297
+ attachServiceToProject,
7968
8298
  environmentOverridesStore,
8299
+ filterEnvForAi,
7969
8300
  environmentResolver,
7970
8301
  auditService,
7971
8302
  isShareable,
7972
8303
  logParserStore,
8304
+ buildServerBuiltins,
7973
8305
  resolveWorkspaceCwd,
7974
8306
  resolveAgentCwd,
7975
8307
  resolveConversationCwd,
@@ -8011,4 +8343,4 @@ export {
8011
8343
  startCliSession,
8012
8344
  chatRouter
8013
8345
  };
8014
- //# sourceMappingURL=chunk-GKK3ACWB.js.map
8346
+ //# sourceMappingURL=chunk-LHVTBWM7.js.map