@runeya/runeya 2.0.92 → 2.0.94
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.
- package/agent/index.js +205 -170
- package/agent/index.js.map +1 -1
- package/agent-manager-3KSS7BHP.js +7 -0
- package/{chunk-PDRWT47K.js → chunk-4PQXBTV6.js} +74 -30
- package/chunk-4PQXBTV6.js.map +1 -0
- package/index.js +2 -2
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/{src-K5L5HTKP.js → src-GGPKDQGD.js} +1002 -936
- package/src-GGPKDQGD.js.map +1 -0
- package/web/assets/AgentScalarChatInterface.vue-CR0iWJNr.js +13 -0
- package/web/assets/AgentTerminalPage-DZj9UulV.js +1 -0
- package/web/assets/AiChatPage-D4h76hus.js +1 -0
- package/web/assets/AppLayout-DusPXiZn.js +1 -0
- package/web/assets/{AppLayout-DiMqQfDk.css → AppLayout-Sk3Qnkr-.css} +1 -1
- package/web/assets/AuditPage-BBEa6MYr.js +1 -0
- package/web/assets/CloudAccountPage-DKgXvPS1.js +1 -0
- package/web/assets/CloudAccountPage-DopITrxL.js +1 -0
- package/web/assets/CloudMessagingPage-BNIbysEO.js +2 -0
- package/web/assets/DashboardPage-CTGAGY7X.js +1 -0
- package/web/assets/DirectoryPickerDialog-BKI9vxkG.js +1 -0
- package/web/assets/{EditorIcon-c_3UtFYp.js → EditorIcon-CdvuLNAP.js} +2 -2
- package/web/assets/EnvironmentForm-BiWvLVax.js +108 -0
- package/web/assets/EnvironmentFormPage-RReX9Ijr.js +1 -0
- package/web/assets/EnvironmentListPage-BW5PlOxl.js +1 -0
- package/web/assets/KanbanBoardPage-BFYgHGl0.js +4 -0
- package/web/assets/KanbanListPage-BAcgRh8Z.js +1 -0
- package/web/assets/LaunchProjectPage-CpiyvCBv.js +1 -0
- package/web/assets/LaunchServicesPage-ChEXnYIi.js +1 -0
- package/web/assets/LogViewer-iTxXl8YQ.js +3 -0
- package/web/assets/OrgKeyPrompt-KRyXRMw7.js +1 -0
- package/web/assets/{ProcessControls-BXu0aujq.js → ProcessControls-DynA7Ock.js} +1 -1
- package/web/assets/ProcessDetailPage-BpgGTkXx.js +1 -0
- package/web/assets/{ProcessMetrics-D-40_Bx4.js → ProcessMetrics-_FGC-0hm.js} +2 -2
- package/web/assets/ProjectDetailPage-B49_-83N.js +1 -0
- package/web/assets/ProjectListPage-CFoEPT2F.js +1 -0
- package/web/assets/RandomJobTestPage-CALSR3WS.js +2 -0
- package/web/assets/ScenarioEditorPage-DxyzCjhy.js +14 -0
- package/web/assets/SendToChatDialog-CeFdMciG.js +1 -0
- package/web/assets/ServiceControlsBar-CI1_piqu.js +1 -0
- package/web/assets/ServiceDetailPage-CVT68kTt.js +2 -0
- package/web/assets/ServiceFormPage-nLRxtrOu.js +1 -0
- package/web/assets/{SettingsPage-BKcxRTQg.css → SettingsPage-CX1EAjNK.css} +1 -1
- package/web/assets/SettingsPage-DDYegVxd.js +2063 -0
- package/web/assets/UnlockPage-D9_ZbMR_.js +1 -0
- package/web/assets/VariablesTable-ClL6KuSo.js +1 -0
- package/web/assets/VaultMigrationPage-rc5OA9Xt.js +1 -0
- package/web/assets/VersionBadge-K5UQnfc6.js +1 -0
- package/web/assets/WikiPage-VeQCqO9Z.js +1 -0
- package/web/assets/WikiView-XCwSa_R7.js +1 -0
- package/web/assets/add-scalar-classes-CvhyJKCs.js +387 -0
- package/web/assets/auth-errors-Cmx-4mn3.js +1 -0
- package/web/assets/{autocomplete-CdduMsds.js → autocomplete-tNXsUW-e.js} +3 -3
- package/web/assets/{basic-shape-diamond.svg-J1CPrYKJ.js → basic-shape-diamond.svg-BgNul67K.js} +1 -1
- package/web/assets/{basic-shape-hexagon.svg-D9pZpKRd.js → basic-shape-hexagon.svg-CILNnZwG.js} +1 -1
- package/web/assets/{basic-shape-primary-circle-ellipse-round.svg-GoFZOez-.js → basic-shape-primary-circle-ellipse-round.svg-OXklrBAn.js} +1 -1
- package/web/assets/{basic-shape-primary-square-rectangle.svg-5sAWcFH7.js → basic-shape-primary-square-rectangle.svg-DYF4zyUj.js} +1 -1
- package/web/assets/{basic-shape-shield.svg-BBhZF-nU.js → basic-shape-shield.svg-CQbzQswT.js} +1 -1
- package/web/assets/{browser-CGF8J-d2.js → browser-CDtVZzm0.js} +1 -1
- package/web/assets/{browser-D9PR5ryM.js → browser-CdTGBSDI.js} +1 -1
- package/web/assets/{card-wcB3LVu3.js → card-BfEdnBhU.js} +2 -2
- package/web/assets/{checkbox-BGl4zewJ.js → checkbox-CTopTVtp.js} +3 -3
- package/web/assets/{chip-BeU7R8v5.js → chip-Cw38kJ50.js} +2 -2
- package/web/assets/{client-mw7vk2NS.js → client-Bjn9AL4v.js} +2 -2
- package/web/assets/cloud-chat.store-BPoTzBeD.js +1 -0
- package/web/assets/cloud-session-D0ue5Z97.js +1 -0
- package/web/assets/column-BtLe8qbf.js +907 -0
- package/web/assets/{computer-device-desktop-monitor.svg-DvELTXaq.js → computer-device-desktop-monitor.svg-ByBKx1CQ.js} +1 -1
- package/web/assets/{computer-device-desktop.svg-Cy5MNLjy.js → computer-device-desktop.svg-BPvzT4sF.js} +1 -1
- package/web/assets/{computer-device-laptop.svg-CeTHd2Gz.js → computer-device-laptop.svg-saGCSB2c.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-android-samsung-back.svg-U357QLLy.js → computer-device-mobile-phone-android-samsung-back.svg-Bo-eisU4.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-android-samsung.svg-BxWQ3WQu.js → computer-device-mobile-phone-android-samsung.svg-Bavaieis.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-iphone-x-back.svg-JTaGwsMH.js → computer-device-mobile-phone-iphone-x-back.svg-BQK9BRXi.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-iphone-x.svg-CG2NhvNR.js → computer-device-mobile-phone-iphone-x.svg-C24hCDuI.js} +1 -1
- package/web/assets/{computer-device-mobile-tablet-touch.svg-0RIIeEQE.js → computer-device-mobile-tablet-touch.svg-CUHV3zSo.js} +1 -1
- package/web/assets/{computer-device-mobile-tablet.svg-BpEHWNNy.js → computer-device-mobile-tablet.svg-C8SRYMmI.js} +1 -1
- package/web/assets/{computer-device-network-ethernet-cat6.svg-ekymSTiB.js → computer-device-network-ethernet-cat6.svg-Ds4kUid3.js} +1 -1
- package/web/assets/{computer-device-network-lan-www.svg-DQ7DjA-N.js → computer-device-network-lan-www.svg-BwIieS6h.js} +1 -1
- package/web/assets/{computer-device-network-wifi-connection.svg-Chlu-E0n.js → computer-device-network-wifi-connection.svg-Q7Mxb3eP.js} +1 -1
- package/web/assets/{computer-device-network-wifi-router.svg-sXuKxg3H.js → computer-device-network-wifi-router.svg-B0PMuY1x.js} +1 -1
- package/web/assets/{cssMode-CmAJhlK2.js → cssMode-8lAGHoa8.js} +1 -1
- package/web/assets/{divider-CIEeFsQF.js → divider-DRKb8XBY.js} +2 -2
- package/web/assets/{docx-preview-BzWsyqjd.js → docx-preview-K0JOmyAw.js} +1 -1
- package/web/assets/{ecology-science-erlenmeyer-flask.svg-DBWUyVvG.js → ecology-science-erlenmeyer-flask.svg-D5wbPwU2.js} +1 -1
- package/web/assets/{fieldset-DbVZGmxF.js → fieldset-jU8x6yyO.js} +2 -2
- package/web/assets/{freemarker2-CpZwjOiK.js → freemarker2-BmTZDOK9.js} +1 -1
- package/web/assets/{handlebars-BF01Ro6D.js → handlebars-DM-mBhq3.js} +1 -1
- package/web/assets/{html-y42MG6La.js → html-BohxI4Ke.js} +1 -1
- package/web/assets/{htmlMode-BiFUKM7B.js → htmlMode-vqRVK3v5.js} +1 -1
- package/web/assets/{image-flash-lightning.svg-D8MQjxej.js → image-flash-lightning.svg-s-LoyOp-.js} +1 -1
- package/web/assets/{image-picture-flower.svg-DhtjWeFt.js → image-picture-flower.svg-CofKZT5Q.js} +1 -1
- package/web/assets/{index-K4MHcRkt.js → index-DHr5P6pq.js} +293 -293
- package/web/assets/index-Da38OOd8.css +1 -0
- package/web/assets/{interface-alert-exclamation-diamond.svg-BnuBbqzl.js → interface-alert-exclamation-diamond.svg-C4C4i4oQ.js} +1 -1
- package/web/assets/{interface-alert-exclamation-triangle-warning.svg-CLIWOLdf.js → interface-alert-exclamation-triangle-warning.svg-C-ogsTXk.js} +1 -1
- package/web/assets/{interface-alert-information-circle.svg--CM4LBgr.js → interface-alert-information-circle.svg-BFpBDkj5.js} +1 -1
- package/web/assets/{interface-award-crown.svg-CwUcjE17.js → interface-award-crown.svg-DfHdQ8rJ.js} +1 -1
- package/web/assets/{interface-bookmark.svg-C-WYwhpR.js → interface-bookmark-tag.svg-DkfXcRMe.js} +1 -1
- package/web/assets/{interface-bookmark-tag.svg-BYkbHYcm.js → interface-bookmark.svg-qCQ3v5rM.js} +1 -1
- package/web/assets/{interface-calendar-date-one.svg-BEV_BtWR.js → interface-calendar-date-one.svg-D2ssTK7X.js} +1 -1
- package/web/assets/{interface-content-book-open-pages.svg-DklVPzGE.js → interface-content-book-open-pages.svg-CH1BmaVm.js} +1 -1
- package/web/assets/{interface-content-book-page.svg-DtEixblx.js → interface-content-book-page.svg-BU6m1d9-.js} +1 -1
- package/web/assets/{interface-content-file.svg-CbdR0tUT.js → interface-content-file.svg-DbsUtWTI.js} +1 -1
- package/web/assets/{interface-content-folder.svg-Bb6W8S8_.js → interface-content-folder.svg-8IvlkKzB.js} +1 -1
- package/web/assets/interface-content-folder.svg-nRYFY3NY.js +1 -0
- package/web/assets/{interface-copy-clipboard.svg-cy8mE1ku.js → interface-copy-clipboard.svg-D8ev9OtX.js} +1 -1
- package/web/assets/{interface-edit-attachment.svg-ujlWFwop.js → interface-edit-attachment.svg-dl-nfI3P.js} +1 -1
- package/web/assets/{interface-edit-binocular.svg-DdndLqEe.js → interface-edit-binocular.svg-Box_OuXH.js} +1 -1
- package/web/assets/{interface-edit-magic-wand.svg-D3PbWjw6.js → interface-edit-magic-wand.svg-DIhMw--x.js} +1 -1
- package/web/assets/{interface-edit-tool-paint-roller.svg-DEJvhvns.js → interface-edit-tool-paint-roller.svg-COUefijc.js} +1 -1
- package/web/assets/{interface-edit-tool-pencil.svg-CSwy7Tpt.js → interface-edit-tool-pencil.svg-BNmSspcl.js} +1 -1
- package/web/assets/{interface-favorite-award.svg-Ct3aGvri.js → interface-favorite-award.svg-Cy-XeB8N.js} +1 -1
- package/web/assets/{interface-favorite-flag.svg-Dt2tGcDG.js → interface-favorite-flag.svg-BVBisei8.js} +1 -1
- package/web/assets/{interface-favorite-heart.svg-BCAdec7C.js → interface-favorite-heart.svg-BkVO2jBo.js} +1 -1
- package/web/assets/{interface-favorite-star.svg-Dcen2Unz.js → interface-favorite-star.svg-Bxe8dqRi.js} +1 -1
- package/web/assets/{interface-favorite-stars-sparkles.svg-BptG3dBN.js → interface-favorite-stars-sparkles.svg-MkrYfhIz.js} +1 -1
- package/web/assets/{interface-hierarchy-flowchart.svg-CG8rKwV2.js → interface-hierarchy-flowchart.svg-De7TQhr3.js} +1 -1
- package/web/assets/{interface-home-house.svg-EjYsHgjY.js → interface-home-house.svg-D_qOil1N.js} +1 -1
- package/web/assets/{interface-hyperlink.svg-R0Inwsnr.js → interface-hyperlink.svg-5S7ugTcP.js} +1 -1
- package/web/assets/{interface-lighting-brightness.svg-82wRZ7U5.js → interface-lighting-brightness.svg-vJA95mbx.js} +1 -1
- package/web/assets/{interface-lock-closed.svg-CKCtxTSF.js → interface-lock-closed.svg-DVL32yBG.js} +1 -1
- package/web/assets/{interface-lock-open-unlock.svg-25bZt-jb.js → interface-lock-open-unlock.svg-C7DBYFPn.js} +1 -1
- package/web/assets/{interface-login-key.svg-C1nVpqWu.js → interface-login-key.svg-CEq51fI1.js} +1 -1
- package/web/assets/{interface-search.svg-Db9i4fOU.js → interface-search.svg-CkP-JMXm.js} +1 -1
- package/web/assets/{interface-setting-cog.svg-C2juGx3i.js → interface-setting-cog.svg-CgR9wxJN.js} +1 -1
- package/web/assets/{interface-share-megaphone-bullhorn.svg-DWKTYrRq.js → interface-share-megaphone-bullhorn.svg-C_VIGsI0.js} +1 -1
- package/web/assets/{interface-share-rocket.svg-D9L6uhiQ.js → interface-share-rocket.svg-aseIyfXq.js} +1 -1
- package/web/assets/{interface-share-satellite.svg-Dt-PZyoP.js → interface-share-satellite.svg-CzkX6PJ2.js} +1 -1
- package/web/assets/{interface-share-space-ship.svg-DbJpVjTn.js → interface-share-space-ship.svg-Df1jdZi5.js} +1 -1
- package/web/assets/{interface-share.svg-9Bxtnx5d.js → interface-share.svg-CioS2p8V.js} +1 -1
- package/web/assets/{interface-signal-square.svg-CYGdCItu.js → interface-signal-square.svg-VUtTXd8G.js} +1 -1
- package/web/assets/{interface-time-clock-circle.svg-0lffJ7tQ.js → interface-time-clock-circle.svg-DWh2OWyC.js} +1 -1
- package/web/assets/{interface-time-hour-glass.svg-BtZTqD1b.js → interface-time-hour-glass.svg-BCqCfi9r.js} +1 -1
- package/web/assets/{interface-users-multiple.svg-B7F73V4j.js → interface-users-multiple.svg-Edac3LOs.js} +1 -1
- package/web/assets/{interface-weather-moon.svg-Co0IUTf8.js → interface-weather-moon.svg-BrK0lmKX.js} +1 -1
- package/web/assets/{javascript-iLWmo9Qr.js → javascript-ByDc_p54.js} +1 -1
- package/web/assets/{jsonMode-D3SRxnAF.js → jsonMode-Cm2EOOd4.js} +1 -1
- package/web/assets/{liquid-D5C_hJy7.js → liquid-z9Tc1tTM.js} +1 -1
- package/web/assets/{lspLanguageFeatures-DeXbFx7Z.js → lspLanguageFeatures-D6O0oAJj.js} +1 -1
- package/web/assets/{mail-chat-bubble-square.svg-Cnn1sRtD.js → mail-chat-bubble-square.svg-obHuGV3I.js} +1 -1
- package/web/assets/{mail-send-email-paper-airplane.svg-CqK1oWPg.js → mail-send-email-paper-airplane.svg-I-JVbCkD.js} +1 -1
- package/web/assets/{mail-send-envelope.svg-DIvASWH1.js → mail-send-envelope.svg-CcYcXCe5.js} +1 -1
- package/web/assets/{mdx-wnkKJwKX.js → mdx-B8bePw34.js} +1 -1
- package/web/assets/{minus-BGc58rrM.js → minus-k3R4JOtO.js} +2 -2
- package/web/assets/modal-CVWJd9ZI.js +5 -0
- package/web/assets/modal-Ccn3uciU.js +1 -0
- package/web/assets/{money-cashier-receipt.svg-CzJyKfSy.js → money-cashier-receipt.svg-BIKxMBIH.js} +1 -1
- package/web/assets/{money-currency-dollar-pay.svg-CwjHgCC1.js → money-currency-dollar-pay.svg-B-HfkTCE.js} +1 -1
- package/web/assets/{money-graph-arrow-increase.svg-C2VxjTpX.js → money-graph-arrow-increase.svg-CnXoTtSD.js} +1 -1
- package/web/assets/{money-graph-bar-chart-increase.svg-CI6bcxy-.js → money-graph-bar-chart-increase.svg-Dt7ly9Tz.js} +1 -1
- package/web/assets/multiselect-BsCXwmy0.js +251 -0
- package/web/assets/{nature-ecology-leaf.svg-DlkkijsA.js → nature-ecology-leaf.svg-TjKZfobq.js} +1 -1
- package/web/assets/{password-CknBOa6c.js → password-dyrMCyHO.js} +4 -4
- package/web/assets/{phone-telephone.svg-DB57c0uQ.js → phone-telephone.svg-CCMqAIP_.js} +1 -1
- package/web/assets/{plus-vTZ3EI82.js → plus-Dg2E4ggP.js} +6 -6
- package/web/assets/process.store-CHdSS5Et.js +1 -0
- package/web/assets/{programming-bug.svg-Bpzz6qqz.js → programming-bug.svg-yyshFuq4.js} +1 -1
- package/web/assets/{programming-cloud.svg-Bu_Znc8m.js → programming-cloud.svg-DPyoJVZM.js} +1 -1
- package/web/assets/{programming-computer-database-server.svg-BzyehrHn.js → programming-computer-database-server.svg-D7pShcvh.js} +1 -1
- package/web/assets/{programming-computer-database.svg-jGG7yJ-F.js → programming-computer-database.svg-CErKDQrw.js} +1 -1
- package/web/assets/{programming-module-four-layout.svg-BUt4Ml7K.js → programming-module-four-layout.svg-B26pG3Bb.js} +1 -1
- package/web/assets/{programming-module-three.svg-DTbRPYAb.js → programming-module-three.svg-CnoN59HX.js} +1 -1
- package/web/assets/{programming-module.svg-z4xhH8Dl.js → programming-module.svg-C02rn1I7.js} +1 -1
- package/web/assets/{programming-script-code.svg-CnJWv1-9.js → programming-script-code.svg-D0sPjoPV.js} +1 -1
- package/web/assets/{python-rG_OzRqj.js → python-1623Ut7s.js} +1 -1
- package/web/assets/{razor-D3sCDiqd.js → razor-CyTiWHYX.js} +1 -1
- package/web/assets/router-DWhykW-F.js +1 -0
- package/web/assets/settings-scope-9i3_Io9Z.js +1 -0
- package/web/assets/{settings.store-Ci_N5bWL.js → settings.store-BPAoJA_7.js} +1 -1
- package/web/assets/{shopping-cart.svg-BKfZC1qE.js → shopping-cart.svg-Cusya5ZE.js} +1 -1
- package/web/assets/{shopping-gift-present.svg-t023rdyN.js → shopping-gift-present.svg-DuhD1jDX.js} +1 -1
- package/web/assets/{shopping-shipping-box-parcel-package.svg-BwzwfQ_c.js → shopping-shipping-box-parcel-package.svg-mUJnCOxq.js} +1 -1
- package/web/assets/src-BiD62eGr.js +1 -0
- package/web/assets/src-CGoYw9sv.css +1 -0
- package/web/assets/{src-DPqmktmn.js → src-HsHwQ5rW.js} +14 -14
- package/web/assets/{tabpanel-B40ITuTH.js → tabpanel-D-R0gqbm.js} +3 -3
- package/web/assets/{tag-new-circle.svg-BIfD1F_x.js → tag-new-circle.svg-DFYYOM3s.js} +1 -1
- package/web/assets/{toggleswitch-Dt_ptl6t.js → toggleswitch-Bv2Y60nl.js} +2 -2
- package/web/assets/{travel-map-earth-globe.svg-CXUdwwcu.js → travel-map-earth-globe.svg-D1KtAG5P.js} +1 -1
- package/web/assets/trpc-4Nls70HO.js +1 -0
- package/web/assets/{tsMode-tZ7zzelW.js → tsMode-DarxEDX3.js} +1 -1
- package/web/assets/{typescript-FIjOqkFs.js → typescript-Bp83QY3R.js} +1 -1
- package/web/assets/useAiChatDrawer-BYR24v6F.js +1 -0
- package/web/assets/useCloudOrg-B1BakNYp.js +572 -0
- package/web/assets/{useCloudOrg-CZ_ZOAVy.css → useCloudOrg-CkiFdVCe.css} +1 -1
- package/web/assets/useProjectCatalog-ClgttEEn.js +1 -0
- package/web/assets/{xml-CdxscNq-.js → xml-CieK61bI.js} +1 -1
- package/web/assets/{yaml-D6DcoEmu.js → yaml-Dd4h-bcV.js} +1 -1
- package/web/index.html +2 -2
- package/agent-manager-U454MXAX.js +0 -7
- package/chunk-PDRWT47K.js.map +0 -1
- package/src-K5L5HTKP.js.map +0 -1
- package/web/assets/AgentScalarChatInterface.vue-BaIR1ZwL.js +0 -13
- package/web/assets/AgentTerminalPage-Chql5o8h.js +0 -1
- package/web/assets/AiChatPage-DijdhDBJ.js +0 -1
- package/web/assets/AppLayout-DRQiJFAe.js +0 -1
- package/web/assets/AuditPage-DBrGkmq6.js +0 -1
- package/web/assets/CloudAccountPage-Bz5yu3CN.js +0 -1
- package/web/assets/CloudAccountPage-CtaTO5Dr.js +0 -1
- package/web/assets/CloudMessagingPage-D1uKwcxg.js +0 -2
- package/web/assets/DashboardPage-BBFsMFk3.js +0 -1
- package/web/assets/DirectoryPickerDialog-DMUrjQdd.js +0 -1
- package/web/assets/EnvironmentForm-D7Cq-8MZ.js +0 -108
- package/web/assets/EnvironmentFormPage-Dgcm1IXC.js +0 -1
- package/web/assets/EnvironmentListPage-kQY6ZGA3.js +0 -1
- package/web/assets/KanbanBoardPage-B5xNcvmj.js +0 -4
- package/web/assets/KanbanListPage-D-hG5Ag0.js +0 -1
- package/web/assets/LaunchProjectPage-BPbq8Mqg.js +0 -1
- package/web/assets/LaunchServicesPage-CKt_9IHU.js +0 -1
- package/web/assets/LogViewer-BCvltLuS.js +0 -3
- package/web/assets/OrgKeyPrompt-_pg1asnX.js +0 -1
- package/web/assets/ProcessDetailPage-ClzLOqgt.js +0 -1
- package/web/assets/ProjectDetailPage-XVg6xk7_.js +0 -1
- package/web/assets/ProjectListPage-BW4wrm6E.js +0 -1
- package/web/assets/RandomJobTestPage-DZ75Nh-v.js +0 -2
- package/web/assets/ScenarioEditorPage-uH-7yybT.js +0 -14
- package/web/assets/SendToChatDialog-nfy9y-Ji.js +0 -1
- package/web/assets/ServiceControlsBar-hNxsBv7d.js +0 -1
- package/web/assets/ServiceDetailPage-DxSGMGDF.js +0 -2
- package/web/assets/ServiceFormPage-QkfjrWmq.js +0 -1
- package/web/assets/SettingsPage-DJLCo3L_.js +0 -2063
- package/web/assets/UnlockPage-BhHpc9pz.js +0 -1
- package/web/assets/VariablesTable-N_1OjM81.js +0 -1
- package/web/assets/VaultMigrationPage-DVrzZhP0.js +0 -1
- package/web/assets/VersionBadge-C8SWxB0u.js +0 -1
- package/web/assets/WikiPage-rOxWNgKc.js +0 -1
- package/web/assets/WikiView-Bh4Rc1_F.js +0 -1
- package/web/assets/add-scalar-classes-DreMq9eS.js +0 -387
- package/web/assets/auth-errors-BOBaCbd9.js +0 -1
- package/web/assets/cloud-chat.store-DteZIY7A.js +0 -1
- package/web/assets/cloud-session-PX6MlRl9.js +0 -1
- package/web/assets/column-D_CDh4mf.js +0 -907
- package/web/assets/index-Cz0azMVO.css +0 -1
- package/web/assets/interface-content-folder.svg-BiARWOa_.js +0 -1
- package/web/assets/modal-CVEyxr-0.js +0 -5
- package/web/assets/modal-DmCFgP0y.js +0 -1
- package/web/assets/multiselect-DYHLYL35.js +0 -251
- package/web/assets/process.store-CeybR5VK.js +0 -1
- package/web/assets/router-Dx2pV4zI.js +0 -1
- package/web/assets/settings-scope-DVqLTAzI.js +0 -1
- package/web/assets/src-3tEmDkie.js +0 -1
- package/web/assets/src-DIxcn8ra.css +0 -1
- package/web/assets/trpc-BkrN7NiU.js +0 -1
- package/web/assets/useAiChatDrawer-DFAtVCez.js +0 -1
- package/web/assets/useCloudOrg-DnZamx1M.js +0 -572
- package/web/assets/useProjectCatalog-B4PXCnXu.js +0 -1
- /package/{agent-manager-U454MXAX.js.map → agent-manager-3KSS7BHP.js.map} +0 -0
|
@@ -5,6 +5,9 @@ import {
|
|
|
5
5
|
AmbiguousProjectError,
|
|
6
6
|
ApiKeyScopeSchema,
|
|
7
7
|
ApiKeysFileSchema,
|
|
8
|
+
ChangelogIndexItemSchema,
|
|
9
|
+
ChangelogReleaseSchema,
|
|
10
|
+
ChangelogSurfaceSchema,
|
|
8
11
|
CreateEnvironmentSchema,
|
|
9
12
|
DockerConfigSchema,
|
|
10
13
|
EDITOR_BY_KEY,
|
|
@@ -114,7 +117,7 @@ import {
|
|
|
114
117
|
wasRead,
|
|
115
118
|
withDeprecatedAliases,
|
|
116
119
|
writeEntity
|
|
117
|
-
} from "./chunk-
|
|
120
|
+
} from "./chunk-4PQXBTV6.js";
|
|
118
121
|
|
|
119
122
|
// ../server/src/create-server.ts
|
|
120
123
|
import express from "express";
|
|
@@ -494,6 +497,28 @@ function compareSemver(a, b) {
|
|
|
494
497
|
}
|
|
495
498
|
return 0;
|
|
496
499
|
}
|
|
500
|
+
var VERSION_CACHE_MS = 4 * 60 * 1e3;
|
|
501
|
+
var versionCache = null;
|
|
502
|
+
async function fetchLatestVersion() {
|
|
503
|
+
if (versionCache && Date.now() - versionCache.at < VERSION_CACHE_MS) {
|
|
504
|
+
return versionCache.latest;
|
|
505
|
+
}
|
|
506
|
+
let latest = null;
|
|
507
|
+
try {
|
|
508
|
+
const res = await fetch(NPM_LATEST_URL, {
|
|
509
|
+
headers: { accept: "application/json" },
|
|
510
|
+
signal: AbortSignal.timeout(5e3)
|
|
511
|
+
});
|
|
512
|
+
if (res.ok) {
|
|
513
|
+
const parsed = z.object({ version: z.string().max(64) }).safeParse(await res.json());
|
|
514
|
+
if (parsed.success) latest = parsed.data.version;
|
|
515
|
+
}
|
|
516
|
+
} catch {
|
|
517
|
+
latest = null;
|
|
518
|
+
}
|
|
519
|
+
versionCache = { at: Date.now(), latest };
|
|
520
|
+
return latest;
|
|
521
|
+
}
|
|
497
522
|
var healthRouter = router({
|
|
498
523
|
check: publicProcedure.meta({ openapi: { method: "GET", path: "/health", tags: ["health"], summary: "Health check" } }).output(z.object({ status: z.literal("ok"), uptime: z.number(), version: z.string() })).query(() => {
|
|
499
524
|
return {
|
|
@@ -512,25 +537,13 @@ var healthRouter = router({
|
|
|
512
537
|
if (appVersion === "dev") {
|
|
513
538
|
return { current: appVersion, latest: null, status: "dev" };
|
|
514
539
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
headers: { accept: "application/json" },
|
|
518
|
-
signal: AbortSignal.timeout(5e3)
|
|
519
|
-
});
|
|
520
|
-
if (!res.ok) {
|
|
521
|
-
return { current: appVersion, latest: null, status: "unknown" };
|
|
522
|
-
}
|
|
523
|
-
const parsed = z.object({ version: z.string().max(64) }).safeParse(await res.json());
|
|
524
|
-
if (!parsed.success) {
|
|
525
|
-
return { current: appVersion, latest: null, status: "unknown" };
|
|
526
|
-
}
|
|
527
|
-
const latest = parsed.data.version;
|
|
528
|
-
const cmp = compareSemver(appVersion, latest);
|
|
529
|
-
const status = cmp === 0 ? "up-to-date" : cmp < 0 ? "outdated" : "ahead";
|
|
530
|
-
return { current: appVersion, latest, status };
|
|
531
|
-
} catch {
|
|
540
|
+
const latest = await fetchLatestVersion();
|
|
541
|
+
if (latest === null) {
|
|
532
542
|
return { current: appVersion, latest: null, status: "unknown" };
|
|
533
543
|
}
|
|
544
|
+
const cmp = compareSemver(appVersion, latest);
|
|
545
|
+
const status = cmp === 0 ? "up-to-date" : cmp < 0 ? "outdated" : "ahead";
|
|
546
|
+
return { current: appVersion, latest, status };
|
|
534
547
|
}),
|
|
535
548
|
systemInfo: protectedProcedure.output(
|
|
536
549
|
z.object({
|
|
@@ -701,18 +714,233 @@ var appUpdateRouter = router({
|
|
|
701
714
|
})
|
|
702
715
|
});
|
|
703
716
|
|
|
704
|
-
// ../server/src/trpc/routers/
|
|
717
|
+
// ../server/src/trpc/routers/changelog.ts
|
|
705
718
|
import { z as z3 } from "zod";
|
|
719
|
+
|
|
720
|
+
// ../server/src/services/cloud-session-store.ts
|
|
721
|
+
import { readFile as readFile2, writeFile as writeFile2, rename as rename2, mkdir as mkdir2, chmod as chmod2, unlink } from "fs/promises";
|
|
722
|
+
import { dirname as dirname3 } from "path";
|
|
723
|
+
import { randomBytes as randomBytes3, timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
724
|
+
var FILENAME = "cloud-session.json";
|
|
725
|
+
var STATE_TTL_MS = 5 * 60 * 1e3;
|
|
726
|
+
var CloudSessionStore = class {
|
|
727
|
+
session = null;
|
|
728
|
+
loaded = false;
|
|
729
|
+
/** Pending login states (CSRF binding between `start` and the callback). */
|
|
730
|
+
pending = /* @__PURE__ */ new Map();
|
|
731
|
+
/**
|
|
732
|
+
* Encrypted, so it lives beside the key that opens it — usually the machine
|
|
733
|
+
* root, but a launch directory owning its own key keeps both together.
|
|
734
|
+
*/
|
|
735
|
+
getFilePath() {
|
|
736
|
+
return keyedFilePath(FILENAME);
|
|
737
|
+
}
|
|
738
|
+
/** Where older versions kept it — read only, so an older Runeya keeps working. */
|
|
739
|
+
getLegacyFilePath() {
|
|
740
|
+
return legacyMachineFilePath(FILENAME);
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* Read the machine file, falling back to the launch directory of old.
|
|
744
|
+
*
|
|
745
|
+
* The legacy file is left in place: the next save writes the new location,
|
|
746
|
+
* and a directory still opened by an older Runeya keeps working meanwhile.
|
|
747
|
+
*/
|
|
748
|
+
async readFromDisk() {
|
|
749
|
+
try {
|
|
750
|
+
return await readFile2(await this.getFilePath(), "utf-8");
|
|
751
|
+
} catch {
|
|
752
|
+
return readFile2(this.getLegacyFilePath(), "utf-8");
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
async load() {
|
|
756
|
+
if (this.loaded) return;
|
|
757
|
+
try {
|
|
758
|
+
const raw = await this.readFromDisk();
|
|
759
|
+
this.session = JSON.parse(raw);
|
|
760
|
+
} catch {
|
|
761
|
+
}
|
|
762
|
+
this.loaded = true;
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* Mint a state value binding a login attempt to this server. Returned to the
|
|
766
|
+
* cloud page and echoed back on the callback, so a redirect we never
|
|
767
|
+
* initiated cannot install a token.
|
|
768
|
+
*/
|
|
769
|
+
createState(returnTo) {
|
|
770
|
+
this.sweepStates();
|
|
771
|
+
const state = randomBytes3(32).toString("hex");
|
|
772
|
+
this.pending.set(state, { expiresAt: Date.now() + STATE_TTL_MS, returnTo });
|
|
773
|
+
return state;
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Consume a state — single use, constant-time compare, TTL enforced. Returns
|
|
777
|
+
* the URL to send the browser back to, or null when the state is unknown or
|
|
778
|
+
* expired (i.e. a callback this server never initiated).
|
|
779
|
+
*/
|
|
780
|
+
consumeState(candidate) {
|
|
781
|
+
this.sweepStates();
|
|
782
|
+
for (const [state, entry] of this.pending) {
|
|
783
|
+
const a = Buffer.from(state);
|
|
784
|
+
const b = Buffer.from(candidate);
|
|
785
|
+
if (a.length === b.length && timingSafeEqual2(a, b)) {
|
|
786
|
+
this.pending.delete(state);
|
|
787
|
+
return entry.expiresAt > Date.now() ? entry.returnTo : null;
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
return null;
|
|
791
|
+
}
|
|
792
|
+
sweepStates() {
|
|
793
|
+
const now = Date.now();
|
|
794
|
+
for (const [state, entry] of this.pending) {
|
|
795
|
+
if (entry.expiresAt <= now) this.pending.delete(state);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
async save() {
|
|
799
|
+
await mkdir2(dirname3(await this.getFilePath()), { recursive: true });
|
|
800
|
+
const filePath = await this.getFilePath();
|
|
801
|
+
const tmpPath = filePath + ".tmp";
|
|
802
|
+
await writeFile2(tmpPath, JSON.stringify(this.session, null, 2), "utf-8");
|
|
803
|
+
await rename2(tmpPath, filePath);
|
|
804
|
+
await chmod2(filePath, 384);
|
|
805
|
+
}
|
|
806
|
+
/** Store the session token obtained from the one-time-token exchange. */
|
|
807
|
+
async set(cloudUrl, token) {
|
|
808
|
+
await this.load();
|
|
809
|
+
this.session = { cloudUrl, encryptedToken: encryptValue(token) };
|
|
810
|
+
await this.save();
|
|
811
|
+
}
|
|
812
|
+
/** The decrypted session token, or null when not logged in. */
|
|
813
|
+
async getToken() {
|
|
814
|
+
await this.load();
|
|
815
|
+
if (!this.session) return null;
|
|
816
|
+
try {
|
|
817
|
+
return decryptValue(this.session.encryptedToken);
|
|
818
|
+
} catch {
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* The cloud this machine is signed into, or null when not linked.
|
|
824
|
+
*
|
|
825
|
+
* Needed to tell "an org I am not a member of" apart from "an org of another
|
|
826
|
+
* cloud instance entirely" — the ids of two clouds share no namespace, so
|
|
827
|
+
* comparing them without this would call every foreign-cloud project a
|
|
828
|
+
* permission problem.
|
|
829
|
+
*/
|
|
830
|
+
async getCloudUrl() {
|
|
831
|
+
await this.load();
|
|
832
|
+
return this.session?.cloudUrl ?? null;
|
|
833
|
+
}
|
|
834
|
+
async isLinked() {
|
|
835
|
+
return await this.getToken() !== null;
|
|
836
|
+
}
|
|
837
|
+
/** Forget the session (sign-out). */
|
|
838
|
+
async clear() {
|
|
839
|
+
await this.load();
|
|
840
|
+
this.session = null;
|
|
841
|
+
this.pending.clear();
|
|
842
|
+
try {
|
|
843
|
+
await unlink(await this.getFilePath());
|
|
844
|
+
} catch {
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
};
|
|
848
|
+
var cloudSessionStore = new CloudSessionStore();
|
|
849
|
+
|
|
850
|
+
// ../server/src/services/cloud-api.ts
|
|
851
|
+
var DEFAULT_CLOUD_API_URL = "https://api.runeya.dev";
|
|
852
|
+
var DEFAULT_CLOUD_APP_URL = "https://runeya.dev";
|
|
853
|
+
function getCloudApiUrl() {
|
|
854
|
+
return (env.CLOUD_URL ?? DEFAULT_CLOUD_API_URL).replace(/\/+$/, "");
|
|
855
|
+
}
|
|
856
|
+
function getCloudAppUrl() {
|
|
857
|
+
return (env.CLOUD_APP_URL ?? DEFAULT_CLOUD_APP_URL).replace(/\/+$/, "");
|
|
858
|
+
}
|
|
859
|
+
var CloudNotLinkedError = class extends Error {
|
|
860
|
+
code = "CLOUD_NOT_LINKED";
|
|
861
|
+
constructor() {
|
|
862
|
+
super("Not linked to the Runeya cloud.");
|
|
863
|
+
this.name = "CloudNotLinkedError";
|
|
864
|
+
}
|
|
865
|
+
};
|
|
866
|
+
async function cloudFetch(path, init = {}) {
|
|
867
|
+
const token = await cloudSessionStore.getToken();
|
|
868
|
+
if (!token) throw new CloudNotLinkedError();
|
|
869
|
+
return fetch(`${getCloudApiUrl()}${path}`, {
|
|
870
|
+
method: init.method ?? "GET",
|
|
871
|
+
headers: {
|
|
872
|
+
Authorization: `Bearer ${token}`,
|
|
873
|
+
// Le cloud refuse (426) les apps trop anciennes pour son schéma courant.
|
|
874
|
+
[APP_VERSION_HEADER]: appVersion,
|
|
875
|
+
...init.body !== void 0 ? { "Content-Type": "application/json" } : {}
|
|
876
|
+
},
|
|
877
|
+
...init.body !== void 0 ? { body: JSON.stringify(init.body) } : {},
|
|
878
|
+
// 15s suits a JSON call; attachment downloads pass a longer budget.
|
|
879
|
+
signal: AbortSignal.timeout(init.timeoutMs ?? 15e3)
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// ../server/src/trpc/routers/changelog.ts
|
|
884
|
+
var CACHE_MS = 5 * 60 * 1e3;
|
|
885
|
+
var cache = /* @__PURE__ */ new Map();
|
|
886
|
+
async function cloudChangelog(path, params) {
|
|
887
|
+
const search = new URLSearchParams();
|
|
888
|
+
for (const [key, value2] of Object.entries(params)) if (value2) search.set(key, value2);
|
|
889
|
+
const url = `${getCloudApiUrl()}${path}?${search.toString()}`;
|
|
890
|
+
const hit = cache.get(url);
|
|
891
|
+
if (hit && Date.now() - hit.at < CACHE_MS) return hit.value;
|
|
892
|
+
const res = await fetch(url, {
|
|
893
|
+
headers: { accept: "application/json" },
|
|
894
|
+
signal: AbortSignal.timeout(8e3)
|
|
895
|
+
});
|
|
896
|
+
if (!res.ok) throw new Error(`changelog: HTTP ${res.status}`);
|
|
897
|
+
const value = await res.json();
|
|
898
|
+
cache.set(url, { at: Date.now(), value });
|
|
899
|
+
return value;
|
|
900
|
+
}
|
|
901
|
+
function appCeiling() {
|
|
902
|
+
return appVersion === "dev" ? null : appVersion;
|
|
903
|
+
}
|
|
904
|
+
var inputSchema = z3.object({
|
|
905
|
+
surface: ChangelogSurfaceSchema,
|
|
906
|
+
/** Dernière version déjà vue par ce navigateur, exclue du résultat. */
|
|
907
|
+
since: z3.string().max(32).nullish()
|
|
908
|
+
});
|
|
909
|
+
var changelogRouter = router({
|
|
910
|
+
/** Ce qu'il y a à lire, sans les corps. */
|
|
911
|
+
index: publicProcedure.input(inputSchema).output(z3.object({ releases: z3.array(ChangelogIndexItemSchema), currentAppVersion: z3.string() })).query(async ({ input }) => {
|
|
912
|
+
const data = await cloudChangelog("/api/changelog", {
|
|
913
|
+
surface: input.surface,
|
|
914
|
+
since: input.since ?? null,
|
|
915
|
+
until: input.surface === "app" ? appCeiling() : null
|
|
916
|
+
});
|
|
917
|
+
const parsed = z3.object({ releases: z3.array(ChangelogIndexItemSchema) }).parse(data);
|
|
918
|
+
return { releases: parsed.releases, currentAppVersion: appVersion };
|
|
919
|
+
}),
|
|
920
|
+
/** Les entrées complètes. */
|
|
921
|
+
releases: publicProcedure.input(inputSchema).output(z3.object({ releases: z3.array(ChangelogReleaseSchema), currentAppVersion: z3.string() })).query(async ({ input }) => {
|
|
922
|
+
const data = await cloudChangelog("/api/changelog/releases", {
|
|
923
|
+
surface: input.surface,
|
|
924
|
+
since: input.since ?? null,
|
|
925
|
+
until: input.surface === "app" ? appCeiling() : null
|
|
926
|
+
});
|
|
927
|
+
const parsed = z3.object({ releases: z3.array(ChangelogReleaseSchema) }).parse(data);
|
|
928
|
+
return { releases: parsed.releases, currentAppVersion: appVersion };
|
|
929
|
+
})
|
|
930
|
+
});
|
|
931
|
+
|
|
932
|
+
// ../server/src/trpc/routers/project.ts
|
|
933
|
+
import { z as z4 } from "zod";
|
|
706
934
|
import { TRPCError as TRPCError3 } from "@trpc/server";
|
|
707
935
|
|
|
708
936
|
// ../server/src/services/project-store.ts
|
|
709
937
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
710
938
|
import { EventEmitter } from "events";
|
|
711
|
-
import { readFile as
|
|
939
|
+
import { readFile as readFile4, writeFile as writeFile5, rename as rename4, mkdir as mkdir4, chmod as chmod4, rm } from "fs/promises";
|
|
712
940
|
import { join as join5 } from "path";
|
|
713
941
|
|
|
714
942
|
// ../server/src/utils/ensure-data-gitignore.ts
|
|
715
|
-
import { writeFile as
|
|
943
|
+
import { writeFile as writeFile3 } from "fs/promises";
|
|
716
944
|
import { join as join3 } from "path";
|
|
717
945
|
var GITIGNORE_CONTENT = `
|
|
718
946
|
#################
|
|
@@ -751,19 +979,19 @@ conversations.private.json
|
|
|
751
979
|
`;
|
|
752
980
|
async function ensureDataGitignore(dataDir) {
|
|
753
981
|
const gitignorePath = join3(dataDir, ".gitignore");
|
|
754
|
-
await
|
|
982
|
+
await writeFile3(gitignorePath, GITIGNORE_CONTENT, "utf-8");
|
|
755
983
|
}
|
|
756
984
|
|
|
757
985
|
// ../server/src/services/project-path-store.ts
|
|
758
|
-
import { readFile as
|
|
986
|
+
import { readFile as readFile3, writeFile as writeFile4, rename as rename3, mkdir as mkdir3, chmod as chmod3, stat } from "fs/promises";
|
|
759
987
|
import { isAbsolute, join as join4, resolve } from "path";
|
|
760
|
-
var
|
|
988
|
+
var FILENAME2 = "project-paths.json";
|
|
761
989
|
var ProjectPathStore = class {
|
|
762
990
|
paths = null;
|
|
763
991
|
async load() {
|
|
764
992
|
if (this.paths) return this.paths;
|
|
765
993
|
try {
|
|
766
|
-
const raw = await
|
|
994
|
+
const raw = await readFile3(machineFilePath(FILENAME2), "utf-8");
|
|
767
995
|
const parsed = JSON.parse(raw);
|
|
768
996
|
this.paths = isPathMap(parsed) ? parsed : {};
|
|
769
997
|
} catch {
|
|
@@ -772,12 +1000,12 @@ var ProjectPathStore = class {
|
|
|
772
1000
|
return this.paths;
|
|
773
1001
|
}
|
|
774
1002
|
async persist() {
|
|
775
|
-
await
|
|
776
|
-
const filePath = machineFilePath(
|
|
1003
|
+
await mkdir3(machineRoot(), { recursive: true });
|
|
1004
|
+
const filePath = machineFilePath(FILENAME2);
|
|
777
1005
|
const tmpPath = `${filePath}.tmp`;
|
|
778
|
-
await
|
|
779
|
-
await
|
|
780
|
-
await
|
|
1006
|
+
await writeFile4(tmpPath, JSON.stringify(this.paths ?? {}, null, 2), "utf-8");
|
|
1007
|
+
await rename3(tmpPath, filePath);
|
|
1008
|
+
await chmod3(filePath, 384);
|
|
781
1009
|
}
|
|
782
1010
|
/** The directory chosen for this project, or null while it has none. */
|
|
783
1011
|
async get(ref) {
|
|
@@ -855,7 +1083,7 @@ async function holdsRuneyaProject(path) {
|
|
|
855
1083
|
var projectPathStore = new ProjectPathStore();
|
|
856
1084
|
|
|
857
1085
|
// ../server/src/services/project-store.ts
|
|
858
|
-
var
|
|
1086
|
+
var FILENAME3 = "project.json";
|
|
859
1087
|
var LEGACY_FILENAME = "projects.json";
|
|
860
1088
|
function toDiskForm(project) {
|
|
861
1089
|
const { activeEnvironmentId: _runtimeOnly, ...rest } = project;
|
|
@@ -865,14 +1093,14 @@ async function readLocalProject() {
|
|
|
865
1093
|
const root = localVaultRoot();
|
|
866
1094
|
let current = null;
|
|
867
1095
|
try {
|
|
868
|
-
const raw = await
|
|
1096
|
+
const raw = await readFile4(join5(root, FILENAME3), "utf-8");
|
|
869
1097
|
const parsed = ProjectSchema.safeParse(JSON.parse(raw));
|
|
870
1098
|
if (parsed.success) current = parsed.data;
|
|
871
1099
|
} catch {
|
|
872
1100
|
}
|
|
873
1101
|
let legacy;
|
|
874
1102
|
try {
|
|
875
|
-
legacy = JSON.parse(await
|
|
1103
|
+
legacy = JSON.parse(await readFile4(join5(root, LEGACY_FILENAME), "utf-8"));
|
|
876
1104
|
} catch {
|
|
877
1105
|
return { local: current, strayCloud: [] };
|
|
878
1106
|
}
|
|
@@ -891,7 +1119,7 @@ async function readCloudProjects() {
|
|
|
891
1119
|
const found = [];
|
|
892
1120
|
for (const { orgId, projectId, root } of await listCloudVaults()) {
|
|
893
1121
|
try {
|
|
894
|
-
const raw = await
|
|
1122
|
+
const raw = await readFile4(join5(root, FILENAME3), "utf-8");
|
|
895
1123
|
const parsed = ProjectSchema.safeParse({ ...JSON.parse(raw), id: projectId, orgId });
|
|
896
1124
|
if (parsed.success) found.push({ project: parsed.data, root });
|
|
897
1125
|
} catch {
|
|
@@ -921,13 +1149,13 @@ var ProjectStore = class {
|
|
|
921
1149
|
/** Emits `'saved'` after every persisted mutation, for the cloud sync bridge. */
|
|
922
1150
|
events = new EventEmitter();
|
|
923
1151
|
getFilePath(root = localVaultRoot()) {
|
|
924
|
-
return join5(root,
|
|
1152
|
+
return join5(root, FILENAME3);
|
|
925
1153
|
}
|
|
926
1154
|
async writeAtomic(filePath, data) {
|
|
927
1155
|
const tmpPath = filePath + ".tmp";
|
|
928
|
-
await
|
|
929
|
-
await
|
|
930
|
-
await
|
|
1156
|
+
await writeFile5(tmpPath, data, "utf-8");
|
|
1157
|
+
await rename4(tmpPath, filePath);
|
|
1158
|
+
await chmod4(filePath, 384);
|
|
931
1159
|
}
|
|
932
1160
|
/** Adopt a project read from disk, remembering which vault it came from. */
|
|
933
1161
|
async absorb(p, root) {
|
|
@@ -1002,10 +1230,10 @@ var ProjectStore = class {
|
|
|
1002
1230
|
await rm(this.getFilePath(), { force: true }).catch(() => {
|
|
1003
1231
|
});
|
|
1004
1232
|
}
|
|
1005
|
-
await
|
|
1233
|
+
await rename4(join5(localVaultRoot(), LEGACY_FILENAME), join5(localVaultRoot(), LEGACY_FILENAME + ".bak")).catch(() => {
|
|
1006
1234
|
});
|
|
1007
1235
|
for (const { project, root } of cloud) {
|
|
1008
|
-
await
|
|
1236
|
+
await mkdir4(root, { recursive: true });
|
|
1009
1237
|
await this.writeAtomic(this.getFilePath(root), JSON.stringify(toDiskForm(project), null, 2));
|
|
1010
1238
|
setProjectVault(project, root);
|
|
1011
1239
|
}
|
|
@@ -1296,9 +1524,9 @@ var projectStore = new ProjectStore();
|
|
|
1296
1524
|
registerProjectLoader(() => projectStore.list().then(() => void 0));
|
|
1297
1525
|
|
|
1298
1526
|
// ../server/src/services/environment-overrides-store.ts
|
|
1299
|
-
import { readFile as
|
|
1300
|
-
import { dirname as
|
|
1301
|
-
var
|
|
1527
|
+
import { readFile as readFile5, writeFile as writeFile6, rename as rename5, mkdir as mkdir5, chmod as chmod5 } from "fs/promises";
|
|
1528
|
+
import { dirname as dirname4, join as join6 } from "path";
|
|
1529
|
+
var FILENAME4 = "environment-overrides.json";
|
|
1302
1530
|
var EnvironmentOverridesStore = class {
|
|
1303
1531
|
data = {};
|
|
1304
1532
|
loaded = false;
|
|
@@ -1330,11 +1558,11 @@ var EnvironmentOverridesStore = class {
|
|
|
1330
1558
|
async rootFor(variableId) {
|
|
1331
1559
|
const root = await environmentStore.rootOfVariable(variableId);
|
|
1332
1560
|
if (root) return root;
|
|
1333
|
-
return this.roots.get(variableId) ??
|
|
1561
|
+
return this.roots.get(variableId) ?? dirname4(await keyedFilePath(FILENAME4));
|
|
1334
1562
|
}
|
|
1335
1563
|
/** Where earlier versions kept them: read once, rewritten to their vaults. */
|
|
1336
1564
|
getLegacyFilePath() {
|
|
1337
|
-
return legacyMachineFilePath(
|
|
1565
|
+
return legacyMachineFilePath(FILENAME4);
|
|
1338
1566
|
}
|
|
1339
1567
|
/**
|
|
1340
1568
|
* Read every vault, then the places older versions used.
|
|
@@ -1350,13 +1578,13 @@ var EnvironmentOverridesStore = class {
|
|
|
1350
1578
|
const roots = await allVaultRoots();
|
|
1351
1579
|
const sources = [
|
|
1352
1580
|
this.getLegacyFilePath(),
|
|
1353
|
-
await keyedFilePath(
|
|
1354
|
-
...roots.map((root) => join6(root,
|
|
1581
|
+
await keyedFilePath(FILENAME4),
|
|
1582
|
+
...roots.map((root) => join6(root, FILENAME4))
|
|
1355
1583
|
];
|
|
1356
1584
|
for (const path of sources) {
|
|
1357
1585
|
let parsed;
|
|
1358
1586
|
try {
|
|
1359
|
-
parsed = JSON.parse(await
|
|
1587
|
+
parsed = JSON.parse(await readFile5(path, "utf-8"));
|
|
1360
1588
|
} catch {
|
|
1361
1589
|
continue;
|
|
1362
1590
|
}
|
|
@@ -1368,11 +1596,11 @@ var EnvironmentOverridesStore = class {
|
|
|
1368
1596
|
parsed,
|
|
1369
1597
|
"environment-overrides",
|
|
1370
1598
|
(variableId) => this.unreadableSecrets.add(variableId),
|
|
1371
|
-
vaultIdOfRoot(
|
|
1599
|
+
vaultIdOfRoot(dirname4(path))
|
|
1372
1600
|
);
|
|
1373
1601
|
for (const [id, override] of Object.entries(decrypted)) {
|
|
1374
1602
|
this.data[id] = { value: override.value };
|
|
1375
|
-
this.roots.set(id,
|
|
1603
|
+
this.roots.set(id, dirname4(path));
|
|
1376
1604
|
}
|
|
1377
1605
|
}
|
|
1378
1606
|
}
|
|
@@ -1407,12 +1635,12 @@ var EnvironmentOverridesStore = class {
|
|
|
1407
1635
|
this.diskEncryptedSlots,
|
|
1408
1636
|
extractEncryptedVariableSlots(encrypted)
|
|
1409
1637
|
);
|
|
1410
|
-
await
|
|
1411
|
-
const path = join6(root,
|
|
1638
|
+
await mkdir5(root, { recursive: true });
|
|
1639
|
+
const path = join6(root, FILENAME4);
|
|
1412
1640
|
const tmpPath = path + ".tmp";
|
|
1413
|
-
await
|
|
1414
|
-
await
|
|
1415
|
-
await
|
|
1641
|
+
await writeFile6(tmpPath, JSON.stringify(encrypted, null, 2), "utf-8");
|
|
1642
|
+
await rename5(tmpPath, path);
|
|
1643
|
+
await chmod5(path, 384);
|
|
1416
1644
|
}
|
|
1417
1645
|
}
|
|
1418
1646
|
/**
|
|
@@ -1849,7 +2077,7 @@ var EnvironmentResolver = class {
|
|
|
1849
2077
|
var environmentResolver = new EnvironmentResolver();
|
|
1850
2078
|
|
|
1851
2079
|
// ../server/src/services/audit-service.ts
|
|
1852
|
-
import { appendFile, readFile as
|
|
2080
|
+
import { appendFile, readFile as readFile6, stat as stat2, rename as rename6, unlink as unlink2, readdir, mkdir as mkdir6 } from "fs/promises";
|
|
1853
2081
|
var AUDIT_FILENAME = "audit.log";
|
|
1854
2082
|
var MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
1855
2083
|
var MAX_AGE_DAYS = 30;
|
|
@@ -1869,7 +2097,7 @@ var AuditService = class {
|
|
|
1869
2097
|
const line = JSON.stringify(record) + "\n";
|
|
1870
2098
|
const filepath = this.getFilePath();
|
|
1871
2099
|
try {
|
|
1872
|
-
await
|
|
2100
|
+
await mkdir6(machineRoot(), { recursive: true });
|
|
1873
2101
|
await appendFile(filepath, line, "utf-8");
|
|
1874
2102
|
await this.rotateIfNeeded();
|
|
1875
2103
|
} catch (err) {
|
|
@@ -1882,7 +2110,7 @@ var AuditService = class {
|
|
|
1882
2110
|
const filepath = this.getFilePath();
|
|
1883
2111
|
let lines;
|
|
1884
2112
|
try {
|
|
1885
|
-
const content = await
|
|
2113
|
+
const content = await readFile6(filepath, "utf-8");
|
|
1886
2114
|
lines = content.trim().split("\n").filter(Boolean);
|
|
1887
2115
|
} catch {
|
|
1888
2116
|
return { entries: [], total: 0 };
|
|
@@ -1915,7 +2143,7 @@ var AuditService = class {
|
|
|
1915
2143
|
try {
|
|
1916
2144
|
const stats = await stat2(filepath);
|
|
1917
2145
|
if (stats.size > MAX_FILE_SIZE) {
|
|
1918
|
-
await
|
|
2146
|
+
await rename6(filepath, this.getRotatedPath());
|
|
1919
2147
|
}
|
|
1920
2148
|
} catch {
|
|
1921
2149
|
}
|
|
@@ -1930,7 +2158,7 @@ var AuditService = class {
|
|
|
1930
2158
|
const ts = Number.parseInt(tsStr, 10);
|
|
1931
2159
|
if (!Number.isNaN(ts) && ts < cutoff) {
|
|
1932
2160
|
try {
|
|
1933
|
-
await
|
|
2161
|
+
await unlink2(machineFilePath(file));
|
|
1934
2162
|
} catch {
|
|
1935
2163
|
}
|
|
1936
2164
|
}
|
|
@@ -1941,11 +2169,11 @@ var AuditService = class {
|
|
|
1941
2169
|
var auditService = new AuditService();
|
|
1942
2170
|
|
|
1943
2171
|
// ../server/src/services/org-keys.ts
|
|
1944
|
-
import { mkdir as
|
|
2172
|
+
import { mkdir as mkdir7 } from "fs/promises";
|
|
1945
2173
|
|
|
1946
2174
|
// ../server/src/services/master-password.ts
|
|
1947
|
-
import { randomBytes as
|
|
1948
|
-
import { readFile as
|
|
2175
|
+
import { randomBytes as randomBytes4, createCipheriv, createDecipheriv } from "crypto";
|
|
2176
|
+
import { readFile as readFile7, writeFile as writeFile7, chmod as chmod6, stat as stat3, rename as rename7 } from "fs/promises";
|
|
1949
2177
|
import { join as join7 } from "path";
|
|
1950
2178
|
import { Entry } from "@napi-rs/keyring";
|
|
1951
2179
|
import { hashRaw as argon2HashRaw } from "@node-rs/argon2";
|
|
@@ -1960,10 +2188,10 @@ var ARGON2_OPTIONS = { memoryCost: 65536, timeCost: 3, parallelism: 4, outputLen
|
|
|
1960
2188
|
async function readKeyFile(filePath) {
|
|
1961
2189
|
const s = await stat3(filePath);
|
|
1962
2190
|
if (s.size > MAX_KEY_FILE_SIZE) throw new Error(`Fichier suspect : ${filePath} (${s.size} octets)`);
|
|
1963
|
-
return
|
|
2191
|
+
return readFile7(filePath);
|
|
1964
2192
|
}
|
|
1965
2193
|
function aesEncrypt(key, plaintext) {
|
|
1966
|
-
const iv =
|
|
2194
|
+
const iv = randomBytes4(12);
|
|
1967
2195
|
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
1968
2196
|
const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
1969
2197
|
const authTag = cipher.getAuthTag();
|
|
@@ -1989,9 +2217,9 @@ async function getPepperFromFile(dataDir) {
|
|
|
1989
2217
|
async function writePepperToFile(dataDir, pepper) {
|
|
1990
2218
|
const filePath = join7(dataDir, PEPPER_FILENAME);
|
|
1991
2219
|
const tmpPath = filePath + ".tmp";
|
|
1992
|
-
await
|
|
1993
|
-
await
|
|
1994
|
-
await
|
|
2220
|
+
await writeFile7(tmpPath, pepper.toString("hex"), "utf-8");
|
|
2221
|
+
await chmod6(tmpPath, 384);
|
|
2222
|
+
await rename7(tmpPath, filePath);
|
|
1995
2223
|
}
|
|
1996
2224
|
function tryKeyringGet() {
|
|
1997
2225
|
try {
|
|
@@ -2015,7 +2243,7 @@ async function getOrCreatePepper(dataDir) {
|
|
|
2015
2243
|
}
|
|
2016
2244
|
const filePepper = await getPepperFromFile(dataDir);
|
|
2017
2245
|
if (filePepper) return filePepper;
|
|
2018
|
-
const pepper =
|
|
2246
|
+
const pepper = randomBytes4(32);
|
|
2019
2247
|
const saved = tryKeyringSet(pepper.toString("hex"));
|
|
2020
2248
|
if (!saved) {
|
|
2021
2249
|
console.warn("[master-password] Keyring unavailable, storing pepper in dataDir (fallback)");
|
|
@@ -2033,16 +2261,16 @@ async function deriveKey(masterPassword, pepper, salt) {
|
|
|
2033
2261
|
}
|
|
2034
2262
|
async function writeEncryptedKey(dataDir, masterPassword, encryptionKey, pepperDir = dataDir) {
|
|
2035
2263
|
const pepper = await getOrCreatePepper(pepperDir);
|
|
2036
|
-
const salt =
|
|
2264
|
+
const salt = randomBytes4(16);
|
|
2037
2265
|
const derivedKey = await deriveKey(masterPassword, pepper, salt);
|
|
2038
2266
|
const payload = aesEncrypt(derivedKey, encryptionKey);
|
|
2039
2267
|
const fileContent = Buffer.concat([salt, payload]);
|
|
2040
2268
|
const encoded = fileContent.toString("base64");
|
|
2041
2269
|
const filePath = join7(dataDir, ENCRYPTED_KEY_FILENAME);
|
|
2042
2270
|
const tmpPath = filePath + ".tmp";
|
|
2043
|
-
await
|
|
2044
|
-
await
|
|
2045
|
-
await
|
|
2271
|
+
await writeFile7(tmpPath, encoded, "utf-8");
|
|
2272
|
+
await chmod6(tmpPath, 384);
|
|
2273
|
+
await rename7(tmpPath, filePath);
|
|
2046
2274
|
}
|
|
2047
2275
|
async function readEncryptedKey(dataDir, masterPassword, pepperDir = dataDir) {
|
|
2048
2276
|
const filePath = join7(dataDir, ENCRYPTED_KEY_FILENAME);
|
|
@@ -2067,8 +2295,8 @@ async function writeVerifyFile(dataDir, encryptionKey) {
|
|
|
2067
2295
|
const payload = aesEncrypt(encryptionKey, Buffer.from(CANARY_PLAINTEXT, "utf-8"));
|
|
2068
2296
|
const filePath = join7(dataDir, VERIFY_FILENAME);
|
|
2069
2297
|
const tmpPath = filePath + ".tmp";
|
|
2070
|
-
await
|
|
2071
|
-
await
|
|
2298
|
+
await writeFile7(tmpPath, payload.toString("base64"), "utf-8");
|
|
2299
|
+
await rename7(tmpPath, filePath);
|
|
2072
2300
|
}
|
|
2073
2301
|
async function verifyEncryptionKey(dataDir, encryptionKey) {
|
|
2074
2302
|
const filePath = join7(dataDir, VERIFY_FILENAME);
|
|
@@ -2142,7 +2370,7 @@ async function unlockOrgKeys(masterPassword) {
|
|
|
2142
2370
|
}
|
|
2143
2371
|
continue;
|
|
2144
2372
|
}
|
|
2145
|
-
await
|
|
2373
|
+
await mkdir7(root, { recursive: true });
|
|
2146
2374
|
await writeEncryptedKey(root, masterPassword, machineKey, await keyRoot());
|
|
2147
2375
|
await writeVerifyFile(root, machineKey);
|
|
2148
2376
|
setEncryptionKeyInMemory(machineKey, orgId);
|
|
@@ -2152,7 +2380,7 @@ async function unlockOrgKeys(masterPassword) {
|
|
|
2152
2380
|
}
|
|
2153
2381
|
async function installOrgKey(orgId, key, masterPassword) {
|
|
2154
2382
|
const root = orgVaultRoot(orgId);
|
|
2155
|
-
await
|
|
2383
|
+
await mkdir7(root, { recursive: true });
|
|
2156
2384
|
const pepperDir = await keyRoot();
|
|
2157
2385
|
await writeEncryptedKey(root, masterPassword, key, pepperDir);
|
|
2158
2386
|
const readBack = await readEncryptedKey(root, masterPassword, pepperDir);
|
|
@@ -2208,7 +2436,7 @@ var projectRouter = router({
|
|
|
2208
2436
|
* `orgId` names which project — the same id can exist in several
|
|
2209
2437
|
* organizations. Left out, the id must answer for exactly one project.
|
|
2210
2438
|
*/
|
|
2211
|
-
get: protectedProcedure.input(
|
|
2439
|
+
get: protectedProcedure.input(z4.object({ id: z4.string().max(128), orgId: z4.string().max(128).nullable().optional() })).query(async ({ input }) => {
|
|
2212
2440
|
const project = await projectStore.get(input);
|
|
2213
2441
|
if (!project) {
|
|
2214
2442
|
throw new TRPCError3({ code: "NOT_FOUND", message: `Project ${input.id} not found` });
|
|
@@ -2222,7 +2450,7 @@ var projectRouter = router({
|
|
|
2222
2450
|
* Environments are intentionally excluded — they carry secret values that
|
|
2223
2451
|
* stay local.
|
|
2224
2452
|
*/
|
|
2225
|
-
export: protectedProcedure.input(
|
|
2453
|
+
export: protectedProcedure.input(z4.object({ id: z4.string().max(128), orgId: z4.string().max(128).nullable().optional() })).query(async ({ input }) => {
|
|
2226
2454
|
const project = await projectStore.get(input);
|
|
2227
2455
|
if (!project) {
|
|
2228
2456
|
throw new TRPCError3({ code: "NOT_FOUND", message: `Project ${input.id} not found` });
|
|
@@ -2232,11 +2460,11 @@ var projectRouter = router({
|
|
|
2232
2460
|
return { project, services };
|
|
2233
2461
|
}),
|
|
2234
2462
|
create: protectedProcedure.input(
|
|
2235
|
-
|
|
2236
|
-
name:
|
|
2237
|
-
description:
|
|
2238
|
-
orgId:
|
|
2239
|
-
serviceIds:
|
|
2463
|
+
z4.object({
|
|
2464
|
+
name: z4.string().min(1).max(200),
|
|
2465
|
+
description: z4.string().max(1e4).optional(),
|
|
2466
|
+
orgId: z4.string().max(128).nullable().optional(),
|
|
2467
|
+
serviceIds: z4.array(z4.string().max(128)).max(1e4).optional()
|
|
2240
2468
|
})
|
|
2241
2469
|
).mutation(async ({ input }) => {
|
|
2242
2470
|
let project;
|
|
@@ -2270,13 +2498,13 @@ var projectRouter = router({
|
|
|
2270
2498
|
return result;
|
|
2271
2499
|
}),
|
|
2272
2500
|
update: protectedProcedure.input(
|
|
2273
|
-
|
|
2274
|
-
id:
|
|
2275
|
-
name:
|
|
2276
|
-
description:
|
|
2277
|
-
orgId:
|
|
2278
|
-
serviceIds:
|
|
2279
|
-
groupOrder:
|
|
2501
|
+
z4.object({
|
|
2502
|
+
id: z4.string().max(128),
|
|
2503
|
+
name: z4.string().min(1).max(200).optional(),
|
|
2504
|
+
description: z4.string().max(1e4).optional(),
|
|
2505
|
+
orgId: z4.string().max(128).nullable().optional(),
|
|
2506
|
+
serviceIds: z4.array(z4.string().max(128)).max(1e4).optional(),
|
|
2507
|
+
groupOrder: z4.array(z4.string().max(200)).max(100).optional()
|
|
2280
2508
|
})
|
|
2281
2509
|
).mutation(async ({ input }) => {
|
|
2282
2510
|
const project = await projectStore.update(input);
|
|
@@ -2286,7 +2514,7 @@ var projectRouter = router({
|
|
|
2286
2514
|
await auditService.log({ userId: "local", action: "update", entityType: "project", entityId: input.id });
|
|
2287
2515
|
return project;
|
|
2288
2516
|
}),
|
|
2289
|
-
delete: protectedProcedure.input(
|
|
2517
|
+
delete: protectedProcedure.input(z4.object({ id: z4.string().max(128), orgId: z4.string().max(128).nullable().optional() })).mutation(async ({ input }) => {
|
|
2290
2518
|
const deleted = await projectStore.delete(input);
|
|
2291
2519
|
if (!deleted) {
|
|
2292
2520
|
throw new TRPCError3({ code: "NOT_FOUND", message: `Project ${input.id} not found` });
|
|
@@ -2294,10 +2522,10 @@ var projectRouter = router({
|
|
|
2294
2522
|
await auditService.log({ userId: "local", action: "delete", entityType: "project", entityId: input.id });
|
|
2295
2523
|
return { success: true };
|
|
2296
2524
|
}),
|
|
2297
|
-
addService: protectedProcedure.input(
|
|
2298
|
-
projectId:
|
|
2299
|
-
orgId:
|
|
2300
|
-
serviceId:
|
|
2525
|
+
addService: protectedProcedure.input(z4.object({
|
|
2526
|
+
projectId: z4.string().max(128),
|
|
2527
|
+
orgId: z4.string().max(128).nullable().optional(),
|
|
2528
|
+
serviceId: z4.string().max(128)
|
|
2301
2529
|
})).mutation(async ({ input }) => {
|
|
2302
2530
|
const target = { id: input.projectId, orgId: input.orgId };
|
|
2303
2531
|
const project = await projectStore.addService(target, input.serviceId);
|
|
@@ -2329,10 +2557,10 @@ var projectRouter = router({
|
|
|
2329
2557
|
});
|
|
2330
2558
|
return project;
|
|
2331
2559
|
}),
|
|
2332
|
-
removeService: protectedProcedure.input(
|
|
2333
|
-
projectId:
|
|
2334
|
-
orgId:
|
|
2335
|
-
serviceId:
|
|
2560
|
+
removeService: protectedProcedure.input(z4.object({
|
|
2561
|
+
projectId: z4.string().max(128),
|
|
2562
|
+
orgId: z4.string().max(128).nullable().optional(),
|
|
2563
|
+
serviceId: z4.string().max(128)
|
|
2336
2564
|
})).mutation(async ({ input }) => {
|
|
2337
2565
|
const project = await projectStore.removeService(
|
|
2338
2566
|
{ id: input.projectId, orgId: input.orgId },
|
|
@@ -2350,10 +2578,10 @@ var projectRouter = router({
|
|
|
2350
2578
|
});
|
|
2351
2579
|
return project;
|
|
2352
2580
|
}),
|
|
2353
|
-
setActiveEnvironment: protectedProcedure.input(
|
|
2354
|
-
projectId:
|
|
2355
|
-
orgId:
|
|
2356
|
-
environmentId:
|
|
2581
|
+
setActiveEnvironment: protectedProcedure.input(z4.object({
|
|
2582
|
+
projectId: z4.string().max(128),
|
|
2583
|
+
orgId: z4.string().max(128).nullable().optional(),
|
|
2584
|
+
environmentId: z4.string().max(128)
|
|
2357
2585
|
})).mutation(async ({ input }) => {
|
|
2358
2586
|
const project = await projectStore.get({ id: input.projectId, orgId: input.orgId });
|
|
2359
2587
|
if (!project) {
|
|
@@ -2433,9 +2661,9 @@ var projectRouter = router({
|
|
|
2433
2661
|
localPaths: protectedProcedure.query(async () => {
|
|
2434
2662
|
return projectPathStore.all();
|
|
2435
2663
|
}),
|
|
2436
|
-
getLocalPath: protectedProcedure.input(
|
|
2437
|
-
id:
|
|
2438
|
-
orgId:
|
|
2664
|
+
getLocalPath: protectedProcedure.input(z4.object({
|
|
2665
|
+
id: z4.string().min(1).max(128),
|
|
2666
|
+
orgId: z4.string().max(128).nullable().optional()
|
|
2439
2667
|
})).query(async ({ input }) => {
|
|
2440
2668
|
return { path: await projectPathStore.get(input) };
|
|
2441
2669
|
}),
|
|
@@ -2446,10 +2674,10 @@ var projectRouter = router({
|
|
|
2446
2674
|
* project was already placed in: two projects sharing a directory is what
|
|
2447
2675
|
* makes services run against the wrong code.
|
|
2448
2676
|
*/
|
|
2449
|
-
setLocalPath: protectedProcedure.input(
|
|
2450
|
-
id:
|
|
2451
|
-
orgId:
|
|
2452
|
-
path:
|
|
2677
|
+
setLocalPath: protectedProcedure.input(z4.object({
|
|
2678
|
+
id: z4.string().min(1).max(128),
|
|
2679
|
+
orgId: z4.string().max(128).nullable().optional(),
|
|
2680
|
+
path: z4.string().min(1).max(4096)
|
|
2453
2681
|
})).mutation(async ({ input }) => {
|
|
2454
2682
|
const project = await projectStore.get(input);
|
|
2455
2683
|
if (!project) throw new TRPCError3({ code: "NOT_FOUND", message: "Projet introuvable" });
|
|
@@ -2467,20 +2695,20 @@ var projectRouter = router({
|
|
|
2467
2695
|
});
|
|
2468
2696
|
}
|
|
2469
2697
|
await projectPathStore.set(project, input.path);
|
|
2470
|
-
await auditService.log("local", "update", "project", input.id, { localPath: input.path });
|
|
2698
|
+
await auditService.log({ userId: "local", action: "update", entityType: "project", entityId: input.id, metadata: { localPath: input.path } });
|
|
2471
2699
|
return { path: input.path };
|
|
2472
2700
|
})
|
|
2473
2701
|
});
|
|
2474
2702
|
|
|
2475
2703
|
// ../server/src/trpc/routers/service.ts
|
|
2476
|
-
import { z as
|
|
2704
|
+
import { z as z5 } from "zod";
|
|
2477
2705
|
import { TRPCError as TRPCError4 } from "@trpc/server";
|
|
2478
2706
|
|
|
2479
2707
|
// ../server/src/services/log-parser-store.ts
|
|
2480
2708
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
2481
2709
|
|
|
2482
2710
|
// ../server/src/services/settings-manager.ts
|
|
2483
|
-
import { readFile as
|
|
2711
|
+
import { readFile as readFile8, writeFile as writeFile8, rename as rename8, mkdir as mkdir8, chmod as chmod7 } from "fs/promises";
|
|
2484
2712
|
import { join as join8 } from "path";
|
|
2485
2713
|
var SETTINGS_FILE = "settings.json";
|
|
2486
2714
|
var SETTINGS_PRIVATE_FILE = "settings.private.json";
|
|
@@ -2506,12 +2734,12 @@ var SettingsManager = class {
|
|
|
2506
2734
|
}
|
|
2507
2735
|
async atomicWrite(filename, data, vault) {
|
|
2508
2736
|
const root = this.rootOf(vault);
|
|
2509
|
-
await
|
|
2737
|
+
await mkdir8(root, { recursive: true });
|
|
2510
2738
|
const filePath = join8(root, filename);
|
|
2511
2739
|
const tmpPath = filePath + ".tmp";
|
|
2512
|
-
await
|
|
2513
|
-
await
|
|
2514
|
-
await
|
|
2740
|
+
await writeFile8(tmpPath, JSON.stringify(data, null, 2), "utf-8");
|
|
2741
|
+
await rename8(tmpPath, filePath);
|
|
2742
|
+
await chmod7(filePath, 384);
|
|
2515
2743
|
}
|
|
2516
2744
|
/**
|
|
2517
2745
|
* Lire le fichier de CE coffre, et rien d'autre.
|
|
@@ -2524,7 +2752,7 @@ var SettingsManager = class {
|
|
|
2524
2752
|
*/
|
|
2525
2753
|
async readJson(filename, vault) {
|
|
2526
2754
|
try {
|
|
2527
|
-
return JSON.parse(await
|
|
2755
|
+
return JSON.parse(await readFile8(join8(this.rootOf(vault), filename), "utf-8"));
|
|
2528
2756
|
} catch {
|
|
2529
2757
|
return null;
|
|
2530
2758
|
}
|
|
@@ -2538,7 +2766,7 @@ var SettingsManager = class {
|
|
|
2538
2766
|
async readMachineJson(filename) {
|
|
2539
2767
|
for (const path of [machineFilePath(filename), legacyMachineFilePath(filename)]) {
|
|
2540
2768
|
try {
|
|
2541
|
-
return JSON.parse(await
|
|
2769
|
+
return JSON.parse(await readFile8(path, "utf-8"));
|
|
2542
2770
|
} catch {
|
|
2543
2771
|
}
|
|
2544
2772
|
}
|
|
@@ -2603,12 +2831,12 @@ var SettingsManager = class {
|
|
|
2603
2831
|
}
|
|
2604
2832
|
async saveSchemaVersion(sv) {
|
|
2605
2833
|
this.schemaVersion = sv;
|
|
2606
|
-
await
|
|
2834
|
+
await mkdir8(machineRoot(), { recursive: true });
|
|
2607
2835
|
const filePath = machineFilePath(SCHEMA_VERSION_FILE);
|
|
2608
2836
|
const tmpPath = filePath + ".tmp";
|
|
2609
|
-
await
|
|
2610
|
-
await
|
|
2611
|
-
await
|
|
2837
|
+
await writeFile8(tmpPath, JSON.stringify(sv, null, 2), "utf-8");
|
|
2838
|
+
await rename8(tmpPath, filePath);
|
|
2839
|
+
await chmod7(filePath, 384);
|
|
2612
2840
|
}
|
|
2613
2841
|
getCurrentSchemaVersion() {
|
|
2614
2842
|
return CURRENT_SCHEMA_VERSION;
|
|
@@ -2817,14 +3045,14 @@ function buildServerBuiltins(input) {
|
|
|
2817
3045
|
import { isAbsolute as isAbsolute3 } from "path";
|
|
2818
3046
|
|
|
2819
3047
|
// ../server/src/services/workspace-cwd.ts
|
|
2820
|
-
import { isAbsolute as isAbsolute2, join as join10, dirname as
|
|
3048
|
+
import { isAbsolute as isAbsolute2, join as join10, dirname as dirname6 } from "path";
|
|
2821
3049
|
|
|
2822
3050
|
// ../server/src/services/conversation-store.ts
|
|
2823
3051
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
2824
|
-
import { readFile as
|
|
2825
|
-
import { dirname as
|
|
3052
|
+
import { readFile as readFile9, writeFile as writeFile9, rename as rename9, mkdir as mkdir9, chmod as chmod8 } from "fs/promises";
|
|
3053
|
+
import { dirname as dirname5, join as join9 } from "path";
|
|
2826
3054
|
import { EventEmitter as EventEmitter2 } from "events";
|
|
2827
|
-
var
|
|
3055
|
+
var FILENAME5 = "conversations.private.json";
|
|
2828
3056
|
async function localProjectId() {
|
|
2829
3057
|
const projects = await projectStore.list().catch(() => []);
|
|
2830
3058
|
return projects.find((p) => !p.orgId)?.id ?? null;
|
|
@@ -2855,11 +3083,11 @@ var ConversationStore = class {
|
|
|
2855
3083
|
* root, but a launch directory owning its own key keeps both together.
|
|
2856
3084
|
*/
|
|
2857
3085
|
getFilePath() {
|
|
2858
|
-
return keyedFilePath(
|
|
3086
|
+
return keyedFilePath(FILENAME5);
|
|
2859
3087
|
}
|
|
2860
3088
|
/** Where older versions kept it — read only, so an older Runeya keeps working. */
|
|
2861
3089
|
getLegacyFilePath() {
|
|
2862
|
-
return legacyMachineFilePath(
|
|
3090
|
+
return legacyMachineFilePath(FILENAME5);
|
|
2863
3091
|
}
|
|
2864
3092
|
/**
|
|
2865
3093
|
* Read the machine file, falling back to the launch directory of old.
|
|
@@ -2869,13 +3097,13 @@ var ConversationStore = class {
|
|
|
2869
3097
|
*/
|
|
2870
3098
|
async readFromDisk() {
|
|
2871
3099
|
try {
|
|
2872
|
-
return await
|
|
3100
|
+
return await readFile9(await this.getFilePath(), "utf-8");
|
|
2873
3101
|
} catch {
|
|
2874
|
-
return
|
|
3102
|
+
return readFile9(this.getLegacyFilePath(), "utf-8");
|
|
2875
3103
|
}
|
|
2876
3104
|
}
|
|
2877
3105
|
async ensureDir() {
|
|
2878
|
-
await
|
|
3106
|
+
await mkdir9(dirname5(await this.getFilePath()), { recursive: true });
|
|
2879
3107
|
}
|
|
2880
3108
|
encryptMessages(messages, vault) {
|
|
2881
3109
|
return encryptValue(JSON.stringify(messages), vault);
|
|
@@ -2966,20 +3194,20 @@ ${new Error("trace").stack}`
|
|
|
2966
3194
|
this.unreadable.clear();
|
|
2967
3195
|
await ensureProjectsLoaded();
|
|
2968
3196
|
const vaults = await allVaultRoots();
|
|
2969
|
-
const legacyPaths = [this.getLegacyFilePath(), await keyedFilePath(
|
|
3197
|
+
const legacyPaths = [this.getLegacyFilePath(), await keyedFilePath(FILENAME5)];
|
|
2970
3198
|
const sources = [
|
|
2971
3199
|
...legacyPaths.map((path) => ({ path, legacy: true })),
|
|
2972
|
-
...vaults.map((root) => ({ path: join9(root,
|
|
3200
|
+
...vaults.map((root) => ({ path: join9(root, FILENAME5), legacy: false }))
|
|
2973
3201
|
];
|
|
2974
3202
|
for (const { path, legacy } of sources) {
|
|
2975
3203
|
let data;
|
|
2976
3204
|
try {
|
|
2977
|
-
data = JSON.parse(await
|
|
3205
|
+
data = JSON.parse(await readFile9(path, "utf-8"));
|
|
2978
3206
|
} catch {
|
|
2979
3207
|
continue;
|
|
2980
3208
|
}
|
|
2981
3209
|
const inherited = legacy ? await localProjectId() : null;
|
|
2982
|
-
const root =
|
|
3210
|
+
const root = dirname5(path);
|
|
2983
3211
|
await rememberFile(path);
|
|
2984
3212
|
for (const item of data) {
|
|
2985
3213
|
try {
|
|
@@ -3049,22 +3277,22 @@ ${new Error("trace").stack}`
|
|
|
3049
3277
|
}
|
|
3050
3278
|
const stale = /* @__PURE__ */ new Set();
|
|
3051
3279
|
for (const root of byRoot.keys()) {
|
|
3052
|
-
const path = join9(root,
|
|
3280
|
+
const path = join9(root, FILENAME5);
|
|
3053
3281
|
if (wasRead(path) && await hasChangedSinceRead(path)) stale.add(root);
|
|
3054
3282
|
}
|
|
3055
3283
|
for (const [root, data] of byRoot) {
|
|
3056
|
-
const filePath = join9(root,
|
|
3284
|
+
const filePath = join9(root, FILENAME5);
|
|
3057
3285
|
if (stale.has(root)) {
|
|
3058
3286
|
console.warn(
|
|
3059
3287
|
`[conversation-store] ${filePath} a chang\xE9 depuis sa lecture \u2014 \xE9criture ignor\xE9e pour ne pas \xE9craser une r\xE9paration faite en dehors du serveur.`
|
|
3060
3288
|
);
|
|
3061
3289
|
continue;
|
|
3062
3290
|
}
|
|
3063
|
-
await
|
|
3291
|
+
await mkdir9(root, { recursive: true });
|
|
3064
3292
|
const tmpPath = `${filePath}.tmp`;
|
|
3065
|
-
await
|
|
3066
|
-
await
|
|
3067
|
-
await
|
|
3293
|
+
await writeFile9(tmpPath, JSON.stringify(data, null, 2), "utf-8");
|
|
3294
|
+
await rename9(tmpPath, filePath);
|
|
3295
|
+
await chmod8(filePath, 384);
|
|
3068
3296
|
await rememberFile(filePath);
|
|
3069
3297
|
}
|
|
3070
3298
|
}
|
|
@@ -3077,7 +3305,7 @@ ${new Error("trace").stack}`
|
|
|
3077
3305
|
async rootFor(conv) {
|
|
3078
3306
|
const known = this.roots.get(conv.id) ?? null;
|
|
3079
3307
|
if (conv.projectId) return rootOfProjectAmong(conv.projectId, known);
|
|
3080
|
-
return known ??
|
|
3308
|
+
return known ?? dirname5(await keyedFilePath(FILENAME5));
|
|
3081
3309
|
}
|
|
3082
3310
|
/**
|
|
3083
3311
|
* Le projet d'une conversation, organisation comprise.
|
|
@@ -3263,7 +3491,7 @@ function anchor(base, raw) {
|
|
|
3263
3491
|
return join10(base, raw);
|
|
3264
3492
|
}
|
|
3265
3493
|
function localVaultRootParent() {
|
|
3266
|
-
return
|
|
3494
|
+
return dirname6(localVaultRoot());
|
|
3267
3495
|
}
|
|
3268
3496
|
async function resolveAgentCwd(target) {
|
|
3269
3497
|
if (target.serviceId) {
|
|
@@ -3358,7 +3586,7 @@ async function resolveServiceVariables(service) {
|
|
|
3358
3586
|
}
|
|
3359
3587
|
var DockerConfigInput = DockerConfigSchema;
|
|
3360
3588
|
var serviceRouter = router({
|
|
3361
|
-
list: protectedProcedure.meta({ openapi: { method: "GET", path: "/services", tags: ["services"], summary: "List all services", protect: true } }).output(
|
|
3589
|
+
list: protectedProcedure.meta({ openapi: { method: "GET", path: "/services", tags: ["services"], summary: "List all services", protect: true } }).output(z5.any()).query(async ({ ctx }) => {
|
|
3362
3590
|
const all = await serviceStore.list();
|
|
3363
3591
|
const allowedIds = getAllowedServiceIds(ctx);
|
|
3364
3592
|
const filtered = allowedIds ? all.filter((s) => allowedIds.has(s.id)) : all;
|
|
@@ -3367,7 +3595,7 @@ var serviceRouter = router({
|
|
|
3367
3595
|
effectiveAgentId: await resolveEffectiveAgentId(s)
|
|
3368
3596
|
})));
|
|
3369
3597
|
}),
|
|
3370
|
-
get: protectedProcedure.meta({ openapi: { method: "GET", path: "/services/{id}", tags: ["services"], summary: "Get a service by ID", protect: true } }).input(
|
|
3598
|
+
get: protectedProcedure.meta({ openapi: { method: "GET", path: "/services/{id}", tags: ["services"], summary: "Get a service by ID", protect: true } }).input(z5.object({ id: z5.string().max(128) })).output(z5.any()).query(async ({ input, ctx }) => {
|
|
3371
3599
|
requireServiceAction(ctx, input.id, "service:read");
|
|
3372
3600
|
const service = await serviceStore.get(input.id);
|
|
3373
3601
|
if (!service) {
|
|
@@ -3375,34 +3603,34 @@ var serviceRouter = router({
|
|
|
3375
3603
|
}
|
|
3376
3604
|
return service;
|
|
3377
3605
|
}),
|
|
3378
|
-
create: protectedProcedure.meta({ openapi: { method: "POST", path: "/services", tags: ["services"], summary: "Create a new service", protect: true } }).output(
|
|
3379
|
-
|
|
3380
|
-
agentId:
|
|
3381
|
-
name:
|
|
3382
|
-
commands:
|
|
3383
|
-
cwd:
|
|
3384
|
-
ports:
|
|
3385
|
-
groups:
|
|
3386
|
-
description:
|
|
3387
|
-
docsPath:
|
|
3388
|
-
url:
|
|
3389
|
-
localUrls:
|
|
3390
|
-
url:
|
|
3391
|
-
port:
|
|
3606
|
+
create: protectedProcedure.meta({ openapi: { method: "POST", path: "/services", tags: ["services"], summary: "Create a new service", protect: true } }).output(z5.any()).input(
|
|
3607
|
+
z5.object({
|
|
3608
|
+
agentId: z5.string().max(128).optional(),
|
|
3609
|
+
name: z5.string().min(1).max(200),
|
|
3610
|
+
commands: z5.array(ServiceCommandSchema).max(50).optional(),
|
|
3611
|
+
cwd: z5.string().max(4096).optional(),
|
|
3612
|
+
ports: z5.array(z5.number().int().min(1).max(65535)).max(20).optional(),
|
|
3613
|
+
groups: z5.array(z5.string().max(200)).max(20).optional(),
|
|
3614
|
+
description: z5.string().max(2e3).optional(),
|
|
3615
|
+
docsPath: z5.string().max(4096).optional(),
|
|
3616
|
+
url: z5.string().max(2048).optional(),
|
|
3617
|
+
localUrls: z5.array(z5.object({
|
|
3618
|
+
url: z5.string().max(253),
|
|
3619
|
+
port: z5.number().int().min(1).max(65535)
|
|
3392
3620
|
})).max(20).optional(),
|
|
3393
|
-
openapiUrl:
|
|
3394
|
-
git:
|
|
3395
|
-
meta:
|
|
3396
|
-
runner:
|
|
3621
|
+
openapiUrl: z5.string().max(2048).optional(),
|
|
3622
|
+
git: z5.object({ remote: z5.string().max(2048).optional(), home: z5.string().max(2048).optional() }).optional(),
|
|
3623
|
+
meta: z5.record(z5.string().max(256), z5.string().max(2e3)).optional().refine((obj) => !obj || Object.keys(obj).length <= 100, { message: "Too many meta keys (max 100)" }),
|
|
3624
|
+
runner: z5.enum(["native", "docker"]).optional().default("native"),
|
|
3397
3625
|
dockerConfig: DockerConfigInput.optional(),
|
|
3398
3626
|
healthCheck: HealthCheckSchema.optional(),
|
|
3399
|
-
autoRestart:
|
|
3627
|
+
autoRestart: z5.boolean().optional().default(false),
|
|
3400
3628
|
restartStrategy: RestartStrategySchema.optional(),
|
|
3401
|
-
maxRestarts:
|
|
3402
|
-
restartBackoffMs:
|
|
3403
|
-
orgId:
|
|
3404
|
-
shortcuts:
|
|
3405
|
-
parserIds:
|
|
3629
|
+
maxRestarts: z5.number().int().nonnegative().optional(),
|
|
3630
|
+
restartBackoffMs: z5.number().int().positive().optional().default(1e3),
|
|
3631
|
+
orgId: z5.string().max(128).nullable().optional(),
|
|
3632
|
+
shortcuts: z5.array(ServiceShortcutSchema).max(50).optional(),
|
|
3633
|
+
parserIds: z5.array(z5.string().max(128)).max(50).optional()
|
|
3406
3634
|
})
|
|
3407
3635
|
).mutation(async ({ input }) => {
|
|
3408
3636
|
if (input.agentId) {
|
|
@@ -3424,38 +3652,38 @@ var serviceRouter = router({
|
|
|
3424
3652
|
await auditService.log({ userId: "local", action: "create", entityType: "service", entityId: service.id, metadata: { name: input.name } });
|
|
3425
3653
|
return service;
|
|
3426
3654
|
}),
|
|
3427
|
-
update: protectedProcedure.meta({ openapi: { method: "PATCH", path: "/services/{id}", tags: ["services"], summary: "Update a service", protect: true } }).output(
|
|
3428
|
-
|
|
3429
|
-
id:
|
|
3430
|
-
agentId:
|
|
3655
|
+
update: protectedProcedure.meta({ openapi: { method: "PATCH", path: "/services/{id}", tags: ["services"], summary: "Update a service", protect: true } }).output(z5.any()).input(
|
|
3656
|
+
z5.object({
|
|
3657
|
+
id: z5.string().max(128),
|
|
3658
|
+
agentId: z5.string().max(128).nullable().optional(),
|
|
3431
3659
|
// null = clear (inherit from env)
|
|
3432
|
-
name:
|
|
3433
|
-
commands:
|
|
3434
|
-
cwd:
|
|
3435
|
-
ports:
|
|
3436
|
-
groups:
|
|
3437
|
-
description:
|
|
3438
|
-
docsPath:
|
|
3439
|
-
url:
|
|
3440
|
-
localUrls:
|
|
3441
|
-
url:
|
|
3442
|
-
port:
|
|
3660
|
+
name: z5.string().min(1).max(200).optional(),
|
|
3661
|
+
commands: z5.array(ServiceCommandSchema).max(50).optional(),
|
|
3662
|
+
cwd: z5.string().max(4096).nullable().optional(),
|
|
3663
|
+
ports: z5.array(z5.number().int().min(1).max(65535)).max(20).optional(),
|
|
3664
|
+
groups: z5.array(z5.string().max(200)).max(20).optional(),
|
|
3665
|
+
description: z5.string().max(2e3).optional(),
|
|
3666
|
+
docsPath: z5.string().max(4096).optional(),
|
|
3667
|
+
url: z5.string().max(2048).optional(),
|
|
3668
|
+
localUrls: z5.array(z5.object({
|
|
3669
|
+
url: z5.string().max(253),
|
|
3670
|
+
port: z5.number().int().min(1).max(65535)
|
|
3443
3671
|
})).max(20).optional(),
|
|
3444
|
-
openapiUrl:
|
|
3445
|
-
git:
|
|
3446
|
-
meta:
|
|
3447
|
-
runner:
|
|
3672
|
+
openapiUrl: z5.string().max(2048).optional(),
|
|
3673
|
+
git: z5.object({ remote: z5.string().max(2048).optional(), home: z5.string().max(2048).optional() }).nullable().optional(),
|
|
3674
|
+
meta: z5.record(z5.string().max(256), z5.string().max(2e3)).nullable().optional().refine((obj) => !obj || Object.keys(obj).length <= 100, { message: "Too many meta keys (max 100)" }),
|
|
3675
|
+
runner: z5.enum(["native", "docker"]).optional(),
|
|
3448
3676
|
dockerConfig: DockerConfigInput.optional(),
|
|
3449
3677
|
healthCheck: HealthCheckSchema.nullable().optional(),
|
|
3450
|
-
autoRestart:
|
|
3451
|
-
clearLogsOnStart:
|
|
3678
|
+
autoRestart: z5.boolean().optional(),
|
|
3679
|
+
clearLogsOnStart: z5.boolean().optional(),
|
|
3452
3680
|
restartStrategy: RestartStrategySchema.optional(),
|
|
3453
|
-
maxRestarts:
|
|
3454
|
-
restartBackoffMs:
|
|
3455
|
-
orgId:
|
|
3456
|
-
shortcuts:
|
|
3457
|
-
parserIds:
|
|
3458
|
-
logSources:
|
|
3681
|
+
maxRestarts: z5.number().int().nonnegative().optional(),
|
|
3682
|
+
restartBackoffMs: z5.number().int().positive().optional(),
|
|
3683
|
+
orgId: z5.string().max(128).nullable().optional(),
|
|
3684
|
+
shortcuts: z5.array(ServiceShortcutSchema).max(50).optional(),
|
|
3685
|
+
parserIds: z5.array(z5.string().max(128)).max(50).optional(),
|
|
3686
|
+
logSources: z5.array(LogSourceConfigSchema).max(20).optional()
|
|
3459
3687
|
})
|
|
3460
3688
|
).mutation(async ({ input }) => {
|
|
3461
3689
|
const existing = await serviceStore.get(input.id);
|
|
@@ -3510,7 +3738,7 @@ var serviceRouter = router({
|
|
|
3510
3738
|
await auditService.log({ userId: "local", action: "update", entityType: "service", entityId: input.id });
|
|
3511
3739
|
return { ...service, effectiveAgentId: await resolveEffectiveAgentId(service), stoppedForAgentChange };
|
|
3512
3740
|
}),
|
|
3513
|
-
delete: protectedProcedure.meta({ openapi: { method: "DELETE", path: "/services/{id}", tags: ["services"], summary: "Delete a service", protect: true } }).input(
|
|
3741
|
+
delete: protectedProcedure.meta({ openapi: { method: "DELETE", path: "/services/{id}", tags: ["services"], summary: "Delete a service", protect: true } }).input(z5.object({ id: z5.string().max(128) })).output(z5.object({ success: z5.literal(true) })).mutation(async ({ input }) => {
|
|
3514
3742
|
const deleted = await serviceStore.delete(input.id);
|
|
3515
3743
|
if (!deleted) {
|
|
3516
3744
|
throw new TRPCError4({ code: "NOT_FOUND", message: `Service ${input.id} not found` });
|
|
@@ -3518,7 +3746,7 @@ var serviceRouter = router({
|
|
|
3518
3746
|
await auditService.log({ userId: "local", action: "delete", entityType: "service", entityId: input.id });
|
|
3519
3747
|
return { success: true };
|
|
3520
3748
|
}),
|
|
3521
|
-
checkCwd: protectedProcedure.input(
|
|
3749
|
+
checkCwd: protectedProcedure.input(z5.object({ id: z5.string().max(128), checkReachability: z5.boolean().optional() })).query(async ({ input }) => {
|
|
3522
3750
|
const service = await serviceStore.get(input.id);
|
|
3523
3751
|
if (!service) {
|
|
3524
3752
|
throw new TRPCError4({ code: "NOT_FOUND", message: `Service ${input.id} not found` });
|
|
@@ -3551,7 +3779,7 @@ var serviceRouter = router({
|
|
|
3551
3779
|
}
|
|
3552
3780
|
return { exists: exists4, canClone, unresolvedVars: [], resolvedCwd, gitMismatch };
|
|
3553
3781
|
}),
|
|
3554
|
-
cloneRepository: protectedProcedure.input(
|
|
3782
|
+
cloneRepository: protectedProcedure.input(z5.object({ id: z5.string().max(128) })).mutation(async ({ input }) => {
|
|
3555
3783
|
const service = await serviceStore.get(input.id);
|
|
3556
3784
|
if (!service) {
|
|
3557
3785
|
throw new TRPCError4({ code: "NOT_FOUND", message: `Service ${input.id} not found` });
|
|
@@ -3574,7 +3802,7 @@ var serviceRouter = router({
|
|
|
3574
3802
|
});
|
|
3575
3803
|
|
|
3576
3804
|
// ../server/src/trpc/routers/agent.ts
|
|
3577
|
-
import { z as
|
|
3805
|
+
import { z as z6 } from "zod";
|
|
3578
3806
|
import { TRPCError as TRPCError5 } from "@trpc/server";
|
|
3579
3807
|
var SUBSCRIPTION_QUEUE_MAX = LOG_BUFFER_SIZE;
|
|
3580
3808
|
var agentRouter = router({
|
|
@@ -3583,7 +3811,7 @@ var agentRouter = router({
|
|
|
3583
3811
|
return agentManager.listAgents();
|
|
3584
3812
|
}),
|
|
3585
3813
|
/** Get a single agent's config and status */
|
|
3586
|
-
get: protectedProcedure.input(
|
|
3814
|
+
get: protectedProcedure.input(z6.object({ id: z6.string().max(128) })).query(({ input }) => {
|
|
3587
3815
|
const agent = agentManager.getAgent(input.id);
|
|
3588
3816
|
if (!agent) {
|
|
3589
3817
|
throw new TRPCError5({ code: "NOT_FOUND", message: `Agent ${input.id} not found` });
|
|
@@ -3595,10 +3823,10 @@ var agentRouter = router({
|
|
|
3595
3823
|
}),
|
|
3596
3824
|
/** Test connectivity to an agent given url + passphrase */
|
|
3597
3825
|
testConnection: protectedProcedure.input(
|
|
3598
|
-
|
|
3599
|
-
url:
|
|
3600
|
-
passphrase:
|
|
3601
|
-
agentId:
|
|
3826
|
+
z6.object({
|
|
3827
|
+
url: z6.string().url().max(2048),
|
|
3828
|
+
passphrase: z6.string().min(1).max(1024).optional(),
|
|
3829
|
+
agentId: z6.string().max(128).optional()
|
|
3602
3830
|
})
|
|
3603
3831
|
).mutation(async ({ input }) => {
|
|
3604
3832
|
let passphrase = input.passphrase;
|
|
@@ -3635,13 +3863,13 @@ var agentRouter = router({
|
|
|
3635
3863
|
}),
|
|
3636
3864
|
/** Register a new agent */
|
|
3637
3865
|
register: protectedProcedure.input(
|
|
3638
|
-
|
|
3639
|
-
name:
|
|
3640
|
-
url:
|
|
3641
|
-
passphrase:
|
|
3866
|
+
z6.object({
|
|
3867
|
+
name: z6.string().min(1).max(100),
|
|
3868
|
+
url: z6.string().url().max(2048),
|
|
3869
|
+
passphrase: z6.string().min(1).max(1024),
|
|
3642
3870
|
// À quelle organisation rattacher l'agent. Absent = la machine, ce que
|
|
3643
3871
|
// font l'agent local et tout client antérieur à ce champ.
|
|
3644
|
-
orgId:
|
|
3872
|
+
orgId: z6.string().min(1).max(128).nullable().optional()
|
|
3645
3873
|
})
|
|
3646
3874
|
).mutation(async ({ input }) => {
|
|
3647
3875
|
const config = await agentManager.register(
|
|
@@ -3654,13 +3882,13 @@ var agentRouter = router({
|
|
|
3654
3882
|
}),
|
|
3655
3883
|
/** Update an existing agent */
|
|
3656
3884
|
update: protectedProcedure.input(
|
|
3657
|
-
|
|
3658
|
-
id:
|
|
3659
|
-
name:
|
|
3660
|
-
url:
|
|
3661
|
-
passphrase:
|
|
3662
|
-
passthroughEnv:
|
|
3663
|
-
|
|
3885
|
+
z6.object({
|
|
3886
|
+
id: z6.string().max(128),
|
|
3887
|
+
name: z6.string().min(1).max(100).optional(),
|
|
3888
|
+
url: z6.string().url().max(2048).optional(),
|
|
3889
|
+
passphrase: z6.string().min(1).max(1024).optional(),
|
|
3890
|
+
passthroughEnv: z6.array(
|
|
3891
|
+
z6.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/).max(256)
|
|
3664
3892
|
).max(100).optional()
|
|
3665
3893
|
})
|
|
3666
3894
|
).mutation(async ({ input }) => {
|
|
@@ -3681,7 +3909,7 @@ var agentRouter = router({
|
|
|
3681
3909
|
}
|
|
3682
3910
|
}),
|
|
3683
3911
|
/** Get resolved passthrough env values from an agent */
|
|
3684
|
-
getPassthroughEnv: protectedProcedure.input(
|
|
3912
|
+
getPassthroughEnv: protectedProcedure.input(z6.object({ id: z6.string().max(128) })).query(async ({ input }) => {
|
|
3685
3913
|
try {
|
|
3686
3914
|
return await agentManager.agentQuery(input.id, "config.getPassthroughEnv");
|
|
3687
3915
|
} catch {
|
|
@@ -3689,7 +3917,7 @@ var agentRouter = router({
|
|
|
3689
3917
|
}
|
|
3690
3918
|
}),
|
|
3691
3919
|
/** Remove a registered agent */
|
|
3692
|
-
remove: protectedProcedure.input(
|
|
3920
|
+
remove: protectedProcedure.input(z6.object({ id: z6.string().max(128) })).mutation(async ({ input }) => {
|
|
3693
3921
|
try {
|
|
3694
3922
|
const removed = await agentManager.remove(input.id);
|
|
3695
3923
|
if (!removed) {
|
|
@@ -3736,7 +3964,7 @@ var agentRouter = router({
|
|
|
3736
3964
|
});
|
|
3737
3965
|
|
|
3738
3966
|
// ../server/src/trpc/routers/process.ts
|
|
3739
|
-
import { z as
|
|
3967
|
+
import { z as z7 } from "zod";
|
|
3740
3968
|
import { TRPCError as TRPCError6 } from "@trpc/server";
|
|
3741
3969
|
var SUBSCRIPTION_QUEUE_MAX2 = LOG_BUFFER_SIZE;
|
|
3742
3970
|
async function* forwardEvents(eventName, filter) {
|
|
@@ -3799,7 +4027,7 @@ async function* forwardLogBatches(agentId, processId) {
|
|
|
3799
4027
|
}
|
|
3800
4028
|
var processRouter = router({
|
|
3801
4029
|
/** List all processes across all connected agents */
|
|
3802
|
-
list: protectedProcedure.meta({ openapi: { method: "GET", path: "/processes", tags: ["processes"], summary: "List all processes", protect: true } }).output(
|
|
4030
|
+
list: protectedProcedure.meta({ openapi: { method: "GET", path: "/processes", tags: ["processes"], summary: "List all processes", protect: true } }).output(z7.any()).query(async () => {
|
|
3803
4031
|
const agents = agentManager.listAgents();
|
|
3804
4032
|
const results = [];
|
|
3805
4033
|
await Promise.allSettled(
|
|
@@ -3816,7 +4044,7 @@ var processRouter = router({
|
|
|
3816
4044
|
return results;
|
|
3817
4045
|
}),
|
|
3818
4046
|
/** Get a single process from a specific agent */
|
|
3819
|
-
get: protectedProcedure.meta({ openapi: { method: "GET", path: "/processes/{agentId}/{id}", tags: ["processes"], summary: "Get a process by agent and ID", protect: true } }).input(
|
|
4047
|
+
get: protectedProcedure.meta({ openapi: { method: "GET", path: "/processes/{agentId}/{id}", tags: ["processes"], summary: "Get a process by agent and ID", protect: true } }).input(z7.object({ agentId: z7.string().max(128), id: z7.string().max(128) })).output(z7.any()).query(async ({ input, ctx }) => {
|
|
3820
4048
|
requireServiceAction(ctx, input.id, "service:read");
|
|
3821
4049
|
const status = agentManager.getStatus(input.agentId);
|
|
3822
4050
|
if (!status) {
|
|
@@ -3830,7 +4058,7 @@ var processRouter = router({
|
|
|
3830
4058
|
* (or restarted). This avoids pushing configs for every service at agent boot,
|
|
3831
4059
|
* which would be wasteful when many services are never started.
|
|
3832
4060
|
* The deploy call is idempotent — creates the process if missing, updates config if it exists. */
|
|
3833
|
-
start: protectedProcedure.meta({ openapi: { method: "POST", path: "/processes/{agentId}/{processId}/start", tags: ["processes"], summary: "Start a process", protect: true } }).input(
|
|
4061
|
+
start: protectedProcedure.meta({ openapi: { method: "POST", path: "/processes/{agentId}/{processId}/start", tags: ["processes"], summary: "Start a process", protect: true } }).input(z7.object({ agentId: z7.string().max(128).optional(), processId: z7.string().max(128) })).output(z7.any()).mutation(async ({ input, ctx }) => {
|
|
3834
4062
|
requireServiceAction(ctx, input.processId, "service:start");
|
|
3835
4063
|
const service = await serviceStore.get(input.processId);
|
|
3836
4064
|
const effectiveAgentId = (service ? await resolveEffectiveAgentId(service) : null) ?? input.agentId ?? null;
|
|
@@ -3868,7 +4096,7 @@ var processRouter = router({
|
|
|
3868
4096
|
return { ...result, agentId: effectiveAgentId };
|
|
3869
4097
|
}),
|
|
3870
4098
|
/** Stop a process on an agent */
|
|
3871
|
-
stop: protectedProcedure.meta({ openapi: { method: "POST", path: "/processes/{agentId}/{processId}/stop", tags: ["processes"], summary: "Stop a process", protect: true } }).input(
|
|
4099
|
+
stop: protectedProcedure.meta({ openapi: { method: "POST", path: "/processes/{agentId}/{processId}/stop", tags: ["processes"], summary: "Stop a process", protect: true } }).input(z7.object({ agentId: z7.string().max(128), processId: z7.string().max(128) })).output(z7.any()).mutation(async ({ input, ctx }) => {
|
|
3872
4100
|
requireServiceAction(ctx, input.processId, "service:stop");
|
|
3873
4101
|
const result = await agentManager.agentMutation(input.agentId, "process.stop", { id: input.processId }, AGENT_STOP_FETCH_TIMEOUT);
|
|
3874
4102
|
await auditService.log({ userId: "local", action: "stop", entityType: "process", entityId: input.processId, metadata: { agentId: input.agentId } });
|
|
@@ -3877,7 +4105,7 @@ var processRouter = router({
|
|
|
3877
4105
|
/** Restart a process on an agent.
|
|
3878
4106
|
* Sends stop → deploy (latest resolved config) → start so that
|
|
3879
4107
|
* config/variable changes take effect. Same lazy deploy pattern as start. */
|
|
3880
|
-
restart: protectedProcedure.meta({ openapi: { method: "POST", path: "/processes/{agentId}/{processId}/restart", tags: ["processes"], summary: "Restart a process", protect: true } }).input(
|
|
4108
|
+
restart: protectedProcedure.meta({ openapi: { method: "POST", path: "/processes/{agentId}/{processId}/restart", tags: ["processes"], summary: "Restart a process", protect: true } }).input(z7.object({ agentId: z7.string().max(128).optional(), processId: z7.string().max(128) })).output(z7.any()).mutation(async ({ input, ctx }) => {
|
|
3881
4109
|
requireServiceAction(ctx, input.processId, "service:restart");
|
|
3882
4110
|
const service = await serviceStore.get(input.processId);
|
|
3883
4111
|
const effectiveAgentId = (service ? await resolveEffectiveAgentId(service) : null) ?? input.agentId ?? null;
|
|
@@ -3910,20 +4138,20 @@ var processRouter = router({
|
|
|
3910
4138
|
return { ...result, agentId: effectiveAgentId };
|
|
3911
4139
|
}),
|
|
3912
4140
|
/** Get buffered logs for a process from an agent */
|
|
3913
|
-
logs: protectedProcedure.meta({ openapi: { method: "GET", path: "/processes/{agentId}/{processId}/logs", tags: ["processes"], summary: "Get buffered logs for a process", protect: true } }).input(
|
|
4141
|
+
logs: protectedProcedure.meta({ openapi: { method: "GET", path: "/processes/{agentId}/{processId}/logs", tags: ["processes"], summary: "Get buffered logs for a process", protect: true } }).input(z7.object({ agentId: z7.string().max(128), processId: z7.string().max(128) })).output(z7.any()).query(async ({ input, ctx }) => {
|
|
3914
4142
|
requireServiceAction(ctx, input.processId, "logs:read");
|
|
3915
4143
|
return agentManager.agentQuery(input.agentId, "process.logs", { id: input.processId });
|
|
3916
4144
|
}),
|
|
3917
4145
|
/** Clear buffered logs for a process on an agent */
|
|
3918
|
-
clearLogBuffer: protectedProcedure.input(
|
|
4146
|
+
clearLogBuffer: protectedProcedure.input(z7.object({ agentId: z7.string().max(128), processId: z7.string().max(128) })).mutation(async ({ input }) => {
|
|
3919
4147
|
await agentManager.agentMutation(input.agentId, "process.clearLogBuffer", { id: input.processId });
|
|
3920
4148
|
await auditService.log({ userId: "local", action: "clearLogBuffer", entityType: "process", entityId: input.processId, metadata: { agentId: input.agentId } });
|
|
3921
4149
|
return { success: true };
|
|
3922
4150
|
}),
|
|
3923
4151
|
/** Execute a shortcut command on an agent, streaming output into the process log */
|
|
3924
|
-
executeShortcut: protectedProcedure.input(
|
|
3925
|
-
agentId:
|
|
3926
|
-
processId:
|
|
4152
|
+
executeShortcut: protectedProcedure.input(z7.object({
|
|
4153
|
+
agentId: z7.string().max(128),
|
|
4154
|
+
processId: z7.string().max(128),
|
|
3927
4155
|
shortcut: ServiceShortcutSchema
|
|
3928
4156
|
})).mutation(async ({ input }) => {
|
|
3929
4157
|
const service = await serviceStore.get(input.processId);
|
|
@@ -3951,12 +4179,12 @@ var processRouter = router({
|
|
|
3951
4179
|
return result;
|
|
3952
4180
|
}),
|
|
3953
4181
|
/** Execute an ad-hoc command on an agent, streaming output into the process log */
|
|
3954
|
-
executeAdHocCommand: protectedProcedure.input(
|
|
3955
|
-
agentId:
|
|
3956
|
-
processId:
|
|
3957
|
-
command:
|
|
3958
|
-
cwd:
|
|
3959
|
-
commandId:
|
|
4182
|
+
executeAdHocCommand: protectedProcedure.input(z7.object({
|
|
4183
|
+
agentId: z7.string().max(128),
|
|
4184
|
+
processId: z7.string().max(128),
|
|
4185
|
+
command: z7.string().min(1).max(4096),
|
|
4186
|
+
cwd: z7.string().max(4096).optional(),
|
|
4187
|
+
commandId: z7.string().max(128).optional()
|
|
3960
4188
|
})).mutation(async ({ input }) => {
|
|
3961
4189
|
const service = await serviceStore.get(input.processId);
|
|
3962
4190
|
if (service) {
|
|
@@ -3990,25 +4218,25 @@ var processRouter = router({
|
|
|
3990
4218
|
return result;
|
|
3991
4219
|
}),
|
|
3992
4220
|
/** Cancel a running shortcut command on an agent */
|
|
3993
|
-
cancelShortcut: protectedProcedure.input(
|
|
3994
|
-
agentId:
|
|
3995
|
-
processId:
|
|
3996
|
-
shortcutId:
|
|
4221
|
+
cancelShortcut: protectedProcedure.input(z7.object({
|
|
4222
|
+
agentId: z7.string().max(128),
|
|
4223
|
+
processId: z7.string().max(128),
|
|
4224
|
+
shortcutId: z7.string().max(128)
|
|
3997
4225
|
})).mutation(async ({ input }) => {
|
|
3998
4226
|
await agentManager.agentMutation(input.agentId, "process.cancelShortcut", { id: input.processId, shortcutId: input.shortcutId });
|
|
3999
4227
|
return { success: true };
|
|
4000
4228
|
}),
|
|
4001
4229
|
/** Cancel a running ad-hoc command on an agent */
|
|
4002
|
-
cancelAdHocCommand: protectedProcedure.input(
|
|
4003
|
-
agentId:
|
|
4004
|
-
processId:
|
|
4005
|
-
commandId:
|
|
4230
|
+
cancelAdHocCommand: protectedProcedure.input(z7.object({
|
|
4231
|
+
agentId: z7.string().max(128),
|
|
4232
|
+
processId: z7.string().max(128),
|
|
4233
|
+
commandId: z7.string().max(128).optional()
|
|
4006
4234
|
})).mutation(async ({ input }) => {
|
|
4007
4235
|
await agentManager.agentMutation(input.agentId, "process.cancelAdHocCommand", { id: input.processId, commandId: input.commandId });
|
|
4008
4236
|
return { success: true };
|
|
4009
4237
|
}),
|
|
4010
4238
|
/** Get current metrics for a process from an agent */
|
|
4011
|
-
metrics: protectedProcedure.input(
|
|
4239
|
+
metrics: protectedProcedure.input(z7.object({ agentId: z7.string().max(128), processId: z7.string().max(128) })).query(async ({ input }) => {
|
|
4012
4240
|
return agentManager.agentQuery(input.agentId, "process.metrics", { id: input.processId });
|
|
4013
4241
|
}),
|
|
4014
4242
|
/**
|
|
@@ -4016,7 +4244,7 @@ var processRouter = router({
|
|
|
4016
4244
|
* Forwards batched events from the AgentWSBridge in real-time.
|
|
4017
4245
|
* Historical logs are fetched separately via process.logs query.
|
|
4018
4246
|
*/
|
|
4019
|
-
onLog: protectedProcedure.input(
|
|
4247
|
+
onLog: protectedProcedure.input(z7.object({ agentId: z7.string().max(128), processId: z7.string().max(128) })).subscription(async function* ({ input, ctx }) {
|
|
4020
4248
|
requireServiceAction(ctx, input.processId, "logs:read");
|
|
4021
4249
|
yield* forwardLogBatches(input.agentId, input.processId);
|
|
4022
4250
|
}),
|
|
@@ -4025,9 +4253,9 @@ var processRouter = router({
|
|
|
4025
4253
|
* Input is optional — omit agentId/processId for global monitoring (dashboard).
|
|
4026
4254
|
* Forwards events from the AgentWSBridge in real-time.
|
|
4027
4255
|
*/
|
|
4028
|
-
onStatus: protectedProcedure.input(
|
|
4029
|
-
agentId:
|
|
4030
|
-
processId:
|
|
4256
|
+
onStatus: protectedProcedure.input(z7.object({
|
|
4257
|
+
agentId: z7.string().max(128).optional(),
|
|
4258
|
+
processId: z7.string().max(128).optional()
|
|
4031
4259
|
}).optional()).subscription(async function* ({ input, ctx }) {
|
|
4032
4260
|
const allowedIds = getAllowedServiceIds(ctx);
|
|
4033
4261
|
if (input?.processId) requireServiceAction(ctx, input.processId, "service:status");
|
|
@@ -4055,9 +4283,9 @@ var processRouter = router({
|
|
|
4055
4283
|
});
|
|
4056
4284
|
}),
|
|
4057
4285
|
/** Subscribe to real-time metrics for a process. */
|
|
4058
|
-
onMetrics: protectedProcedure.input(
|
|
4059
|
-
agentId:
|
|
4060
|
-
processId:
|
|
4286
|
+
onMetrics: protectedProcedure.input(z7.object({
|
|
4287
|
+
agentId: z7.string().max(128).optional(),
|
|
4288
|
+
processId: z7.string().max(128).optional()
|
|
4061
4289
|
}).optional()).subscription(async function* ({ input, ctx }) {
|
|
4062
4290
|
const allowedIds = getAllowedServiceIds(ctx);
|
|
4063
4291
|
if (input?.processId) requireServiceAction(ctx, input.processId, "service:status");
|
|
@@ -4069,9 +4297,9 @@ var processRouter = router({
|
|
|
4069
4297
|
});
|
|
4070
4298
|
}),
|
|
4071
4299
|
/** Subscribe to real-time health status changes. */
|
|
4072
|
-
onHealth: protectedProcedure.input(
|
|
4073
|
-
agentId:
|
|
4074
|
-
processId:
|
|
4300
|
+
onHealth: protectedProcedure.input(z7.object({
|
|
4301
|
+
agentId: z7.string().max(128).optional(),
|
|
4302
|
+
processId: z7.string().max(128).optional()
|
|
4075
4303
|
}).optional()).subscription(async function* ({ input, ctx }) {
|
|
4076
4304
|
const allowedIds = getAllowedServiceIds(ctx);
|
|
4077
4305
|
if (input?.processId) requireServiceAction(ctx, input.processId, "service:healthcheck");
|
|
@@ -4085,186 +4313,21 @@ var processRouter = router({
|
|
|
4085
4313
|
});
|
|
4086
4314
|
|
|
4087
4315
|
// ../server/src/trpc/routers/audit.ts
|
|
4088
|
-
import { z as
|
|
4316
|
+
import { z as z8 } from "zod";
|
|
4089
4317
|
var auditRouter = router({
|
|
4090
|
-
list: protectedProcedure.input(
|
|
4091
|
-
action:
|
|
4092
|
-
entityType:
|
|
4093
|
-
entityId:
|
|
4094
|
-
limit:
|
|
4095
|
-
offset:
|
|
4318
|
+
list: protectedProcedure.input(z8.object({
|
|
4319
|
+
action: z8.string().max(50).optional(),
|
|
4320
|
+
entityType: z8.string().max(50).optional(),
|
|
4321
|
+
entityId: z8.string().max(100).optional(),
|
|
4322
|
+
limit: z8.number().int().positive().max(100).default(50),
|
|
4323
|
+
offset: z8.number().int().nonnegative().default(0)
|
|
4096
4324
|
}).optional()).query(async ({ input }) => {
|
|
4097
4325
|
return auditService.list(input ?? {});
|
|
4098
4326
|
})
|
|
4099
4327
|
});
|
|
4100
4328
|
|
|
4101
4329
|
// ../server/src/trpc/routers/setup.ts
|
|
4102
|
-
import { z as
|
|
4103
|
-
|
|
4104
|
-
// ../server/src/services/cloud-session-store.ts
|
|
4105
|
-
import { readFile as readFile9, writeFile as writeFile9, rename as rename9, mkdir as mkdir9, chmod as chmod8, unlink as unlink2 } from "fs/promises";
|
|
4106
|
-
import { dirname as dirname6 } from "path";
|
|
4107
|
-
import { randomBytes as randomBytes4, timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
4108
|
-
var FILENAME5 = "cloud-session.json";
|
|
4109
|
-
var STATE_TTL_MS = 5 * 60 * 1e3;
|
|
4110
|
-
var CloudSessionStore = class {
|
|
4111
|
-
session = null;
|
|
4112
|
-
loaded = false;
|
|
4113
|
-
/** Pending login states (CSRF binding between `start` and the callback). */
|
|
4114
|
-
pending = /* @__PURE__ */ new Map();
|
|
4115
|
-
/**
|
|
4116
|
-
* Encrypted, so it lives beside the key that opens it — usually the machine
|
|
4117
|
-
* root, but a launch directory owning its own key keeps both together.
|
|
4118
|
-
*/
|
|
4119
|
-
getFilePath() {
|
|
4120
|
-
return keyedFilePath(FILENAME5);
|
|
4121
|
-
}
|
|
4122
|
-
/** Where older versions kept it — read only, so an older Runeya keeps working. */
|
|
4123
|
-
getLegacyFilePath() {
|
|
4124
|
-
return legacyMachineFilePath(FILENAME5);
|
|
4125
|
-
}
|
|
4126
|
-
/**
|
|
4127
|
-
* Read the machine file, falling back to the launch directory of old.
|
|
4128
|
-
*
|
|
4129
|
-
* The legacy file is left in place: the next save writes the new location,
|
|
4130
|
-
* and a directory still opened by an older Runeya keeps working meanwhile.
|
|
4131
|
-
*/
|
|
4132
|
-
async readFromDisk() {
|
|
4133
|
-
try {
|
|
4134
|
-
return await readFile9(await this.getFilePath(), "utf-8");
|
|
4135
|
-
} catch {
|
|
4136
|
-
return readFile9(this.getLegacyFilePath(), "utf-8");
|
|
4137
|
-
}
|
|
4138
|
-
}
|
|
4139
|
-
async load() {
|
|
4140
|
-
if (this.loaded) return;
|
|
4141
|
-
try {
|
|
4142
|
-
const raw = await this.readFromDisk();
|
|
4143
|
-
this.session = JSON.parse(raw);
|
|
4144
|
-
} catch {
|
|
4145
|
-
}
|
|
4146
|
-
this.loaded = true;
|
|
4147
|
-
}
|
|
4148
|
-
/**
|
|
4149
|
-
* Mint a state value binding a login attempt to this server. Returned to the
|
|
4150
|
-
* cloud page and echoed back on the callback, so a redirect we never
|
|
4151
|
-
* initiated cannot install a token.
|
|
4152
|
-
*/
|
|
4153
|
-
createState(returnTo) {
|
|
4154
|
-
this.sweepStates();
|
|
4155
|
-
const state = randomBytes4(32).toString("hex");
|
|
4156
|
-
this.pending.set(state, { expiresAt: Date.now() + STATE_TTL_MS, returnTo });
|
|
4157
|
-
return state;
|
|
4158
|
-
}
|
|
4159
|
-
/**
|
|
4160
|
-
* Consume a state — single use, constant-time compare, TTL enforced. Returns
|
|
4161
|
-
* the URL to send the browser back to, or null when the state is unknown or
|
|
4162
|
-
* expired (i.e. a callback this server never initiated).
|
|
4163
|
-
*/
|
|
4164
|
-
consumeState(candidate) {
|
|
4165
|
-
this.sweepStates();
|
|
4166
|
-
for (const [state, entry] of this.pending) {
|
|
4167
|
-
const a = Buffer.from(state);
|
|
4168
|
-
const b = Buffer.from(candidate);
|
|
4169
|
-
if (a.length === b.length && timingSafeEqual2(a, b)) {
|
|
4170
|
-
this.pending.delete(state);
|
|
4171
|
-
return entry.expiresAt > Date.now() ? entry.returnTo : null;
|
|
4172
|
-
}
|
|
4173
|
-
}
|
|
4174
|
-
return null;
|
|
4175
|
-
}
|
|
4176
|
-
sweepStates() {
|
|
4177
|
-
const now = Date.now();
|
|
4178
|
-
for (const [state, entry] of this.pending) {
|
|
4179
|
-
if (entry.expiresAt <= now) this.pending.delete(state);
|
|
4180
|
-
}
|
|
4181
|
-
}
|
|
4182
|
-
async save() {
|
|
4183
|
-
await mkdir9(dirname6(await this.getFilePath()), { recursive: true });
|
|
4184
|
-
const filePath = await this.getFilePath();
|
|
4185
|
-
const tmpPath = filePath + ".tmp";
|
|
4186
|
-
await writeFile9(tmpPath, JSON.stringify(this.session, null, 2), "utf-8");
|
|
4187
|
-
await rename9(tmpPath, filePath);
|
|
4188
|
-
await chmod8(filePath, 384);
|
|
4189
|
-
}
|
|
4190
|
-
/** Store the session token obtained from the one-time-token exchange. */
|
|
4191
|
-
async set(cloudUrl, token) {
|
|
4192
|
-
await this.load();
|
|
4193
|
-
this.session = { cloudUrl, encryptedToken: encryptValue(token) };
|
|
4194
|
-
await this.save();
|
|
4195
|
-
}
|
|
4196
|
-
/** The decrypted session token, or null when not logged in. */
|
|
4197
|
-
async getToken() {
|
|
4198
|
-
await this.load();
|
|
4199
|
-
if (!this.session) return null;
|
|
4200
|
-
try {
|
|
4201
|
-
return decryptValue(this.session.encryptedToken);
|
|
4202
|
-
} catch {
|
|
4203
|
-
return null;
|
|
4204
|
-
}
|
|
4205
|
-
}
|
|
4206
|
-
/**
|
|
4207
|
-
* The cloud this machine is signed into, or null when not linked.
|
|
4208
|
-
*
|
|
4209
|
-
* Needed to tell "an org I am not a member of" apart from "an org of another
|
|
4210
|
-
* cloud instance entirely" — the ids of two clouds share no namespace, so
|
|
4211
|
-
* comparing them without this would call every foreign-cloud project a
|
|
4212
|
-
* permission problem.
|
|
4213
|
-
*/
|
|
4214
|
-
async getCloudUrl() {
|
|
4215
|
-
await this.load();
|
|
4216
|
-
return this.session?.cloudUrl ?? null;
|
|
4217
|
-
}
|
|
4218
|
-
async isLinked() {
|
|
4219
|
-
return await this.getToken() !== null;
|
|
4220
|
-
}
|
|
4221
|
-
/** Forget the session (sign-out). */
|
|
4222
|
-
async clear() {
|
|
4223
|
-
await this.load();
|
|
4224
|
-
this.session = null;
|
|
4225
|
-
this.pending.clear();
|
|
4226
|
-
try {
|
|
4227
|
-
await unlink2(await this.getFilePath());
|
|
4228
|
-
} catch {
|
|
4229
|
-
}
|
|
4230
|
-
}
|
|
4231
|
-
};
|
|
4232
|
-
var cloudSessionStore = new CloudSessionStore();
|
|
4233
|
-
|
|
4234
|
-
// ../server/src/services/cloud-api.ts
|
|
4235
|
-
var DEFAULT_CLOUD_API_URL = "https://api.runeya.dev";
|
|
4236
|
-
var DEFAULT_CLOUD_APP_URL = "https://runeya.dev";
|
|
4237
|
-
function getCloudApiUrl() {
|
|
4238
|
-
return (env.CLOUD_URL ?? DEFAULT_CLOUD_API_URL).replace(/\/+$/, "");
|
|
4239
|
-
}
|
|
4240
|
-
function getCloudAppUrl() {
|
|
4241
|
-
return (env.CLOUD_APP_URL ?? DEFAULT_CLOUD_APP_URL).replace(/\/+$/, "");
|
|
4242
|
-
}
|
|
4243
|
-
var CloudNotLinkedError = class extends Error {
|
|
4244
|
-
code = "CLOUD_NOT_LINKED";
|
|
4245
|
-
constructor() {
|
|
4246
|
-
super("Not linked to the Runeya cloud.");
|
|
4247
|
-
this.name = "CloudNotLinkedError";
|
|
4248
|
-
}
|
|
4249
|
-
};
|
|
4250
|
-
async function cloudFetch(path, init = {}) {
|
|
4251
|
-
const token = await cloudSessionStore.getToken();
|
|
4252
|
-
if (!token) throw new CloudNotLinkedError();
|
|
4253
|
-
return fetch(`${getCloudApiUrl()}${path}`, {
|
|
4254
|
-
method: init.method ?? "GET",
|
|
4255
|
-
headers: {
|
|
4256
|
-
Authorization: `Bearer ${token}`,
|
|
4257
|
-
// Le cloud refuse (426) les apps trop anciennes pour son schéma courant.
|
|
4258
|
-
[APP_VERSION_HEADER]: appVersion,
|
|
4259
|
-
...init.body !== void 0 ? { "Content-Type": "application/json" } : {}
|
|
4260
|
-
},
|
|
4261
|
-
...init.body !== void 0 ? { body: JSON.stringify(init.body) } : {},
|
|
4262
|
-
// 15s suits a JSON call; attachment downloads pass a longer budget.
|
|
4263
|
-
signal: AbortSignal.timeout(init.timeoutMs ?? 15e3)
|
|
4264
|
-
});
|
|
4265
|
-
}
|
|
4266
|
-
|
|
4267
|
-
// ../server/src/trpc/routers/setup.ts
|
|
4330
|
+
import { z as z9 } from "zod";
|
|
4268
4331
|
var setupRouter = router({
|
|
4269
4332
|
/**
|
|
4270
4333
|
* Check if encryption key is required (project initialized but no key).
|
|
@@ -4364,9 +4427,9 @@ var setupRouter = router({
|
|
|
4364
4427
|
* une validation de la clé à adopter rendait le parcours impossible : vert
|
|
4365
4428
|
* quand le geste est inutile, rouge sinon.
|
|
4366
4429
|
*/
|
|
4367
|
-
checkOrgKeyLocal: protectedProcedure.input(
|
|
4368
|
-
orgId:
|
|
4369
|
-
keyHex:
|
|
4430
|
+
checkOrgKeyLocal: protectedProcedure.input(z9.object({
|
|
4431
|
+
orgId: z9.string().min(1).max(128),
|
|
4432
|
+
keyHex: z9.string().length(64).regex(/^[0-9a-f]+$/i, "Invalid hex format")
|
|
4370
4433
|
})).query(async ({ input }) => {
|
|
4371
4434
|
const canary = await readVerifyFile(orgVaultRoot(input.orgId));
|
|
4372
4435
|
if (!canary) return { isCurrentKey: false, hasCanary: false };
|
|
@@ -4381,8 +4444,8 @@ var setupRouter = router({
|
|
|
4381
4444
|
* Spawns the local agent if in local-simple mode.
|
|
4382
4445
|
*/
|
|
4383
4446
|
submitEncryptionKey: publicProcedure.input(
|
|
4384
|
-
|
|
4385
|
-
keyHex:
|
|
4447
|
+
z9.object({
|
|
4448
|
+
keyHex: z9.string().length(64).regex(/^[0-9a-f]+$/i, "Invalid hex format")
|
|
4386
4449
|
})
|
|
4387
4450
|
).mutation(async ({ input }) => {
|
|
4388
4451
|
try {
|
|
@@ -4401,32 +4464,32 @@ var setupRouter = router({
|
|
|
4401
4464
|
});
|
|
4402
4465
|
|
|
4403
4466
|
// ../server/src/trpc/routers/environment.ts
|
|
4404
|
-
import { z as
|
|
4467
|
+
import { z as z10 } from "zod";
|
|
4405
4468
|
import { TRPCError as TRPCError7 } from "@trpc/server";
|
|
4406
4469
|
var environmentRouter = router({
|
|
4407
|
-
list: protectedProcedure.input(
|
|
4408
|
-
projectId:
|
|
4409
|
-
orgId:
|
|
4470
|
+
list: protectedProcedure.input(z10.object({
|
|
4471
|
+
projectId: z10.string().max(128),
|
|
4472
|
+
orgId: z10.string().max(128).nullable().optional()
|
|
4410
4473
|
})).query(async ({ input }) => {
|
|
4411
4474
|
return await environmentStore.list(input.projectId, input.orgId);
|
|
4412
4475
|
}),
|
|
4413
|
-
get: protectedProcedure.input(
|
|
4476
|
+
get: protectedProcedure.input(z10.object({ id: z10.string().max(128) })).query(async ({ input }) => {
|
|
4414
4477
|
const env2 = await environmentStore.get(input.id);
|
|
4415
4478
|
if (!env2) throw new TRPCError7({ code: "NOT_FOUND", message: `Environment ${input.id} not found` });
|
|
4416
4479
|
return env2;
|
|
4417
4480
|
}),
|
|
4418
|
-
listByScope: protectedProcedure.input(
|
|
4419
|
-
projectId:
|
|
4420
|
-
orgId:
|
|
4421
|
-
scope:
|
|
4481
|
+
listByScope: protectedProcedure.input(z10.object({
|
|
4482
|
+
projectId: z10.string().max(128),
|
|
4483
|
+
orgId: z10.string().max(128).nullable().optional(),
|
|
4484
|
+
scope: z10.enum(["global", "service"])
|
|
4422
4485
|
})).query(async ({ input }) => {
|
|
4423
4486
|
return await environmentStore.listByScope(input.projectId, input.scope, input.orgId);
|
|
4424
4487
|
}),
|
|
4425
|
-
findServiceEnvironment: protectedProcedure.input(
|
|
4488
|
+
findServiceEnvironment: protectedProcedure.input(z10.object({ serviceId: z10.string().max(128), globalEnvId: z10.string().max(128) })).query(async ({ input }) => {
|
|
4426
4489
|
return await environmentStore.findServiceEnvironment(input.serviceId, input.globalEnvId);
|
|
4427
4490
|
}),
|
|
4428
4491
|
create: protectedProcedure.input(CreateEnvironmentSchema.extend({
|
|
4429
|
-
orgId:
|
|
4492
|
+
orgId: z10.string().max(128).nullable().optional()
|
|
4430
4493
|
})).mutation(async ({ input }) => {
|
|
4431
4494
|
const { orgId, ...environment } = input;
|
|
4432
4495
|
const target = { id: input.projectId, orgId };
|
|
@@ -4478,7 +4541,7 @@ var environmentRouter = router({
|
|
|
4478
4541
|
}
|
|
4479
4542
|
return env2;
|
|
4480
4543
|
}),
|
|
4481
|
-
delete: protectedProcedure.input(
|
|
4544
|
+
delete: protectedProcedure.input(z10.object({ id: z10.string().max(128) })).mutation(async ({ input }) => {
|
|
4482
4545
|
const env2 = await environmentStore.get(input.id);
|
|
4483
4546
|
if (!env2) throw new TRPCError7({ code: "NOT_FOUND", message: `Environment ${input.id} not found` });
|
|
4484
4547
|
if (env2.immutable) {
|
|
@@ -4492,7 +4555,7 @@ var environmentRouter = router({
|
|
|
4492
4555
|
await projectStore.removeEnvironment(environmentStore.projectRefOf(env2) ?? env2.projectId, input.id);
|
|
4493
4556
|
return { success: true };
|
|
4494
4557
|
}),
|
|
4495
|
-
resolve: protectedProcedure.input(
|
|
4558
|
+
resolve: protectedProcedure.input(z10.object({ environmentId: z10.string().max(128) })).query(async ({ input, ctx }) => {
|
|
4496
4559
|
const { includeSecrets } = requireEnvAction(ctx, input.environmentId, "env:read");
|
|
4497
4560
|
const env2 = await environmentStore.get(input.environmentId);
|
|
4498
4561
|
if (!env2) throw new TRPCError7({ code: "NOT_FOUND", message: `Environment ${input.environmentId} not found` });
|
|
@@ -4511,7 +4574,7 @@ var environmentRouter = router({
|
|
|
4511
4574
|
}
|
|
4512
4575
|
return resolved;
|
|
4513
4576
|
}),
|
|
4514
|
-
resolveFlat: protectedProcedure.meta({ openapi: { method: "GET", path: "/environments/{environmentId}/resolve-flat", tags: ["environments"], summary: "Resolve environment variables as a flat key-value map", protect: true } }).input(
|
|
4577
|
+
resolveFlat: protectedProcedure.meta({ openapi: { method: "GET", path: "/environments/{environmentId}/resolve-flat", tags: ["environments"], summary: "Resolve environment variables as a flat key-value map", protect: true } }).input(z10.object({ environmentId: z10.string().max(128) })).output(z10.record(z10.string(), z10.string())).query(async ({ input, ctx }) => {
|
|
4515
4578
|
const { includeSecrets } = requireEnvAction(ctx, input.environmentId, "env:read");
|
|
4516
4579
|
const env2 = await environmentStore.get(input.environmentId);
|
|
4517
4580
|
if (!env2) throw new TRPCError7({ code: "NOT_FOUND", message: `Environment ${input.environmentId} not found` });
|
|
@@ -4527,8 +4590,8 @@ var environmentRouter = router({
|
|
|
4527
4590
|
return result;
|
|
4528
4591
|
}),
|
|
4529
4592
|
// --- Overrides (flat, by variableId) ---
|
|
4530
|
-
setOverride: protectedProcedure.input(
|
|
4531
|
-
variableId:
|
|
4593
|
+
setOverride: protectedProcedure.input(z10.object({
|
|
4594
|
+
variableId: z10.string().max(128),
|
|
4532
4595
|
// Only the value slot: the env var name comes from the variable
|
|
4533
4596
|
// definition (a `key` sent by an older client is stripped here).
|
|
4534
4597
|
variable: VariableOverrideSchema
|
|
@@ -4536,8 +4599,8 @@ var environmentRouter = router({
|
|
|
4536
4599
|
await environmentOverridesStore.setOverride(input.variableId, input.variable);
|
|
4537
4600
|
return { success: true };
|
|
4538
4601
|
}),
|
|
4539
|
-
removeOverride: protectedProcedure.input(
|
|
4540
|
-
variableId:
|
|
4602
|
+
removeOverride: protectedProcedure.input(z10.object({
|
|
4603
|
+
variableId: z10.string().max(128)
|
|
4541
4604
|
})).mutation(async ({ input }) => {
|
|
4542
4605
|
await environmentOverridesStore.removeOverride(input.variableId);
|
|
4543
4606
|
return { success: true };
|
|
@@ -4545,9 +4608,9 @@ var environmentRouter = router({
|
|
|
4545
4608
|
getOverrides: protectedProcedure.query(async () => {
|
|
4546
4609
|
return await environmentOverridesStore.getAll();
|
|
4547
4610
|
}),
|
|
4548
|
-
upsertVariable: protectedProcedure.meta({ openapi: { method: "PUT", path: "/environments/{environmentId}/variables/{variableId}", tags: ["environments"], summary: "Upsert a variable in an environment", protect: true } }).output(
|
|
4549
|
-
environmentId:
|
|
4550
|
-
variableId:
|
|
4611
|
+
upsertVariable: protectedProcedure.meta({ openapi: { method: "PUT", path: "/environments/{environmentId}/variables/{variableId}", tags: ["environments"], summary: "Upsert a variable in an environment", protect: true } }).output(z10.any()).input(z10.object({
|
|
4612
|
+
environmentId: z10.string().max(128),
|
|
4613
|
+
variableId: z10.string().max(128),
|
|
4551
4614
|
variable: VariableSchema
|
|
4552
4615
|
})).mutation(async ({ input, ctx }) => {
|
|
4553
4616
|
requireEnvAction(ctx, input.environmentId, "env:write");
|
|
@@ -4562,12 +4625,12 @@ var environmentRouter = router({
|
|
|
4562
4625
|
* define it, and variables that reference it through {{environment.KEY}}.
|
|
4563
4626
|
* Used by the UI to warn before editing a shared variable from a resolved view.
|
|
4564
4627
|
*/
|
|
4565
|
-
keyUsages: protectedProcedure.input(
|
|
4566
|
-
projectId:
|
|
4567
|
-
orgId:
|
|
4568
|
-
key:
|
|
4628
|
+
keyUsages: protectedProcedure.input(z10.object({
|
|
4629
|
+
projectId: z10.string().max(128),
|
|
4630
|
+
orgId: z10.string().max(128).nullable().optional(),
|
|
4631
|
+
key: z10.string().min(1).max(256),
|
|
4569
4632
|
/** Environment holding the variable about to be edited — enables inherited-impact detection */
|
|
4570
|
-
environmentId:
|
|
4633
|
+
environmentId: z10.string().max(128).optional()
|
|
4571
4634
|
})).query(async ({ input }) => {
|
|
4572
4635
|
const environments = await environmentStore.list(input.projectId, input.orgId);
|
|
4573
4636
|
const services = await serviceStore.list();
|
|
@@ -4624,9 +4687,9 @@ var environmentRouter = router({
|
|
|
4624
4687
|
}
|
|
4625
4688
|
return { definedIn, referencedBy, inheritedBy };
|
|
4626
4689
|
}),
|
|
4627
|
-
removeVariable: protectedProcedure.input(
|
|
4628
|
-
environmentId:
|
|
4629
|
-
variableId:
|
|
4690
|
+
removeVariable: protectedProcedure.input(z10.object({
|
|
4691
|
+
environmentId: z10.string().max(128),
|
|
4692
|
+
variableId: z10.string().max(128)
|
|
4630
4693
|
})).mutation(async ({ input }) => {
|
|
4631
4694
|
const env2 = await environmentStore.get(input.environmentId);
|
|
4632
4695
|
if (!env2) throw new TRPCError7({ code: "NOT_FOUND", message: `Environment ${input.environmentId} not found` });
|
|
@@ -4638,7 +4701,7 @@ var environmentRouter = router({
|
|
|
4638
4701
|
|
|
4639
4702
|
// ../server/src/trpc/routers/settings.ts
|
|
4640
4703
|
import { promises as dns } from "dns";
|
|
4641
|
-
import { z as
|
|
4704
|
+
import { z as z12 } from "zod";
|
|
4642
4705
|
import { TRPCError as TRPCError8 } from "@trpc/server";
|
|
4643
4706
|
|
|
4644
4707
|
// ../server/src/services/settings-scope.ts
|
|
@@ -4654,12 +4717,12 @@ async function vaultOfProject(projectId) {
|
|
|
4654
4717
|
import { networkInterfaces } from "os";
|
|
4655
4718
|
import { readFile as readFile10, writeFile as writeFile10, rename as rename10, mkdir as mkdir10 } from "fs/promises";
|
|
4656
4719
|
import { join as join11 } from "path";
|
|
4657
|
-
import { z as
|
|
4720
|
+
import { z as z11 } from "zod";
|
|
4658
4721
|
var LOOPBACK2 = "127.0.0.1";
|
|
4659
4722
|
var ANY = "0.0.0.0";
|
|
4660
4723
|
var NETWORK_FILE = "network.json";
|
|
4661
|
-
var NetworkFileSchema =
|
|
4662
|
-
instances:
|
|
4724
|
+
var NetworkFileSchema = z11.object({
|
|
4725
|
+
instances: z11.record(z11.string(), z11.object({ lanEnabled: z11.boolean().default(false) })).default({})
|
|
4663
4726
|
});
|
|
4664
4727
|
var httpServer = null;
|
|
4665
4728
|
function instanceKey() {
|
|
@@ -4779,8 +4842,8 @@ function maskApiKey2(plaintext) {
|
|
|
4779
4842
|
return plaintext.slice(0, 4) + "****" + plaintext.slice(-4);
|
|
4780
4843
|
}
|
|
4781
4844
|
var ScopeShape = {
|
|
4782
|
-
orgId:
|
|
4783
|
-
projectId:
|
|
4845
|
+
orgId: z12.string().max(128).nullable().optional(),
|
|
4846
|
+
projectId: z12.string().max(128).optional()
|
|
4784
4847
|
};
|
|
4785
4848
|
async function scopeOf(input) {
|
|
4786
4849
|
return input?.orgId ?? await vaultOfProject(input?.projectId);
|
|
@@ -4818,7 +4881,7 @@ var settingsRouter = router({
|
|
|
4818
4881
|
* celle de l'onglet qui bascule, ne sont pas coupées. Le choix est mémorisé
|
|
4819
4882
|
* dans les réglages, donc conservé au prochain démarrage.
|
|
4820
4883
|
*/
|
|
4821
|
-
setLanMode: protectedProcedure.input(
|
|
4884
|
+
setLanMode: protectedProcedure.input(z12.object({ enabled: z12.boolean() })).mutation(async ({ input }) => {
|
|
4822
4885
|
try {
|
|
4823
4886
|
return await setLanMode(input.enabled);
|
|
4824
4887
|
} catch (err) {
|
|
@@ -4843,7 +4906,7 @@ var settingsRouter = router({
|
|
|
4843
4906
|
/**
|
|
4844
4907
|
* Get notification preferences
|
|
4845
4908
|
*/
|
|
4846
|
-
getNotificationPreferences: protectedProcedure.input(
|
|
4909
|
+
getNotificationPreferences: protectedProcedure.input(z12.object(ScopeShape).optional()).query(async ({ input }) => {
|
|
4847
4910
|
const priv = await settingsManager.getPrivateSettings(await scopeOf(input));
|
|
4848
4911
|
return NotificationPreferencesSchema.parse(priv.notifications ?? {});
|
|
4849
4912
|
}),
|
|
@@ -4871,7 +4934,7 @@ var settingsRouter = router({
|
|
|
4871
4934
|
* parseur d'organisation se modifie pour toute l'équipe, et l'interface doit
|
|
4872
4935
|
* pouvoir le dire avant que quelqu'un le change sans le savoir.
|
|
4873
4936
|
*/
|
|
4874
|
-
listParsers: protectedProcedure.input(
|
|
4937
|
+
listParsers: protectedProcedure.input(z12.object(ScopeShape).optional()).query(async ({ input }) => {
|
|
4875
4938
|
const vault = await scopeOf(input);
|
|
4876
4939
|
return listWithOrigin(await logParserStore.list(vault), vault);
|
|
4877
4940
|
}),
|
|
@@ -4883,7 +4946,7 @@ var settingsRouter = router({
|
|
|
4883
4946
|
* retard — affichant une liste dans laquelle le parseur qu'un service vient
|
|
4884
4947
|
* de référencer n'existe pas encore.
|
|
4885
4948
|
*/
|
|
4886
|
-
onParsersChanged: protectedProcedure.input(
|
|
4949
|
+
onParsersChanged: protectedProcedure.input(z12.object(ScopeShape).optional()).subscription(async function* ({ input, signal }) {
|
|
4887
4950
|
const vault = await scopeOf(input);
|
|
4888
4951
|
let pending = true;
|
|
4889
4952
|
let wake = null;
|
|
@@ -4921,7 +4984,7 @@ var settingsRouter = router({
|
|
|
4921
4984
|
/**
|
|
4922
4985
|
* Get single parser by ID
|
|
4923
4986
|
*/
|
|
4924
|
-
getParser: protectedProcedure.input(
|
|
4987
|
+
getParser: protectedProcedure.input(z12.object({ id: z12.string().max(128), ...ScopeShape })).query(async ({ input }) => {
|
|
4925
4988
|
const parser = await logParserStore.get(input.id, await scopeOf(input));
|
|
4926
4989
|
if (!parser) {
|
|
4927
4990
|
throw new TRPCError8({ code: "NOT_FOUND", message: `Parser not found: ${input.id}` });
|
|
@@ -4969,7 +5032,7 @@ var settingsRouter = router({
|
|
|
4969
5032
|
/**
|
|
4970
5033
|
* Delete parser by ID
|
|
4971
5034
|
*/
|
|
4972
|
-
deleteParser: protectedProcedure.input(
|
|
5035
|
+
deleteParser: protectedProcedure.input(z12.object({ id: z12.string().max(128), ...ScopeShape })).mutation(async ({ input }) => {
|
|
4973
5036
|
if (input.id.startsWith("native:")) {
|
|
4974
5037
|
throw new TRPCError8({ code: "FORBIDDEN", message: "Cannot delete built-in parsers" });
|
|
4975
5038
|
}
|
|
@@ -4985,7 +5048,7 @@ var settingsRouter = router({
|
|
|
4985
5048
|
/**
|
|
4986
5049
|
* List AI providers (API keys are masked)
|
|
4987
5050
|
*/
|
|
4988
|
-
listAIProviders: protectedProcedure.input(
|
|
5051
|
+
listAIProviders: protectedProcedure.input(z12.object(ScopeShape).optional()).query(async ({ input }) => {
|
|
4989
5052
|
const vault = await scopeOf(input);
|
|
4990
5053
|
const priv = await settingsManager.getPrivateSettings(vault);
|
|
4991
5054
|
return (priv.aiProviders ?? []).map((p) => {
|
|
@@ -5003,12 +5066,12 @@ var settingsRouter = router({
|
|
|
5003
5066
|
/**
|
|
5004
5067
|
* Create AI provider
|
|
5005
5068
|
*/
|
|
5006
|
-
createAIProvider: protectedProcedure.input(
|
|
5007
|
-
name:
|
|
5069
|
+
createAIProvider: protectedProcedure.input(z12.object({
|
|
5070
|
+
name: z12.string().min(1).max(200),
|
|
5008
5071
|
provider: AIProviderSchema.shape.provider,
|
|
5009
|
-
apiKey:
|
|
5072
|
+
apiKey: z12.string().max(500).optional(),
|
|
5010
5073
|
// optional for providers like Ollama
|
|
5011
|
-
model:
|
|
5074
|
+
model: z12.string().max(200).optional(),
|
|
5012
5075
|
...ScopeShape
|
|
5013
5076
|
})).mutation(async ({ input }) => {
|
|
5014
5077
|
if (input.provider !== "ollama" && !input.apiKey?.trim()) {
|
|
@@ -5041,12 +5104,12 @@ var settingsRouter = router({
|
|
|
5041
5104
|
/**
|
|
5042
5105
|
* Update AI provider (apiKey optional — omit to keep existing)
|
|
5043
5106
|
*/
|
|
5044
|
-
updateAIProvider: protectedProcedure.input(
|
|
5045
|
-
id:
|
|
5046
|
-
name:
|
|
5107
|
+
updateAIProvider: protectedProcedure.input(z12.object({
|
|
5108
|
+
id: z12.string().min(1).max(128),
|
|
5109
|
+
name: z12.string().min(1).max(200).optional(),
|
|
5047
5110
|
provider: AIProviderSchema.shape.provider.optional(),
|
|
5048
|
-
apiKey:
|
|
5049
|
-
model:
|
|
5111
|
+
apiKey: z12.string().min(1).max(500).optional(),
|
|
5112
|
+
model: z12.string().max(200).optional(),
|
|
5050
5113
|
...ScopeShape
|
|
5051
5114
|
})).mutation(async ({ input }) => {
|
|
5052
5115
|
const vault = await scopeOf(input);
|
|
@@ -5079,7 +5142,7 @@ var settingsRouter = router({
|
|
|
5079
5142
|
/**
|
|
5080
5143
|
* Delete AI provider
|
|
5081
5144
|
*/
|
|
5082
|
-
deleteAIProvider: protectedProcedure.input(
|
|
5145
|
+
deleteAIProvider: protectedProcedure.input(z12.object({ id: z12.string().min(1).max(128), ...ScopeShape })).mutation(async ({ input }) => {
|
|
5083
5146
|
const vault = await scopeOf(input);
|
|
5084
5147
|
const priv = await settingsManager.getPrivateSettings(vault);
|
|
5085
5148
|
const providers = priv.aiProviders ?? [];
|
|
@@ -5093,7 +5156,7 @@ var settingsRouter = router({
|
|
|
5093
5156
|
/**
|
|
5094
5157
|
* Set one provider as active (clears active flag on all others)
|
|
5095
5158
|
*/
|
|
5096
|
-
setActiveAIProvider: protectedProcedure.input(
|
|
5159
|
+
setActiveAIProvider: protectedProcedure.input(z12.object({ id: z12.string().min(1).max(128), ...ScopeShape })).mutation(async ({ input }) => {
|
|
5097
5160
|
const vault = await scopeOf(input);
|
|
5098
5161
|
const priv = await settingsManager.getPrivateSettings(vault);
|
|
5099
5162
|
const providers = priv.aiProviders ?? [];
|
|
@@ -5109,7 +5172,7 @@ var settingsRouter = router({
|
|
|
5109
5172
|
/**
|
|
5110
5173
|
* Get Traefik config for a specific agent (never returns credentials or cert key in plain text)
|
|
5111
5174
|
*/
|
|
5112
|
-
getAgentTraefikConfig: protectedProcedure.input(
|
|
5175
|
+
getAgentTraefikConfig: protectedProcedure.input(z12.object({ agentId: z12.string().max(128) })).query(async ({ input }) => {
|
|
5113
5176
|
const raw = agentStore.getTraefikConfig(input.agentId);
|
|
5114
5177
|
const parsed = raw ? TraefikConfigSchema.safeParse(raw) : null;
|
|
5115
5178
|
const config = parsed?.success ? parsed.data : null;
|
|
@@ -5129,16 +5192,16 @@ var settingsRouter = router({
|
|
|
5129
5192
|
/**
|
|
5130
5193
|
* Update Traefik config for a specific agent (credentials are encrypted before saving)
|
|
5131
5194
|
*/
|
|
5132
|
-
updateAgentTraefikConfig: protectedProcedure.input(
|
|
5133
|
-
agentId:
|
|
5134
|
-
enabled:
|
|
5135
|
-
acmeEmail:
|
|
5136
|
-
wildcardDomain:
|
|
5137
|
-
httpPort:
|
|
5138
|
-
httpsPort:
|
|
5139
|
-
dnsProvider:
|
|
5140
|
-
dnsCredentials:
|
|
5141
|
-
acmeStaging:
|
|
5195
|
+
updateAgentTraefikConfig: protectedProcedure.input(z12.object({
|
|
5196
|
+
agentId: z12.string().max(128),
|
|
5197
|
+
enabled: z12.boolean().optional(),
|
|
5198
|
+
acmeEmail: z12.string().email().max(256).optional(),
|
|
5199
|
+
wildcardDomain: z12.string().max(253).optional(),
|
|
5200
|
+
httpPort: z12.number().int().min(1).max(65535).optional(),
|
|
5201
|
+
httpsPort: z12.number().int().min(1).max(65535).optional(),
|
|
5202
|
+
dnsProvider: z12.string().max(64).optional(),
|
|
5203
|
+
dnsCredentials: z12.record(z12.string().max(64), z12.string().max(2048)).optional(),
|
|
5204
|
+
acmeStaging: z12.boolean().optional()
|
|
5142
5205
|
})).mutation(async ({ input }) => {
|
|
5143
5206
|
const { agentId, ...fields } = input;
|
|
5144
5207
|
const raw = agentStore.getTraefikConfig(agentId);
|
|
@@ -5167,13 +5230,13 @@ var settingsRouter = router({
|
|
|
5167
5230
|
/**
|
|
5168
5231
|
* Get Traefik config files content for a specific agent
|
|
5169
5232
|
*/
|
|
5170
|
-
getAgentTraefikConfigFiles: protectedProcedure.input(
|
|
5233
|
+
getAgentTraefikConfigFiles: protectedProcedure.input(z12.object({ agentId: z12.string().max(128) })).query(async ({ input }) => {
|
|
5171
5234
|
return agentManager.agentQuery(
|
|
5172
5235
|
input.agentId,
|
|
5173
5236
|
"config.getTraefikConfigFiles"
|
|
5174
5237
|
);
|
|
5175
5238
|
}),
|
|
5176
|
-
getAgentTraefikFileTree: protectedProcedure.input(
|
|
5239
|
+
getAgentTraefikFileTree: protectedProcedure.input(z12.object({ agentId: z12.string().max(128) })).query(async ({ input }) => {
|
|
5177
5240
|
return agentManager.agentQuery(
|
|
5178
5241
|
input.agentId,
|
|
5179
5242
|
"config.getTraefikFileTree"
|
|
@@ -5182,7 +5245,7 @@ var settingsRouter = router({
|
|
|
5182
5245
|
/**
|
|
5183
5246
|
* Get Traefik container logs for a specific agent (snapshot)
|
|
5184
5247
|
*/
|
|
5185
|
-
getAgentTraefikLogs: protectedProcedure.input(
|
|
5248
|
+
getAgentTraefikLogs: protectedProcedure.input(z12.object({ agentId: z12.string().max(128), lines: z12.number().int().min(1).max(500).default(100) })).query(async ({ input }) => {
|
|
5186
5249
|
const result = await agentManager.agentQuery(
|
|
5187
5250
|
input.agentId,
|
|
5188
5251
|
"config.getTraefikLogs",
|
|
@@ -5193,7 +5256,7 @@ var settingsRouter = router({
|
|
|
5193
5256
|
/**
|
|
5194
5257
|
* Stream Traefik logs in real-time (subscription, yields new lines every 500ms)
|
|
5195
5258
|
*/
|
|
5196
|
-
streamAgentTraefikLogs: protectedProcedure.input(
|
|
5259
|
+
streamAgentTraefikLogs: protectedProcedure.input(z12.object({ agentId: z12.string().max(128) })).subscription(async function* ({ input, signal }) {
|
|
5197
5260
|
let seen = 0;
|
|
5198
5261
|
while (!signal?.aborted) {
|
|
5199
5262
|
try {
|
|
@@ -5216,7 +5279,7 @@ var settingsRouter = router({
|
|
|
5216
5279
|
/**
|
|
5217
5280
|
* Restart Traefik container on a specific agent (re-pushes config first to handle agent restarts)
|
|
5218
5281
|
*/
|
|
5219
|
-
restartAgentTraefik: protectedProcedure.input(
|
|
5282
|
+
restartAgentTraefik: protectedProcedure.input(z12.object({ agentId: z12.string().max(128) })).mutation(async ({ input }) => {
|
|
5220
5283
|
const raw = agentStore.getTraefikConfig(input.agentId);
|
|
5221
5284
|
const parsed = raw ? TraefikConfigSchema.safeParse(raw) : null;
|
|
5222
5285
|
const config = parsed?.success ? parsed.data : null;
|
|
@@ -5229,7 +5292,7 @@ var settingsRouter = router({
|
|
|
5229
5292
|
/**
|
|
5230
5293
|
* Force certificate renewal for a specific agent (wipes acme.json + restarts container)
|
|
5231
5294
|
*/
|
|
5232
|
-
renewAgentTraefikCert: protectedProcedure.input(
|
|
5295
|
+
renewAgentTraefikCert: protectedProcedure.input(z12.object({ agentId: z12.string().max(128) })).mutation(async ({ input }) => {
|
|
5233
5296
|
const raw = agentStore.getTraefikConfig(input.agentId);
|
|
5234
5297
|
const parsed = raw ? TraefikConfigSchema.safeParse(raw) : null;
|
|
5235
5298
|
const config = parsed?.success ? parsed.data : null;
|
|
@@ -5242,7 +5305,7 @@ var settingsRouter = router({
|
|
|
5242
5305
|
/**
|
|
5243
5306
|
* Validate Traefik configuration for a specific agent
|
|
5244
5307
|
*/
|
|
5245
|
-
validateAgentTraefikConfig: protectedProcedure.input(
|
|
5308
|
+
validateAgentTraefikConfig: protectedProcedure.input(z12.object({ agentId: z12.string().max(128) })).query(async ({ input }) => {
|
|
5246
5309
|
const raw = agentStore.getTraefikConfig(input.agentId);
|
|
5247
5310
|
const parsed = raw ? TraefikConfigSchema.safeParse(raw) : null;
|
|
5248
5311
|
const config = parsed?.success ? parsed.data : null;
|
|
@@ -5344,12 +5407,12 @@ var settingsRouter = router({
|
|
|
5344
5407
|
* Test parser code: compile and run it against sample logs, return per-line results
|
|
5345
5408
|
*/
|
|
5346
5409
|
testParser: protectedProcedure.input(
|
|
5347
|
-
|
|
5348
|
-
code:
|
|
5349
|
-
sampleLogs:
|
|
5350
|
-
|
|
5351
|
-
raw:
|
|
5352
|
-
stream:
|
|
5410
|
+
z12.object({
|
|
5411
|
+
code: z12.string().max(5e4),
|
|
5412
|
+
sampleLogs: z12.array(
|
|
5413
|
+
z12.object({
|
|
5414
|
+
raw: z12.string().max(16384),
|
|
5415
|
+
stream: z12.enum(["stdout", "stderr"])
|
|
5353
5416
|
})
|
|
5354
5417
|
).max(100).default([])
|
|
5355
5418
|
})
|
|
@@ -5393,7 +5456,7 @@ var settingsRouter = router({
|
|
|
5393
5456
|
});
|
|
5394
5457
|
|
|
5395
5458
|
// ../server/src/trpc/routers/editor.ts
|
|
5396
|
-
import { z as
|
|
5459
|
+
import { z as z14 } from "zod";
|
|
5397
5460
|
import { TRPCError as TRPCError9 } from "@trpc/server";
|
|
5398
5461
|
import { execFile as execFile3, spawn as spawn2 } from "child_process";
|
|
5399
5462
|
import { stat as stat4 } from "fs/promises";
|
|
@@ -5404,19 +5467,19 @@ import { homedir as homedir2 } from "os";
|
|
|
5404
5467
|
import { readFile as readFile11, writeFile as writeFile11, rename as rename11, mkdir as mkdir11, chmod as chmod9 } from "fs/promises";
|
|
5405
5468
|
import { join as join12 } from "path";
|
|
5406
5469
|
import { homedir } from "os";
|
|
5407
|
-
import { z as
|
|
5470
|
+
import { z as z13 } from "zod";
|
|
5408
5471
|
var CONFIG_DIR = join12(homedir(), ".runeya");
|
|
5409
5472
|
var CONFIG_FILE = "runeya.conf";
|
|
5410
|
-
var EditorPreferencesSchema =
|
|
5411
|
-
default:
|
|
5412
|
-
}).catchall(
|
|
5413
|
-
var ProjectSettingsSchema =
|
|
5414
|
-
settings:
|
|
5473
|
+
var EditorPreferencesSchema = z13.object({
|
|
5474
|
+
default: z13.string().max(64).optional()
|
|
5475
|
+
}).catchall(z13.string().max(64)).refine((obj) => Object.keys(obj).length <= 500, "Too many editor preferences");
|
|
5476
|
+
var ProjectSettingsSchema = z13.object({
|
|
5477
|
+
settings: z13.object({
|
|
5415
5478
|
editors: EditorPreferencesSchema.optional()
|
|
5416
5479
|
}).optional()
|
|
5417
5480
|
});
|
|
5418
|
-
var UserConfigSchema =
|
|
5419
|
-
|
|
5481
|
+
var UserConfigSchema = z13.record(
|
|
5482
|
+
z13.string().max(128),
|
|
5420
5483
|
ProjectSettingsSchema
|
|
5421
5484
|
).refine((obj) => Object.keys(obj).length <= 100, "Too many projects in config");
|
|
5422
5485
|
function configKey(ref) {
|
|
@@ -5493,7 +5556,7 @@ async function getServiceCwd(serviceId) {
|
|
|
5493
5556
|
}
|
|
5494
5557
|
async function isCommandAvailable(command) {
|
|
5495
5558
|
return new Promise((resolve7) => {
|
|
5496
|
-
execFile3("which", [command], { timeout: 5e3 }, (err) => {
|
|
5559
|
+
execFile3("which", [command], { timeout: 5e3, windowsHide: true }, (err) => {
|
|
5497
5560
|
resolve7(!err);
|
|
5498
5561
|
});
|
|
5499
5562
|
});
|
|
@@ -5508,16 +5571,16 @@ var editorRouter = router({
|
|
|
5508
5571
|
);
|
|
5509
5572
|
return results;
|
|
5510
5573
|
}),
|
|
5511
|
-
getPreferences: protectedProcedure.input(
|
|
5512
|
-
projectId:
|
|
5513
|
-
orgId:
|
|
5574
|
+
getPreferences: protectedProcedure.input(z14.object({
|
|
5575
|
+
projectId: z14.string().max(128),
|
|
5576
|
+
orgId: z14.string().max(128).nullable().optional()
|
|
5514
5577
|
})).query(async ({ input }) => {
|
|
5515
5578
|
return userConfigManager.getEditorPreferences({ id: input.projectId, orgId: input.orgId });
|
|
5516
5579
|
}),
|
|
5517
|
-
setDefault: protectedProcedure.input(
|
|
5518
|
-
projectId:
|
|
5519
|
-
orgId:
|
|
5520
|
-
editorKey:
|
|
5580
|
+
setDefault: protectedProcedure.input(z14.object({
|
|
5581
|
+
projectId: z14.string().max(128),
|
|
5582
|
+
orgId: z14.string().max(128).nullable().optional(),
|
|
5583
|
+
editorKey: z14.string().max(64)
|
|
5521
5584
|
})).mutation(async ({ input }) => {
|
|
5522
5585
|
if (!EDITOR_BY_KEY.has(input.editorKey)) {
|
|
5523
5586
|
throw new TRPCError9({ code: "BAD_REQUEST", message: `Unknown editor: ${input.editorKey}` });
|
|
@@ -5529,11 +5592,11 @@ var editorRouter = router({
|
|
|
5529
5592
|
);
|
|
5530
5593
|
return { success: true };
|
|
5531
5594
|
}),
|
|
5532
|
-
setServiceEditor: protectedProcedure.input(
|
|
5533
|
-
projectId:
|
|
5534
|
-
orgId:
|
|
5535
|
-
serviceId:
|
|
5536
|
-
editorKey:
|
|
5595
|
+
setServiceEditor: protectedProcedure.input(z14.object({
|
|
5596
|
+
projectId: z14.string().max(128),
|
|
5597
|
+
orgId: z14.string().max(128).nullable().optional(),
|
|
5598
|
+
serviceId: z14.string().max(128),
|
|
5599
|
+
editorKey: z14.string().max(64)
|
|
5537
5600
|
})).mutation(async ({ input }) => {
|
|
5538
5601
|
if (!EDITOR_BY_KEY.has(input.editorKey)) {
|
|
5539
5602
|
throw new TRPCError9({ code: "BAD_REQUEST", message: `Unknown editor: ${input.editorKey}` });
|
|
@@ -5545,10 +5608,10 @@ var editorRouter = router({
|
|
|
5545
5608
|
);
|
|
5546
5609
|
return { success: true };
|
|
5547
5610
|
}),
|
|
5548
|
-
removeServiceEditor: protectedProcedure.input(
|
|
5549
|
-
projectId:
|
|
5550
|
-
orgId:
|
|
5551
|
-
serviceId:
|
|
5611
|
+
removeServiceEditor: protectedProcedure.input(z14.object({
|
|
5612
|
+
projectId: z14.string().max(128),
|
|
5613
|
+
orgId: z14.string().max(128).nullable().optional(),
|
|
5614
|
+
serviceId: z14.string().max(128)
|
|
5552
5615
|
})).mutation(async ({ input }) => {
|
|
5553
5616
|
await userConfigManager.removeEditorPreference(
|
|
5554
5617
|
{ id: input.projectId, orgId: input.orgId },
|
|
@@ -5556,9 +5619,9 @@ var editorRouter = router({
|
|
|
5556
5619
|
);
|
|
5557
5620
|
return { success: true };
|
|
5558
5621
|
}),
|
|
5559
|
-
open: protectedProcedure.input(
|
|
5560
|
-
editorKey:
|
|
5561
|
-
path:
|
|
5622
|
+
open: protectedProcedure.input(z14.object({
|
|
5623
|
+
editorKey: z14.string().max(64),
|
|
5624
|
+
path: z14.string().max(4096)
|
|
5562
5625
|
})).mutation(async ({ input }) => {
|
|
5563
5626
|
const editor = EDITOR_BY_KEY.get(input.editorKey);
|
|
5564
5627
|
if (!editor) {
|
|
@@ -5581,10 +5644,10 @@ var editorRouter = router({
|
|
|
5581
5644
|
child.unref();
|
|
5582
5645
|
return { success: true };
|
|
5583
5646
|
}),
|
|
5584
|
-
openFile: protectedProcedure.input(
|
|
5585
|
-
editorKey:
|
|
5586
|
-
serviceId:
|
|
5587
|
-
relativePath:
|
|
5647
|
+
openFile: protectedProcedure.input(z14.object({
|
|
5648
|
+
editorKey: z14.string().max(64),
|
|
5649
|
+
serviceId: z14.string().max(128),
|
|
5650
|
+
relativePath: z14.string().max(4096)
|
|
5588
5651
|
})).mutation(async ({ input }) => {
|
|
5589
5652
|
const editor = EDITOR_BY_KEY.get(input.editorKey);
|
|
5590
5653
|
if (!editor) {
|
|
@@ -5612,7 +5675,7 @@ var editorRouter = router({
|
|
|
5612
5675
|
});
|
|
5613
5676
|
|
|
5614
5677
|
// ../server/src/trpc/routers/api-keys.ts
|
|
5615
|
-
import { z as
|
|
5678
|
+
import { z as z15 } from "zod";
|
|
5616
5679
|
import { TRPCError as TRPCError10 } from "@trpc/server";
|
|
5617
5680
|
import { mkdir as mkdir12, writeFile as writeFile12 } from "fs/promises";
|
|
5618
5681
|
import { join as join14, dirname as dirname7 } from "path";
|
|
@@ -5621,43 +5684,43 @@ var ALLOWED_SKILL_PATHS = /* @__PURE__ */ new Set([
|
|
|
5621
5684
|
".cursor/rules/runeya.mdc",
|
|
5622
5685
|
".windsurf/rules/runeya.md"
|
|
5623
5686
|
]);
|
|
5624
|
-
var KeyInputSchema =
|
|
5625
|
-
name:
|
|
5687
|
+
var KeyInputSchema = z15.object({
|
|
5688
|
+
name: z15.string().min(1).max(200),
|
|
5626
5689
|
scopes: ApiKeyScopeSchema,
|
|
5627
|
-
isPublic:
|
|
5690
|
+
isPublic: z15.boolean().default(false)
|
|
5628
5691
|
});
|
|
5629
5692
|
var apiKeysRouter = router({
|
|
5630
5693
|
list: protectedProcedure.query(() => apiKeyStore.list()),
|
|
5631
|
-
create: protectedProcedure.input(KeyInputSchema.extend({ orgId:
|
|
5694
|
+
create: protectedProcedure.input(KeyInputSchema.extend({ orgId: z15.string().min(1).max(128).nullable().optional() })).mutation(
|
|
5632
5695
|
({ input }) => apiKeyStore.create(input.name, input.scopes, input.isPublic, input.orgId ?? null)
|
|
5633
5696
|
),
|
|
5634
5697
|
/**
|
|
5635
5698
|
* Renvoie le secret d'une seule clé, sur demande explicite. `list` ne le
|
|
5636
5699
|
* contient pas : une clé ne doit jamais être re-servie en masse.
|
|
5637
5700
|
*/
|
|
5638
|
-
reveal: protectedProcedure.input(
|
|
5701
|
+
reveal: protectedProcedure.input(z15.object({ id: z15.string().max(128) })).query(async ({ input }) => {
|
|
5639
5702
|
const key = await apiKeyStore.reveal(input.id);
|
|
5640
5703
|
if (!key) throw new TRPCError10({ code: "NOT_FOUND", message: "API key not found" });
|
|
5641
5704
|
return { key };
|
|
5642
5705
|
}),
|
|
5643
|
-
update: protectedProcedure.input(KeyInputSchema.extend({ id:
|
|
5706
|
+
update: protectedProcedure.input(KeyInputSchema.extend({ id: z15.string().max(128) })).mutation(async ({ input }) => {
|
|
5644
5707
|
const updated = await apiKeyStore.update(input.id, input.name, input.scopes, input.isPublic);
|
|
5645
5708
|
if (!updated) throw new TRPCError10({ code: "NOT_FOUND", message: "API key not found" });
|
|
5646
5709
|
return maskApiKey(updated);
|
|
5647
5710
|
}),
|
|
5648
|
-
remove: protectedProcedure.input(
|
|
5711
|
+
remove: protectedProcedure.input(z15.object({ id: z15.string().max(128) })).mutation(async ({ input }) => {
|
|
5649
5712
|
const removed = await apiKeyStore.remove(input.id);
|
|
5650
5713
|
if (!removed) throw new TRPCError10({ code: "NOT_FOUND", message: "API key not found" });
|
|
5651
5714
|
return { success: true };
|
|
5652
5715
|
}),
|
|
5653
|
-
renewKey: protectedProcedure.input(
|
|
5716
|
+
renewKey: protectedProcedure.input(z15.object({ id: z15.string().max(128) })).mutation(async ({ input }) => {
|
|
5654
5717
|
const renewed = await apiKeyStore.renewKey(input.id);
|
|
5655
5718
|
if (!renewed) throw new TRPCError10({ code: "NOT_FOUND", message: "API key not found" });
|
|
5656
5719
|
return renewed;
|
|
5657
5720
|
}),
|
|
5658
|
-
writeSkillFile: protectedProcedure.input(
|
|
5659
|
-
relativePath:
|
|
5660
|
-
content:
|
|
5721
|
+
writeSkillFile: protectedProcedure.input(z15.object({
|
|
5722
|
+
relativePath: z15.string().max(256),
|
|
5723
|
+
content: z15.string().max(32768)
|
|
5661
5724
|
})).mutation(async ({ input }) => {
|
|
5662
5725
|
if (!ALLOWED_SKILL_PATHS.has(input.relativePath)) {
|
|
5663
5726
|
throw new TRPCError10({ code: "BAD_REQUEST", message: "Chemin non autoris\xE9" });
|
|
@@ -5670,7 +5733,7 @@ var apiKeysRouter = router({
|
|
|
5670
5733
|
});
|
|
5671
5734
|
|
|
5672
5735
|
// ../server/src/trpc/routers/chat.ts
|
|
5673
|
-
import { z as
|
|
5736
|
+
import { z as z18 } from "zod";
|
|
5674
5737
|
import Anthropic2 from "@anthropic-ai/sdk";
|
|
5675
5738
|
import OpenAI2 from "openai";
|
|
5676
5739
|
import { execFile as execFile4 } from "child_process";
|
|
@@ -6343,12 +6406,12 @@ async function codexSessionExists(sessionId) {
|
|
|
6343
6406
|
import { TRPCError as TRPCError12 } from "@trpc/server";
|
|
6344
6407
|
|
|
6345
6408
|
// ../server/src/trpc/shared-schemas.ts
|
|
6346
|
-
import { z as
|
|
6347
|
-
var Id128Schema =
|
|
6348
|
-
var ConversationIdSchema =
|
|
6349
|
-
var NameSchema =
|
|
6350
|
-
var ShortString200Schema =
|
|
6351
|
-
var DescriptionSchema =
|
|
6409
|
+
import { z as z16 } from "zod";
|
|
6410
|
+
var Id128Schema = z16.string().max(128);
|
|
6411
|
+
var ConversationIdSchema = z16.string().max(128);
|
|
6412
|
+
var NameSchema = z16.string().min(1).max(200);
|
|
6413
|
+
var ShortString200Schema = z16.string().max(200);
|
|
6414
|
+
var DescriptionSchema = z16.string().max(2e3);
|
|
6352
6415
|
var OptionalProviderIdSchema = Id128Schema.optional();
|
|
6353
6416
|
|
|
6354
6417
|
// ../server/src/services/llms-txt-generator.ts
|
|
@@ -7722,7 +7785,7 @@ async function resolveImagesToBase64(images, contextId) {
|
|
|
7722
7785
|
}
|
|
7723
7786
|
|
|
7724
7787
|
// ../server/src/trpc/routers/cloud-auth.ts
|
|
7725
|
-
import { z as
|
|
7788
|
+
import { z as z17 } from "zod";
|
|
7726
7789
|
import { hostname } from "os";
|
|
7727
7790
|
import { basename } from "path";
|
|
7728
7791
|
import { TRPCError as TRPCError11 } from "@trpc/server";
|
|
@@ -7767,7 +7830,7 @@ function isAllowedProxyPath(path) {
|
|
|
7767
7830
|
}
|
|
7768
7831
|
var cloudAuthRouter = router({
|
|
7769
7832
|
/** Build the cloud authorization URL to open in the browser. */
|
|
7770
|
-
startLogin: protectedProcedure.input(
|
|
7833
|
+
startLogin: protectedProcedure.input(z17.object({ returnTo: z17.string().url().max(2048) })).mutation(async ({ input }) => {
|
|
7771
7834
|
const callback = callbackForReturnTo(input.returnTo);
|
|
7772
7835
|
if (!callback) {
|
|
7773
7836
|
throw new TRPCError11({
|
|
@@ -7815,7 +7878,7 @@ var cloudAuthRouter = router({
|
|
|
7815
7878
|
* drops the session, and the local token is dropped here too, so nothing is
|
|
7816
7879
|
* left holding a dead credential.
|
|
7817
7880
|
*/
|
|
7818
|
-
revokeDevice: protectedProcedure.input(
|
|
7881
|
+
revokeDevice: protectedProcedure.input(z17.object({ id: z17.string().min(1).max(128) })).mutation(async ({ input }) => {
|
|
7819
7882
|
const res = await cloudFetch2("/api/auth/device/revoke", { method: "POST", body: { id: input.id } });
|
|
7820
7883
|
if (!res.ok) {
|
|
7821
7884
|
if (res.status === 401) await cloudSessionStore.clear();
|
|
@@ -7832,11 +7895,11 @@ var cloudAuthRouter = router({
|
|
|
7832
7895
|
* the cloud: the web UI asks its own server, which holds the credential.
|
|
7833
7896
|
*/
|
|
7834
7897
|
proxy: protectedProcedure.input(
|
|
7835
|
-
|
|
7836
|
-
path:
|
|
7837
|
-
method:
|
|
7838
|
-
query:
|
|
7839
|
-
body:
|
|
7898
|
+
z17.object({
|
|
7899
|
+
path: z17.string().min(1).max(512),
|
|
7900
|
+
method: z17.enum(["GET", "POST"]).default("GET"),
|
|
7901
|
+
query: z17.record(z17.string().max(128), z17.string().max(2048)).optional(),
|
|
7902
|
+
body: z17.unknown().optional()
|
|
7840
7903
|
})
|
|
7841
7904
|
).mutation(async ({ input }) => {
|
|
7842
7905
|
if (!isAllowedProxyPath(input.path)) {
|
|
@@ -8545,7 +8608,7 @@ function tailTranscript(opts) {
|
|
|
8545
8608
|
|
|
8546
8609
|
// ../server/src/services/ai-runners/claude-pty-runner.ts
|
|
8547
8610
|
async function getAgentManager() {
|
|
8548
|
-
const { agentManager: agentManager2 } = await import("./agent-manager-
|
|
8611
|
+
const { agentManager: agentManager2 } = await import("./agent-manager-3KSS7BHP.js");
|
|
8549
8612
|
return agentManager2;
|
|
8550
8613
|
}
|
|
8551
8614
|
function buildPtyArgs(params, sessionId, opts) {
|
|
@@ -8980,6 +9043,7 @@ var ClaudeCodeRunner = class {
|
|
|
8980
9043
|
});
|
|
8981
9044
|
params.onCommand?.(`claude ${displayArgs.join(" ")}`);
|
|
8982
9045
|
const proc = spawn3("claude", args, {
|
|
9046
|
+
windowsHide: true,
|
|
8983
9047
|
stdio: ["pipe", "pipe", "pipe"],
|
|
8984
9048
|
shell: false,
|
|
8985
9049
|
env: env2
|
|
@@ -9128,6 +9192,7 @@ var CodexAppServerClient = class extends EventEmitter3 {
|
|
|
9128
9192
|
async connect(runeyaEnv) {
|
|
9129
9193
|
const env2 = { ...process.env, ...runeyaEnv };
|
|
9130
9194
|
this.proc = spawn4("codex", [...resolveMcpArgs(env2), "app-server"], {
|
|
9195
|
+
windowsHide: true,
|
|
9131
9196
|
stdio: ["pipe", "pipe", "pipe"],
|
|
9132
9197
|
env: env2
|
|
9133
9198
|
});
|
|
@@ -9286,7 +9351,7 @@ async function shutdownCodexAppServer() {
|
|
|
9286
9351
|
}
|
|
9287
9352
|
}
|
|
9288
9353
|
async function getAgentManager2() {
|
|
9289
|
-
const { agentManager: agentManager2 } = await import("./agent-manager-
|
|
9354
|
+
const { agentManager: agentManager2 } = await import("./agent-manager-3KSS7BHP.js");
|
|
9290
9355
|
return agentManager2;
|
|
9291
9356
|
}
|
|
9292
9357
|
function parseRuneyaCurlCommand(command) {
|
|
@@ -9727,18 +9792,18 @@ ${prompt}`;
|
|
|
9727
9792
|
|
|
9728
9793
|
// ../server/src/trpc/routers/chat.ts
|
|
9729
9794
|
var execFileAsync3 = promisify3(execFile4);
|
|
9730
|
-
var MessageSchema =
|
|
9731
|
-
role:
|
|
9732
|
-
content:
|
|
9795
|
+
var MessageSchema = z18.object({
|
|
9796
|
+
role: z18.enum(["user", "assistant"]),
|
|
9797
|
+
content: z18.string().max(1e5)
|
|
9733
9798
|
});
|
|
9734
|
-
var ImagePartSchema =
|
|
9735
|
-
type:
|
|
9736
|
-
imageId:
|
|
9737
|
-
url:
|
|
9738
|
-
mimeType:
|
|
9739
|
-
altText:
|
|
9799
|
+
var ImagePartSchema = z18.object({
|
|
9800
|
+
type: z18.literal("image"),
|
|
9801
|
+
imageId: z18.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
|
|
9802
|
+
url: z18.string().max(500),
|
|
9803
|
+
mimeType: z18.string().max(100),
|
|
9804
|
+
altText: z18.string().max(500).optional()
|
|
9740
9805
|
});
|
|
9741
|
-
var ImagePartsSchema =
|
|
9806
|
+
var ImagePartsSchema = z18.array(ImagePartSchema).max(5).optional();
|
|
9742
9807
|
var LANGUAGE_INSTRUCTION = "Always respond in the same language the user writes in.";
|
|
9743
9808
|
async function buildSystemPrompt(apiKey) {
|
|
9744
9809
|
const allServices = await serviceStore.list();
|
|
@@ -10125,24 +10190,24 @@ async function startCodexSession(convId, prompt, opts = {}) {
|
|
|
10125
10190
|
});
|
|
10126
10191
|
return { session, done };
|
|
10127
10192
|
}
|
|
10128
|
-
var MessagePartSchema =
|
|
10129
|
-
|
|
10130
|
-
|
|
10131
|
-
|
|
10132
|
-
type:
|
|
10193
|
+
var MessagePartSchema = z18.discriminatedUnion("type", [
|
|
10194
|
+
z18.object({ type: z18.literal("thinking"), text: z18.string().max(1e5) }),
|
|
10195
|
+
z18.object({ type: z18.literal("text"), text: z18.string().max(1e5) }),
|
|
10196
|
+
z18.object({
|
|
10197
|
+
type: z18.literal("tool"),
|
|
10133
10198
|
id: Id128Schema,
|
|
10134
10199
|
name: Id128Schema,
|
|
10135
|
-
input:
|
|
10136
|
-
rawInput:
|
|
10137
|
-
result:
|
|
10138
|
-
isError:
|
|
10139
|
-
pending:
|
|
10200
|
+
input: z18.record(z18.string(), z18.unknown()).optional(),
|
|
10201
|
+
rawInput: z18.string().max(1e4).optional(),
|
|
10202
|
+
result: z18.unknown().optional(),
|
|
10203
|
+
isError: z18.boolean().optional(),
|
|
10204
|
+
pending: z18.boolean()
|
|
10140
10205
|
})
|
|
10141
10206
|
]);
|
|
10142
|
-
var StoredMessageSchema =
|
|
10143
|
-
role:
|
|
10144
|
-
content:
|
|
10145
|
-
parts:
|
|
10207
|
+
var StoredMessageSchema = z18.object({
|
|
10208
|
+
role: z18.enum(["user", "assistant"]),
|
|
10209
|
+
content: z18.string().max(1e5),
|
|
10210
|
+
parts: z18.array(MessagePartSchema).max(200).optional()
|
|
10146
10211
|
});
|
|
10147
10212
|
async function conversationCwd(conv) {
|
|
10148
10213
|
return resolveConversationCwd(conv.id);
|
|
@@ -10156,7 +10221,7 @@ var chatRouter = router({
|
|
|
10156
10221
|
* et sans le même filtre il y reversait toutes les conversations de la
|
|
10157
10222
|
* machine, une seconde après un chargement pourtant filtré.
|
|
10158
10223
|
*/
|
|
10159
|
-
onChanged: protectedProcedure.input(
|
|
10224
|
+
onChanged: protectedProcedure.input(z18.object({
|
|
10160
10225
|
projectId: Id128Schema.optional(),
|
|
10161
10226
|
orgId: Id128Schema.nullable().optional()
|
|
10162
10227
|
}).optional()).subscription(async function* ({ input }) {
|
|
@@ -10204,7 +10269,7 @@ var chatRouter = router({
|
|
|
10204
10269
|
* reachable where they were written, without leaking into every other
|
|
10205
10270
|
* organization's projects.
|
|
10206
10271
|
*/
|
|
10207
|
-
list: protectedProcedure.input(
|
|
10272
|
+
list: protectedProcedure.input(z18.object({
|
|
10208
10273
|
projectId: Id128Schema.optional(),
|
|
10209
10274
|
orgId: Id128Schema.nullable().optional()
|
|
10210
10275
|
}).optional()).query(async ({ input }) => {
|
|
@@ -10212,24 +10277,24 @@ var chatRouter = router({
|
|
|
10212
10277
|
if (!projectId) return conversationStore.list();
|
|
10213
10278
|
return conversationStore.listForProject({ id: projectId, orgId: input?.orgId });
|
|
10214
10279
|
}),
|
|
10215
|
-
get: protectedProcedure.input(
|
|
10280
|
+
get: protectedProcedure.input(z18.object({ id: Id128Schema })).query(async ({ input }) => {
|
|
10216
10281
|
const conv = await conversationStore.get(input.id);
|
|
10217
10282
|
if (!conv) throw new TRPCError12({ code: "NOT_FOUND", message: "Conversation not found" });
|
|
10218
10283
|
return conv;
|
|
10219
10284
|
}),
|
|
10220
|
-
create: protectedProcedure.input(
|
|
10285
|
+
create: protectedProcedure.input(z18.object({
|
|
10221
10286
|
title: ShortString200Schema.optional(),
|
|
10222
|
-
isCli:
|
|
10223
|
-
runner:
|
|
10287
|
+
isCli: z18.boolean().optional(),
|
|
10288
|
+
runner: z18.enum(["claude-code", "codex"]).optional(),
|
|
10224
10289
|
providerId: Id128Schema.optional(),
|
|
10225
10290
|
scenarioId: Id128Schema.optional(),
|
|
10226
|
-
scenarioInput:
|
|
10291
|
+
scenarioInput: z18.string().max(1e5).optional(),
|
|
10227
10292
|
kanbanBoardId: Id128Schema.optional(),
|
|
10228
10293
|
kanbanCardId: Id128Schema.optional(),
|
|
10229
10294
|
// The project the conversation is about: only the caller knows which
|
|
10230
10295
|
// one it is looking at.
|
|
10231
10296
|
projectId: Id128Schema.optional(),
|
|
10232
|
-
orgId:
|
|
10297
|
+
orgId: z18.string().max(128).nullable().optional()
|
|
10233
10298
|
})).mutation(async ({ input }) => {
|
|
10234
10299
|
let scenario = null;
|
|
10235
10300
|
if (input.scenarioId) {
|
|
@@ -10260,20 +10325,20 @@ var chatRouter = router({
|
|
|
10260
10325
|
}
|
|
10261
10326
|
return conv;
|
|
10262
10327
|
}),
|
|
10263
|
-
update: protectedProcedure.input(
|
|
10328
|
+
update: protectedProcedure.input(z18.object({
|
|
10264
10329
|
id: Id128Schema,
|
|
10265
10330
|
title: ShortString200Schema.optional(),
|
|
10266
|
-
messages:
|
|
10267
|
-
contextUsage:
|
|
10268
|
-
inputTokens:
|
|
10269
|
-
contextWindow:
|
|
10331
|
+
messages: z18.array(StoredMessageSchema).max(500).optional(),
|
|
10332
|
+
contextUsage: z18.object({
|
|
10333
|
+
inputTokens: z18.number().int().nonnegative(),
|
|
10334
|
+
contextWindow: z18.number().int().positive()
|
|
10270
10335
|
}).optional()
|
|
10271
10336
|
})).mutation(async ({ input }) => {
|
|
10272
10337
|
const conv = await conversationStore.update(input.id, { title: input.title, messages: input.messages, contextUsage: input.contextUsage });
|
|
10273
10338
|
if (!conv) throw new TRPCError12({ code: "NOT_FOUND", message: "Conversation not found" });
|
|
10274
10339
|
return conv;
|
|
10275
10340
|
}),
|
|
10276
|
-
delete: protectedProcedure.input(
|
|
10341
|
+
delete: protectedProcedure.input(z18.object({ id: Id128Schema })).mutation(async ({ input }) => {
|
|
10277
10342
|
const existing = await conversationStore.get(input.id);
|
|
10278
10343
|
if (!existing) throw new TRPCError12({ code: "NOT_FOUND", message: "Conversation not found" });
|
|
10279
10344
|
for (const agent of agentManager.listAgents()) {
|
|
@@ -10295,18 +10360,18 @@ var chatRouter = router({
|
|
|
10295
10360
|
(err) => console.error("[chat.delete] Image cleanup error:", err)
|
|
10296
10361
|
);
|
|
10297
10362
|
}),
|
|
10298
|
-
archive: protectedProcedure.input(
|
|
10363
|
+
archive: protectedProcedure.input(z18.object({ id: Id128Schema, archived: z18.boolean() })).mutation(async ({ input }) => {
|
|
10299
10364
|
const conv = await conversationStore.update(input.id, { archived: input.archived });
|
|
10300
10365
|
if (!conv) throw new TRPCError12({ code: "NOT_FOUND", message: "Conversation not found" });
|
|
10301
10366
|
return conv;
|
|
10302
10367
|
})
|
|
10303
10368
|
}),
|
|
10304
|
-
listModels: protectedProcedure.input(
|
|
10369
|
+
listModels: protectedProcedure.input(z18.object({
|
|
10305
10370
|
providerId: Id128Schema.optional(),
|
|
10306
10371
|
// Le projet dit de quelle organisation lire les fournisseurs ; absent,
|
|
10307
10372
|
// ce sont ceux du poste.
|
|
10308
10373
|
projectId: Id128Schema.optional(),
|
|
10309
|
-
orgId:
|
|
10374
|
+
orgId: z18.string().max(128).nullable().optional()
|
|
10310
10375
|
}).optional()).query(async ({ input }) => {
|
|
10311
10376
|
const active = await getActiveProvider(
|
|
10312
10377
|
input?.providerId,
|
|
@@ -10319,7 +10384,7 @@ var chatRouter = router({
|
|
|
10319
10384
|
return [];
|
|
10320
10385
|
}
|
|
10321
10386
|
}),
|
|
10322
|
-
checkCliAvailability: protectedProcedure.input(
|
|
10387
|
+
checkCliAvailability: protectedProcedure.input(z18.object({ agentId: Id128Schema.optional() }).optional()).query(async ({ input }) => {
|
|
10323
10388
|
if (input?.agentId) {
|
|
10324
10389
|
try {
|
|
10325
10390
|
const res = await agentManager.agentQuery(
|
|
@@ -10332,17 +10397,17 @@ var chatRouter = router({
|
|
|
10332
10397
|
}
|
|
10333
10398
|
}
|
|
10334
10399
|
const [claudeOk, codexOk] = await Promise.all([
|
|
10335
|
-
execFileAsync3("claude", ["--version"], { timeout: 5e3, shell: false }).then(() => true).catch(() => false),
|
|
10336
|
-
execFileAsync3("codex", ["--version"], { timeout: 5e3, shell: false }).then(() => true).catch(() => false)
|
|
10400
|
+
execFileAsync3("claude", ["--version"], { timeout: 5e3, shell: false, windowsHide: true }).then(() => true).catch(() => false),
|
|
10401
|
+
execFileAsync3("codex", ["--version"], { timeout: 5e3, shell: false, windowsHide: true }).then(() => true).catch(() => false)
|
|
10337
10402
|
]);
|
|
10338
10403
|
return { available: claudeOk, codexAvailable: codexOk };
|
|
10339
10404
|
}),
|
|
10340
|
-
enhanceScenarioPrompt: protectedProcedure.input(
|
|
10341
|
-
text:
|
|
10405
|
+
enhanceScenarioPrompt: protectedProcedure.input(z18.object({
|
|
10406
|
+
text: z18.string().max(1e4),
|
|
10342
10407
|
providerId: Id128Schema.optional(),
|
|
10343
|
-
model:
|
|
10408
|
+
model: z18.string().max(200).optional(),
|
|
10344
10409
|
projectId: Id128Schema.optional(),
|
|
10345
|
-
orgId:
|
|
10410
|
+
orgId: z18.string().max(128).nullable().optional()
|
|
10346
10411
|
})).mutation(async ({ input }) => {
|
|
10347
10412
|
const active = await getActiveProvider(
|
|
10348
10413
|
input.providerId,
|
|
@@ -10399,22 +10464,22 @@ Return ONLY the improved text, no explanation, no preamble.`;
|
|
|
10399
10464
|
}
|
|
10400
10465
|
}),
|
|
10401
10466
|
getStreamingStatus: protectedProcedure.query(() => activeSessionRegistry.listActive()),
|
|
10402
|
-
stopSession: protectedProcedure.input(
|
|
10467
|
+
stopSession: protectedProcedure.input(z18.object({ conversationId: ConversationIdSchema })).mutation(({ input }) => {
|
|
10403
10468
|
if (process.env.RUNEYA_DEBUG) console.log("[chat]: stopSession");
|
|
10404
10469
|
const killed = activeSessionRegistry.kill(input.conversationId);
|
|
10405
10470
|
if (!killed) throw new TRPCError12({ code: "NOT_FOUND", message: "No active session for this conversation" });
|
|
10406
10471
|
return { ok: true };
|
|
10407
10472
|
}),
|
|
10408
|
-
streamViaClaudeCode: protectedProcedure.input(
|
|
10473
|
+
streamViaClaudeCode: protectedProcedure.input(z18.object({
|
|
10409
10474
|
conversationId: ConversationIdSchema,
|
|
10410
|
-
prompt:
|
|
10411
|
-
contextNote:
|
|
10475
|
+
prompt: z18.string().max(1e5),
|
|
10476
|
+
contextNote: z18.string().max(2e5).optional(),
|
|
10412
10477
|
model: ShortString200Schema.optional(),
|
|
10413
|
-
effort:
|
|
10414
|
-
reconnect:
|
|
10478
|
+
effort: z18.enum(["low", "medium", "high"]).optional(),
|
|
10479
|
+
reconnect: z18.boolean().optional(),
|
|
10415
10480
|
agentId: Id128Schema.optional(),
|
|
10416
|
-
environmentId:
|
|
10417
|
-
imageIds:
|
|
10481
|
+
environmentId: z18.string().max(128).optional(),
|
|
10482
|
+
imageIds: z18.array(z18.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(),
|
|
10418
10483
|
imageParts: ImagePartsSchema
|
|
10419
10484
|
})).subscription(async function* ({ input, ctx, signal }) {
|
|
10420
10485
|
if (process.env.RUNEYA_DEBUG) console.log("[chat]: Reconnect");
|
|
@@ -10525,15 +10590,15 @@ ${imagePaths.map((p) => `Image: ${p}`).join("\n")}` : cliPrompt;
|
|
|
10525
10590
|
if (process.env.RUNEYA_DEBUG) console.log("[chat]: drainSession...");
|
|
10526
10591
|
yield* drainSession(session, signal, false);
|
|
10527
10592
|
}),
|
|
10528
|
-
streamViaCodex: protectedProcedure.input(
|
|
10593
|
+
streamViaCodex: protectedProcedure.input(z18.object({
|
|
10529
10594
|
conversationId: ConversationIdSchema,
|
|
10530
|
-
prompt:
|
|
10531
|
-
contextNote:
|
|
10595
|
+
prompt: z18.string().max(1e5),
|
|
10596
|
+
contextNote: z18.string().max(2e5).optional(),
|
|
10532
10597
|
model: ShortString200Schema.optional(),
|
|
10533
|
-
reconnect:
|
|
10598
|
+
reconnect: z18.boolean().optional(),
|
|
10534
10599
|
agentId: Id128Schema.optional(),
|
|
10535
|
-
environmentId:
|
|
10536
|
-
imageIds:
|
|
10600
|
+
environmentId: z18.string().max(128).optional(),
|
|
10601
|
+
imageIds: z18.array(z18.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(),
|
|
10537
10602
|
imageParts: ImagePartsSchema
|
|
10538
10603
|
})).subscription(async function* ({ input, ctx, signal }) {
|
|
10539
10604
|
const existingSession = activeSessionRegistry.get(input.conversationId);
|
|
@@ -10611,13 +10676,13 @@ ${input.prompt}` : input.prompt;
|
|
|
10611
10676
|
});
|
|
10612
10677
|
yield* drainSession(session, signal, false);
|
|
10613
10678
|
}),
|
|
10614
|
-
send: protectedProcedure.input(
|
|
10679
|
+
send: protectedProcedure.input(z18.object({
|
|
10615
10680
|
conversationId: ConversationIdSchema,
|
|
10616
|
-
messages:
|
|
10681
|
+
messages: z18.array(MessageSchema).min(0).max(100),
|
|
10617
10682
|
model: ShortString200Schema.optional(),
|
|
10618
|
-
contextNote:
|
|
10619
|
-
reconnect:
|
|
10620
|
-
imageIds:
|
|
10683
|
+
contextNote: z18.string().max(2e5).optional(),
|
|
10684
|
+
reconnect: z18.boolean().optional(),
|
|
10685
|
+
imageIds: z18.array(z18.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(),
|
|
10621
10686
|
imageParts: ImagePartsSchema
|
|
10622
10687
|
})).subscription(async function* ({ input, ctx, signal }) {
|
|
10623
10688
|
const existingSession = activeSessionRegistry.get(input.conversationId);
|
|
@@ -10735,25 +10800,25 @@ ${input.prompt}` : input.prompt;
|
|
|
10735
10800
|
// ── PTY passthrough (interactive Claude Code session) ────────────────────
|
|
10736
10801
|
pty: router({
|
|
10737
10802
|
/** Start a PTY session running `claude --resume <sessionId>` (or fresh). */
|
|
10738
|
-
start: protectedProcedure.input(
|
|
10739
|
-
agentId:
|
|
10740
|
-
sessionId:
|
|
10741
|
-
runner:
|
|
10742
|
-
resume:
|
|
10743
|
-
model:
|
|
10744
|
-
cwd:
|
|
10803
|
+
start: protectedProcedure.input(z18.object({
|
|
10804
|
+
agentId: z18.string().max(128).optional(),
|
|
10805
|
+
sessionId: z18.string().max(128).optional(),
|
|
10806
|
+
runner: z18.enum(["claude-code", "codex"]).default("claude-code"),
|
|
10807
|
+
resume: z18.boolean().default(false),
|
|
10808
|
+
model: z18.string().max(128).optional(),
|
|
10809
|
+
cwd: z18.string().max(4096).optional(),
|
|
10745
10810
|
/** Anchors the session when no explicit cwd is given. */
|
|
10746
|
-
serviceId:
|
|
10811
|
+
serviceId: z18.string().max(128).optional(),
|
|
10747
10812
|
projectId: Id128Schema.optional(),
|
|
10748
|
-
orgId:
|
|
10749
|
-
cols:
|
|
10750
|
-
rows:
|
|
10751
|
-
enableMcp:
|
|
10752
|
-
apiBaseUrl:
|
|
10753
|
-
environmentId:
|
|
10754
|
-
attachedContexts:
|
|
10755
|
-
label:
|
|
10756
|
-
text:
|
|
10813
|
+
orgId: z18.string().max(128).nullable().optional(),
|
|
10814
|
+
cols: z18.number().int().min(1).max(1e3).default(120),
|
|
10815
|
+
rows: z18.number().int().min(1).max(1e3).default(30),
|
|
10816
|
+
enableMcp: z18.boolean().default(false),
|
|
10817
|
+
apiBaseUrl: z18.string().max(512).optional(),
|
|
10818
|
+
environmentId: z18.string().max(128).optional(),
|
|
10819
|
+
attachedContexts: z18.array(z18.object({
|
|
10820
|
+
label: z18.string().max(200),
|
|
10821
|
+
text: z18.string().max(1e6)
|
|
10757
10822
|
})).max(20).optional()
|
|
10758
10823
|
})).mutation(async ({ input, ctx }) => {
|
|
10759
10824
|
const t0 = Date.now();
|
|
@@ -10912,10 +10977,10 @@ Context:
|
|
|
10912
10977
|
return { spawnId: res.spawnId, agentId, reattached: false };
|
|
10913
10978
|
}),
|
|
10914
10979
|
/** Subscribe to PTY output stream (raw text with ANSI). */
|
|
10915
|
-
stream: protectedProcedure.input(
|
|
10916
|
-
agentId:
|
|
10917
|
-
spawnId:
|
|
10918
|
-
fromOffset:
|
|
10980
|
+
stream: protectedProcedure.input(z18.object({
|
|
10981
|
+
agentId: z18.string().max(128).optional(),
|
|
10982
|
+
spawnId: z18.string().max(128),
|
|
10983
|
+
fromOffset: z18.number().int().min(0).default(0)
|
|
10919
10984
|
})).subscription(async function* ({ input, signal }) {
|
|
10920
10985
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10921
10986
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10967,10 +11032,10 @@ Context:
|
|
|
10967
11032
|
}
|
|
10968
11033
|
}),
|
|
10969
11034
|
/** Write input to a PTY session (keystrokes from xterm). */
|
|
10970
|
-
write: protectedProcedure.input(
|
|
10971
|
-
agentId:
|
|
10972
|
-
spawnId:
|
|
10973
|
-
data:
|
|
11035
|
+
write: protectedProcedure.input(z18.object({
|
|
11036
|
+
agentId: z18.string().max(128).optional(),
|
|
11037
|
+
spawnId: z18.string().max(128),
|
|
11038
|
+
data: z18.string().max(1e6)
|
|
10974
11039
|
})).mutation(async ({ input }) => {
|
|
10975
11040
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10976
11041
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10980,11 +11045,11 @@ Context:
|
|
|
10980
11045
|
});
|
|
10981
11046
|
}),
|
|
10982
11047
|
/** Resize a PTY session. */
|
|
10983
|
-
resize: protectedProcedure.input(
|
|
10984
|
-
agentId:
|
|
10985
|
-
spawnId:
|
|
10986
|
-
cols:
|
|
10987
|
-
rows:
|
|
11048
|
+
resize: protectedProcedure.input(z18.object({
|
|
11049
|
+
agentId: z18.string().max(128).optional(),
|
|
11050
|
+
spawnId: z18.string().max(128),
|
|
11051
|
+
cols: z18.number().int().min(1).max(1e3),
|
|
11052
|
+
rows: z18.number().int().min(1).max(1e3)
|
|
10988
11053
|
})).mutation(async ({ input }) => {
|
|
10989
11054
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10990
11055
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -11000,11 +11065,11 @@ Context:
|
|
|
11000
11065
|
* picks it up. Returns the tmp path and which clipboard method succeeded
|
|
11001
11066
|
* (null if none — caller should inject `@<path>` instead of Ctrl+V).
|
|
11002
11067
|
*/
|
|
11003
|
-
pasteImage: protectedProcedure.input(
|
|
11004
|
-
agentId:
|
|
11005
|
-
sessionId:
|
|
11006
|
-
mimeType:
|
|
11007
|
-
base64:
|
|
11068
|
+
pasteImage: protectedProcedure.input(z18.object({
|
|
11069
|
+
agentId: z18.string().max(128).optional(),
|
|
11070
|
+
sessionId: z18.string().max(128).optional(),
|
|
11071
|
+
mimeType: z18.string().max(64),
|
|
11072
|
+
base64: z18.string().max(15e6)
|
|
11008
11073
|
})).mutation(async ({ input }) => {
|
|
11009
11074
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
11010
11075
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -11022,7 +11087,7 @@ Context:
|
|
|
11022
11087
|
* Read the transcript Claude Code stores on disk for a given session.
|
|
11023
11088
|
* Returns parsed JSONL entries (user / assistant messages, tool uses, etc.).
|
|
11024
11089
|
*/
|
|
11025
|
-
transcript: protectedProcedure.input(
|
|
11090
|
+
transcript: protectedProcedure.input(z18.object({ sessionId: z18.string().max(128) })).query(async ({ input }) => {
|
|
11026
11091
|
return readClaudeTranscript(input.sessionId);
|
|
11027
11092
|
}),
|
|
11028
11093
|
/**
|
|
@@ -11030,9 +11095,9 @@ Context:
|
|
|
11030
11095
|
* when was the transcript JSONL last touched? Used by the non-PTY view
|
|
11031
11096
|
* to show a "Claude is thinking…" indicator while output streams.
|
|
11032
11097
|
*/
|
|
11033
|
-
activity: protectedProcedure.input(
|
|
11034
|
-
agentId:
|
|
11035
|
-
sessionId:
|
|
11098
|
+
activity: protectedProcedure.input(z18.object({
|
|
11099
|
+
agentId: z18.string().max(128).optional(),
|
|
11100
|
+
sessionId: z18.string().max(128)
|
|
11036
11101
|
})).query(async ({ input }) => {
|
|
11037
11102
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
11038
11103
|
let running = false;
|
|
@@ -11058,7 +11123,7 @@ Context:
|
|
|
11058
11123
|
* them on the conversation, so the non-PTY chat view stays in sync.
|
|
11059
11124
|
* Uses the conversation id as session id (PTY sessions are spawned that way).
|
|
11060
11125
|
*/
|
|
11061
|
-
syncTranscript: protectedProcedure.input(
|
|
11126
|
+
syncTranscript: protectedProcedure.input(z18.object({ conversationId: ConversationIdSchema })).mutation(async ({ input }) => {
|
|
11062
11127
|
const conv = await conversationStore.get(input.conversationId);
|
|
11063
11128
|
if (!conv) {
|
|
11064
11129
|
throw new TRPCError12({ code: "NOT_FOUND", message: `Conversation ${input.conversationId} not found` });
|
|
@@ -11072,14 +11137,14 @@ Context:
|
|
|
11072
11137
|
* with the given sessionId. Used to benchmark the PTY → tRPC → xterm.js
|
|
11073
11138
|
* pipeline. Open the conversation in PTY mode to attach to it.
|
|
11074
11139
|
*/
|
|
11075
|
-
debugStress: protectedProcedure.input(
|
|
11076
|
-
sessionId:
|
|
11077
|
-
agentId:
|
|
11078
|
-
bytesPerSec:
|
|
11079
|
-
chunkSize:
|
|
11080
|
-
durationMs:
|
|
11081
|
-
cols:
|
|
11082
|
-
rows:
|
|
11140
|
+
debugStress: protectedProcedure.input(z18.object({
|
|
11141
|
+
sessionId: z18.string().max(128),
|
|
11142
|
+
agentId: z18.string().max(128).optional(),
|
|
11143
|
+
bytesPerSec: z18.number().int().min(100).max(1e7).default(5e4),
|
|
11144
|
+
chunkSize: z18.number().int().min(1).max(65536).default(256),
|
|
11145
|
+
durationMs: z18.number().int().min(0).max(36e5).default(0),
|
|
11146
|
+
cols: z18.number().int().min(1).max(1e3).default(120),
|
|
11147
|
+
rows: z18.number().int().min(1).max(1e3).default(30)
|
|
11083
11148
|
})).mutation(async ({ input }) => {
|
|
11084
11149
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
11085
11150
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -11126,9 +11191,9 @@ Context:
|
|
|
11126
11191
|
return { spawnId: res.spawnId, agentId, stressSessionId };
|
|
11127
11192
|
}),
|
|
11128
11193
|
/** Kill a PTY session. */
|
|
11129
|
-
kill: protectedProcedure.input(
|
|
11130
|
-
agentId:
|
|
11131
|
-
spawnId:
|
|
11194
|
+
kill: protectedProcedure.input(z18.object({
|
|
11195
|
+
agentId: z18.string().max(128).optional(),
|
|
11196
|
+
spawnId: z18.string().max(128)
|
|
11132
11197
|
})).mutation(async ({ input }) => {
|
|
11133
11198
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
11134
11199
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -11140,16 +11205,16 @@ Context:
|
|
|
11140
11205
|
});
|
|
11141
11206
|
|
|
11142
11207
|
// ../server/src/trpc/routers/git.ts
|
|
11143
|
-
import { z as
|
|
11208
|
+
import { z as z19 } from "zod";
|
|
11144
11209
|
import { TRPCError as TRPCError13 } from "@trpc/server";
|
|
11145
11210
|
import Anthropic3 from "@anthropic-ai/sdk";
|
|
11146
11211
|
import OpenAI3 from "openai";
|
|
11147
|
-
var SERVICE_ID_SCHEMA =
|
|
11148
|
-
var SAFE_PATH_SCHEMA =
|
|
11212
|
+
var SERVICE_ID_SCHEMA = z19.string().max(128);
|
|
11213
|
+
var SAFE_PATH_SCHEMA = z19.string().min(1).max(4096).refine((p) => !p.startsWith("/") && !p.includes("../"), {
|
|
11149
11214
|
message: "Path must be relative and not traverse up"
|
|
11150
11215
|
});
|
|
11151
|
-
var REMOTE_SCHEMA =
|
|
11152
|
-
var BRANCH_SCHEMA =
|
|
11216
|
+
var REMOTE_SCHEMA = z19.string().min(1).max(128).regex(/^[a-zA-Z0-9_\-.]+$/);
|
|
11217
|
+
var BRANCH_SCHEMA = z19.string().min(1).max(256).regex(/^[a-zA-Z0-9._\-/]+$/);
|
|
11153
11218
|
async function resolveServiceContext(serviceId) {
|
|
11154
11219
|
const service = await serviceStore.get(serviceId);
|
|
11155
11220
|
if (!service) {
|
|
@@ -11163,11 +11228,11 @@ async function resolveServiceContext(serviceId) {
|
|
|
11163
11228
|
}
|
|
11164
11229
|
var gitTargetShape = {
|
|
11165
11230
|
serviceId: SERVICE_ID_SCHEMA.optional(),
|
|
11166
|
-
agentId:
|
|
11231
|
+
agentId: z19.string().max(128).optional(),
|
|
11167
11232
|
/** Anchors on a project when no service is targeted (e.g. from the AI chat). */
|
|
11168
|
-
projectId:
|
|
11233
|
+
projectId: z19.string().max(128).optional(),
|
|
11169
11234
|
/** Son organisation : un id de projet seul peut en nommer un par organisation. */
|
|
11170
|
-
orgId:
|
|
11235
|
+
orgId: z19.string().max(128).nullable().optional()
|
|
11171
11236
|
};
|
|
11172
11237
|
async function resolveGitContext(input) {
|
|
11173
11238
|
if (input.serviceId) return resolveServiceContext(input.serviceId);
|
|
@@ -11180,82 +11245,82 @@ async function resolveGitContext(input) {
|
|
|
11180
11245
|
}
|
|
11181
11246
|
var gitRouter = router({
|
|
11182
11247
|
/** Get full git status */
|
|
11183
|
-
status: protectedProcedure.input(
|
|
11248
|
+
status: protectedProcedure.input(z19.object({ ...gitTargetShape })).query(async ({ input }) => {
|
|
11184
11249
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11185
11250
|
return agentManager.agentQuery(agentId, "git.status", { cwd });
|
|
11186
11251
|
}),
|
|
11187
11252
|
/** Get commit log */
|
|
11188
|
-
log: protectedProcedure.input(
|
|
11253
|
+
log: protectedProcedure.input(z19.object({ ...gitTargetShape, limit: z19.number().int().min(1).max(200).default(50) })).query(async ({ input }) => {
|
|
11189
11254
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11190
11255
|
return agentManager.agentQuery(agentId, "git.log", { cwd, limit: input.limit });
|
|
11191
11256
|
}),
|
|
11192
11257
|
/** List local and remote branches */
|
|
11193
|
-
branches: protectedProcedure.input(
|
|
11258
|
+
branches: protectedProcedure.input(z19.object({ ...gitTargetShape })).query(async ({ input }) => {
|
|
11194
11259
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11195
11260
|
return agentManager.agentQuery(agentId, "git.branches", { cwd });
|
|
11196
11261
|
}),
|
|
11197
11262
|
/** Checkout a branch */
|
|
11198
|
-
checkout: protectedProcedure.input(
|
|
11263
|
+
checkout: protectedProcedure.input(z19.object({ ...gitTargetShape, branch: BRANCH_SCHEMA, create: z19.boolean().default(false) })).mutation(async ({ input }) => {
|
|
11199
11264
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11200
11265
|
return agentManager.agentMutation(agentId, "git.checkout", { cwd, branch: input.branch, create: input.create });
|
|
11201
11266
|
}),
|
|
11202
11267
|
/** Stage files */
|
|
11203
|
-
stage: protectedProcedure.input(
|
|
11268
|
+
stage: protectedProcedure.input(z19.object({ ...gitTargetShape, paths: z19.array(SAFE_PATH_SCHEMA).min(1).max(500) })).mutation(async ({ input }) => {
|
|
11204
11269
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11205
11270
|
return agentManager.agentMutation(agentId, "git.stage", { cwd, paths: input.paths });
|
|
11206
11271
|
}),
|
|
11207
11272
|
/** Stage all files */
|
|
11208
|
-
stageAll: protectedProcedure.input(
|
|
11273
|
+
stageAll: protectedProcedure.input(z19.object({ ...gitTargetShape })).mutation(async ({ input }) => {
|
|
11209
11274
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11210
11275
|
return agentManager.agentMutation(agentId, "git.stageAll", { cwd });
|
|
11211
11276
|
}),
|
|
11212
11277
|
/** Unstage files */
|
|
11213
|
-
unstage: protectedProcedure.input(
|
|
11278
|
+
unstage: protectedProcedure.input(z19.object({ ...gitTargetShape, paths: z19.array(SAFE_PATH_SCHEMA).min(1).max(500) })).mutation(async ({ input }) => {
|
|
11214
11279
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11215
11280
|
return agentManager.agentMutation(agentId, "git.unstage", { cwd, paths: input.paths });
|
|
11216
11281
|
}),
|
|
11217
11282
|
/** Unstage all files */
|
|
11218
|
-
unstageAll: protectedProcedure.input(
|
|
11283
|
+
unstageAll: protectedProcedure.input(z19.object({ ...gitTargetShape })).mutation(async ({ input }) => {
|
|
11219
11284
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11220
11285
|
return agentManager.agentMutation(agentId, "git.unstageAll", { cwd });
|
|
11221
11286
|
}),
|
|
11222
11287
|
/** Commit staged changes */
|
|
11223
|
-
commit: protectedProcedure.input(
|
|
11288
|
+
commit: protectedProcedure.input(z19.object({ ...gitTargetShape, message: z19.string().min(1).max(4096) })).mutation(async ({ input }) => {
|
|
11224
11289
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11225
11290
|
return agentManager.agentMutation(agentId, "git.commit", { cwd, message: input.message });
|
|
11226
11291
|
}),
|
|
11227
11292
|
/** Push to remote */
|
|
11228
|
-
push: protectedProcedure.input(
|
|
11293
|
+
push: protectedProcedure.input(z19.object({ ...gitTargetShape, remote: REMOTE_SCHEMA.default("origin"), setUpstream: z19.boolean().default(false) })).mutation(async ({ input }) => {
|
|
11229
11294
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11230
11295
|
return agentManager.agentMutation(agentId, "git.push", { cwd, remote: input.remote, setUpstream: input.setUpstream });
|
|
11231
11296
|
}),
|
|
11232
11297
|
/** Pull from remote */
|
|
11233
|
-
pull: protectedProcedure.input(
|
|
11298
|
+
pull: protectedProcedure.input(z19.object({ ...gitTargetShape, remote: REMOTE_SCHEMA.default("origin") })).mutation(async ({ input }) => {
|
|
11234
11299
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11235
11300
|
return agentManager.agentMutation(agentId, "git.pull", { cwd, remote: input.remote });
|
|
11236
11301
|
}),
|
|
11237
11302
|
/** Fetch from remote */
|
|
11238
|
-
fetch: protectedProcedure.input(
|
|
11303
|
+
fetch: protectedProcedure.input(z19.object({ ...gitTargetShape, remote: REMOTE_SCHEMA.default("origin") })).mutation(async ({ input }) => {
|
|
11239
11304
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11240
11305
|
return agentManager.agentMutation(agentId, "git.fetch", { cwd, remote: input.remote });
|
|
11241
11306
|
}),
|
|
11242
11307
|
/** Get diff for a file or the whole index */
|
|
11243
|
-
diff: protectedProcedure.input(
|
|
11308
|
+
diff: protectedProcedure.input(z19.object({
|
|
11244
11309
|
...gitTargetShape,
|
|
11245
|
-
path:
|
|
11246
|
-
staged:
|
|
11247
|
-
untracked:
|
|
11310
|
+
path: z19.string().max(4096).optional(),
|
|
11311
|
+
staged: z19.boolean().default(false),
|
|
11312
|
+
untracked: z19.boolean().default(false)
|
|
11248
11313
|
})).query(async ({ input }) => {
|
|
11249
11314
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11250
11315
|
return agentManager.agentQuery(agentId, "git.diff", { cwd, path: input.path, staged: input.staged, untracked: input.untracked });
|
|
11251
11316
|
}),
|
|
11252
11317
|
/** Discard changes to working tree files */
|
|
11253
|
-
discard: protectedProcedure.input(
|
|
11318
|
+
discard: protectedProcedure.input(z19.object({ ...gitTargetShape, paths: z19.array(SAFE_PATH_SCHEMA).min(1).max(500) })).mutation(async ({ input }) => {
|
|
11254
11319
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11255
11320
|
return agentManager.agentMutation(agentId, "git.discard", { cwd, paths: input.paths });
|
|
11256
11321
|
}),
|
|
11257
11322
|
/** Generate a commit message from staged diffs using AI (diff fetched from agent, AI runs on server) */
|
|
11258
|
-
generateCommitMessage: protectedProcedure.input(
|
|
11323
|
+
generateCommitMessage: protectedProcedure.input(z19.object({ ...gitTargetShape, providerId: OptionalProviderIdSchema, model: z19.string().max(200).optional() })).mutation(async ({ input }) => {
|
|
11259
11324
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11260
11325
|
const { diff } = await agentManager.agentQuery(agentId, "git.stagedDiff", { cwd });
|
|
11261
11326
|
if (!diff.trim()) {
|
|
@@ -11302,42 +11367,42 @@ Rules:
|
|
|
11302
11367
|
throw new TRPCError13({ code: "BAD_REQUEST", message: "Unsupported AI provider" });
|
|
11303
11368
|
}),
|
|
11304
11369
|
/** Merge a branch into the current branch */
|
|
11305
|
-
merge: protectedProcedure.input(
|
|
11370
|
+
merge: protectedProcedure.input(z19.object({ ...gitTargetShape, branch: BRANCH_SCHEMA, noFf: z19.boolean().default(false) })).mutation(async ({ input }) => {
|
|
11306
11371
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11307
11372
|
return agentManager.agentMutation(agentId, "git.merge", { cwd, branch: input.branch, noFf: input.noFf });
|
|
11308
11373
|
}),
|
|
11309
11374
|
/** Rebase current branch onto another branch */
|
|
11310
|
-
rebase: protectedProcedure.input(
|
|
11375
|
+
rebase: protectedProcedure.input(z19.object({ ...gitTargetShape, branch: BRANCH_SCHEMA })).mutation(async ({ input }) => {
|
|
11311
11376
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11312
11377
|
return agentManager.agentMutation(agentId, "git.rebase", { cwd, branch: input.branch });
|
|
11313
11378
|
}),
|
|
11314
11379
|
/** List stash entries */
|
|
11315
|
-
stashList: protectedProcedure.input(
|
|
11380
|
+
stashList: protectedProcedure.input(z19.object({ ...gitTargetShape })).query(async ({ input }) => {
|
|
11316
11381
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11317
11382
|
return agentManager.agentQuery(agentId, "git.stashList", { cwd });
|
|
11318
11383
|
}),
|
|
11319
11384
|
/** Stash current changes */
|
|
11320
|
-
stashPush: protectedProcedure.input(
|
|
11385
|
+
stashPush: protectedProcedure.input(z19.object({ ...gitTargetShape, message: z19.string().max(4096).optional(), includeUntracked: z19.boolean().default(true) })).mutation(async ({ input }) => {
|
|
11321
11386
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11322
11387
|
return agentManager.agentMutation(agentId, "git.stashPush", { cwd, message: input.message, includeUntracked: input.includeUntracked });
|
|
11323
11388
|
}),
|
|
11324
11389
|
/** Pop a stash entry */
|
|
11325
|
-
stashPop: protectedProcedure.input(
|
|
11390
|
+
stashPop: protectedProcedure.input(z19.object({ ...gitTargetShape, index: z19.number().int().min(0).max(1e3).default(0) })).mutation(async ({ input }) => {
|
|
11326
11391
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11327
11392
|
return agentManager.agentMutation(agentId, "git.stashPop", { cwd, index: input.index });
|
|
11328
11393
|
}),
|
|
11329
11394
|
/** Apply a stash entry without dropping it */
|
|
11330
|
-
stashApply: protectedProcedure.input(
|
|
11395
|
+
stashApply: protectedProcedure.input(z19.object({ ...gitTargetShape, index: z19.number().int().min(0).max(1e3).default(0) })).mutation(async ({ input }) => {
|
|
11331
11396
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11332
11397
|
return agentManager.agentMutation(agentId, "git.stashApply", { cwd, index: input.index });
|
|
11333
11398
|
}),
|
|
11334
11399
|
/** Drop a stash entry */
|
|
11335
|
-
stashDrop: protectedProcedure.input(
|
|
11400
|
+
stashDrop: protectedProcedure.input(z19.object({ ...gitTargetShape, index: z19.number().int().min(0).max(1e3).default(0) })).mutation(async ({ input }) => {
|
|
11336
11401
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11337
11402
|
return agentManager.agentMutation(agentId, "git.stashDrop", { cwd, index: input.index });
|
|
11338
11403
|
}),
|
|
11339
11404
|
/** Watch .git/ for changes and stream updated status */
|
|
11340
|
-
onStatusChange: protectedProcedure.input(
|
|
11405
|
+
onStatusChange: protectedProcedure.input(z19.object({ ...gitTargetShape })).subscription(async function* ({ input }) {
|
|
11341
11406
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11342
11407
|
const queue = [];
|
|
11343
11408
|
let resolve7 = null;
|
|
@@ -11384,7 +11449,7 @@ Rules:
|
|
|
11384
11449
|
}
|
|
11385
11450
|
}),
|
|
11386
11451
|
/** List remotes */
|
|
11387
|
-
remotes: protectedProcedure.input(
|
|
11452
|
+
remotes: protectedProcedure.input(z19.object({ ...gitTargetShape })).query(async ({ input }) => {
|
|
11388
11453
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
11389
11454
|
return agentManager.agentQuery(agentId, "git.remotes", { cwd });
|
|
11390
11455
|
})
|
|
@@ -11393,7 +11458,7 @@ Rules:
|
|
|
11393
11458
|
// ../server/src/trpc/routers/scenario.ts
|
|
11394
11459
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
11395
11460
|
import { TRPCError as TRPCError16 } from "@trpc/server";
|
|
11396
|
-
import { z as
|
|
11461
|
+
import { z as z20 } from "zod";
|
|
11397
11462
|
|
|
11398
11463
|
// ../server/src/trpc/crud-procedure-utils.ts
|
|
11399
11464
|
import { TRPCError as TRPCError14 } from "@trpc/server";
|
|
@@ -12992,28 +13057,28 @@ Modify the scenario. Keep existing ids when possible.`;
|
|
|
12992
13057
|
return `Generate an scenario org-chart based on: ${userPrompt}`;
|
|
12993
13058
|
}
|
|
12994
13059
|
var ScopeShape2 = {
|
|
12995
|
-
orgId:
|
|
13060
|
+
orgId: z20.string().max(128).nullable().optional(),
|
|
12996
13061
|
projectId: Id128Schema.optional()
|
|
12997
13062
|
};
|
|
12998
13063
|
async function scopeOf2(input) {
|
|
12999
13064
|
return input?.orgId ?? await vaultOfProject(input?.projectId);
|
|
13000
13065
|
}
|
|
13001
13066
|
var scenarioRouter = router({
|
|
13002
|
-
list: protectedProcedure.input(
|
|
13003
|
-
get: protectedProcedure.input(
|
|
13067
|
+
list: protectedProcedure.input(z20.object(ScopeShape2).optional()).query(async ({ input }) => scenarioStore.list(await scopeOf2(input))),
|
|
13068
|
+
get: protectedProcedure.input(z20.object({ id: Id128Schema, ...ScopeShape2 })).query(async ({ input }) => getOrNotFound(
|
|
13004
13069
|
async () => scenarioStore.get(input.id, await scopeOf2(input)),
|
|
13005
13070
|
"Scenario not found"
|
|
13006
13071
|
)),
|
|
13007
|
-
create: protectedProcedure.input(
|
|
13072
|
+
create: protectedProcedure.input(z20.object({
|
|
13008
13073
|
name: NameSchema,
|
|
13009
|
-
icon:
|
|
13074
|
+
icon: z20.string().max(64).optional(),
|
|
13010
13075
|
description: DescriptionSchema.optional(),
|
|
13011
13076
|
leaderId: Id128Schema,
|
|
13012
|
-
groups:
|
|
13013
|
-
nodes:
|
|
13014
|
-
traversalMode:
|
|
13015
|
-
presetId:
|
|
13016
|
-
isPublished:
|
|
13077
|
+
groups: z20.array(ScenarioGroupSchema).max(100).optional(),
|
|
13078
|
+
nodes: z20.array(ScenarioNodeSchema).min(1).max(500),
|
|
13079
|
+
traversalMode: z20.enum(["hierarchical", "topological"]).optional(),
|
|
13080
|
+
presetId: z20.string().max(128).optional(),
|
|
13081
|
+
isPublished: z20.boolean().optional(),
|
|
13017
13082
|
...ScopeShape2
|
|
13018
13083
|
})).mutation(({ input }) => {
|
|
13019
13084
|
const now = Date.now();
|
|
@@ -13032,17 +13097,17 @@ var scenarioRouter = router({
|
|
|
13032
13097
|
updatedAt: now
|
|
13033
13098
|
}));
|
|
13034
13099
|
}),
|
|
13035
|
-
update: protectedProcedure.input(
|
|
13100
|
+
update: protectedProcedure.input(z20.object({
|
|
13036
13101
|
id: Id128Schema,
|
|
13037
13102
|
name: NameSchema.optional(),
|
|
13038
|
-
icon:
|
|
13103
|
+
icon: z20.string().max(64).optional(),
|
|
13039
13104
|
description: DescriptionSchema.optional(),
|
|
13040
13105
|
leaderId: Id128Schema.optional(),
|
|
13041
|
-
groups:
|
|
13042
|
-
nodes:
|
|
13043
|
-
traversalMode:
|
|
13044
|
-
presetId:
|
|
13045
|
-
isPublished:
|
|
13106
|
+
groups: z20.array(ScenarioGroupSchema).max(100).optional(),
|
|
13107
|
+
nodes: z20.array(ScenarioNodeSchema).min(1).max(500).optional(),
|
|
13108
|
+
traversalMode: z20.enum(["hierarchical", "topological"]).optional(),
|
|
13109
|
+
presetId: z20.string().max(128).optional(),
|
|
13110
|
+
isPublished: z20.boolean().optional(),
|
|
13046
13111
|
...ScopeShape2
|
|
13047
13112
|
})).mutation(({ input }) => updateOrThrow(
|
|
13048
13113
|
async () => scenarioStore.update(input.id, {
|
|
@@ -13059,22 +13124,22 @@ var scenarioRouter = router({
|
|
|
13059
13124
|
}, await scopeOf2(input)),
|
|
13060
13125
|
"Scenario not found"
|
|
13061
13126
|
)),
|
|
13062
|
-
delete: protectedProcedure.input(
|
|
13127
|
+
delete: protectedProcedure.input(z20.object({ id: Id128Schema, ...ScopeShape2 })).mutation(({ input }) => deleteOrNotFound(
|
|
13063
13128
|
async () => scenarioStore.delete(input.id, await scopeOf2(input)),
|
|
13064
13129
|
"Scenario not found"
|
|
13065
13130
|
)),
|
|
13066
|
-
run: protectedProcedure.input(
|
|
13131
|
+
run: protectedProcedure.input(z20.object({
|
|
13067
13132
|
conversationId: ConversationIdSchema,
|
|
13068
13133
|
scenarioId: Id128Schema,
|
|
13069
|
-
userRequest:
|
|
13070
|
-
runnerOverride:
|
|
13134
|
+
userRequest: z20.string().max(1e5),
|
|
13135
|
+
runnerOverride: z20.enum(["claude-code", "codex"]).optional(),
|
|
13071
13136
|
modelOverride: Id128Schema.optional(),
|
|
13072
13137
|
agentId: Id128Schema.optional(),
|
|
13073
13138
|
/** Anchors the run's working directory on the project it belongs to. */
|
|
13074
13139
|
projectId: Id128Schema.optional(),
|
|
13075
13140
|
/** Son organisation : sans elle, un id partagé désignerait un projet au hasard. */
|
|
13076
|
-
orgId:
|
|
13077
|
-
resume:
|
|
13141
|
+
orgId: z20.string().max(128).nullable().optional(),
|
|
13142
|
+
resume: z20.boolean().optional()
|
|
13078
13143
|
})).subscription(async function* ({ input, signal }) {
|
|
13079
13144
|
const scenario = await scenarioStore.get(input.scenarioId, await scopeOf2(input));
|
|
13080
13145
|
if (!scenario) throw new TRPCError16({ code: "NOT_FOUND", message: "Scenario not found" });
|
|
@@ -13094,41 +13159,41 @@ var scenarioRouter = router({
|
|
|
13094
13159
|
}
|
|
13095
13160
|
yield* tapBus(input.conversationId, signal ?? new AbortController().signal);
|
|
13096
13161
|
}),
|
|
13097
|
-
stop: protectedProcedure.input(
|
|
13162
|
+
stop: protectedProcedure.input(z20.object({ conversationId: ConversationIdSchema })).mutation(({ input }) => {
|
|
13098
13163
|
abortScenario(input.conversationId);
|
|
13099
13164
|
return { ok: true };
|
|
13100
13165
|
}),
|
|
13101
|
-
sendNodeInput: protectedProcedure.input(
|
|
13166
|
+
sendNodeInput: protectedProcedure.input(z20.object({
|
|
13102
13167
|
conversationId: ConversationIdSchema,
|
|
13103
13168
|
nodeId: Id128Schema,
|
|
13104
|
-
text:
|
|
13169
|
+
text: z20.string().min(1).max(1e5)
|
|
13105
13170
|
})).mutation(({ input }) => {
|
|
13106
13171
|
const resolved = resolveNodeInput(input.conversationId, input.nodeId, input.text);
|
|
13107
13172
|
if (!resolved) throw new TRPCError16({ code: "NOT_FOUND", message: "No pending input request for this node" });
|
|
13108
13173
|
return { ok: true };
|
|
13109
13174
|
}),
|
|
13110
|
-
isRunning: protectedProcedure.input(
|
|
13111
|
-
runState: protectedProcedure.input(
|
|
13175
|
+
isRunning: protectedProcedure.input(z20.object({ conversationId: ConversationIdSchema })).query(({ input }) => ({ running: isScenarioRunning(input.conversationId) })),
|
|
13176
|
+
runState: protectedProcedure.input(z20.object({ conversationId: ConversationIdSchema })).query(({ input }) => {
|
|
13112
13177
|
const runState = scenarioRunStore.getRunState(input.conversationId);
|
|
13113
13178
|
return runState ?? { nodeStates: {}, nodeOutputs: {}, activeNodeId: void 0 };
|
|
13114
13179
|
}),
|
|
13115
|
-
getPersistedRunState: protectedProcedure.input(
|
|
13180
|
+
getPersistedRunState: protectedProcedure.input(z20.object({ conversationId: ConversationIdSchema })).query(async ({ input }) => {
|
|
13116
13181
|
return await scenarioRunStore.loadPersistedRunState(input.conversationId);
|
|
13117
13182
|
}),
|
|
13118
|
-
getReadme: protectedProcedure.input(
|
|
13183
|
+
getReadme: protectedProcedure.input(z20.object({ conversationId: ConversationIdSchema })).query(async ({ input }) => {
|
|
13119
13184
|
return await scenarioRunStore.readReadme(input.conversationId);
|
|
13120
13185
|
}),
|
|
13121
|
-
getSnapshot: protectedProcedure.input(
|
|
13186
|
+
getSnapshot: protectedProcedure.input(z20.object({ conversationId: ConversationIdSchema })).query(async ({ input }) => {
|
|
13122
13187
|
return await scenarioRunStore.loadScenarioSnapshot(input.conversationId);
|
|
13123
13188
|
}),
|
|
13124
|
-
streamGenerateWithAI: protectedProcedure.input(
|
|
13125
|
-
prompt:
|
|
13189
|
+
streamGenerateWithAI: protectedProcedure.input(z20.object({
|
|
13190
|
+
prompt: z20.string().min(1).max(1e4),
|
|
13126
13191
|
providerId: OptionalProviderIdSchema,
|
|
13127
|
-
model:
|
|
13128
|
-
current:
|
|
13192
|
+
model: z20.string().max(200).optional(),
|
|
13193
|
+
current: z20.object({
|
|
13129
13194
|
leaderId: Id128Schema,
|
|
13130
|
-
groups:
|
|
13131
|
-
nodes:
|
|
13195
|
+
groups: z20.array(ScenarioGroupSchema).max(100),
|
|
13196
|
+
nodes: z20.array(ScenarioNodeSchema).max(500)
|
|
13132
13197
|
}).optional()
|
|
13133
13198
|
})).subscription(async function* ({ input, signal }) {
|
|
13134
13199
|
const userMessage = buildScenarioUserMessage(input.prompt, input.current);
|
|
@@ -13141,7 +13206,7 @@ var scenarioRouter = router({
|
|
|
13141
13206
|
signal: signal ?? void 0
|
|
13142
13207
|
});
|
|
13143
13208
|
}),
|
|
13144
|
-
streamRunEvents: protectedProcedure.input(
|
|
13209
|
+
streamRunEvents: protectedProcedure.input(z20.object({ conversationId: ConversationIdSchema })).subscription(async function* ({ input }) {
|
|
13145
13210
|
const convId = input.conversationId;
|
|
13146
13211
|
const runState = scenarioRunStore.getRunState(convId);
|
|
13147
13212
|
if (runState) {
|
|
@@ -13155,14 +13220,14 @@ var scenarioRouter = router({
|
|
|
13155
13220
|
* open a debug PTY with `claude --resume <sessionId>` on the right agent.
|
|
13156
13221
|
* Falls back to the persisted run-state for past nodes.
|
|
13157
13222
|
*/
|
|
13158
|
-
getNodeSession: protectedProcedure.input(
|
|
13223
|
+
getNodeSession: protectedProcedure.input(z20.object({
|
|
13159
13224
|
conversationId: ConversationIdSchema,
|
|
13160
13225
|
nodeId: Id128Schema
|
|
13161
13226
|
})).query(async ({ input }) => {
|
|
13162
13227
|
return await scenarioRunStore.getNodeSessionPersistent(input.conversationId, input.nodeId);
|
|
13163
13228
|
}),
|
|
13164
13229
|
listPresets: protectedProcedure.query(() => listPresets()),
|
|
13165
|
-
getPreset: protectedProcedure.input(
|
|
13230
|
+
getPreset: protectedProcedure.input(z20.object({ id: Id128Schema })).query(({ input }) => {
|
|
13166
13231
|
const preset = getPreset(input.id);
|
|
13167
13232
|
if (!preset) throw new TRPCError16({ code: "NOT_FOUND", message: "Preset not found" });
|
|
13168
13233
|
return preset;
|
|
@@ -13172,7 +13237,7 @@ var scenarioRouter = router({
|
|
|
13172
13237
|
// ../server/src/trpc/routers/debug.ts
|
|
13173
13238
|
import { randomUUID as randomUUID9 } from "crypto";
|
|
13174
13239
|
import { TRPCError as TRPCError17 } from "@trpc/server";
|
|
13175
|
-
import { z as
|
|
13240
|
+
import { z as z21 } from "zod";
|
|
13176
13241
|
var MAX_BUFFER3 = 300;
|
|
13177
13242
|
var jobs = /* @__PURE__ */ new Map();
|
|
13178
13243
|
function publish(job, event) {
|
|
@@ -13229,9 +13294,9 @@ async function* tapJob(job, signal) {
|
|
|
13229
13294
|
}
|
|
13230
13295
|
}
|
|
13231
13296
|
var debugRouter = router({
|
|
13232
|
-
startRandomJob: protectedProcedure.input(
|
|
13233
|
-
intervalMs:
|
|
13234
|
-
maxTicks:
|
|
13297
|
+
startRandomJob: protectedProcedure.input(z21.object({
|
|
13298
|
+
intervalMs: z21.number().int().min(100).max(5e3).optional(),
|
|
13299
|
+
maxTicks: z21.number().int().min(1).max(1e4).optional()
|
|
13235
13300
|
}).optional()).mutation(({ input }) => {
|
|
13236
13301
|
const jobId = randomUUID9();
|
|
13237
13302
|
const intervalMs = input?.intervalMs ?? 400;
|
|
@@ -13265,15 +13330,15 @@ var debugRouter = router({
|
|
|
13265
13330
|
jobs.set(jobId, job);
|
|
13266
13331
|
return { jobId, intervalMs, maxTicks, startedAt: job.startedAt };
|
|
13267
13332
|
}),
|
|
13268
|
-
streamRandomJob: protectedProcedure.input(
|
|
13333
|
+
streamRandomJob: protectedProcedure.input(z21.object({ jobId: z21.string().max(128) })).subscription(async function* ({ input, signal }) {
|
|
13269
13334
|
const job = jobs.get(input.jobId);
|
|
13270
13335
|
if (!job) {
|
|
13271
13336
|
throw new TRPCError17({ code: "NOT_FOUND", message: "Random job not found" });
|
|
13272
13337
|
}
|
|
13273
13338
|
yield* tapJob(job, signal ?? new AbortController().signal);
|
|
13274
13339
|
}),
|
|
13275
|
-
stopRandomJob: protectedProcedure.input(
|
|
13276
|
-
randomJobStatus: protectedProcedure.input(
|
|
13340
|
+
stopRandomJob: protectedProcedure.input(z21.object({ jobId: z21.string().max(128) })).mutation(({ input }) => ({ ok: stopJob(input.jobId, "stopped") })),
|
|
13341
|
+
randomJobStatus: protectedProcedure.input(z21.object({ jobId: z21.string().max(128) })).query(({ input }) => {
|
|
13277
13342
|
const job = jobs.get(input.jobId);
|
|
13278
13343
|
return {
|
|
13279
13344
|
running: !!job && !job.done,
|
|
@@ -13283,7 +13348,7 @@ var debugRouter = router({
|
|
|
13283
13348
|
});
|
|
13284
13349
|
|
|
13285
13350
|
// ../server/src/trpc/routers/diagnostics.ts
|
|
13286
|
-
import { z as
|
|
13351
|
+
import { z as z22 } from "zod";
|
|
13287
13352
|
import { TRPCError as TRPCError18 } from "@trpc/server";
|
|
13288
13353
|
|
|
13289
13354
|
// ../server/src/services/log-buffer.ts
|
|
@@ -13355,7 +13420,7 @@ function onEntry(listener) {
|
|
|
13355
13420
|
// ../server/src/trpc/routers/diagnostics.ts
|
|
13356
13421
|
var diagnosticsRouter = router({
|
|
13357
13422
|
/** Backlog for a client that just opened the panel. */
|
|
13358
|
-
recentLogs: protectedProcedure.input(
|
|
13423
|
+
recentLogs: protectedProcedure.input(z22.object({ limit: z22.number().int().min(1).max(2e3).default(500) }).optional()).query(({ input }) => recentEntries(input?.limit ?? 500)),
|
|
13359
13424
|
/**
|
|
13360
13425
|
* Live log stream.
|
|
13361
13426
|
*
|
|
@@ -13364,7 +13429,7 @@ var diagnosticsRouter = router({
|
|
|
13364
13429
|
* silently loses lines, which is precisely what someone watching a boot
|
|
13365
13430
|
* failure cannot afford.
|
|
13366
13431
|
*/
|
|
13367
|
-
streamLogs: protectedProcedure.input(
|
|
13432
|
+
streamLogs: protectedProcedure.input(z22.object({ afterSeq: z22.number().int().nonnegative().default(0) }).optional()).subscription(async function* ({ input, signal }) {
|
|
13368
13433
|
for (const entry of entriesSince(input?.afterSeq ?? 0)) yield entry;
|
|
13369
13434
|
const queue = [];
|
|
13370
13435
|
let wake = null;
|
|
@@ -13398,7 +13463,7 @@ var diagnosticsRouter = router({
|
|
|
13398
13463
|
* refused. That is what keeps this from being a way to signal arbitrary
|
|
13399
13464
|
* processes with the server's privileges.
|
|
13400
13465
|
*/
|
|
13401
|
-
killInstance: protectedProcedure.input(
|
|
13466
|
+
killInstance: protectedProcedure.input(z22.object({ pid: z22.number().int().positive() })).mutation(async ({ input }) => {
|
|
13402
13467
|
try {
|
|
13403
13468
|
return await killInstance(input.pid);
|
|
13404
13469
|
} catch (err) {
|
|
@@ -13426,7 +13491,7 @@ var diagnosticsRouter = router({
|
|
|
13426
13491
|
* reproductible : instance trop ancienne pour avoir publié sa ligne de
|
|
13427
13492
|
* commande, ou lancée avec un secret que le registre ne conserve pas.
|
|
13428
13493
|
*/
|
|
13429
|
-
restartInstance: protectedProcedure.input(
|
|
13494
|
+
restartInstance: protectedProcedure.input(z22.object({ pid: z22.number().int().positive() })).mutation(async ({ input }) => {
|
|
13430
13495
|
try {
|
|
13431
13496
|
if (input.pid === process.pid) {
|
|
13432
13497
|
const { relauncherPid, port } = await scheduleSelfRestart();
|
|
@@ -13450,7 +13515,7 @@ var diagnosticsRouter = router({
|
|
|
13450
13515
|
});
|
|
13451
13516
|
|
|
13452
13517
|
// ../server/src/trpc/routers/kanban-queue.ts
|
|
13453
|
-
import { z as
|
|
13518
|
+
import { z as z23 } from "zod";
|
|
13454
13519
|
|
|
13455
13520
|
// ../server/src/services/kanban-queue.ts
|
|
13456
13521
|
import { randomUUID as randomUUID10 } from "crypto";
|
|
@@ -13638,36 +13703,36 @@ var kanbanQueue = new KanbanQueueService();
|
|
|
13638
13703
|
// ../server/src/trpc/routers/kanban-queue.ts
|
|
13639
13704
|
var kanbanQueueRouter = router({
|
|
13640
13705
|
getState: protectedProcedure.query(() => kanbanQueue.getState()),
|
|
13641
|
-
add: protectedProcedure.input(
|
|
13642
|
-
boardId:
|
|
13643
|
-
cardId:
|
|
13644
|
-
runner:
|
|
13645
|
-
model:
|
|
13646
|
-
scenarioId:
|
|
13706
|
+
add: protectedProcedure.input(z23.object({
|
|
13707
|
+
boardId: z23.string().max(128),
|
|
13708
|
+
cardId: z23.string().max(128),
|
|
13709
|
+
runner: z23.enum(["claude-code", "codex"]).optional(),
|
|
13710
|
+
model: z23.string().max(128).optional(),
|
|
13711
|
+
scenarioId: z23.string().max(128).optional(),
|
|
13647
13712
|
// Le projet ouvert quand la carte a été mise en file : la conversation
|
|
13648
13713
|
// qui en naîtra lui appartient, plutôt que de rester orpheline et de
|
|
13649
13714
|
// s'afficher dans tous les projets.
|
|
13650
|
-
projectId:
|
|
13651
|
-
orgId:
|
|
13715
|
+
projectId: z23.string().max(128).optional(),
|
|
13716
|
+
orgId: z23.string().max(128).nullable().optional()
|
|
13652
13717
|
})).mutation(({ input }) => kanbanQueue.add(input)),
|
|
13653
|
-
addColumn: protectedProcedure.input(
|
|
13654
|
-
boardId:
|
|
13655
|
-
columnId:
|
|
13656
|
-
runner:
|
|
13657
|
-
model:
|
|
13658
|
-
scenarioId:
|
|
13659
|
-
projectId:
|
|
13660
|
-
orgId:
|
|
13718
|
+
addColumn: protectedProcedure.input(z23.object({
|
|
13719
|
+
boardId: z23.string().max(128),
|
|
13720
|
+
columnId: z23.string().max(128),
|
|
13721
|
+
runner: z23.enum(["claude-code", "codex"]).optional(),
|
|
13722
|
+
model: z23.string().max(128).optional(),
|
|
13723
|
+
scenarioId: z23.string().max(128).optional(),
|
|
13724
|
+
projectId: z23.string().max(128).optional(),
|
|
13725
|
+
orgId: z23.string().max(128).nullable().optional()
|
|
13661
13726
|
})).mutation(async ({ input }) => {
|
|
13662
13727
|
const { boardId, columnId, ...options } = input;
|
|
13663
13728
|
return kanbanQueue.addColumn(boardId, columnId, options);
|
|
13664
13729
|
}),
|
|
13665
|
-
remove: protectedProcedure.input(
|
|
13730
|
+
remove: protectedProcedure.input(z23.object({ itemId: z23.string().max(128) })).mutation(({ input }) => ({ removed: kanbanQueue.remove(input.itemId) })),
|
|
13666
13731
|
stopAll: protectedProcedure.mutation(() => {
|
|
13667
13732
|
kanbanQueue.stopAll();
|
|
13668
13733
|
return { ok: true };
|
|
13669
13734
|
}),
|
|
13670
|
-
setMaxConcurrent: protectedProcedure.input(
|
|
13735
|
+
setMaxConcurrent: protectedProcedure.input(z23.object({ max: z23.number().int().min(1).max(20) })).mutation(({ input }) => {
|
|
13671
13736
|
kanbanQueue.setMaxConcurrent(input.max);
|
|
13672
13737
|
return kanbanQueue.getState();
|
|
13673
13738
|
}),
|
|
@@ -13705,7 +13770,7 @@ import { mkdir as mkdir17, readdir as readdir5, rm as rm3, stat as stat5, writeF
|
|
|
13705
13770
|
import { createHash } from "crypto";
|
|
13706
13771
|
import { tmpdir } from "os";
|
|
13707
13772
|
import { join as join20 } from "path";
|
|
13708
|
-
import { z as
|
|
13773
|
+
import { z as z24 } from "zod";
|
|
13709
13774
|
import { TRPCError as TRPCError19 } from "@trpc/server";
|
|
13710
13775
|
function summarizeCard(card, boardId, columnTitle) {
|
|
13711
13776
|
return {
|
|
@@ -13793,9 +13858,9 @@ var kanbanRouter = router({
|
|
|
13793
13858
|
* card graph, so listing them in full would be megabytes to answer "which
|
|
13794
13859
|
* boards exist?". Use `getBoard` for the cards of one.
|
|
13795
13860
|
*/
|
|
13796
|
-
listBoards: protectedProcedure.input(
|
|
13797
|
-
includeArchived:
|
|
13798
|
-
organizationId:
|
|
13861
|
+
listBoards: protectedProcedure.input(z24.object({
|
|
13862
|
+
includeArchived: z24.boolean().optional(),
|
|
13863
|
+
organizationId: z24.string().max(128).optional()
|
|
13799
13864
|
}).optional()).query(async ({ input }) => {
|
|
13800
13865
|
const { organizationId, boards } = await kanbanStore.list(
|
|
13801
13866
|
input?.includeArchived ?? false,
|
|
@@ -13821,7 +13886,7 @@ var kanbanRouter = router({
|
|
|
13821
13886
|
};
|
|
13822
13887
|
}),
|
|
13823
13888
|
/** One board: its columns, and the cards in each. */
|
|
13824
|
-
getBoard: protectedProcedure.input(
|
|
13889
|
+
getBoard: protectedProcedure.input(z24.object({ boardId: z24.string().max(128) })).query(async ({ input }) => {
|
|
13825
13890
|
const board = await kanbanStore.get(input.boardId);
|
|
13826
13891
|
if (!board) return { board: null };
|
|
13827
13892
|
const { links } = await kanbanStore.cardLinks(input.boardId);
|
|
@@ -13860,11 +13925,11 @@ var kanbanRouter = router({
|
|
|
13860
13925
|
* organization — or one board when `boardId` is given. Archived boards are
|
|
13861
13926
|
* left out: they are what the team decided to stop looking at.
|
|
13862
13927
|
*/
|
|
13863
|
-
searchCards: protectedProcedure.input(
|
|
13864
|
-
query:
|
|
13865
|
-
boardId:
|
|
13866
|
-
limit:
|
|
13867
|
-
organizationId:
|
|
13928
|
+
searchCards: protectedProcedure.input(z24.object({
|
|
13929
|
+
query: z24.string().min(1).max(256),
|
|
13930
|
+
boardId: z24.string().max(128).optional(),
|
|
13931
|
+
limit: z24.number().int().min(1).max(100).optional(),
|
|
13932
|
+
organizationId: z24.string().max(128).optional()
|
|
13868
13933
|
})).query(async ({ input }) => {
|
|
13869
13934
|
return kanbanStore.searchCards(input);
|
|
13870
13935
|
}),
|
|
@@ -13877,10 +13942,10 @@ var kanbanRouter = router({
|
|
|
13877
13942
|
* qu'un `commentCount`, et rien n'en donnait le texte. Cette route est la
|
|
13878
13943
|
* relecture, pour une seule carte : c'est le journal qui pèse, pas le reste.
|
|
13879
13944
|
*/
|
|
13880
|
-
getCardComments: protectedProcedure.input(
|
|
13881
|
-
boardId:
|
|
13882
|
-
cardId:
|
|
13883
|
-
limit:
|
|
13945
|
+
getCardComments: protectedProcedure.input(z24.object({
|
|
13946
|
+
boardId: z24.string().max(128),
|
|
13947
|
+
cardId: z24.string().max(128),
|
|
13948
|
+
limit: z24.number().int().min(1).max(200).optional()
|
|
13884
13949
|
})).query(async ({ input }) => {
|
|
13885
13950
|
const history = await kanbanStore.cardHistory(input.boardId, input.cardId);
|
|
13886
13951
|
const comments = history.filter((e) => e.type === "comment");
|
|
@@ -13909,18 +13974,18 @@ var kanbanRouter = router({
|
|
|
13909
13974
|
* `getBoard` en donne déjà l'essentiel carte par carte ; cette route sert
|
|
13910
13975
|
* quand c'est l'arbre lui-même qu'on veut, dates et auteurs compris.
|
|
13911
13976
|
*/
|
|
13912
|
-
getCardLinks: protectedProcedure.input(
|
|
13977
|
+
getCardLinks: protectedProcedure.input(z24.object({ boardId: z24.string().max(128) })).query(async ({ input }) => kanbanStore.cardLinks(input.boardId)),
|
|
13913
13978
|
/**
|
|
13914
13979
|
* Rattacher une carte à une carte parente, ou l'en détacher.
|
|
13915
13980
|
*
|
|
13916
13981
|
* Sans `parentCardId`, le lien est retiré. Le parent peut vivre sur un autre
|
|
13917
13982
|
* tableau : `parentBoardId` le désigne alors, sinon c'est celui de la carte.
|
|
13918
13983
|
*/
|
|
13919
|
-
setCardParent: protectedProcedure.input(
|
|
13920
|
-
boardId:
|
|
13921
|
-
cardId:
|
|
13922
|
-
parentCardId:
|
|
13923
|
-
parentBoardId:
|
|
13984
|
+
setCardParent: protectedProcedure.input(z24.object({
|
|
13985
|
+
boardId: z24.string().max(128),
|
|
13986
|
+
cardId: z24.string().max(128),
|
|
13987
|
+
parentCardId: z24.string().max(128).optional(),
|
|
13988
|
+
parentBoardId: z24.string().max(128).optional()
|
|
13924
13989
|
})).mutation(async ({ input }) => {
|
|
13925
13990
|
const ok = await kanbanStore.setCardParent(
|
|
13926
13991
|
input.boardId,
|
|
@@ -13932,31 +13997,31 @@ var kanbanRouter = router({
|
|
|
13932
13997
|
}
|
|
13933
13998
|
return { ok: true };
|
|
13934
13999
|
}),
|
|
13935
|
-
moveCard: protectedProcedure.input(
|
|
13936
|
-
boardId:
|
|
13937
|
-
cardId:
|
|
13938
|
-
targetColumn:
|
|
14000
|
+
moveCard: protectedProcedure.input(z24.object({
|
|
14001
|
+
boardId: z24.string().max(128),
|
|
14002
|
+
cardId: z24.string().max(128),
|
|
14003
|
+
targetColumn: z24.string().max(256)
|
|
13939
14004
|
})).mutation(async ({ input }) => {
|
|
13940
14005
|
await executeKanbanCommands(input.boardId, input.cardId, [
|
|
13941
14006
|
{ type: "move_card", columnTitle: input.targetColumn }
|
|
13942
14007
|
]);
|
|
13943
14008
|
return { ok: true };
|
|
13944
14009
|
}),
|
|
13945
|
-
addComment: protectedProcedure.input(
|
|
13946
|
-
boardId:
|
|
13947
|
-
cardId:
|
|
13948
|
-
comment:
|
|
14010
|
+
addComment: protectedProcedure.input(z24.object({
|
|
14011
|
+
boardId: z24.string().max(128),
|
|
14012
|
+
cardId: z24.string().max(128),
|
|
14013
|
+
comment: z24.string().max(1e5)
|
|
13949
14014
|
})).mutation(async ({ input }) => {
|
|
13950
14015
|
await executeKanbanCommands(input.boardId, input.cardId, [
|
|
13951
14016
|
{ type: "add_comment", comment: input.comment }
|
|
13952
14017
|
]);
|
|
13953
14018
|
return { ok: true };
|
|
13954
14019
|
}),
|
|
13955
|
-
addCard: protectedProcedure.input(
|
|
13956
|
-
boardId:
|
|
13957
|
-
column:
|
|
13958
|
-
title:
|
|
13959
|
-
content:
|
|
14020
|
+
addCard: protectedProcedure.input(z24.object({
|
|
14021
|
+
boardId: z24.string().max(128),
|
|
14022
|
+
column: z24.string().max(256),
|
|
14023
|
+
title: z24.string().max(512),
|
|
14024
|
+
content: z24.string().max(2e4).optional()
|
|
13960
14025
|
})).mutation(async ({ input }) => {
|
|
13961
14026
|
await executeKanbanBoardCommands(input.boardId, [
|
|
13962
14027
|
{ type: "add_card", columnTitle: input.column, cardTitle: input.title, cardContent: input.content }
|
|
@@ -13969,7 +14034,7 @@ var kanbanRouter = router({
|
|
|
13969
14034
|
* `getBoard` rapatrie le tableau entier pour n'en regarder qu'une ; et il ne
|
|
13970
14035
|
* porte pas les cartes rangées. Une carte s'adresse par son identifiant.
|
|
13971
14036
|
*/
|
|
13972
|
-
getCard: protectedProcedure.input(
|
|
14037
|
+
getCard: protectedProcedure.input(z24.object({ boardId: z24.string().max(128), cardId: z24.string().max(128) })).query(async ({ input }) => {
|
|
13973
14038
|
const found = await kanbanStore.card(input.boardId, input.cardId);
|
|
13974
14039
|
if (!found) throw new Error(`Carte ${input.cardId} introuvable sur le tableau ${input.boardId}.`);
|
|
13975
14040
|
return { ...summarizeCard(found.card, input.boardId, ""), columnId: found.columnId };
|
|
@@ -13983,16 +14048,16 @@ var kanbanRouter = router({
|
|
|
13983
14048
|
* Un champ absent n'est pas touché ; `null` l'efface. La distinction compte —
|
|
13984
14049
|
* changer un titre ne doit pas vider une couleur.
|
|
13985
14050
|
*/
|
|
13986
|
-
updateCard: protectedProcedure.input(
|
|
13987
|
-
boardId:
|
|
13988
|
-
cardId:
|
|
13989
|
-
title:
|
|
13990
|
-
content:
|
|
13991
|
-
priority:
|
|
13992
|
-
color:
|
|
13993
|
-
groups:
|
|
13994
|
-
deadline:
|
|
13995
|
-
assignees:
|
|
14051
|
+
updateCard: protectedProcedure.input(z24.object({
|
|
14052
|
+
boardId: z24.string().max(128),
|
|
14053
|
+
cardId: z24.string().max(128),
|
|
14054
|
+
title: z24.string().min(1).max(512).optional(),
|
|
14055
|
+
content: z24.string().max(1e5).optional(),
|
|
14056
|
+
priority: z24.number().int().min(1).max(10).nullable().optional(),
|
|
14057
|
+
color: z24.string().max(32).nullable().optional(),
|
|
14058
|
+
groups: z24.array(z24.string().min(1).max(60)).max(30).optional(),
|
|
14059
|
+
deadline: z24.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional(),
|
|
14060
|
+
assignees: z24.array(z24.string().max(128)).max(50).optional()
|
|
13996
14061
|
})).mutation(async ({ input }) => {
|
|
13997
14062
|
const { boardId, cardId, content, ...rest } = input;
|
|
13998
14063
|
const patch = { ...rest };
|
|
@@ -14003,10 +14068,10 @@ var kanbanRouter = router({
|
|
|
14003
14068
|
return summarizeCard(card, boardId, "");
|
|
14004
14069
|
}),
|
|
14005
14070
|
/** Ranger une carte, ou la reprendre. */
|
|
14006
|
-
setCardArchived: protectedProcedure.input(
|
|
14007
|
-
boardId:
|
|
14008
|
-
cardId:
|
|
14009
|
-
archived:
|
|
14071
|
+
setCardArchived: protectedProcedure.input(z24.object({
|
|
14072
|
+
boardId: z24.string().max(128),
|
|
14073
|
+
cardId: z24.string().max(128),
|
|
14074
|
+
archived: z24.boolean()
|
|
14010
14075
|
})).mutation(async ({ input }) => {
|
|
14011
14076
|
const ok = await kanbanStore.setCardArchived(input.boardId, input.cardId, input.archived);
|
|
14012
14077
|
if (!ok) throw new Error(`La carte ${input.cardId} n'a pas pu \xEAtre ${input.archived ? "archiv\xE9e" : "reprise"}.`);
|
|
@@ -14018,13 +14083,13 @@ var kanbanRouter = router({
|
|
|
14018
14083
|
* Sans cette liste, assigner revient à deviner un identifiant — et l'agent
|
|
14019
14084
|
* n'a aucun moyen de le trouver.
|
|
14020
14085
|
*/
|
|
14021
|
-
listMembers: protectedProcedure.input(
|
|
14086
|
+
listMembers: protectedProcedure.input(z24.object({ organizationId: z24.string().max(128).optional() })).query(async ({ input }) => ({ members: await kanbanStore.members(input.organizationId) })),
|
|
14022
14087
|
/**
|
|
14023
14088
|
* Fetch one card attachment from the cloud and drop it on this machine, so an
|
|
14024
14089
|
* agent can open it with its own file tools. The bytes never go through the
|
|
14025
14090
|
* prompt: the card context lists the attachments, this returns a path.
|
|
14026
14091
|
*/
|
|
14027
|
-
downloadAttachment: protectedProcedure.input(
|
|
14092
|
+
downloadAttachment: protectedProcedure.input(z24.object({ attachmentId: z24.string().max(128) })).mutation(async ({ input }) => {
|
|
14028
14093
|
const id = input.attachmentId;
|
|
14029
14094
|
if (!ATTACHMENT_ID_REGEX.test(id)) {
|
|
14030
14095
|
throw new TRPCError19({ code: "BAD_REQUEST", message: "Invalid attachment id" });
|
|
@@ -14057,21 +14122,21 @@ var kanbanRouter = router({
|
|
|
14057
14122
|
});
|
|
14058
14123
|
|
|
14059
14124
|
// ../server/src/trpc/routers/terminal.ts
|
|
14060
|
-
import { z as
|
|
14125
|
+
import { z as z25 } from "zod";
|
|
14061
14126
|
import { TRPCError as TRPCError20 } from "@trpc/server";
|
|
14062
14127
|
var terminalRouter = router({
|
|
14063
14128
|
/** Create a PTY shell session on the target agent */
|
|
14064
|
-
create: protectedProcedure.input(
|
|
14065
|
-
agentId:
|
|
14066
|
-
cwd:
|
|
14129
|
+
create: protectedProcedure.input(z25.object({
|
|
14130
|
+
agentId: z25.string().max(128),
|
|
14131
|
+
cwd: z25.string().max(512).optional(),
|
|
14067
14132
|
/** Anchors the terminal when no explicit cwd is given. */
|
|
14068
|
-
serviceId:
|
|
14069
|
-
projectId:
|
|
14133
|
+
serviceId: z25.string().max(128).optional(),
|
|
14134
|
+
projectId: z25.string().max(128).optional(),
|
|
14070
14135
|
/** L'organisation du projet : un id seul peut en nommer un par organisation. */
|
|
14071
|
-
orgId:
|
|
14072
|
-
cols:
|
|
14073
|
-
rows:
|
|
14074
|
-
title:
|
|
14136
|
+
orgId: z25.string().max(128).nullable().optional(),
|
|
14137
|
+
cols: z25.number().int().min(1).max(512).optional(),
|
|
14138
|
+
rows: z25.number().int().min(1).max(256).optional(),
|
|
14139
|
+
title: z25.string().max(128).optional()
|
|
14075
14140
|
})).mutation(async ({ input }) => {
|
|
14076
14141
|
const result = await agentManager.agentMutation(
|
|
14077
14142
|
input.agentId,
|
|
@@ -14092,17 +14157,17 @@ var terminalRouter = router({
|
|
|
14092
14157
|
return result;
|
|
14093
14158
|
}),
|
|
14094
14159
|
/** Les sessions PTY encore vivantes sur l'agent (onglets à retrouver) */
|
|
14095
|
-
list: protectedProcedure.input(
|
|
14160
|
+
list: protectedProcedure.input(z25.object({ agentId: z25.string().max(128) })).query(async ({ input }) => {
|
|
14096
14161
|
return agentManager.agentQuery(
|
|
14097
14162
|
input.agentId,
|
|
14098
14163
|
"terminal.list"
|
|
14099
14164
|
);
|
|
14100
14165
|
}),
|
|
14101
14166
|
/** Renommer un onglet */
|
|
14102
|
-
rename: protectedProcedure.input(
|
|
14103
|
-
agentId:
|
|
14104
|
-
sessionId:
|
|
14105
|
-
title:
|
|
14167
|
+
rename: protectedProcedure.input(z25.object({
|
|
14168
|
+
agentId: z25.string().max(128),
|
|
14169
|
+
sessionId: z25.string().max(128),
|
|
14170
|
+
title: z25.string().max(128)
|
|
14106
14171
|
})).mutation(async ({ input }) => {
|
|
14107
14172
|
await agentManager.agentMutation(
|
|
14108
14173
|
input.agentId,
|
|
@@ -14112,10 +14177,10 @@ var terminalRouter = router({
|
|
|
14112
14177
|
return { ok: true };
|
|
14113
14178
|
}),
|
|
14114
14179
|
/** Send keystrokes / data to a PTY session */
|
|
14115
|
-
write: protectedProcedure.input(
|
|
14116
|
-
agentId:
|
|
14117
|
-
sessionId:
|
|
14118
|
-
data:
|
|
14180
|
+
write: protectedProcedure.input(z25.object({
|
|
14181
|
+
agentId: z25.string().max(128),
|
|
14182
|
+
sessionId: z25.string().max(128),
|
|
14183
|
+
data: z25.string().max(65536)
|
|
14119
14184
|
})).mutation(async ({ input }) => {
|
|
14120
14185
|
await agentManager.agentMutation(
|
|
14121
14186
|
input.agentId,
|
|
@@ -14125,11 +14190,11 @@ var terminalRouter = router({
|
|
|
14125
14190
|
return { ok: true };
|
|
14126
14191
|
}),
|
|
14127
14192
|
/** Resize the PTY */
|
|
14128
|
-
resize: protectedProcedure.input(
|
|
14129
|
-
agentId:
|
|
14130
|
-
sessionId:
|
|
14131
|
-
cols:
|
|
14132
|
-
rows:
|
|
14193
|
+
resize: protectedProcedure.input(z25.object({
|
|
14194
|
+
agentId: z25.string().max(128),
|
|
14195
|
+
sessionId: z25.string().max(128),
|
|
14196
|
+
cols: z25.number().int().min(1).max(512),
|
|
14197
|
+
rows: z25.number().int().min(1).max(256)
|
|
14133
14198
|
})).mutation(async ({ input }) => {
|
|
14134
14199
|
await agentManager.agentMutation(
|
|
14135
14200
|
input.agentId,
|
|
@@ -14139,9 +14204,9 @@ var terminalRouter = router({
|
|
|
14139
14204
|
return { ok: true };
|
|
14140
14205
|
}),
|
|
14141
14206
|
/** Destroy a PTY session */
|
|
14142
|
-
destroy: protectedProcedure.input(
|
|
14143
|
-
agentId:
|
|
14144
|
-
sessionId:
|
|
14207
|
+
destroy: protectedProcedure.input(z25.object({
|
|
14208
|
+
agentId: z25.string().max(128),
|
|
14209
|
+
sessionId: z25.string().max(128)
|
|
14145
14210
|
})).mutation(async ({ input }) => {
|
|
14146
14211
|
await agentManager.agentMutation(
|
|
14147
14212
|
input.agentId,
|
|
@@ -14151,11 +14216,11 @@ var terminalRouter = router({
|
|
|
14151
14216
|
return { ok: true };
|
|
14152
14217
|
}),
|
|
14153
14218
|
/** Stream PTY output — proxied via AgentWSBridge dynamic subscription */
|
|
14154
|
-
onData: protectedProcedure.input(
|
|
14155
|
-
agentId:
|
|
14156
|
-
sessionId:
|
|
14219
|
+
onData: protectedProcedure.input(z25.object({
|
|
14220
|
+
agentId: z25.string().max(128),
|
|
14221
|
+
sessionId: z25.string().max(128),
|
|
14157
14222
|
/** Rejouer l'historique de la session avant le flux temps réel. */
|
|
14158
|
-
replay:
|
|
14223
|
+
replay: z25.boolean().optional()
|
|
14159
14224
|
})).subscription(async function* ({ input }) {
|
|
14160
14225
|
const queue = [];
|
|
14161
14226
|
let resolve7 = null;
|
|
@@ -14204,11 +14269,11 @@ var terminalRouter = router({
|
|
|
14204
14269
|
});
|
|
14205
14270
|
|
|
14206
14271
|
// ../server/src/trpc/routers/utility.ts
|
|
14207
|
-
import { z as
|
|
14272
|
+
import { z as z26 } from "zod";
|
|
14208
14273
|
var MAX_WAIT_MS = 5 * 60 * 1e3;
|
|
14209
14274
|
var utilityRouter = router({
|
|
14210
|
-
wait: protectedProcedure.input(
|
|
14211
|
-
ms:
|
|
14275
|
+
wait: protectedProcedure.input(z26.object({
|
|
14276
|
+
ms: z26.number().int().min(0).max(MAX_WAIT_MS)
|
|
14212
14277
|
})).mutation(async ({ input }) => {
|
|
14213
14278
|
await new Promise((resolve7) => setTimeout(resolve7, input.ms));
|
|
14214
14279
|
return { waited: input.ms };
|
|
@@ -14216,15 +14281,15 @@ var utilityRouter = router({
|
|
|
14216
14281
|
});
|
|
14217
14282
|
|
|
14218
14283
|
// ../server/src/trpc/routers/wiki.ts
|
|
14219
|
-
import { z as
|
|
14284
|
+
import { z as z27 } from "zod";
|
|
14220
14285
|
import { TRPCError as TRPCError21 } from "@trpc/server";
|
|
14221
14286
|
import { readFile as readFile16, readdir as readdir6, stat as stat6, realpath, writeFile as writeFile16, mkdir as mkdir18, rename as rename13, rm as rm4 } from "fs/promises";
|
|
14222
14287
|
import { resolve as resolvePath, join as join21, relative, sep as sep3, dirname as dirname9 } from "path";
|
|
14223
|
-
var SCOPE_SCHEMA =
|
|
14224
|
-
|
|
14225
|
-
|
|
14288
|
+
var SCOPE_SCHEMA = z27.union([
|
|
14289
|
+
z27.literal("global"),
|
|
14290
|
+
z27.string().regex(/^service:[A-Za-z0-9_-]{1,128}$/, "Invalid service scope")
|
|
14226
14291
|
]);
|
|
14227
|
-
var REL_PATH_SCHEMA =
|
|
14292
|
+
var REL_PATH_SCHEMA = z27.string().min(1).max(512).regex(/^[A-Za-z0-9_./-]+$/).refine((p) => !p.includes("..") && !p.startsWith("/"), {
|
|
14228
14293
|
message: "Path must be a relative path without traversal"
|
|
14229
14294
|
});
|
|
14230
14295
|
var MAX_FILES = 500;
|
|
@@ -14244,9 +14309,9 @@ var IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
|
14244
14309
|
"target",
|
|
14245
14310
|
"out"
|
|
14246
14311
|
]);
|
|
14247
|
-
var DocsEntrySchema =
|
|
14248
|
-
|
|
14249
|
-
|
|
14312
|
+
var DocsEntrySchema = z27.lazy(() => z27.union([
|
|
14313
|
+
z27.object({ type: z27.literal("file"), name: z27.string(), path: z27.string() }),
|
|
14314
|
+
z27.object({ type: z27.literal("dir"), name: z27.string(), path: z27.string(), children: z27.array(DocsEntrySchema) })
|
|
14250
14315
|
]));
|
|
14251
14316
|
async function resolveScope(scope) {
|
|
14252
14317
|
if (scope === "global") {
|
|
@@ -14336,7 +14401,7 @@ async function resolveSafeLocal(root, relPath, requireExist) {
|
|
|
14336
14401
|
return resolvePath(realParent, target.slice(parent.length).replace(/^[\\/]+/, ""));
|
|
14337
14402
|
}
|
|
14338
14403
|
var wikiRouter = router({
|
|
14339
|
-
list: protectedProcedure.input(
|
|
14404
|
+
list: protectedProcedure.input(z27.object({ scope: SCOPE_SCHEMA })).output(z27.object({ root: z27.string(), entries: z27.array(DocsEntrySchema), truncated: z27.boolean() })).query(async ({ input }) => {
|
|
14340
14405
|
const target = await resolveScope(input.scope);
|
|
14341
14406
|
if (target.mode === "agent") {
|
|
14342
14407
|
return agentManager.agentQuery(target.agentId, "wiki.listRepoMarkdown", { cwd: target.cwd });
|
|
@@ -14345,7 +14410,7 @@ var wikiRouter = router({
|
|
|
14345
14410
|
const entries2 = await walkLocal(target.root, target.root, 0, counter);
|
|
14346
14411
|
return { root: target.root, entries: entries2, truncated: counter.n >= MAX_FILES };
|
|
14347
14412
|
}),
|
|
14348
|
-
read: protectedProcedure.input(
|
|
14413
|
+
read: protectedProcedure.input(z27.object({ scope: SCOPE_SCHEMA, path: REL_PATH_SCHEMA })).output(z27.object({ path: z27.string(), content: z27.string() })).query(async ({ input }) => {
|
|
14349
14414
|
if (!/\.(md|markdown)$/i.test(input.path)) {
|
|
14350
14415
|
throw new TRPCError21({ code: "BAD_REQUEST", message: "Seuls les .md/.markdown sont autoris\xE9s" });
|
|
14351
14416
|
}
|
|
@@ -14360,7 +14425,7 @@ var wikiRouter = router({
|
|
|
14360
14425
|
const content = await readFile16(file, "utf-8");
|
|
14361
14426
|
return { path: input.path, content };
|
|
14362
14427
|
}),
|
|
14363
|
-
write: protectedProcedure.input(
|
|
14428
|
+
write: protectedProcedure.input(z27.object({ scope: SCOPE_SCHEMA, path: REL_PATH_SCHEMA, content: z27.string().max(5e6) })).mutation(async ({ input }) => {
|
|
14364
14429
|
if (!/\.(md|markdown)$/i.test(input.path)) {
|
|
14365
14430
|
throw new TRPCError21({ code: "BAD_REQUEST", message: "Seuls les .md/.markdown sont autoris\xE9s" });
|
|
14366
14431
|
}
|
|
@@ -14373,7 +14438,7 @@ var wikiRouter = router({
|
|
|
14373
14438
|
await writeFile16(file, input.content, "utf-8");
|
|
14374
14439
|
return { path: input.path, ok: true };
|
|
14375
14440
|
}),
|
|
14376
|
-
createFile: protectedProcedure.input(
|
|
14441
|
+
createFile: protectedProcedure.input(z27.object({ scope: SCOPE_SCHEMA, path: REL_PATH_SCHEMA })).mutation(async ({ input }) => {
|
|
14377
14442
|
if (!/\.(md|markdown)$/i.test(input.path)) {
|
|
14378
14443
|
throw new TRPCError21({ code: "BAD_REQUEST", message: "Seuls les .md/.markdown sont autoris\xE9s" });
|
|
14379
14444
|
}
|
|
@@ -14392,7 +14457,7 @@ var wikiRouter = router({
|
|
|
14392
14457
|
await writeFile16(file, "", "utf-8");
|
|
14393
14458
|
return { path: input.path, ok: true };
|
|
14394
14459
|
}),
|
|
14395
|
-
createDir: protectedProcedure.input(
|
|
14460
|
+
createDir: protectedProcedure.input(z27.object({ scope: SCOPE_SCHEMA, path: REL_PATH_SCHEMA })).mutation(async ({ input }) => {
|
|
14396
14461
|
const target = await resolveScope(input.scope);
|
|
14397
14462
|
if (target.mode === "agent") {
|
|
14398
14463
|
return agentManager.agentMutation(target.agentId, "wiki.createDir", { cwd: target.cwd, path: input.path });
|
|
@@ -14401,7 +14466,7 @@ var wikiRouter = router({
|
|
|
14401
14466
|
await mkdir18(dir, { recursive: true });
|
|
14402
14467
|
return { path: input.path, ok: true };
|
|
14403
14468
|
}),
|
|
14404
|
-
rename: protectedProcedure.input(
|
|
14469
|
+
rename: protectedProcedure.input(z27.object({ scope: SCOPE_SCHEMA, fromPath: REL_PATH_SCHEMA, toPath: REL_PATH_SCHEMA })).mutation(async ({ input }) => {
|
|
14405
14470
|
const target = await resolveScope(input.scope);
|
|
14406
14471
|
if (target.mode === "agent") {
|
|
14407
14472
|
return agentManager.agentMutation(target.agentId, "wiki.renamePath", { cwd: target.cwd, fromPath: input.fromPath, toPath: input.toPath });
|
|
@@ -14418,7 +14483,7 @@ var wikiRouter = router({
|
|
|
14418
14483
|
await rename13(from, to);
|
|
14419
14484
|
return { fromPath: input.fromPath, toPath: input.toPath, ok: true };
|
|
14420
14485
|
}),
|
|
14421
|
-
ensureRoot: protectedProcedure.input(
|
|
14486
|
+
ensureRoot: protectedProcedure.input(z27.object({ scope: SCOPE_SCHEMA })).mutation(async ({ input }) => {
|
|
14422
14487
|
if (input.scope === "global") {
|
|
14423
14488
|
await resolveScope("global");
|
|
14424
14489
|
return { ok: true };
|
|
@@ -14431,7 +14496,7 @@ var wikiRouter = router({
|
|
|
14431
14496
|
const cwd = await resolveWorkspaceCwd({ serviceId, override: service.docsPath?.trim() || void 0 });
|
|
14432
14497
|
return agentManager.agentMutation(agentId, "wiki.ensureRoot", { cwd });
|
|
14433
14498
|
}),
|
|
14434
|
-
delete: protectedProcedure.input(
|
|
14499
|
+
delete: protectedProcedure.input(z27.object({ scope: SCOPE_SCHEMA, path: REL_PATH_SCHEMA })).mutation(async ({ input }) => {
|
|
14435
14500
|
const target = await resolveScope(input.scope);
|
|
14436
14501
|
if (target.mode === "agent") {
|
|
14437
14502
|
return agentManager.agentMutation(target.agentId, "wiki.deletePath", { cwd: target.cwd, path: input.path });
|
|
@@ -14457,7 +14522,7 @@ var configRouter = router({
|
|
|
14457
14522
|
});
|
|
14458
14523
|
|
|
14459
14524
|
// ../server/src/trpc/routers/cloud-sync.ts
|
|
14460
|
-
import { z as
|
|
14525
|
+
import { z as z28 } from "zod";
|
|
14461
14526
|
import { TRPCError as TRPCError22 } from "@trpc/server";
|
|
14462
14527
|
|
|
14463
14528
|
// ../server/src/services/org-sync-scope.ts
|
|
@@ -15624,10 +15689,10 @@ var cloudSyncRouter = router({
|
|
|
15624
15689
|
* "open this project" is the whole gesture.
|
|
15625
15690
|
*/
|
|
15626
15691
|
trackProject: protectedProcedure.input(
|
|
15627
|
-
|
|
15628
|
-
orgId:
|
|
15629
|
-
cloudUrl:
|
|
15630
|
-
projectId:
|
|
15692
|
+
z28.object({
|
|
15693
|
+
orgId: z28.string().min(1).max(128),
|
|
15694
|
+
cloudUrl: z28.string().url().max(2048),
|
|
15695
|
+
projectId: z28.string().min(1).max(128)
|
|
15631
15696
|
})
|
|
15632
15697
|
).mutation(async ({ input }) => {
|
|
15633
15698
|
await assertOrgReadable(input.orgId);
|
|
@@ -15661,10 +15726,10 @@ var cloudSyncRouter = router({
|
|
|
15661
15726
|
* fusionné.
|
|
15662
15727
|
*/
|
|
15663
15728
|
publishProject: protectedProcedure.input(
|
|
15664
|
-
|
|
15665
|
-
orgId:
|
|
15666
|
-
cloudUrl:
|
|
15667
|
-
projectId:
|
|
15729
|
+
z28.object({
|
|
15730
|
+
orgId: z28.string().min(1).max(128),
|
|
15731
|
+
cloudUrl: z28.string().url().max(2048),
|
|
15732
|
+
projectId: z28.string().min(1).max(128)
|
|
15668
15733
|
})
|
|
15669
15734
|
).mutation(async ({ input }) => {
|
|
15670
15735
|
const local = await projectStore.get({ id: input.projectId, orgId: null });
|
|
@@ -15705,9 +15770,9 @@ var cloudSyncRouter = router({
|
|
|
15705
15770
|
* publié. Le cloud, lui, ne peut pas répondre — il n'a que du chiffré sous
|
|
15706
15771
|
* les yeux — donc le canari est rapatrié et jugé ici.
|
|
15707
15772
|
*/
|
|
15708
|
-
checkOrgKey: protectedProcedure.input(
|
|
15709
|
-
orgId:
|
|
15710
|
-
keyHex:
|
|
15773
|
+
checkOrgKey: protectedProcedure.input(z28.object({
|
|
15774
|
+
orgId: z28.string().min(1).max(128),
|
|
15775
|
+
keyHex: z28.string().length(64).regex(/^[0-9a-f]+$/i)
|
|
15711
15776
|
})).query(async ({ input }) => {
|
|
15712
15777
|
const res = await cloudFetch2(
|
|
15713
15778
|
`/api/auth/organization/canary?organizationId=${encodeURIComponent(input.orgId)}`,
|
|
@@ -15729,7 +15794,7 @@ var cloudSyncRouter = router({
|
|
|
15729
15794
|
* que l'interface puisse proposer ni l'adoption ni la remise à zéro — le seul
|
|
15730
15795
|
* chemin qui la répare. Rien n'est écrit ici, ni sur le disque ni sur le cloud.
|
|
15731
15796
|
*/
|
|
15732
|
-
orgKeyStatus: protectedProcedure.input(
|
|
15797
|
+
orgKeyStatus: protectedProcedure.input(z28.object({ orgId: z28.string().min(1).max(128) })).query(async ({ input }) => {
|
|
15733
15798
|
const key = getEncryptionKey(input.orgId);
|
|
15734
15799
|
if (!key) return { status: "unknown" };
|
|
15735
15800
|
const res = await cloudFetch2(
|
|
@@ -15751,10 +15816,10 @@ var cloudSyncRouter = router({
|
|
|
15751
15816
|
* Bornée au coffre de l'organisation et à ceux de ses projets : les autres
|
|
15752
15817
|
* organisations et la machine gardent leur clé.
|
|
15753
15818
|
*/
|
|
15754
|
-
adoptOrgKey: protectedProcedure.input(
|
|
15755
|
-
orgId:
|
|
15756
|
-
keyHex:
|
|
15757
|
-
masterPassword:
|
|
15819
|
+
adoptOrgKey: protectedProcedure.input(z28.object({
|
|
15820
|
+
orgId: z28.string().min(1).max(128),
|
|
15821
|
+
keyHex: z28.string().length(64).regex(/^[0-9a-f]+$/i),
|
|
15822
|
+
masterPassword: z28.string().min(1).max(1024)
|
|
15758
15823
|
})).mutation(async ({ input }) => {
|
|
15759
15824
|
const report = await adoptOrgKey(
|
|
15760
15825
|
input.orgId,
|
|
@@ -15778,7 +15843,7 @@ var cloudSyncRouter = router({
|
|
|
15778
15843
|
* Elle ne re-chiffre rien : ce qui a déjà été synchronisé sous l'ancienne clé
|
|
15779
15844
|
* reste illisible. L'interface le dit avant de la déclencher.
|
|
15780
15845
|
*/
|
|
15781
|
-
resetOrgKey: protectedProcedure.input(
|
|
15846
|
+
resetOrgKey: protectedProcedure.input(z28.object({ orgId: z28.string().min(1).max(128) })).mutation(async ({ input }) => {
|
|
15782
15847
|
const canary = await readVerifyFile(orgVaultRoot(input.orgId)) ?? await readVerifyFile(await keyRoot());
|
|
15783
15848
|
if (!canary) {
|
|
15784
15849
|
throw new TRPCError22({
|
|
@@ -15808,9 +15873,9 @@ var cloudSyncRouter = router({
|
|
|
15808
15873
|
* every other member and for this one on another machine.
|
|
15809
15874
|
*/
|
|
15810
15875
|
untrackProject: protectedProcedure.input(
|
|
15811
|
-
|
|
15812
|
-
orgId:
|
|
15813
|
-
projectId:
|
|
15876
|
+
z28.object({
|
|
15877
|
+
orgId: z28.string().min(1).max(128),
|
|
15878
|
+
projectId: z28.string().min(1).max(128)
|
|
15814
15879
|
})
|
|
15815
15880
|
).mutation(async ({ input }) => {
|
|
15816
15881
|
await cloudSyncBridge.unfollowProject(input.orgId, input.projectId);
|
|
@@ -15826,9 +15891,9 @@ var cloudSyncRouter = router({
|
|
|
15826
15891
|
* membre, ce qui évite d'effacer les fichiers si le cloud a refusé l'ordre.
|
|
15827
15892
|
*/
|
|
15828
15893
|
deleteProjectFromOrg: protectedProcedure.input(
|
|
15829
|
-
|
|
15830
|
-
orgId:
|
|
15831
|
-
projectId:
|
|
15894
|
+
z28.object({
|
|
15895
|
+
orgId: z28.string().min(1).max(128),
|
|
15896
|
+
projectId: z28.string().min(1).max(128)
|
|
15832
15897
|
})
|
|
15833
15898
|
).mutation(async ({ input }) => {
|
|
15834
15899
|
let res;
|
|
@@ -15872,10 +15937,10 @@ var cloudSyncRouter = router({
|
|
|
15872
15937
|
* afficher. Le nom est donc recopié dans le tampon du coffre au passage, là
|
|
15873
15938
|
* où il est déjà lu au démarrage suivant.
|
|
15874
15939
|
*/
|
|
15875
|
-
rememberOrgNames: protectedProcedure.input(
|
|
15876
|
-
orgs:
|
|
15877
|
-
orgId:
|
|
15878
|
-
name:
|
|
15940
|
+
rememberOrgNames: protectedProcedure.input(z28.object({
|
|
15941
|
+
orgs: z28.array(z28.object({
|
|
15942
|
+
orgId: z28.string().min(1).max(128),
|
|
15943
|
+
name: z28.string().min(1).max(100)
|
|
15879
15944
|
})).max(200)
|
|
15880
15945
|
})).mutation(async ({ input }) => {
|
|
15881
15946
|
for (const { orgId, name } of input.orgs) await rememberOrgName(orgId, name);
|
|
@@ -15905,7 +15970,7 @@ var cloudSyncRouter = router({
|
|
|
15905
15970
|
* Un 404 efface le logo retenu — l'organisation en a retiré un — tandis qu'un
|
|
15906
15971
|
* réseau muet laisse en place ce qui est déjà là : hors ligne, on garde.
|
|
15907
15972
|
*/
|
|
15908
|
-
cacheOrgLogos: protectedProcedure.input(
|
|
15973
|
+
cacheOrgLogos: protectedProcedure.input(z28.object({ orgIds: z28.array(z28.string().min(1).max(128)).max(200) })).mutation(async ({ input }) => {
|
|
15909
15974
|
const clouds = await readOrgClouds();
|
|
15910
15975
|
let cached = 0;
|
|
15911
15976
|
for (const orgId of input.orgIds) {
|
|
@@ -15967,9 +16032,9 @@ var cloudSyncRouter = router({
|
|
|
15967
16032
|
import { readdir as readdir8, stat as stat8 } from "fs/promises";
|
|
15968
16033
|
import { homedir as homedir5 } from "os";
|
|
15969
16034
|
import { isAbsolute as isAbsolute4, join as join25, resolve as resolve5, dirname as dirname10, basename as basename2 } from "path";
|
|
15970
|
-
import { z as
|
|
16035
|
+
import { z as z29 } from "zod";
|
|
15971
16036
|
var MAX_ENTRIES2 = 500;
|
|
15972
|
-
var PATH_SCHEMA =
|
|
16037
|
+
var PATH_SCHEMA = z29.string().min(1).max(4096);
|
|
15973
16038
|
function safeResolve(input) {
|
|
15974
16039
|
if (input.includes("\0")) throw new Error("Chemin invalide");
|
|
15975
16040
|
const expanded = input.startsWith("~") ? join25(homedir5(), input.slice(1)) : input;
|
|
@@ -15993,7 +16058,7 @@ var filesystemRouter = router({
|
|
|
15993
16058
|
* Hidden entries are skipped: they are noise for choosing a workspace, and
|
|
15994
16059
|
* `.runeya` itself would invite placing a project inside another's data.
|
|
15995
16060
|
*/
|
|
15996
|
-
listDirectories: protectedProcedure.input(
|
|
16061
|
+
listDirectories: protectedProcedure.input(z29.object({ path: PATH_SCHEMA })).query(async ({ input }) => {
|
|
15997
16062
|
const dir = safeResolve(input.path);
|
|
15998
16063
|
const info = await stat8(dir).catch(() => null);
|
|
15999
16064
|
if (!info?.isDirectory()) {
|
|
@@ -16027,10 +16092,10 @@ var filesystemRouter = router({
|
|
|
16027
16092
|
* Two projects in one directory is what makes services run against the wrong
|
|
16028
16093
|
* code, so a directory that already holds one is refused outright.
|
|
16029
16094
|
*/
|
|
16030
|
-
checkProjectTarget: protectedProcedure.input(
|
|
16095
|
+
checkProjectTarget: protectedProcedure.input(z29.object({
|
|
16031
16096
|
path: PATH_SCHEMA,
|
|
16032
|
-
projectId:
|
|
16033
|
-
orgId:
|
|
16097
|
+
projectId: z29.string().min(1).max(128),
|
|
16098
|
+
orgId: z29.string().max(128).nullable().optional()
|
|
16034
16099
|
})).query(async ({ input }) => {
|
|
16035
16100
|
const dir = safeResolve(input.path);
|
|
16036
16101
|
const info = await stat8(dir).catch(() => null);
|
|
@@ -16052,6 +16117,7 @@ var filesystemRouter = router({
|
|
|
16052
16117
|
var appRouter = router({
|
|
16053
16118
|
health: healthRouter,
|
|
16054
16119
|
appUpdate: appUpdateRouter,
|
|
16120
|
+
changelog: changelogRouter,
|
|
16055
16121
|
diagnostics: diagnosticsRouter,
|
|
16056
16122
|
project: projectRouter,
|
|
16057
16123
|
service: serviceRouter,
|
|
@@ -16434,7 +16500,7 @@ async function runLegacyMigration(dataDir) {
|
|
|
16434
16500
|
}
|
|
16435
16501
|
console.log("[legacy-migration] Legacy Runeya data detected, starting migration\u2026");
|
|
16436
16502
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").substring(0, 19);
|
|
16437
|
-
const legacyTmp =
|
|
16503
|
+
const legacyTmp = `${legacyRoot}-tmp`;
|
|
16438
16504
|
await rename17(legacyRoot, legacyTmp);
|
|
16439
16505
|
await mkdir24(dataDir, { recursive: true });
|
|
16440
16506
|
const legacyOld = join28(dataDir, `backup-${timestamp}`);
|
|
@@ -18364,4 +18430,4 @@ export {
|
|
|
18364
18430
|
pullEnv,
|
|
18365
18431
|
registerInstance
|
|
18366
18432
|
};
|
|
18367
|
-
//# sourceMappingURL=src-
|
|
18433
|
+
//# sourceMappingURL=src-GGPKDQGD.js.map
|