@runeya/runeya 2.0.71 → 2.0.73
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 +208 -160
- package/agent/index.js.map +1 -1
- package/agent-manager-LBV3CVHB.js +7 -0
- package/{chunk-Z3KAXI7V.js → chunk-OTJQEK4D.js} +240 -29
- package/chunk-OTJQEK4D.js.map +1 -0
- package/index.js +3 -2
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/{src-Q3PSCMS7.js → src-MY5W5AYS.js} +828 -633
- package/src-MY5W5AYS.js.map +1 -0
- package/web/assets/AgentScalarChatInterface.vue-369U2Skl.js +13 -0
- package/web/assets/AgentTerminalPage-RHehuR0e.js +1 -0
- package/web/assets/AiChatPage-BbgFeCu5.js +1 -0
- package/web/assets/AppLayout-CvEbrCSS.js +1 -0
- package/web/assets/{AppLayout-BqXoW05V.css → AppLayout-Dj8VrBzz.css} +1 -1
- package/web/assets/AuditPage-BRBcRwff.js +1 -0
- package/web/assets/CloudAccountPage-C9Y4zQYc.js +1 -0
- package/web/assets/CloudAccountPage-DmDrYdSX.js +1 -0
- package/web/assets/CloudMessagingPage-j2dztUz1.js +2 -0
- package/web/assets/DashboardPage-DbgOaKaI.js +1 -0
- package/web/assets/DirectoryPickerDialog-B5a7tO0P.js +1 -0
- package/web/assets/{EditorIcon-JRryeySJ.js → EditorIcon-C32poOg-.js} +2 -2
- package/web/assets/EnvironmentForm-CjnghPBi.js +108 -0
- package/web/assets/EnvironmentFormPage-VkOp77jY.js +1 -0
- package/web/assets/EnvironmentListPage-GkrefCj6.js +1 -0
- package/web/assets/KanbanBoardPage-CCl8dmwn.css +1 -0
- package/web/assets/KanbanBoardPage-CkrXazSk.js +4 -0
- package/web/assets/KanbanListPage-CtC0GWl8.js +1 -0
- package/web/assets/LaunchProjectPage-BrmWhutG.css +1 -0
- package/web/assets/LaunchProjectPage-Zx3L-5pP.js +1 -0
- package/web/assets/LaunchServicesPage-CMxUWoNQ.css +1 -0
- package/web/assets/LaunchServicesPage-Du56bNpD.js +1 -0
- package/web/assets/LogViewer-CusYWOVz.js +3 -0
- package/web/assets/OrgKeyPrompt-BhsICoTI.js +1 -0
- package/web/assets/{ProcessControls-BPQXGKib.js → ProcessControls-CNrbnTpl.js} +1 -1
- package/web/assets/ProcessDetailPage-h8RXTZkW.js +1 -0
- package/web/assets/{ProcessMetrics-D7L708Em.js → ProcessMetrics-B6Zf110f.js} +2 -2
- package/web/assets/ProjectDetailPage-B_fowFne.js +1 -0
- package/web/assets/ProjectListPage-DA9HaZW1.js +1 -0
- package/web/assets/RandomJobTestPage-BlKmN8WR.js +2 -0
- package/web/assets/ScenarioEditorPage-DxmF9C9y.js +14 -0
- package/web/assets/SendToChatDialog-CKDis_oY.js +1 -0
- package/web/assets/ServiceControlsBar-DqWOWB8l.js +1 -0
- package/web/assets/ServiceDetailPage-D4w7i_m0.js +2 -0
- package/web/assets/ServiceFormPage-D9EeSeKX.js +1 -0
- package/web/assets/SettingsPage-1zz5wMpp.js +2063 -0
- package/web/assets/{SettingsPage-CScovMi5.css → SettingsPage-ClUsbLPy.css} +1 -1
- package/web/assets/UnlockPage-BkqsC0ML.css +1 -0
- package/web/assets/UnlockPage-C4b4tv9Z.js +1 -0
- package/web/assets/VariablesTable-BQW0OS3C.js +1 -0
- package/web/assets/VaultMigrationPage-B20L2W_w.css +1 -0
- package/web/assets/VaultMigrationPage-B24yEz24.js +1 -0
- package/web/assets/VersionBadge-AuIQKahq.js +1 -0
- package/web/assets/WikiPage-YnXchmy7.js +1 -0
- package/web/assets/WikiView-B4FOcZxi.js +1 -0
- package/web/assets/add-scalar-classes-Bb4tLm0z.js +387 -0
- package/web/assets/auth-errors-CtC8HAvD.js +1 -0
- package/web/assets/autocomplete-LUb8fDRi.js +308 -0
- package/web/assets/{basic-shape-diamond.svg-C8K6YjGj.js → basic-shape-diamond.svg-CCzIrujg.js} +1 -1
- package/web/assets/{basic-shape-hexagon.svg-C9PeXR6S.js → basic-shape-hexagon.svg-DdSh-N2z.js} +1 -1
- package/web/assets/{basic-shape-primary-circle-ellipse-round.svg-CfBLN6Yj.js → basic-shape-primary-circle-ellipse-round.svg-DsMpzYdr.js} +1 -1
- package/web/assets/{basic-shape-primary-square-rectangle.svg-D2QPBP5_.js → basic-shape-primary-square-rectangle.svg-S5aiKynO.js} +1 -1
- package/web/assets/{basic-shape-shield.svg-ClsEFdja.js → basic-shape-shield.svg-06mLN5Kq.js} +1 -1
- package/web/assets/{browser-D7ZckEFz.js → browser-B6kPJYkH.js} +1 -1
- package/web/assets/{browser-CF5_9QqR.js → browser-CvGRE98D.js} +1 -1
- package/web/assets/card-DQ-7UOQt.js +32 -0
- package/web/assets/{checkbox-CfwNXlF_.js → checkbox-CIizqAL5.js} +3 -3
- package/web/assets/{chip-3tOoBrD7.js → chip-CKY-cFPm.js} +2 -2
- package/web/assets/client-Cem5gxc3.js +24 -0
- package/web/assets/cloud-chat.store-JxTqY8hH.js +1 -0
- package/web/assets/cloud-session-BsgS9t9u.js +1 -0
- package/web/assets/column-C1iIQeFS.js +907 -0
- package/web/assets/{computer-device-desktop-monitor.svg-9f4DSNLj.js → computer-device-desktop-monitor.svg-pZKLXVEO.js} +1 -1
- package/web/assets/{computer-device-desktop.svg-BYoXiEOE.js → computer-device-desktop.svg-CPuJoG2N.js} +1 -1
- package/web/assets/{computer-device-laptop.svg-DR1sEMdL.js → computer-device-laptop.svg-B2lqbpvX.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-android-samsung-back.svg-B-AOaBuq.js → computer-device-mobile-phone-android-samsung-back.svg-C91mPbw_.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-android-samsung.svg-Dw4z_H5H.js → computer-device-mobile-phone-android-samsung.svg-CgjjMhRB.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-iphone-x-back.svg-BtqMb2Wo.js → computer-device-mobile-phone-iphone-x-back.svg-DdpW-odT.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-iphone-x.svg-eYEM_VXA.js → computer-device-mobile-phone-iphone-x.svg-B_qWFdEx.js} +1 -1
- package/web/assets/{computer-device-mobile-tablet-touch.svg-jLD41nvm.js → computer-device-mobile-tablet-touch.svg-BzehkLNH.js} +1 -1
- package/web/assets/{computer-device-mobile-tablet.svg-D_7_M1GK.js → computer-device-mobile-tablet.svg-rkDIg0TG.js} +1 -1
- package/web/assets/{computer-device-network-ethernet-cat6.svg-B_527QGY.js → computer-device-network-ethernet-cat6.svg-B-d_wrR_.js} +1 -1
- package/web/assets/{computer-device-network-lan-www.svg-ClZIaUOH.js → computer-device-network-lan-www.svg-TIELALfm.js} +1 -1
- package/web/assets/{computer-device-network-wifi-connection.svg-DC4OCJY0.js → computer-device-network-wifi-connection.svg-DbXW3PhA.js} +1 -1
- package/web/assets/{computer-device-network-wifi-router.svg-BWPpobCc.js → computer-device-network-wifi-router.svg-D_35yOXc.js} +1 -1
- package/web/assets/{cssMode-CXUrkdrQ.js → cssMode-B7e_eNPV.js} +1 -1
- package/web/assets/{divider-BrO5nkpd.js → divider-BHKktSGp.js} +2 -2
- package/web/assets/{docx-preview-tE714WSD.js → docx-preview-DlxCg_6l.js} +1 -1
- package/web/assets/{ecology-science-erlenmeyer-flask.svg-o8D0ASmr.js → ecology-science-erlenmeyer-flask.svg-Dl6fsl4J.js} +1 -1
- package/web/assets/{fieldset-LX5cdTvN.js → fieldset-De5JS2HC.js} +2 -2
- package/web/assets/{freemarker2-DJ82s0fP.js → freemarker2-BZ1pmGPV.js} +1 -1
- package/web/assets/{handlebars-BXFlY2Lu.js → handlebars-DQnFd9h7.js} +1 -1
- package/web/assets/{html-CqDVypOC.js → html-C0efjIn9.js} +1 -1
- package/web/assets/{htmlMode-DrHxdTQP.js → htmlMode-ChFMbKcf.js} +1 -1
- package/web/assets/{image-flash-lightning.svg-BDPMOynq.js → image-flash-lightning.svg-B7e5E2Qw.js} +1 -1
- package/web/assets/{image-picture-flower.svg-D-AJaery.js → image-picture-flower.svg-Cw1CZ_Iv.js} +1 -1
- package/web/assets/{index-CICxLkjp.css → index-B___lI4D.css} +1 -1
- package/web/assets/{index-a6DAapTb.js → index-nY5cynKj.js} +238 -238
- package/web/assets/{interface-alert-exclamation-diamond.svg-CV7M0IVQ.js → interface-alert-exclamation-diamond.svg-BSUXkUin.js} +1 -1
- package/web/assets/{interface-alert-exclamation-triangle-warning.svg-B8NapiB7.js → interface-alert-exclamation-triangle-warning.svg-BYqq_OZy.js} +1 -1
- package/web/assets/{interface-alert-information-circle.svg-eQIFULjG.js → interface-alert-information-circle.svg-BhCupwNF.js} +1 -1
- package/web/assets/{interface-award-crown.svg-D-4fclUD.js → interface-award-crown.svg-BSbmsgu7.js} +1 -1
- package/web/assets/{interface-bookmark.svg-XdbYDqqk.js → interface-bookmark-tag.svg-C9Tj2VKg.js} +1 -1
- package/web/assets/{interface-bookmark-tag.svg-Jy6EOdau.js → interface-bookmark.svg-DImT79em.js} +1 -1
- package/web/assets/{interface-calendar-date-one.svg-BIoXVZrz.js → interface-calendar-date-one.svg-emGvRYfy.js} +1 -1
- package/web/assets/{interface-content-book-open-pages.svg-DHwJbBvQ.js → interface-content-book-open-pages.svg-DZvD8n9A.js} +1 -1
- package/web/assets/{interface-content-book-page.svg-47msUBN_.js → interface-content-book-page.svg--RPY0ONx.js} +1 -1
- package/web/assets/{interface-content-file.svg-DXw9W8QM.js → interface-content-file.svg-BhkPpAIG.js} +1 -1
- package/web/assets/interface-content-folder.svg-DNkHJfTi.js +1 -0
- package/web/assets/{interface-content-folder.svg-BmK_IJv8.js → interface-content-folder.svg-_Qz96t7R.js} +1 -1
- package/web/assets/{interface-copy-clipboard.svg-CQ1rQN0L.js → interface-copy-clipboard.svg-DBVvMdKB.js} +1 -1
- package/web/assets/{interface-edit-attachment.svg-C3aTaTh_.js → interface-edit-attachment.svg-Bq9IjtmQ.js} +1 -1
- package/web/assets/{interface-edit-binocular.svg-B2Ue_tgs.js → interface-edit-binocular.svg-BFUljAkg.js} +1 -1
- package/web/assets/{interface-edit-magic-wand.svg-DDKse-Wy.js → interface-edit-magic-wand.svg-DSWYEf6V.js} +1 -1
- package/web/assets/{interface-edit-tool-paint-roller.svg-C2ABby1f.js → interface-edit-tool-paint-roller.svg-iMYCD-Af.js} +1 -1
- package/web/assets/{interface-edit-tool-pencil.svg-CNjYbknQ.js → interface-edit-tool-pencil.svg-D7jUKckt.js} +1 -1
- package/web/assets/{interface-favorite-award.svg-DWqSHfIa.js → interface-favorite-award.svg-CLCdfKlW.js} +1 -1
- package/web/assets/{interface-favorite-flag.svg-CNUsr98g.js → interface-favorite-flag.svg-CMNediEx.js} +1 -1
- package/web/assets/{interface-favorite-heart.svg-3Eb366FO.js → interface-favorite-heart.svg-9AfGidiX.js} +1 -1
- package/web/assets/{interface-favorite-star.svg-CVJ3aq1n.js → interface-favorite-star.svg-DD76FDcq.js} +1 -1
- package/web/assets/{interface-favorite-stars-sparkles.svg-BfXhPBbs.js → interface-favorite-stars-sparkles.svg-DZmc8XpZ.js} +1 -1
- package/web/assets/{interface-hierarchy-flowchart.svg-DzsqKrYq.js → interface-hierarchy-flowchart.svg-DbdQ6BrN.js} +1 -1
- package/web/assets/{interface-home-house.svg-BnXbuyZn.js → interface-home-house.svg-BIWYFqhm.js} +1 -1
- package/web/assets/{interface-hyperlink.svg-BsmSmyP5.js → interface-hyperlink.svg-CknF1YxB.js} +1 -1
- package/web/assets/{interface-lighting-brightness.svg-BywVQRo9.js → interface-lighting-brightness.svg-B3Svsmp0.js} +1 -1
- package/web/assets/{interface-lock-closed.svg-BLPORc_h.js → interface-lock-closed.svg-CTmwhMsF.js} +1 -1
- package/web/assets/{interface-lock-open-unlock.svg-CaYlbVmU.js → interface-lock-open-unlock.svg-BSC0HJE5.js} +1 -1
- package/web/assets/{interface-login-key.svg-D5F_9MJ0.js → interface-login-key.svg-CmPadurO.js} +1 -1
- package/web/assets/{interface-search.svg-CF1D8GIV.js → interface-search.svg-BbWqGsiC.js} +1 -1
- package/web/assets/{interface-setting-cog.svg-D4AOKG2g.js → interface-setting-cog.svg-D336jNxR.js} +1 -1
- package/web/assets/{interface-share-megaphone-bullhorn.svg-BIfr2_va.js → interface-share-megaphone-bullhorn.svg-BEPIq-yB.js} +1 -1
- package/web/assets/{interface-share-rocket.svg-NDd3dv1t.js → interface-share-rocket.svg-bi0Fp7B7.js} +1 -1
- package/web/assets/{interface-share-satellite.svg-CVDJbmT-.js → interface-share-satellite.svg-DZ-FBSOP.js} +1 -1
- package/web/assets/{interface-share-space-ship.svg-D0ZLJNO2.js → interface-share-space-ship.svg-CL8kfexn.js} +1 -1
- package/web/assets/{interface-share.svg-WpwbpOes.js → interface-share.svg-B4NzC8MW.js} +1 -1
- package/web/assets/{interface-signal-square.svg-DnfzUw_B.js → interface-signal-square.svg-Do9HNC1g.js} +1 -1
- package/web/assets/{interface-time-clock-circle.svg-BhxciNvX.js → interface-time-clock-circle.svg-BiwVEBFE.js} +1 -1
- package/web/assets/{interface-time-hour-glass.svg-DBzSaSHQ.js → interface-time-hour-glass.svg-Bj4400VR.js} +1 -1
- package/web/assets/{interface-users-multiple.svg-BULh1giq.js → interface-users-multiple.svg-wf0xHt7S.js} +1 -1
- package/web/assets/{interface-weather-moon.svg-D377V2os.js → interface-weather-moon.svg-CHq44y1K.js} +1 -1
- package/web/assets/{javascript-BTXoJ3Qy.js → javascript-C5gAX9Ho.js} +1 -1
- package/web/assets/{jsonMode-D4a3Khim.js → jsonMode-Cah11eZC.js} +2 -2
- package/web/assets/{liquid-DfO0R4Mk.js → liquid-CS5lfWiD.js} +1 -1
- package/web/assets/{lspLanguageFeatures-BvPWuQFt.js → lspLanguageFeatures-DrQCZerv.js} +3 -3
- package/web/assets/{mail-chat-bubble-square.svg-SK3IJ6QN.js → mail-chat-bubble-square.svg-Bn4lLCAH.js} +1 -1
- package/web/assets/{mail-send-email-paper-airplane.svg-CJFA7B2E.js → mail-send-email-paper-airplane.svg-0dbuhy9s.js} +1 -1
- package/web/assets/{mail-send-envelope.svg-eO_-QNyE.js → mail-send-envelope.svg-D7MrBGJp.js} +1 -1
- package/web/assets/{mdx-G_vwFSSe.js → mdx-B4jzso3k.js} +1 -1
- package/web/assets/{message-CxPw04rG.js → message-DnHiYCym.js} +2 -2
- package/web/assets/{minus-Dp5ez1-1.js → minus-BbLiFqfk.js} +2 -2
- package/web/assets/modal-BVB2xBJ_.js +1 -0
- package/web/assets/modal-dKcYqKht.js +5 -0
- package/web/assets/{money-cashier-receipt.svg-EutWthy8.js → money-cashier-receipt.svg-C3G7AK7q.js} +1 -1
- package/web/assets/{money-currency-dollar-pay.svg-MnLj-orw.js → money-currency-dollar-pay.svg-DCj0-yon.js} +1 -1
- package/web/assets/{money-graph-arrow-increase.svg-CVCZ3TyJ.js → money-graph-arrow-increase.svg-DxdQlcuf.js} +1 -1
- package/web/assets/{money-graph-bar-chart-increase.svg-DiUmCuhj.js → money-graph-bar-chart-increase.svg-Cm-WIBNr.js} +1 -1
- package/web/assets/multiselect-C8IBJ6lu.js +251 -0
- package/web/assets/{nature-ecology-leaf.svg-ByaLs72Y.js → nature-ecology-leaf.svg-BDz3LTpd.js} +1 -1
- package/web/assets/{password-CxtOqagM.js → password-DEuFV3TX.js} +4 -4
- package/web/assets/{phone-telephone.svg-BKz6Jkwn.js → phone-telephone.svg-DRL7_jEB.js} +1 -1
- package/web/assets/{plus-BPT_7GGk.js → plus-CdxO2Yq9.js} +6 -6
- package/web/assets/process.store-CauAk_PY.js +1 -0
- package/web/assets/{programming-bug.svg-BwSc8f0s.js → programming-bug.svg-BDftmfZl.js} +1 -1
- package/web/assets/{programming-cloud.svg-CEIulNEp.js → programming-cloud.svg-i-GCH3f4.js} +1 -1
- package/web/assets/{programming-computer-database-server.svg-Bc_F3NH0.js → programming-computer-database-server.svg-CC2MM4RA.js} +1 -1
- package/web/assets/{programming-computer-database.svg-AYLkzJJE.js → programming-computer-database.svg-CwD3IE7b.js} +1 -1
- package/web/assets/{programming-module-four-layout.svg-DLpzPxNB.js → programming-module-four-layout.svg-L5WQW7eZ.js} +1 -1
- package/web/assets/{programming-module-three.svg-CcuZn8dz.js → programming-module-three.svg-BqKxUh2a.js} +1 -1
- package/web/assets/{programming-module.svg-BjbGpQeu.js → programming-module.svg-B5HGxk_5.js} +1 -1
- package/web/assets/{programming-script-code.svg-poyfodgC.js → programming-script-code.svg-C6b1t67U.js} +1 -1
- package/web/assets/{python-DpMMlrWM.js → python-PWdcATjU.js} +1 -1
- package/web/assets/{razor-Ba_mg6U5.js → razor-D2OFUF9W.js} +1 -1
- package/web/assets/router-WC51nlcm.js +1 -0
- package/web/assets/settings-scope-CIL2r-x6.js +1 -0
- package/web/assets/settings.store-Cx63DJSu.js +1 -0
- package/web/assets/{shopping-cart.svg-BX2KYVCw.js → shopping-cart.svg-C4eUOPuW.js} +1 -1
- package/web/assets/{shopping-gift-present.svg-BOl2vYLg.js → shopping-gift-present.svg-DWR1Ue0b.js} +1 -1
- package/web/assets/{shopping-shipping-box-parcel-package.svg-gxfbOgnM.js → shopping-shipping-box-parcel-package.svg-vIUMJCzM.js} +1 -1
- package/web/assets/src-CG6NRFnq.js +1 -0
- package/web/assets/{src-D0LXRijj.js → src-D3B9QT3f.js} +34 -34
- package/web/assets/tabpanel-Dt8wxAUn.js +150 -0
- package/web/assets/{tag-new-circle.svg-CTRMBJyc.js → tag-new-circle.svg-CrLYLp-g.js} +1 -1
- package/web/assets/{toggleswitch-DcDrXRKn.js → toggleswitch-DXNKoD3W.js} +2 -2
- package/web/assets/{travel-map-earth-globe.svg-BPp4IapC.js → travel-map-earth-globe.svg-CbJkEfGx.js} +1 -1
- package/web/assets/trpc-BTkvhuSo.js +1 -0
- package/web/assets/{tsMode-HfLOT-e5.js → tsMode-BWnOhIDG.js} +6 -6
- package/web/assets/{typescript-DJAEsDnw.js → typescript-Ca6d0Xpt.js} +1 -1
- package/web/assets/useAiChatDrawer-DbiVGX1A.js +1 -0
- package/web/assets/useCloudOrg-CYZgY69j.css +1 -0
- package/web/assets/useCloudOrg-JI0t8ZfS.js +97 -0
- package/web/assets/{useProjectCatalog-C95cDPIr.js → useProjectCatalog-T9HoUKsV.js} +1 -1
- package/web/assets/{xml-1frg7aol.js → xml-DJnU4yP8.js} +1 -1
- package/web/assets/{yaml-DXzDcMOS.js → yaml-DJC6BhFp.js} +1 -1
- package/web/index.html +2 -2
- package/agent-manager-UUSQK6S2.js +0 -7
- package/chunk-Z3KAXI7V.js.map +0 -1
- package/src-Q3PSCMS7.js.map +0 -1
- package/web/assets/AgentScalarChatInterface.vue-Cin_Rbay.js +0 -13
- package/web/assets/AgentTerminalPage-YgCQj_Mj.js +0 -1
- package/web/assets/AiChatPage-cIE_ZdF6.js +0 -1
- package/web/assets/AppLayout-dYfSESzv.js +0 -1
- package/web/assets/AuditPage-Bw3-G8ZM.js +0 -1
- package/web/assets/CloudAccountPage-CA4dMsIm.js +0 -1
- package/web/assets/CloudAccountPage-DjljrEI_.js +0 -1
- package/web/assets/CloudMessagingPage-CbfH2vPo.js +0 -2
- package/web/assets/DashboardPage-Cn3bUyhR.js +0 -1
- package/web/assets/DirectoryPickerDialog-BmsAi5gR.js +0 -1
- package/web/assets/EnvironmentForm-BfF9IFRB.js +0 -108
- package/web/assets/EnvironmentFormPage-CebWv3I_.js +0 -1
- package/web/assets/EnvironmentListPage-DDJGOHvR.js +0 -1
- package/web/assets/KanbanBoardPage-BMXyvHOl.js +0 -4
- package/web/assets/KanbanBoardPage-JjjS4BfO.css +0 -1
- package/web/assets/KanbanListPage-YMm_7vzg.js +0 -1
- package/web/assets/LaunchProjectPage--S6EXtGb.css +0 -1
- package/web/assets/LaunchProjectPage-Da21oFjw.js +0 -1
- package/web/assets/LaunchServicesPage-8YJT1stQ.js +0 -1
- package/web/assets/LaunchServicesPage-pWREsZTD.css +0 -1
- package/web/assets/LogViewer-BYNRWqlP.js +0 -3
- package/web/assets/OrgKeyPrompt-De8D0zzy.js +0 -1
- package/web/assets/ProcessDetailPage-CVwMbU6x.js +0 -1
- package/web/assets/ProjectDetailPage-BjBN3hnN.js +0 -1
- package/web/assets/ProjectListPage-BRXKT6op.js +0 -1
- package/web/assets/RandomJobTestPage-dhDNam5v.js +0 -2
- package/web/assets/ScenarioEditorPage-yOp4ZF14.js +0 -14
- package/web/assets/SendToChatDialog-o4y1Q-OD.js +0 -1
- package/web/assets/ServiceControlsBar-BH1ZEFkK.js +0 -1
- package/web/assets/ServiceDetailPage-CFb0blqq.js +0 -2
- package/web/assets/ServiceFormPage-DzFQ_M1-.js +0 -1
- package/web/assets/SettingsPage-Bcs3tnUy.js +0 -2063
- package/web/assets/UnlockPage-BAxKs_K9.js +0 -1
- package/web/assets/UnlockPage-DE_HJy8h.css +0 -1
- package/web/assets/VariablesTable-CSuAPeF-.js +0 -1
- package/web/assets/VaultMigrationPage-BGJ2PP-7.css +0 -1
- package/web/assets/VaultMigrationPage-BJX9kunL.js +0 -1
- package/web/assets/VersionBadge-B9Wvyvf6.js +0 -1
- package/web/assets/WikiPage-CBZFOPL_.js +0 -1
- package/web/assets/WikiView-DxPrGyFy.js +0 -1
- package/web/assets/add-scalar-classes-vtTXFTZ6.js +0 -387
- package/web/assets/auth-errors-DpUvxKid.js +0 -1
- package/web/assets/autocomplete-BakcEoGP.js +0 -308
- package/web/assets/card-DcpoBJHQ.js +0 -32
- package/web/assets/client-CKBKBNVm.js +0 -24
- package/web/assets/cloud-chat.store-Ci1DBP5j.js +0 -1
- package/web/assets/cloud-session-CzYQ65k8.js +0 -1
- package/web/assets/column-CVuKYYbZ.js +0 -907
- package/web/assets/interface-content-folder.svg-BikaY449.js +0 -1
- package/web/assets/modal-CGT4d1lM.js +0 -5
- package/web/assets/modal-D_N6NaGL.js +0 -1
- package/web/assets/multiselect-C6uayHqj.js +0 -251
- package/web/assets/process.store-CMxuFjFg.js +0 -1
- package/web/assets/router-QZ5Z8Lh7.js +0 -1
- package/web/assets/settings-scope-D7umae8c.js +0 -1
- package/web/assets/settings.store-Dte8TdJb.js +0 -1
- package/web/assets/src-DWvNj-EG.js +0 -1
- package/web/assets/tabpanel-Bkt-f7d6.js +0 -150
- package/web/assets/trpc-Dtgb4BMw.js +0 -1
- package/web/assets/useAiChatDrawer-fzyQ-fyM.js +0 -1
- package/web/assets/useCloudOrg-BdpqnN19.css +0 -1
- package/web/assets/useCloudOrg-Bg7-icbW.js +0 -97
- /package/{agent-manager-UUSQK6S2.js.map → agent-manager-LBV3CVHB.js.map} +0 -0
- /package/web/assets/{uuid-CXjA27vZ.js → uuid-FpfcaBnR.js} +0 -0
|
@@ -85,8 +85,10 @@ import {
|
|
|
85
85
|
registerProjectLoader,
|
|
86
86
|
rememberFile,
|
|
87
87
|
rememberOrgName,
|
|
88
|
+
restartInstance,
|
|
88
89
|
rootOfProjectAmong,
|
|
89
90
|
rootOfProjectRef,
|
|
91
|
+
scheduleSelfRestart,
|
|
90
92
|
serviceStore,
|
|
91
93
|
setEncryptionKey,
|
|
92
94
|
setEncryptionKeyInMemory,
|
|
@@ -101,7 +103,7 @@ import {
|
|
|
101
103
|
vaultIdOfRoot,
|
|
102
104
|
wasRead,
|
|
103
105
|
writeEntity
|
|
104
|
-
} from "./chunk-
|
|
106
|
+
} from "./chunk-OTJQEK4D.js";
|
|
105
107
|
|
|
106
108
|
// ../server/src/create-server.ts
|
|
107
109
|
import express from "express";
|
|
@@ -4376,7 +4378,7 @@ var environmentRouter = router({
|
|
|
4376
4378
|
|
|
4377
4379
|
// ../server/src/trpc/routers/settings.ts
|
|
4378
4380
|
import { promises as dns } from "dns";
|
|
4379
|
-
import { z as
|
|
4381
|
+
import { z as z11 } from "zod";
|
|
4380
4382
|
import { TRPCError as TRPCError8 } from "@trpc/server";
|
|
4381
4383
|
|
|
4382
4384
|
// ../server/src/services/settings-scope.ts
|
|
@@ -4388,6 +4390,122 @@ async function vaultOfProject(projectId) {
|
|
|
4388
4390
|
return refs[0]?.orgId ?? void 0;
|
|
4389
4391
|
}
|
|
4390
4392
|
|
|
4393
|
+
// ../server/src/services/lan-mode.ts
|
|
4394
|
+
import { networkInterfaces } from "os";
|
|
4395
|
+
import { readFile as readFile10, writeFile as writeFile10, rename as rename10, mkdir as mkdir10 } from "fs/promises";
|
|
4396
|
+
import { join as join11 } from "path";
|
|
4397
|
+
import { z as z10 } from "zod";
|
|
4398
|
+
var LOOPBACK = "127.0.0.1";
|
|
4399
|
+
var ANY = "0.0.0.0";
|
|
4400
|
+
var NETWORK_FILE = "network.json";
|
|
4401
|
+
var NetworkFileSchema = z10.object({
|
|
4402
|
+
instances: z10.record(z10.string(), z10.object({ lanEnabled: z10.boolean().default(false) })).default({})
|
|
4403
|
+
});
|
|
4404
|
+
var httpServer = null;
|
|
4405
|
+
function instanceKey() {
|
|
4406
|
+
return env.DATA_DIR;
|
|
4407
|
+
}
|
|
4408
|
+
function networkFilePath() {
|
|
4409
|
+
return join11(machineRoot(), NETWORK_FILE);
|
|
4410
|
+
}
|
|
4411
|
+
async function readFileState() {
|
|
4412
|
+
try {
|
|
4413
|
+
return NetworkFileSchema.parse(JSON.parse(await readFile10(networkFilePath(), "utf-8")));
|
|
4414
|
+
} catch {
|
|
4415
|
+
return { instances: {} };
|
|
4416
|
+
}
|
|
4417
|
+
}
|
|
4418
|
+
async function readPersisted() {
|
|
4419
|
+
const state = await readFileState();
|
|
4420
|
+
return state.instances[instanceKey()]?.lanEnabled ?? false;
|
|
4421
|
+
}
|
|
4422
|
+
async function writePersisted(lanEnabled) {
|
|
4423
|
+
const root = machineRoot();
|
|
4424
|
+
await mkdir10(root, { recursive: true });
|
|
4425
|
+
const state = await readFileState();
|
|
4426
|
+
state.instances[instanceKey()] = { lanEnabled };
|
|
4427
|
+
const filePath = networkFilePath();
|
|
4428
|
+
const tmpPath = filePath + ".tmp";
|
|
4429
|
+
await writeFile10(tmpPath, JSON.stringify(state, null, 2), "utf-8");
|
|
4430
|
+
await rename10(tmpPath, filePath);
|
|
4431
|
+
}
|
|
4432
|
+
function registerHttpServer(server) {
|
|
4433
|
+
httpServer = server;
|
|
4434
|
+
}
|
|
4435
|
+
function lanIps() {
|
|
4436
|
+
const found = [];
|
|
4437
|
+
for (const nets of Object.values(networkInterfaces())) {
|
|
4438
|
+
for (const net of nets ?? []) {
|
|
4439
|
+
if (net.family === "IPv4" && !net.internal) found.push(net.address);
|
|
4440
|
+
}
|
|
4441
|
+
}
|
|
4442
|
+
return found;
|
|
4443
|
+
}
|
|
4444
|
+
function currentPort() {
|
|
4445
|
+
const address = httpServer?.address();
|
|
4446
|
+
return typeof address === "object" && address ? address.port : env.PORT;
|
|
4447
|
+
}
|
|
4448
|
+
function networkInfo() {
|
|
4449
|
+
const port = currentPort();
|
|
4450
|
+
return {
|
|
4451
|
+
host: env.HOST,
|
|
4452
|
+
port,
|
|
4453
|
+
lanEnabled: env.RUNEYA_LAN_PROXY,
|
|
4454
|
+
lanUrls: env.RUNEYA_LAN_PROXY ? lanIps().map((ip) => `http://${ip}:${port}`) : []
|
|
4455
|
+
};
|
|
4456
|
+
}
|
|
4457
|
+
function setHost(host, enabled) {
|
|
4458
|
+
env.HOST = host;
|
|
4459
|
+
env.RUNEYA_HOST = host;
|
|
4460
|
+
env.RUNEYA_LAN_PROXY = enabled;
|
|
4461
|
+
process.env.RUNEYA_HOST = host;
|
|
4462
|
+
process.env.RUNEYA_LAN_PROXY = enabled ? "true" : "false";
|
|
4463
|
+
}
|
|
4464
|
+
async function rebind(host, previousHost) {
|
|
4465
|
+
const server = httpServer;
|
|
4466
|
+
if (!server?.listening) return;
|
|
4467
|
+
const port = currentPort();
|
|
4468
|
+
const listenOn = (target) => new Promise((resolve7, reject) => {
|
|
4469
|
+
const onError = (err) => {
|
|
4470
|
+
server.removeListener("listening", onListening);
|
|
4471
|
+
reject(err);
|
|
4472
|
+
};
|
|
4473
|
+
const onListening = () => {
|
|
4474
|
+
server.removeListener("error", onError);
|
|
4475
|
+
resolve7();
|
|
4476
|
+
};
|
|
4477
|
+
server.once("error", onError);
|
|
4478
|
+
server.once("listening", onListening);
|
|
4479
|
+
server.listen(port, target);
|
|
4480
|
+
});
|
|
4481
|
+
server.close(() => {
|
|
4482
|
+
});
|
|
4483
|
+
try {
|
|
4484
|
+
await listenOn(host);
|
|
4485
|
+
} catch (err) {
|
|
4486
|
+
setHost(previousHost, previousHost === ANY);
|
|
4487
|
+
await listenOn(previousHost).catch(() => {
|
|
4488
|
+
});
|
|
4489
|
+
throw err;
|
|
4490
|
+
}
|
|
4491
|
+
}
|
|
4492
|
+
async function applyPersistedLanMode() {
|
|
4493
|
+
if (env.RUNEYA_LAN_PROXY) return;
|
|
4494
|
+
if (env.HOST !== LOOPBACK && env.HOST !== "localhost") return;
|
|
4495
|
+
if (!await readPersisted()) return;
|
|
4496
|
+
setHost(ANY, true);
|
|
4497
|
+
console.log("[server] LAN mode: activ\xE9 par les r\xE9glages \u2014 \xE9coute sur 0.0.0.0");
|
|
4498
|
+
}
|
|
4499
|
+
async function setLanMode(enabled) {
|
|
4500
|
+
await writePersisted(enabled);
|
|
4501
|
+
const previousHost = env.HOST;
|
|
4502
|
+
const host = enabled ? ANY : LOOPBACK;
|
|
4503
|
+
setHost(host, enabled);
|
|
4504
|
+
if (host !== previousHost) await rebind(host, previousHost);
|
|
4505
|
+
console.log(`[server] LAN mode: ${enabled ? "activ\xE9" : "d\xE9sactiv\xE9"} \u2014 \xE9coute sur ${host}`);
|
|
4506
|
+
return networkInfo();
|
|
4507
|
+
}
|
|
4508
|
+
|
|
4391
4509
|
// ../server/src/trpc/routers/settings.ts
|
|
4392
4510
|
var NotificationPreferencesPatchSchema = NotificationPreferencesSchema.partial().strict();
|
|
4393
4511
|
function maskApiKey2(plaintext) {
|
|
@@ -4395,8 +4513,8 @@ function maskApiKey2(plaintext) {
|
|
|
4395
4513
|
return plaintext.slice(0, 4) + "****" + plaintext.slice(-4);
|
|
4396
4514
|
}
|
|
4397
4515
|
var ScopeShape = {
|
|
4398
|
-
orgId:
|
|
4399
|
-
projectId:
|
|
4516
|
+
orgId: z11.string().max(128).nullable().optional(),
|
|
4517
|
+
projectId: z11.string().max(128).optional()
|
|
4400
4518
|
};
|
|
4401
4519
|
async function scopeOf(input) {
|
|
4402
4520
|
return input?.orgId ?? await vaultOfProject(input?.projectId);
|
|
@@ -4423,6 +4541,27 @@ var settingsRouter = router({
|
|
|
4423
4541
|
// whichever directory the server happened to be started in.
|
|
4424
4542
|
machineDir: machineRoot()
|
|
4425
4543
|
})),
|
|
4544
|
+
/**
|
|
4545
|
+
* Où le serveur écoute, et s'il est joignable depuis le réseau local.
|
|
4546
|
+
*/
|
|
4547
|
+
getNetwork: protectedProcedure.query(() => networkInfo()),
|
|
4548
|
+
/**
|
|
4549
|
+
* Exposer — ou retirer — Runeya du réseau local, sans redémarrage.
|
|
4550
|
+
*
|
|
4551
|
+
* La socket d'écoute est rouverte sur place : les connexions en cours, dont
|
|
4552
|
+
* celle de l'onglet qui bascule, ne sont pas coupées. Le choix est mémorisé
|
|
4553
|
+
* dans les réglages, donc conservé au prochain démarrage.
|
|
4554
|
+
*/
|
|
4555
|
+
setLanMode: protectedProcedure.input(z11.object({ enabled: z11.boolean() })).mutation(async ({ input }) => {
|
|
4556
|
+
try {
|
|
4557
|
+
return await setLanMode(input.enabled);
|
|
4558
|
+
} catch (err) {
|
|
4559
|
+
throw new TRPCError8({
|
|
4560
|
+
code: "INTERNAL_SERVER_ERROR",
|
|
4561
|
+
message: `Impossible de changer l'adresse d'\xE9coute : ${err.message}`
|
|
4562
|
+
});
|
|
4563
|
+
}
|
|
4564
|
+
}),
|
|
4426
4565
|
/**
|
|
4427
4566
|
* Update settings (mode, cloudUrl)
|
|
4428
4567
|
*/
|
|
@@ -4438,7 +4577,7 @@ var settingsRouter = router({
|
|
|
4438
4577
|
/**
|
|
4439
4578
|
* Get notification preferences
|
|
4440
4579
|
*/
|
|
4441
|
-
getNotificationPreferences: protectedProcedure.input(
|
|
4580
|
+
getNotificationPreferences: protectedProcedure.input(z11.object(ScopeShape).optional()).query(async ({ input }) => {
|
|
4442
4581
|
const priv = await settingsManager.getPrivateSettings(await scopeOf(input));
|
|
4443
4582
|
return NotificationPreferencesSchema.parse(priv.notifications ?? {});
|
|
4444
4583
|
}),
|
|
@@ -4469,7 +4608,7 @@ var settingsRouter = router({
|
|
|
4469
4608
|
/**
|
|
4470
4609
|
* Get single parser by ID
|
|
4471
4610
|
*/
|
|
4472
|
-
getParser: protectedProcedure.input(
|
|
4611
|
+
getParser: protectedProcedure.input(z11.object({ id: z11.string().max(128) })).query(async ({ input }) => {
|
|
4473
4612
|
const settings = await settingsManager.getSettings();
|
|
4474
4613
|
const parser = (settings.logParsers || []).find((p) => p.id === input.id);
|
|
4475
4614
|
if (!parser) {
|
|
@@ -4544,7 +4683,7 @@ var settingsRouter = router({
|
|
|
4544
4683
|
/**
|
|
4545
4684
|
* Delete parser by ID
|
|
4546
4685
|
*/
|
|
4547
|
-
deleteParser: protectedProcedure.input(
|
|
4686
|
+
deleteParser: protectedProcedure.input(z11.object({ id: z11.string().max(128) })).mutation(async ({ input }) => {
|
|
4548
4687
|
const settings = await settingsManager.getSettings();
|
|
4549
4688
|
const newParsers = (settings.logParsers || []).filter(
|
|
4550
4689
|
(p) => p.id !== input.id
|
|
@@ -4567,7 +4706,7 @@ var settingsRouter = router({
|
|
|
4567
4706
|
/**
|
|
4568
4707
|
* List AI providers (API keys are masked)
|
|
4569
4708
|
*/
|
|
4570
|
-
listAIProviders: protectedProcedure.input(
|
|
4709
|
+
listAIProviders: protectedProcedure.input(z11.object(ScopeShape).optional()).query(async ({ input }) => {
|
|
4571
4710
|
const vault = await scopeOf(input);
|
|
4572
4711
|
const priv = await settingsManager.getPrivateSettings(vault);
|
|
4573
4712
|
return (priv.aiProviders ?? []).map((p) => {
|
|
@@ -4585,12 +4724,12 @@ var settingsRouter = router({
|
|
|
4585
4724
|
/**
|
|
4586
4725
|
* Create AI provider
|
|
4587
4726
|
*/
|
|
4588
|
-
createAIProvider: protectedProcedure.input(
|
|
4589
|
-
name:
|
|
4727
|
+
createAIProvider: protectedProcedure.input(z11.object({
|
|
4728
|
+
name: z11.string().min(1).max(200),
|
|
4590
4729
|
provider: AIProviderSchema.shape.provider,
|
|
4591
|
-
apiKey:
|
|
4730
|
+
apiKey: z11.string().max(500).optional(),
|
|
4592
4731
|
// optional for providers like Ollama
|
|
4593
|
-
model:
|
|
4732
|
+
model: z11.string().max(200).optional(),
|
|
4594
4733
|
...ScopeShape
|
|
4595
4734
|
})).mutation(async ({ input }) => {
|
|
4596
4735
|
if (input.provider !== "ollama" && !input.apiKey?.trim()) {
|
|
@@ -4623,12 +4762,12 @@ var settingsRouter = router({
|
|
|
4623
4762
|
/**
|
|
4624
4763
|
* Update AI provider (apiKey optional — omit to keep existing)
|
|
4625
4764
|
*/
|
|
4626
|
-
updateAIProvider: protectedProcedure.input(
|
|
4627
|
-
id:
|
|
4628
|
-
name:
|
|
4765
|
+
updateAIProvider: protectedProcedure.input(z11.object({
|
|
4766
|
+
id: z11.string().min(1).max(128),
|
|
4767
|
+
name: z11.string().min(1).max(200).optional(),
|
|
4629
4768
|
provider: AIProviderSchema.shape.provider.optional(),
|
|
4630
|
-
apiKey:
|
|
4631
|
-
model:
|
|
4769
|
+
apiKey: z11.string().min(1).max(500).optional(),
|
|
4770
|
+
model: z11.string().max(200).optional(),
|
|
4632
4771
|
...ScopeShape
|
|
4633
4772
|
})).mutation(async ({ input }) => {
|
|
4634
4773
|
const vault = await scopeOf(input);
|
|
@@ -4661,7 +4800,7 @@ var settingsRouter = router({
|
|
|
4661
4800
|
/**
|
|
4662
4801
|
* Delete AI provider
|
|
4663
4802
|
*/
|
|
4664
|
-
deleteAIProvider: protectedProcedure.input(
|
|
4803
|
+
deleteAIProvider: protectedProcedure.input(z11.object({ id: z11.string().min(1).max(128), ...ScopeShape })).mutation(async ({ input }) => {
|
|
4665
4804
|
const vault = await scopeOf(input);
|
|
4666
4805
|
const priv = await settingsManager.getPrivateSettings(vault);
|
|
4667
4806
|
const providers = priv.aiProviders ?? [];
|
|
@@ -4675,7 +4814,7 @@ var settingsRouter = router({
|
|
|
4675
4814
|
/**
|
|
4676
4815
|
* Set one provider as active (clears active flag on all others)
|
|
4677
4816
|
*/
|
|
4678
|
-
setActiveAIProvider: protectedProcedure.input(
|
|
4817
|
+
setActiveAIProvider: protectedProcedure.input(z11.object({ id: z11.string().min(1).max(128), ...ScopeShape })).mutation(async ({ input }) => {
|
|
4679
4818
|
const vault = await scopeOf(input);
|
|
4680
4819
|
const priv = await settingsManager.getPrivateSettings(vault);
|
|
4681
4820
|
const providers = priv.aiProviders ?? [];
|
|
@@ -4691,7 +4830,7 @@ var settingsRouter = router({
|
|
|
4691
4830
|
/**
|
|
4692
4831
|
* Get Traefik config for a specific agent (never returns credentials or cert key in plain text)
|
|
4693
4832
|
*/
|
|
4694
|
-
getAgentTraefikConfig: protectedProcedure.input(
|
|
4833
|
+
getAgentTraefikConfig: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).query(async ({ input }) => {
|
|
4695
4834
|
const raw = agentStore.getTraefikConfig(input.agentId);
|
|
4696
4835
|
const parsed = raw ? TraefikConfigSchema.safeParse(raw) : null;
|
|
4697
4836
|
const config = parsed?.success ? parsed.data : null;
|
|
@@ -4711,16 +4850,16 @@ var settingsRouter = router({
|
|
|
4711
4850
|
/**
|
|
4712
4851
|
* Update Traefik config for a specific agent (credentials are encrypted before saving)
|
|
4713
4852
|
*/
|
|
4714
|
-
updateAgentTraefikConfig: protectedProcedure.input(
|
|
4715
|
-
agentId:
|
|
4716
|
-
enabled:
|
|
4717
|
-
acmeEmail:
|
|
4718
|
-
wildcardDomain:
|
|
4719
|
-
httpPort:
|
|
4720
|
-
httpsPort:
|
|
4721
|
-
dnsProvider:
|
|
4722
|
-
dnsCredentials:
|
|
4723
|
-
acmeStaging:
|
|
4853
|
+
updateAgentTraefikConfig: protectedProcedure.input(z11.object({
|
|
4854
|
+
agentId: z11.string().max(128),
|
|
4855
|
+
enabled: z11.boolean().optional(),
|
|
4856
|
+
acmeEmail: z11.string().email().max(256).optional(),
|
|
4857
|
+
wildcardDomain: z11.string().max(253).optional(),
|
|
4858
|
+
httpPort: z11.number().int().min(1).max(65535).optional(),
|
|
4859
|
+
httpsPort: z11.number().int().min(1).max(65535).optional(),
|
|
4860
|
+
dnsProvider: z11.string().max(64).optional(),
|
|
4861
|
+
dnsCredentials: z11.record(z11.string().max(64), z11.string().max(2048)).optional(),
|
|
4862
|
+
acmeStaging: z11.boolean().optional()
|
|
4724
4863
|
})).mutation(async ({ input }) => {
|
|
4725
4864
|
const { agentId, ...fields } = input;
|
|
4726
4865
|
const raw = agentStore.getTraefikConfig(agentId);
|
|
@@ -4749,13 +4888,13 @@ var settingsRouter = router({
|
|
|
4749
4888
|
/**
|
|
4750
4889
|
* Get Traefik config files content for a specific agent
|
|
4751
4890
|
*/
|
|
4752
|
-
getAgentTraefikConfigFiles: protectedProcedure.input(
|
|
4891
|
+
getAgentTraefikConfigFiles: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).query(async ({ input }) => {
|
|
4753
4892
|
return agentManager.agentQuery(
|
|
4754
4893
|
input.agentId,
|
|
4755
4894
|
"config.getTraefikConfigFiles"
|
|
4756
4895
|
);
|
|
4757
4896
|
}),
|
|
4758
|
-
getAgentTraefikFileTree: protectedProcedure.input(
|
|
4897
|
+
getAgentTraefikFileTree: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).query(async ({ input }) => {
|
|
4759
4898
|
return agentManager.agentQuery(
|
|
4760
4899
|
input.agentId,
|
|
4761
4900
|
"config.getTraefikFileTree"
|
|
@@ -4764,7 +4903,7 @@ var settingsRouter = router({
|
|
|
4764
4903
|
/**
|
|
4765
4904
|
* Get Traefik container logs for a specific agent (snapshot)
|
|
4766
4905
|
*/
|
|
4767
|
-
getAgentTraefikLogs: protectedProcedure.input(
|
|
4906
|
+
getAgentTraefikLogs: protectedProcedure.input(z11.object({ agentId: z11.string().max(128), lines: z11.number().int().min(1).max(500).default(100) })).query(async ({ input }) => {
|
|
4768
4907
|
const result = await agentManager.agentQuery(
|
|
4769
4908
|
input.agentId,
|
|
4770
4909
|
"config.getTraefikLogs",
|
|
@@ -4775,7 +4914,7 @@ var settingsRouter = router({
|
|
|
4775
4914
|
/**
|
|
4776
4915
|
* Stream Traefik logs in real-time (subscription, yields new lines every 500ms)
|
|
4777
4916
|
*/
|
|
4778
|
-
streamAgentTraefikLogs: protectedProcedure.input(
|
|
4917
|
+
streamAgentTraefikLogs: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).subscription(async function* ({ input, signal }) {
|
|
4779
4918
|
let seen = 0;
|
|
4780
4919
|
while (!signal?.aborted) {
|
|
4781
4920
|
try {
|
|
@@ -4798,7 +4937,7 @@ var settingsRouter = router({
|
|
|
4798
4937
|
/**
|
|
4799
4938
|
* Restart Traefik container on a specific agent (re-pushes config first to handle agent restarts)
|
|
4800
4939
|
*/
|
|
4801
|
-
restartAgentTraefik: protectedProcedure.input(
|
|
4940
|
+
restartAgentTraefik: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).mutation(async ({ input }) => {
|
|
4802
4941
|
const raw = agentStore.getTraefikConfig(input.agentId);
|
|
4803
4942
|
const parsed = raw ? TraefikConfigSchema.safeParse(raw) : null;
|
|
4804
4943
|
const config = parsed?.success ? parsed.data : null;
|
|
@@ -4811,7 +4950,7 @@ var settingsRouter = router({
|
|
|
4811
4950
|
/**
|
|
4812
4951
|
* Force certificate renewal for a specific agent (wipes acme.json + restarts container)
|
|
4813
4952
|
*/
|
|
4814
|
-
renewAgentTraefikCert: protectedProcedure.input(
|
|
4953
|
+
renewAgentTraefikCert: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).mutation(async ({ input }) => {
|
|
4815
4954
|
const raw = agentStore.getTraefikConfig(input.agentId);
|
|
4816
4955
|
const parsed = raw ? TraefikConfigSchema.safeParse(raw) : null;
|
|
4817
4956
|
const config = parsed?.success ? parsed.data : null;
|
|
@@ -4824,7 +4963,7 @@ var settingsRouter = router({
|
|
|
4824
4963
|
/**
|
|
4825
4964
|
* Validate Traefik configuration for a specific agent
|
|
4826
4965
|
*/
|
|
4827
|
-
validateAgentTraefikConfig: protectedProcedure.input(
|
|
4966
|
+
validateAgentTraefikConfig: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).query(async ({ input }) => {
|
|
4828
4967
|
const raw = agentStore.getTraefikConfig(input.agentId);
|
|
4829
4968
|
const parsed = raw ? TraefikConfigSchema.safeParse(raw) : null;
|
|
4830
4969
|
const config = parsed?.success ? parsed.data : null;
|
|
@@ -4926,12 +5065,12 @@ var settingsRouter = router({
|
|
|
4926
5065
|
* Test parser code: compile and run it against sample logs, return per-line results
|
|
4927
5066
|
*/
|
|
4928
5067
|
testParser: protectedProcedure.input(
|
|
4929
|
-
|
|
4930
|
-
code:
|
|
4931
|
-
sampleLogs:
|
|
4932
|
-
|
|
4933
|
-
raw:
|
|
4934
|
-
stream:
|
|
5068
|
+
z11.object({
|
|
5069
|
+
code: z11.string().max(5e4),
|
|
5070
|
+
sampleLogs: z11.array(
|
|
5071
|
+
z11.object({
|
|
5072
|
+
raw: z11.string().max(16384),
|
|
5073
|
+
stream: z11.enum(["stdout", "stderr"])
|
|
4935
5074
|
})
|
|
4936
5075
|
).max(100).default([])
|
|
4937
5076
|
})
|
|
@@ -4975,30 +5114,30 @@ var settingsRouter = router({
|
|
|
4975
5114
|
});
|
|
4976
5115
|
|
|
4977
5116
|
// ../server/src/trpc/routers/editor.ts
|
|
4978
|
-
import { z as
|
|
5117
|
+
import { z as z13 } from "zod";
|
|
4979
5118
|
import { TRPCError as TRPCError9 } from "@trpc/server";
|
|
4980
5119
|
import { execFile as execFile3, spawn as spawn2 } from "child_process";
|
|
4981
5120
|
import { stat as stat4 } from "fs/promises";
|
|
4982
|
-
import { resolve as resolve2, join as
|
|
5121
|
+
import { resolve as resolve2, join as join13 } from "path";
|
|
4983
5122
|
import { homedir as homedir2 } from "os";
|
|
4984
5123
|
|
|
4985
5124
|
// ../server/src/services/user-config-manager.ts
|
|
4986
|
-
import { readFile as
|
|
4987
|
-
import { join as
|
|
5125
|
+
import { readFile as readFile11, writeFile as writeFile11, rename as rename11, mkdir as mkdir11, chmod as chmod9 } from "fs/promises";
|
|
5126
|
+
import { join as join12 } from "path";
|
|
4988
5127
|
import { homedir } from "os";
|
|
4989
|
-
import { z as
|
|
4990
|
-
var CONFIG_DIR =
|
|
5128
|
+
import { z as z12 } from "zod";
|
|
5129
|
+
var CONFIG_DIR = join12(homedir(), ".runeya");
|
|
4991
5130
|
var CONFIG_FILE = "runeya.conf";
|
|
4992
|
-
var EditorPreferencesSchema =
|
|
4993
|
-
default:
|
|
4994
|
-
}).catchall(
|
|
4995
|
-
var ProjectSettingsSchema =
|
|
4996
|
-
settings:
|
|
5131
|
+
var EditorPreferencesSchema = z12.object({
|
|
5132
|
+
default: z12.string().max(64).optional()
|
|
5133
|
+
}).catchall(z12.string().max(64)).refine((obj) => Object.keys(obj).length <= 500, "Too many editor preferences");
|
|
5134
|
+
var ProjectSettingsSchema = z12.object({
|
|
5135
|
+
settings: z12.object({
|
|
4997
5136
|
editors: EditorPreferencesSchema.optional()
|
|
4998
5137
|
}).optional()
|
|
4999
5138
|
});
|
|
5000
|
-
var UserConfigSchema =
|
|
5001
|
-
|
|
5139
|
+
var UserConfigSchema = z12.record(
|
|
5140
|
+
z12.string().max(128),
|
|
5002
5141
|
ProjectSettingsSchema
|
|
5003
5142
|
).refine((obj) => Object.keys(obj).length <= 100, "Too many projects in config");
|
|
5004
5143
|
function configKey(ref) {
|
|
@@ -5007,20 +5146,20 @@ function configKey(ref) {
|
|
|
5007
5146
|
var UserConfigManager = class {
|
|
5008
5147
|
config = null;
|
|
5009
5148
|
async ensureDir() {
|
|
5010
|
-
await
|
|
5149
|
+
await mkdir11(CONFIG_DIR, { recursive: true });
|
|
5011
5150
|
}
|
|
5012
5151
|
async atomicWrite(data) {
|
|
5013
5152
|
await this.ensureDir();
|
|
5014
|
-
const filePath =
|
|
5153
|
+
const filePath = join12(CONFIG_DIR, CONFIG_FILE);
|
|
5015
5154
|
const tmpPath = filePath + ".tmp";
|
|
5016
|
-
await
|
|
5017
|
-
await
|
|
5155
|
+
await writeFile11(tmpPath, JSON.stringify(data, null, 2), "utf-8");
|
|
5156
|
+
await rename11(tmpPath, filePath);
|
|
5018
5157
|
await chmod9(filePath, 384);
|
|
5019
5158
|
}
|
|
5020
5159
|
async getConfig() {
|
|
5021
5160
|
if (!this.config) {
|
|
5022
5161
|
try {
|
|
5023
|
-
const raw = await
|
|
5162
|
+
const raw = await readFile11(join12(CONFIG_DIR, CONFIG_FILE), "utf-8");
|
|
5024
5163
|
const parsed = UserConfigSchema.safeParse(JSON.parse(raw));
|
|
5025
5164
|
this.config = parsed.success ? parsed.data : {};
|
|
5026
5165
|
} catch {
|
|
@@ -5090,16 +5229,16 @@ var editorRouter = router({
|
|
|
5090
5229
|
);
|
|
5091
5230
|
return results;
|
|
5092
5231
|
}),
|
|
5093
|
-
getPreferences: protectedProcedure.input(
|
|
5094
|
-
projectId:
|
|
5095
|
-
orgId:
|
|
5232
|
+
getPreferences: protectedProcedure.input(z13.object({
|
|
5233
|
+
projectId: z13.string().max(128),
|
|
5234
|
+
orgId: z13.string().max(128).nullable().optional()
|
|
5096
5235
|
})).query(async ({ input }) => {
|
|
5097
5236
|
return userConfigManager.getEditorPreferences({ id: input.projectId, orgId: input.orgId });
|
|
5098
5237
|
}),
|
|
5099
|
-
setDefault: protectedProcedure.input(
|
|
5100
|
-
projectId:
|
|
5101
|
-
orgId:
|
|
5102
|
-
editorKey:
|
|
5238
|
+
setDefault: protectedProcedure.input(z13.object({
|
|
5239
|
+
projectId: z13.string().max(128),
|
|
5240
|
+
orgId: z13.string().max(128).nullable().optional(),
|
|
5241
|
+
editorKey: z13.string().max(64)
|
|
5103
5242
|
})).mutation(async ({ input }) => {
|
|
5104
5243
|
if (!EDITOR_BY_KEY.has(input.editorKey)) {
|
|
5105
5244
|
throw new TRPCError9({ code: "BAD_REQUEST", message: `Unknown editor: ${input.editorKey}` });
|
|
@@ -5111,11 +5250,11 @@ var editorRouter = router({
|
|
|
5111
5250
|
);
|
|
5112
5251
|
return { success: true };
|
|
5113
5252
|
}),
|
|
5114
|
-
setServiceEditor: protectedProcedure.input(
|
|
5115
|
-
projectId:
|
|
5116
|
-
orgId:
|
|
5117
|
-
serviceId:
|
|
5118
|
-
editorKey:
|
|
5253
|
+
setServiceEditor: protectedProcedure.input(z13.object({
|
|
5254
|
+
projectId: z13.string().max(128),
|
|
5255
|
+
orgId: z13.string().max(128).nullable().optional(),
|
|
5256
|
+
serviceId: z13.string().max(128),
|
|
5257
|
+
editorKey: z13.string().max(64)
|
|
5119
5258
|
})).mutation(async ({ input }) => {
|
|
5120
5259
|
if (!EDITOR_BY_KEY.has(input.editorKey)) {
|
|
5121
5260
|
throw new TRPCError9({ code: "BAD_REQUEST", message: `Unknown editor: ${input.editorKey}` });
|
|
@@ -5127,10 +5266,10 @@ var editorRouter = router({
|
|
|
5127
5266
|
);
|
|
5128
5267
|
return { success: true };
|
|
5129
5268
|
}),
|
|
5130
|
-
removeServiceEditor: protectedProcedure.input(
|
|
5131
|
-
projectId:
|
|
5132
|
-
orgId:
|
|
5133
|
-
serviceId:
|
|
5269
|
+
removeServiceEditor: protectedProcedure.input(z13.object({
|
|
5270
|
+
projectId: z13.string().max(128),
|
|
5271
|
+
orgId: z13.string().max(128).nullable().optional(),
|
|
5272
|
+
serviceId: z13.string().max(128)
|
|
5134
5273
|
})).mutation(async ({ input }) => {
|
|
5135
5274
|
await userConfigManager.removeEditorPreference(
|
|
5136
5275
|
{ id: input.projectId, orgId: input.orgId },
|
|
@@ -5138,9 +5277,9 @@ var editorRouter = router({
|
|
|
5138
5277
|
);
|
|
5139
5278
|
return { success: true };
|
|
5140
5279
|
}),
|
|
5141
|
-
open: protectedProcedure.input(
|
|
5142
|
-
editorKey:
|
|
5143
|
-
path:
|
|
5280
|
+
open: protectedProcedure.input(z13.object({
|
|
5281
|
+
editorKey: z13.string().max(64),
|
|
5282
|
+
path: z13.string().max(4096)
|
|
5144
5283
|
})).mutation(async ({ input }) => {
|
|
5145
5284
|
const editor = EDITOR_BY_KEY.get(input.editorKey);
|
|
5146
5285
|
if (!editor) {
|
|
@@ -5163,17 +5302,17 @@ var editorRouter = router({
|
|
|
5163
5302
|
child.unref();
|
|
5164
5303
|
return { success: true };
|
|
5165
5304
|
}),
|
|
5166
|
-
openFile: protectedProcedure.input(
|
|
5167
|
-
editorKey:
|
|
5168
|
-
serviceId:
|
|
5169
|
-
relativePath:
|
|
5305
|
+
openFile: protectedProcedure.input(z13.object({
|
|
5306
|
+
editorKey: z13.string().max(64),
|
|
5307
|
+
serviceId: z13.string().max(128),
|
|
5308
|
+
relativePath: z13.string().max(4096)
|
|
5170
5309
|
})).mutation(async ({ input }) => {
|
|
5171
5310
|
const editor = EDITOR_BY_KEY.get(input.editorKey);
|
|
5172
5311
|
if (!editor) {
|
|
5173
5312
|
throw new TRPCError9({ code: "BAD_REQUEST", message: `Unknown editor: ${input.editorKey}` });
|
|
5174
5313
|
}
|
|
5175
5314
|
const cwd = await getServiceCwd(input.serviceId);
|
|
5176
|
-
const filePath =
|
|
5315
|
+
const filePath = join13(cwd, input.relativePath);
|
|
5177
5316
|
if (!filePath.startsWith(cwd)) {
|
|
5178
5317
|
throw new TRPCError9({ code: "BAD_REQUEST", message: "Path traversal not allowed" });
|
|
5179
5318
|
}
|
|
@@ -5194,65 +5333,65 @@ var editorRouter = router({
|
|
|
5194
5333
|
});
|
|
5195
5334
|
|
|
5196
5335
|
// ../server/src/trpc/routers/api-keys.ts
|
|
5197
|
-
import { z as
|
|
5336
|
+
import { z as z14 } from "zod";
|
|
5198
5337
|
import { TRPCError as TRPCError10 } from "@trpc/server";
|
|
5199
|
-
import { mkdir as
|
|
5200
|
-
import { join as
|
|
5338
|
+
import { mkdir as mkdir12, writeFile as writeFile12 } from "fs/promises";
|
|
5339
|
+
import { join as join14, dirname as dirname7 } from "path";
|
|
5201
5340
|
var ALLOWED_SKILL_PATHS = /* @__PURE__ */ new Set([
|
|
5202
5341
|
".claude/skills/runeya/SKILL.md",
|
|
5203
5342
|
".cursor/rules/runeya.mdc",
|
|
5204
5343
|
".windsurf/rules/runeya.md"
|
|
5205
5344
|
]);
|
|
5206
|
-
var KeyInputSchema =
|
|
5207
|
-
name:
|
|
5345
|
+
var KeyInputSchema = z14.object({
|
|
5346
|
+
name: z14.string().min(1).max(200),
|
|
5208
5347
|
scopes: ApiKeyScopeSchema,
|
|
5209
|
-
isPublic:
|
|
5348
|
+
isPublic: z14.boolean().default(false)
|
|
5210
5349
|
});
|
|
5211
5350
|
var apiKeysRouter = router({
|
|
5212
5351
|
list: protectedProcedure.query(() => apiKeyStore.list()),
|
|
5213
|
-
create: protectedProcedure.input(KeyInputSchema.extend({ orgId:
|
|
5352
|
+
create: protectedProcedure.input(KeyInputSchema.extend({ orgId: z14.string().min(1).max(128).nullable().optional() })).mutation(
|
|
5214
5353
|
({ input }) => apiKeyStore.create(input.name, input.scopes, input.isPublic, input.orgId ?? null)
|
|
5215
5354
|
),
|
|
5216
5355
|
/**
|
|
5217
5356
|
* Renvoie le secret d'une seule clé, sur demande explicite. `list` ne le
|
|
5218
5357
|
* contient pas : une clé ne doit jamais être re-servie en masse.
|
|
5219
5358
|
*/
|
|
5220
|
-
reveal: protectedProcedure.input(
|
|
5359
|
+
reveal: protectedProcedure.input(z14.object({ id: z14.string().max(128) })).query(async ({ input }) => {
|
|
5221
5360
|
const key = await apiKeyStore.reveal(input.id);
|
|
5222
5361
|
if (!key) throw new TRPCError10({ code: "NOT_FOUND", message: "API key not found" });
|
|
5223
5362
|
return { key };
|
|
5224
5363
|
}),
|
|
5225
|
-
update: protectedProcedure.input(KeyInputSchema.extend({ id:
|
|
5364
|
+
update: protectedProcedure.input(KeyInputSchema.extend({ id: z14.string().max(128) })).mutation(async ({ input }) => {
|
|
5226
5365
|
const updated = await apiKeyStore.update(input.id, input.name, input.scopes, input.isPublic);
|
|
5227
5366
|
if (!updated) throw new TRPCError10({ code: "NOT_FOUND", message: "API key not found" });
|
|
5228
5367
|
return maskApiKey(updated);
|
|
5229
5368
|
}),
|
|
5230
|
-
remove: protectedProcedure.input(
|
|
5369
|
+
remove: protectedProcedure.input(z14.object({ id: z14.string().max(128) })).mutation(async ({ input }) => {
|
|
5231
5370
|
const removed = await apiKeyStore.remove(input.id);
|
|
5232
5371
|
if (!removed) throw new TRPCError10({ code: "NOT_FOUND", message: "API key not found" });
|
|
5233
5372
|
return { success: true };
|
|
5234
5373
|
}),
|
|
5235
|
-
renewKey: protectedProcedure.input(
|
|
5374
|
+
renewKey: protectedProcedure.input(z14.object({ id: z14.string().max(128) })).mutation(async ({ input }) => {
|
|
5236
5375
|
const renewed = await apiKeyStore.renewKey(input.id);
|
|
5237
5376
|
if (!renewed) throw new TRPCError10({ code: "NOT_FOUND", message: "API key not found" });
|
|
5238
5377
|
return renewed;
|
|
5239
5378
|
}),
|
|
5240
|
-
writeSkillFile: protectedProcedure.input(
|
|
5241
|
-
relativePath:
|
|
5242
|
-
content:
|
|
5379
|
+
writeSkillFile: protectedProcedure.input(z14.object({
|
|
5380
|
+
relativePath: z14.string().max(256),
|
|
5381
|
+
content: z14.string().max(32768)
|
|
5243
5382
|
})).mutation(async ({ input }) => {
|
|
5244
5383
|
if (!ALLOWED_SKILL_PATHS.has(input.relativePath)) {
|
|
5245
5384
|
throw new TRPCError10({ code: "BAD_REQUEST", message: "Chemin non autoris\xE9" });
|
|
5246
5385
|
}
|
|
5247
|
-
const abs =
|
|
5248
|
-
await
|
|
5249
|
-
await
|
|
5386
|
+
const abs = join14(await resolveWorkspaceCwd({}), input.relativePath);
|
|
5387
|
+
await mkdir12(dirname7(abs), { recursive: true });
|
|
5388
|
+
await writeFile12(abs, input.content, { encoding: "utf-8", mode: 420 });
|
|
5250
5389
|
return { path: input.relativePath };
|
|
5251
5390
|
})
|
|
5252
5391
|
});
|
|
5253
5392
|
|
|
5254
5393
|
// ../server/src/trpc/routers/chat.ts
|
|
5255
|
-
import { z as
|
|
5394
|
+
import { z as z17 } from "zod";
|
|
5256
5395
|
import Anthropic2 from "@anthropic-ai/sdk";
|
|
5257
5396
|
import OpenAI2 from "openai";
|
|
5258
5397
|
import { execFile as execFile4 } from "child_process";
|
|
@@ -5606,11 +5745,11 @@ function buildApiDocs(apiBaseUrl, apiToken) {
|
|
|
5606
5745
|
}
|
|
5607
5746
|
|
|
5608
5747
|
// ../server/src/services/claude-transcript-sync.ts
|
|
5609
|
-
import { readdir as readdir2, access, readFile as
|
|
5748
|
+
import { readdir as readdir2, access, readFile as readFile12 } from "fs/promises";
|
|
5610
5749
|
import { watch } from "fs";
|
|
5611
5750
|
import { homedir as homedir3 } from "os";
|
|
5612
|
-
import { join as
|
|
5613
|
-
var PROJECTS_DIR =
|
|
5751
|
+
import { join as join15 } from "path";
|
|
5752
|
+
var PROJECTS_DIR = join15(homedir3(), ".claude", "projects");
|
|
5614
5753
|
var DEFAULT_TITLES = /* @__PURE__ */ new Set(["", "New conversation", "Nouvelle conversation"]);
|
|
5615
5754
|
async function findClaudeSessionFile(sessionId) {
|
|
5616
5755
|
let entries2;
|
|
@@ -5621,7 +5760,7 @@ async function findClaudeSessionFile(sessionId) {
|
|
|
5621
5760
|
}
|
|
5622
5761
|
const filename = `${sessionId}.jsonl`;
|
|
5623
5762
|
for (const dir of entries2) {
|
|
5624
|
-
const candidate =
|
|
5763
|
+
const candidate = join15(PROJECTS_DIR, dir, filename);
|
|
5625
5764
|
try {
|
|
5626
5765
|
await access(candidate);
|
|
5627
5766
|
return candidate;
|
|
@@ -5636,7 +5775,7 @@ async function claudeSessionExists(sessionId) {
|
|
|
5636
5775
|
async function readClaudeTranscript(sessionId) {
|
|
5637
5776
|
const path = await findClaudeSessionFile(sessionId);
|
|
5638
5777
|
if (!path) return { found: false, path: null, entries: [] };
|
|
5639
|
-
const raw = await
|
|
5778
|
+
const raw = await readFile12(path, "utf-8");
|
|
5640
5779
|
const entries2 = [];
|
|
5641
5780
|
for (const line of raw.split("\n")) {
|
|
5642
5781
|
if (!line.trim()) continue;
|
|
@@ -5784,7 +5923,7 @@ async function startClaudeTranscriptWatcher() {
|
|
|
5784
5923
|
}
|
|
5785
5924
|
for (const dir of topLevel) {
|
|
5786
5925
|
try {
|
|
5787
|
-
const w = watch(
|
|
5926
|
+
const w = watch(join15(PROJECTS_DIR, dir), (_event, filename) => {
|
|
5788
5927
|
handleFsEvent(filename ? filename.toString() : null);
|
|
5789
5928
|
});
|
|
5790
5929
|
w.on("error", () => {
|
|
@@ -5810,8 +5949,8 @@ function stopClaudeTranscriptWatcher() {
|
|
|
5810
5949
|
// ../server/src/services/codex-sessions.ts
|
|
5811
5950
|
import { readdir as readdir3 } from "fs/promises";
|
|
5812
5951
|
import { homedir as homedir4 } from "os";
|
|
5813
|
-
import { join as
|
|
5814
|
-
var SESSIONS_DIR =
|
|
5952
|
+
import { join as join16 } from "path";
|
|
5953
|
+
var SESSIONS_DIR = join16(homedir4(), ".codex", "sessions");
|
|
5815
5954
|
async function findCodexSessionFile(sessionId) {
|
|
5816
5955
|
const suffix = `-${sessionId}.jsonl`;
|
|
5817
5956
|
async function walk(dir) {
|
|
@@ -5822,7 +5961,7 @@ async function findCodexSessionFile(sessionId) {
|
|
|
5822
5961
|
return null;
|
|
5823
5962
|
}
|
|
5824
5963
|
for (const entry of entries2) {
|
|
5825
|
-
const full =
|
|
5964
|
+
const full = join16(dir, entry.name);
|
|
5826
5965
|
if (entry.isDirectory()) {
|
|
5827
5966
|
const found = await walk(full);
|
|
5828
5967
|
if (found) return found;
|
|
@@ -5842,12 +5981,12 @@ async function codexSessionExists(sessionId) {
|
|
|
5842
5981
|
import { TRPCError as TRPCError12 } from "@trpc/server";
|
|
5843
5982
|
|
|
5844
5983
|
// ../server/src/trpc/shared-schemas.ts
|
|
5845
|
-
import { z as
|
|
5846
|
-
var Id128Schema =
|
|
5847
|
-
var ConversationIdSchema =
|
|
5848
|
-
var NameSchema =
|
|
5849
|
-
var ShortString200Schema =
|
|
5850
|
-
var DescriptionSchema =
|
|
5984
|
+
import { z as z15 } from "zod";
|
|
5985
|
+
var Id128Schema = z15.string().max(128);
|
|
5986
|
+
var ConversationIdSchema = z15.string().max(128);
|
|
5987
|
+
var NameSchema = z15.string().min(1).max(200);
|
|
5988
|
+
var ShortString200Schema = z15.string().max(200);
|
|
5989
|
+
var DescriptionSchema = z15.string().max(2e3);
|
|
5851
5990
|
var OptionalProviderIdSchema = Id128Schema.optional();
|
|
5852
5991
|
|
|
5853
5992
|
// ../server/src/services/llms-txt-generator.ts
|
|
@@ -6782,11 +6921,11 @@ var ScenarioStore = class {
|
|
|
6782
6921
|
var scenarioStore = new ScenarioStore();
|
|
6783
6922
|
|
|
6784
6923
|
// ../server/src/services/scenario-run-store.ts
|
|
6785
|
-
import { mkdir as
|
|
6786
|
-
import { join as
|
|
6924
|
+
import { mkdir as mkdir14, rm as rm2, readFile as readFile14 } from "fs/promises";
|
|
6925
|
+
import { join as join17 } from "path";
|
|
6787
6926
|
|
|
6788
6927
|
// ../server/src/services/run-store-utils.ts
|
|
6789
|
-
import { chmod as chmod10, mkdir as
|
|
6928
|
+
import { chmod as chmod10, mkdir as mkdir13, rename as rename12, writeFile as writeFile13, readFile as readFile13 } from "fs/promises";
|
|
6790
6929
|
import { dirname as dirname8, resolve as resolve3, sep } from "path";
|
|
6791
6930
|
var SAFE_PATH_SEGMENT_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/;
|
|
6792
6931
|
function resolveConversationRunDir(rootDirName, conversationId) {
|
|
@@ -6801,10 +6940,10 @@ function resolveConversationRunDir(rootDirName, conversationId) {
|
|
|
6801
6940
|
return dir;
|
|
6802
6941
|
}
|
|
6803
6942
|
async function atomicWriteSecure(filePath, content) {
|
|
6804
|
-
await
|
|
6943
|
+
await mkdir13(dirname8(filePath), { recursive: true });
|
|
6805
6944
|
const tmpPath = `${filePath}.tmp`;
|
|
6806
|
-
await
|
|
6807
|
-
await
|
|
6945
|
+
await writeFile13(tmpPath, content, "utf-8");
|
|
6946
|
+
await rename12(tmpPath, filePath);
|
|
6808
6947
|
await chmod10(filePath, 384);
|
|
6809
6948
|
}
|
|
6810
6949
|
async function atomicWriteJsonSecure(filePath, data, pretty = false) {
|
|
@@ -6812,7 +6951,7 @@ async function atomicWriteJsonSecure(filePath, data, pretty = false) {
|
|
|
6812
6951
|
}
|
|
6813
6952
|
async function readJsonFileSafe(filePath) {
|
|
6814
6953
|
try {
|
|
6815
|
-
const raw = await
|
|
6954
|
+
const raw = await readFile13(filePath, "utf-8");
|
|
6816
6955
|
return JSON.parse(raw);
|
|
6817
6956
|
} catch {
|
|
6818
6957
|
return null;
|
|
@@ -6835,7 +6974,7 @@ var ScenarioRunStore = class _ScenarioRunStore {
|
|
|
6835
6974
|
}
|
|
6836
6975
|
async initializeConversationWorkspace(conversationId, scenario, userInput) {
|
|
6837
6976
|
const dir = this.getRunDir(conversationId);
|
|
6838
|
-
await
|
|
6977
|
+
await mkdir14(dir, { recursive: true });
|
|
6839
6978
|
await this.saveScenarioSnapshot(conversationId, scenario);
|
|
6840
6979
|
const nodesById = new Map(scenario.nodes.map((p) => [p.id, p]));
|
|
6841
6980
|
const teamMap = new Map(scenario.groups.map((t2) => [t2.id, t2.name]));
|
|
@@ -6860,8 +6999,8 @@ var ScenarioRunStore = class _ScenarioRunStore {
|
|
|
6860
6999
|
"- Use read-only references from linked upstream files as context.",
|
|
6861
7000
|
""
|
|
6862
7001
|
].join("\n");
|
|
6863
|
-
await atomicWriteSecure(
|
|
6864
|
-
await atomicWriteSecure(
|
|
7002
|
+
await atomicWriteSecure(join17(dir, "README.md"), overview);
|
|
7003
|
+
await atomicWriteSecure(join17(dir, "USER_REQUEST.md"), `# User request
|
|
6865
7004
|
|
|
6866
7005
|
${userInput.trim() || "(empty)"}
|
|
6867
7006
|
`);
|
|
@@ -6887,7 +7026,7 @@ ${userInput.trim() || "(empty)"}
|
|
|
6887
7026
|
"- Waiting for assignment.",
|
|
6888
7027
|
""
|
|
6889
7028
|
].join("\n");
|
|
6890
|
-
await atomicWriteSecure(
|
|
7029
|
+
await atomicWriteSecure(join17(dir, fileName), content);
|
|
6891
7030
|
}
|
|
6892
7031
|
}
|
|
6893
7032
|
async deleteRunDir(conversationId) {
|
|
@@ -6947,7 +7086,7 @@ ${userInput.trim() || "(empty)"}
|
|
|
6947
7086
|
if (!runState) return;
|
|
6948
7087
|
try {
|
|
6949
7088
|
const dir = this.getRunDir(conversationId);
|
|
6950
|
-
await
|
|
7089
|
+
await mkdir14(dir, { recursive: true });
|
|
6951
7090
|
const data = {
|
|
6952
7091
|
nodeStates: { ...runState.nodeStates },
|
|
6953
7092
|
nodeOutputs: { ...runState.nodeOutputs },
|
|
@@ -6955,18 +7094,18 @@ ${userInput.trim() || "(empty)"}
|
|
|
6955
7094
|
...Object.keys(runState.nodeAgentIds).length > 0 ? { nodeAgentIds: { ...runState.nodeAgentIds } } : {},
|
|
6956
7095
|
...Object.keys(runState.waitingInputs).length > 0 ? { waitingInputs: { ...runState.waitingInputs } } : {}
|
|
6957
7096
|
};
|
|
6958
|
-
await atomicWriteJsonSecure(
|
|
7097
|
+
await atomicWriteJsonSecure(join17(dir, "run-state.json"), data);
|
|
6959
7098
|
} catch {
|
|
6960
7099
|
}
|
|
6961
7100
|
}
|
|
6962
7101
|
async loadPersistedRunState(conversationId) {
|
|
6963
7102
|
const dir = this.getRunDir(conversationId);
|
|
6964
|
-
return readJsonFileSafe(
|
|
7103
|
+
return readJsonFileSafe(join17(dir, "run-state.json"));
|
|
6965
7104
|
}
|
|
6966
7105
|
async readUserRequest(conversationId) {
|
|
6967
7106
|
try {
|
|
6968
7107
|
const dir = this.getRunDir(conversationId);
|
|
6969
|
-
const content = await
|
|
7108
|
+
const content = await readFile14(join17(dir, "USER_REQUEST.md"), "utf-8");
|
|
6970
7109
|
return content.replace(/^#\s*User request\s*\n+/, "").trim() || null;
|
|
6971
7110
|
} catch {
|
|
6972
7111
|
return null;
|
|
@@ -6975,23 +7114,23 @@ ${userInput.trim() || "(empty)"}
|
|
|
6975
7114
|
async readReadme(conversationId) {
|
|
6976
7115
|
try {
|
|
6977
7116
|
const dir = this.getRunDir(conversationId);
|
|
6978
|
-
return await
|
|
7117
|
+
return await readFile14(join17(dir, "README.md"), "utf-8");
|
|
6979
7118
|
} catch {
|
|
6980
7119
|
return null;
|
|
6981
7120
|
}
|
|
6982
7121
|
}
|
|
6983
7122
|
async saveScenarioSnapshot(conversationId, scenario) {
|
|
6984
7123
|
const dir = this.getRunDir(conversationId);
|
|
6985
|
-
await
|
|
7124
|
+
await mkdir14(dir, { recursive: true });
|
|
6986
7125
|
await atomicWriteJsonSecure(
|
|
6987
|
-
|
|
7126
|
+
join17(dir, _ScenarioRunStore.SCENARIO_SNAPSHOT_FILE),
|
|
6988
7127
|
scenario,
|
|
6989
7128
|
true
|
|
6990
7129
|
);
|
|
6991
7130
|
}
|
|
6992
7131
|
async loadScenarioSnapshot(conversationId) {
|
|
6993
7132
|
const dir = this.getRunDir(conversationId);
|
|
6994
|
-
return readJsonFileSafe(
|
|
7133
|
+
return readJsonFileSafe(join17(dir, _ScenarioRunStore.SCENARIO_SNAPSHOT_FILE));
|
|
6995
7134
|
}
|
|
6996
7135
|
};
|
|
6997
7136
|
var scenarioRunStore = new ScenarioRunStore();
|
|
@@ -7037,9 +7176,9 @@ async function fetchProviderModels(provider, plaintextKey) {
|
|
|
7037
7176
|
|
|
7038
7177
|
// ../server/src/services/image-storage.service.ts
|
|
7039
7178
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
7040
|
-
import { mkdir as
|
|
7179
|
+
import { mkdir as mkdir15, writeFile as writeFile14, readFile as readFile15, unlink as unlink3, readdir as readdir4 } from "fs/promises";
|
|
7041
7180
|
import { existsSync as existsSync2 } from "fs";
|
|
7042
|
-
import { join as
|
|
7181
|
+
import { join as join18, extname, resolve as resolve4, sep as sep2 } from "path";
|
|
7043
7182
|
var ALLOWED_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
7044
7183
|
"image/png",
|
|
7045
7184
|
"image/jpeg",
|
|
@@ -7056,7 +7195,7 @@ var ImageStorageService = class {
|
|
|
7056
7195
|
this.dir = dir;
|
|
7057
7196
|
}
|
|
7058
7197
|
async ensureTmpDir() {
|
|
7059
|
-
await
|
|
7198
|
+
await mkdir15(this.dir, { recursive: true, mode: 448 });
|
|
7060
7199
|
}
|
|
7061
7200
|
async saveImage(buffer, originalName, mimeType, contextId) {
|
|
7062
7201
|
if (!ALLOWED_MIME_TYPES.has(mimeType)) {
|
|
@@ -7076,15 +7215,15 @@ var ImageStorageService = class {
|
|
|
7076
7215
|
const imageId = randomUUID4();
|
|
7077
7216
|
const safeExt = ext.replace(/[^a-z.]/g, "");
|
|
7078
7217
|
const fileName = `${imageId}${safeExt}`;
|
|
7079
|
-
const filePath =
|
|
7218
|
+
const filePath = join18(this.dir, fileName);
|
|
7080
7219
|
const resolvedPath = resolve4(filePath);
|
|
7081
7220
|
const resolvedDir = resolve4(this.dir);
|
|
7082
7221
|
if (resolvedPath !== resolvedDir && !resolvedPath.startsWith(resolvedDir + sep2)) {
|
|
7083
7222
|
throw new Error("Invalid file path");
|
|
7084
7223
|
}
|
|
7085
|
-
await
|
|
7224
|
+
await writeFile14(filePath, buffer, { mode: 384 });
|
|
7086
7225
|
const meta = { imageId, filePath, mimeType, originalName, createdAt: Date.now(), contextId };
|
|
7087
|
-
await
|
|
7226
|
+
await writeFile14(`${filePath}.meta.json`, JSON.stringify(meta), { encoding: "utf-8", mode: 384 });
|
|
7088
7227
|
return meta;
|
|
7089
7228
|
}
|
|
7090
7229
|
/**
|
|
@@ -7102,7 +7241,7 @@ var ImageStorageService = class {
|
|
|
7102
7241
|
const files = await readdir4(this.dir);
|
|
7103
7242
|
const metaFile = files.find((f) => f.startsWith(imageId) && f.endsWith(".meta.json"));
|
|
7104
7243
|
if (!metaFile) return null;
|
|
7105
|
-
const raw = JSON.parse(await
|
|
7244
|
+
const raw = JSON.parse(await readFile15(join18(this.dir, metaFile), "utf-8"));
|
|
7106
7245
|
if (expectedContextId !== void 0 && raw.contextId !== expectedContextId) return null;
|
|
7107
7246
|
if (!existsSync2(raw.filePath)) return null;
|
|
7108
7247
|
return { filePath: raw.filePath, mimeType: raw.mimeType, contextId: raw.contextId };
|
|
@@ -7128,7 +7267,7 @@ var ImageStorageService = class {
|
|
|
7128
7267
|
await Promise.all(
|
|
7129
7268
|
files.filter((f) => f.endsWith(".meta.json")).map(async (file) => {
|
|
7130
7269
|
try {
|
|
7131
|
-
const raw = JSON.parse(await
|
|
7270
|
+
const raw = JSON.parse(await readFile15(join18(this.dir, file), "utf-8"));
|
|
7132
7271
|
if (raw.contextId === contextId) {
|
|
7133
7272
|
await unlink3(raw.filePath).catch(() => {
|
|
7134
7273
|
});
|
|
@@ -7143,7 +7282,7 @@ var ImageStorageService = class {
|
|
|
7143
7282
|
async readImageAsBase64(imageId, expectedContextId) {
|
|
7144
7283
|
const result = await this.getImagePath(imageId, expectedContextId);
|
|
7145
7284
|
if (!result) return null;
|
|
7146
|
-
const buffer = await
|
|
7285
|
+
const buffer = await readFile15(result.filePath);
|
|
7147
7286
|
return { base64: buffer.toString("base64"), mimeType: result.mimeType };
|
|
7148
7287
|
}
|
|
7149
7288
|
async listExpiredImages(ttlMs = IMAGE_TTL_MS) {
|
|
@@ -7158,7 +7297,7 @@ var ImageStorageService = class {
|
|
|
7158
7297
|
for (const file of files) {
|
|
7159
7298
|
if (!file.endsWith(".meta.json")) continue;
|
|
7160
7299
|
try {
|
|
7161
|
-
const raw = JSON.parse(await
|
|
7300
|
+
const raw = JSON.parse(await readFile15(join18(this.dir, file), "utf-8"));
|
|
7162
7301
|
if (now - raw.createdAt > ttlMs) expired.push(raw);
|
|
7163
7302
|
} catch {
|
|
7164
7303
|
}
|
|
@@ -7224,7 +7363,7 @@ async function resolveImagesToBase64(images, contextId) {
|
|
|
7224
7363
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
7225
7364
|
|
|
7226
7365
|
// ../server/src/trpc/routers/cloud-auth.ts
|
|
7227
|
-
import { z as
|
|
7366
|
+
import { z as z16 } from "zod";
|
|
7228
7367
|
import { hostname } from "os";
|
|
7229
7368
|
import { basename } from "path";
|
|
7230
7369
|
import { TRPCError as TRPCError11 } from "@trpc/server";
|
|
@@ -7259,7 +7398,7 @@ function isAllowedProxyPath(path) {
|
|
|
7259
7398
|
}
|
|
7260
7399
|
var cloudAuthRouter = router({
|
|
7261
7400
|
/** Build the cloud authorization URL to open in the browser. */
|
|
7262
|
-
startLogin: protectedProcedure.input(
|
|
7401
|
+
startLogin: protectedProcedure.input(z16.object({ returnTo: z16.string().url().max(2048) })).mutation(async ({ input }) => {
|
|
7263
7402
|
if (!isLocalOrigin(input.returnTo)) {
|
|
7264
7403
|
throw new TRPCError11({ code: "BAD_REQUEST", message: "returnTo must be a local origin." });
|
|
7265
7404
|
}
|
|
@@ -7304,7 +7443,7 @@ var cloudAuthRouter = router({
|
|
|
7304
7443
|
* drops the session, and the local token is dropped here too, so nothing is
|
|
7305
7444
|
* left holding a dead credential.
|
|
7306
7445
|
*/
|
|
7307
|
-
revokeDevice: protectedProcedure.input(
|
|
7446
|
+
revokeDevice: protectedProcedure.input(z16.object({ id: z16.string().min(1).max(128) })).mutation(async ({ input }) => {
|
|
7308
7447
|
const res = await cloudFetch2("/api/auth/device/revoke", { method: "POST", body: { id: input.id } });
|
|
7309
7448
|
if (!res.ok) {
|
|
7310
7449
|
if (res.status === 401) await cloudSessionStore.clear();
|
|
@@ -7321,11 +7460,11 @@ var cloudAuthRouter = router({
|
|
|
7321
7460
|
* the cloud: the web UI asks its own server, which holds the credential.
|
|
7322
7461
|
*/
|
|
7323
7462
|
proxy: protectedProcedure.input(
|
|
7324
|
-
|
|
7325
|
-
path:
|
|
7326
|
-
method:
|
|
7327
|
-
query:
|
|
7328
|
-
body:
|
|
7463
|
+
z16.object({
|
|
7464
|
+
path: z16.string().min(1).max(512),
|
|
7465
|
+
method: z16.enum(["GET", "POST"]).default("GET"),
|
|
7466
|
+
query: z16.record(z16.string().max(128), z16.string().max(2048)).optional(),
|
|
7467
|
+
body: z16.unknown().optional()
|
|
7329
7468
|
})
|
|
7330
7469
|
).mutation(async ({ input }) => {
|
|
7331
7470
|
if (!isAllowedProxyPath(input.path)) {
|
|
@@ -7386,12 +7525,12 @@ async function callCloud(path, init = {}) {
|
|
|
7386
7525
|
const res = await cloudFetch2(`/api/auth${path}`, init);
|
|
7387
7526
|
if (!res.ok) {
|
|
7388
7527
|
console.error("[kanban-store] cloud call failed: %s %s", res.status, path);
|
|
7389
|
-
return { ok: false, data: null, reason: planGateMessage(res.status, path) };
|
|
7528
|
+
return { ok: false, data: null, reason: planGateMessage(res.status, path), status: res.status };
|
|
7390
7529
|
}
|
|
7391
|
-
return { ok: true, data: await res.json(), reason: null };
|
|
7530
|
+
return { ok: true, data: await res.json(), reason: null, status: res.status };
|
|
7392
7531
|
} catch (err) {
|
|
7393
7532
|
console.error("[kanban-store] cloud call errored:", err);
|
|
7394
|
-
return { ok: false, data: null, reason: `Appel au cloud impossible : ${err.message}
|
|
7533
|
+
return { ok: false, data: null, reason: `Appel au cloud impossible : ${err.message}`, status: null };
|
|
7395
7534
|
}
|
|
7396
7535
|
}
|
|
7397
7536
|
function must(res) {
|
|
@@ -7470,6 +7609,20 @@ var KanbanStore = class {
|
|
|
7470
7609
|
});
|
|
7471
7610
|
return res.ok;
|
|
7472
7611
|
}
|
|
7612
|
+
/**
|
|
7613
|
+
* Ajouter une carte, sans réécrire le tableau.
|
|
7614
|
+
*
|
|
7615
|
+
* La colonne se nomme par son titre : c'est ce que connaît une IA qui lit un
|
|
7616
|
+
* tableau, et le cloud le résout. Deux ajouts qui se croisent se rangent tous
|
|
7617
|
+
* les deux, ce qu'une sauvegarde de tableau entier ne garantissait pas.
|
|
7618
|
+
*/
|
|
7619
|
+
async addCard(boardId, input) {
|
|
7620
|
+
const res = await callCloud("/kanban/card/add", {
|
|
7621
|
+
method: "POST",
|
|
7622
|
+
body: { boardId, ...input }
|
|
7623
|
+
});
|
|
7624
|
+
return { card: res.data?.card ?? null, unsupported: res.status === 404 };
|
|
7625
|
+
}
|
|
7473
7626
|
/** Déplacer une carte, sans réécrire le tableau. */
|
|
7474
7627
|
async moveCard(boardId, cardId, toColumnId) {
|
|
7475
7628
|
const res = await callCloud("/kanban/card/move", {
|
|
@@ -7562,7 +7715,6 @@ async function executeKanbanCommands(boardId, cardId, commands, conversationId)
|
|
|
7562
7715
|
return;
|
|
7563
7716
|
}
|
|
7564
7717
|
}
|
|
7565
|
-
let pendingBoardWrite = false;
|
|
7566
7718
|
for (const cmd of commands) {
|
|
7567
7719
|
if (cmd.type === "move_card" && cmd.columnTitle) {
|
|
7568
7720
|
const target = board.columns.find(
|
|
@@ -7578,11 +7730,9 @@ async function executeKanbanCommands(boardId, cardId, commands, conversationId)
|
|
|
7578
7730
|
const ok = await kanbanStore.addComment(board.id, cardId, cmd.comment, conversationId);
|
|
7579
7731
|
if (!ok) console.warn(`[kanban-commands] add_comment failed: card=${cardId}`);
|
|
7580
7732
|
} else if (cmd.type === "add_card" && cmd.columnTitle && cmd.cardTitle) {
|
|
7581
|
-
|
|
7582
|
-
pendingBoardWrite = true;
|
|
7733
|
+
await addCardOrFallback(board, cmd.columnTitle, cmd.cardTitle, cmd.cardContent);
|
|
7583
7734
|
}
|
|
7584
7735
|
}
|
|
7585
|
-
if (pendingBoardWrite) await kanbanStore.update({ id: board.id, columns: board.columns });
|
|
7586
7736
|
}
|
|
7587
7737
|
async function executeKanbanBoardCommands(boardId, commands) {
|
|
7588
7738
|
if (commands.length === 0) return;
|
|
@@ -7590,30 +7740,38 @@ async function executeKanbanBoardCommands(boardId, commands) {
|
|
|
7590
7740
|
if (!board) return;
|
|
7591
7741
|
for (const cmd of commands) {
|
|
7592
7742
|
if (cmd.type === "add_card" && cmd.columnTitle && cmd.cardTitle) {
|
|
7593
|
-
|
|
7743
|
+
await addCardOrFallback(board, cmd.columnTitle, cmd.cardTitle, cmd.cardContent);
|
|
7594
7744
|
}
|
|
7595
7745
|
}
|
|
7596
|
-
await kanbanStore.update({ id: board.id, columns: board.columns });
|
|
7597
7746
|
}
|
|
7598
|
-
function
|
|
7747
|
+
async function addCardOrFallback(board, columnTitle, cardTitle, cardContent) {
|
|
7748
|
+
const { card, unsupported } = await kanbanStore.addCard(board.id, {
|
|
7749
|
+
column: columnTitle,
|
|
7750
|
+
title: cardTitle,
|
|
7751
|
+
markdown: cardContent
|
|
7752
|
+
});
|
|
7753
|
+
if (card) return;
|
|
7754
|
+
if (!unsupported) {
|
|
7755
|
+
console.warn(`[kanban-commands] add_card failed: column="${columnTitle}"`);
|
|
7756
|
+
return;
|
|
7757
|
+
}
|
|
7758
|
+
console.warn("[kanban-commands] cloud sans /kanban/card/add \u2014 repli sur la sauvegarde du tableau");
|
|
7599
7759
|
const col = board.columns.find((c) => c.title.toLowerCase() === columnTitle.toLowerCase());
|
|
7600
7760
|
if (!col) return;
|
|
7601
7761
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
7602
|
-
|
|
7762
|
+
col.cards.push({
|
|
7603
7763
|
id: randomUUID5(),
|
|
7604
7764
|
title: cardTitle,
|
|
7605
7765
|
markdown: cardContent ?? "",
|
|
7606
7766
|
images: [],
|
|
7607
|
-
// `.default([])` on the schema makes these optional on the wire but required
|
|
7608
|
-
// on the inferred type — a card built by hand has to supply them.
|
|
7609
7767
|
attachments: [],
|
|
7610
7768
|
assignees: [],
|
|
7611
|
-
order: col.cards.
|
|
7769
|
+
order: col.cards.reduce((max, c) => Math.max(max, c.order + 1), 0),
|
|
7612
7770
|
history: [{ type: "created", timestamp: now, detail: `AI \u2014 In column "${col.title}"` }],
|
|
7613
7771
|
createdAt: now,
|
|
7614
7772
|
updatedAt: now
|
|
7615
|
-
};
|
|
7616
|
-
|
|
7773
|
+
});
|
|
7774
|
+
await kanbanStore.update({ id: board.id, columns: board.columns });
|
|
7617
7775
|
}
|
|
7618
7776
|
function formatSize(bytes) {
|
|
7619
7777
|
if (bytes < 1024) return `${bytes} o`;
|
|
@@ -7963,7 +8121,7 @@ function tailTranscript(opts) {
|
|
|
7963
8121
|
|
|
7964
8122
|
// ../server/src/services/ai-runners/claude-pty-runner.ts
|
|
7965
8123
|
async function getAgentManager() {
|
|
7966
|
-
const { agentManager: agentManager2 } = await import("./agent-manager-
|
|
8124
|
+
const { agentManager: agentManager2 } = await import("./agent-manager-LBV3CVHB.js");
|
|
7967
8125
|
return agentManager2;
|
|
7968
8126
|
}
|
|
7969
8127
|
function buildPtyArgs(params, sessionId, opts) {
|
|
@@ -8704,7 +8862,7 @@ async function shutdownCodexAppServer() {
|
|
|
8704
8862
|
}
|
|
8705
8863
|
}
|
|
8706
8864
|
async function getAgentManager2() {
|
|
8707
|
-
const { agentManager: agentManager2 } = await import("./agent-manager-
|
|
8865
|
+
const { agentManager: agentManager2 } = await import("./agent-manager-LBV3CVHB.js");
|
|
8708
8866
|
return agentManager2;
|
|
8709
8867
|
}
|
|
8710
8868
|
function parseRuneyaCurlCommand(command) {
|
|
@@ -9145,18 +9303,18 @@ ${prompt}`;
|
|
|
9145
9303
|
|
|
9146
9304
|
// ../server/src/trpc/routers/chat.ts
|
|
9147
9305
|
var execFileAsync3 = promisify3(execFile4);
|
|
9148
|
-
var MessageSchema =
|
|
9149
|
-
role:
|
|
9150
|
-
content:
|
|
9306
|
+
var MessageSchema = z17.object({
|
|
9307
|
+
role: z17.enum(["user", "assistant"]),
|
|
9308
|
+
content: z17.string().max(1e5)
|
|
9151
9309
|
});
|
|
9152
|
-
var ImagePartSchema =
|
|
9153
|
-
type:
|
|
9154
|
-
imageId:
|
|
9155
|
-
url:
|
|
9156
|
-
mimeType:
|
|
9157
|
-
altText:
|
|
9310
|
+
var ImagePartSchema = z17.object({
|
|
9311
|
+
type: z17.literal("image"),
|
|
9312
|
+
imageId: z17.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
|
|
9313
|
+
url: z17.string().max(500),
|
|
9314
|
+
mimeType: z17.string().max(100),
|
|
9315
|
+
altText: z17.string().max(500).optional()
|
|
9158
9316
|
});
|
|
9159
|
-
var ImagePartsSchema =
|
|
9317
|
+
var ImagePartsSchema = z17.array(ImagePartSchema).max(5).optional();
|
|
9160
9318
|
var LANGUAGE_INSTRUCTION = "Always respond in the same language the user writes in.";
|
|
9161
9319
|
async function buildSystemPrompt(apiKey) {
|
|
9162
9320
|
const allServices = await serviceStore.list();
|
|
@@ -9543,24 +9701,24 @@ async function startCodexSession(convId, prompt, opts = {}) {
|
|
|
9543
9701
|
});
|
|
9544
9702
|
return { session, done };
|
|
9545
9703
|
}
|
|
9546
|
-
var MessagePartSchema =
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
type:
|
|
9704
|
+
var MessagePartSchema = z17.discriminatedUnion("type", [
|
|
9705
|
+
z17.object({ type: z17.literal("thinking"), text: z17.string().max(1e5) }),
|
|
9706
|
+
z17.object({ type: z17.literal("text"), text: z17.string().max(1e5) }),
|
|
9707
|
+
z17.object({
|
|
9708
|
+
type: z17.literal("tool"),
|
|
9551
9709
|
id: Id128Schema,
|
|
9552
9710
|
name: Id128Schema,
|
|
9553
|
-
input:
|
|
9554
|
-
rawInput:
|
|
9555
|
-
result:
|
|
9556
|
-
isError:
|
|
9557
|
-
pending:
|
|
9711
|
+
input: z17.record(z17.string(), z17.unknown()).optional(),
|
|
9712
|
+
rawInput: z17.string().max(1e4).optional(),
|
|
9713
|
+
result: z17.unknown().optional(),
|
|
9714
|
+
isError: z17.boolean().optional(),
|
|
9715
|
+
pending: z17.boolean()
|
|
9558
9716
|
})
|
|
9559
9717
|
]);
|
|
9560
|
-
var StoredMessageSchema =
|
|
9561
|
-
role:
|
|
9562
|
-
content:
|
|
9563
|
-
parts:
|
|
9718
|
+
var StoredMessageSchema = z17.object({
|
|
9719
|
+
role: z17.enum(["user", "assistant"]),
|
|
9720
|
+
content: z17.string().max(1e5),
|
|
9721
|
+
parts: z17.array(MessagePartSchema).max(200).optional()
|
|
9564
9722
|
});
|
|
9565
9723
|
async function conversationCwd(conv) {
|
|
9566
9724
|
return resolveConversationCwd(conv.id);
|
|
@@ -9574,7 +9732,7 @@ var chatRouter = router({
|
|
|
9574
9732
|
* et sans le même filtre il y reversait toutes les conversations de la
|
|
9575
9733
|
* machine, une seconde après un chargement pourtant filtré.
|
|
9576
9734
|
*/
|
|
9577
|
-
onChanged: protectedProcedure.input(
|
|
9735
|
+
onChanged: protectedProcedure.input(z17.object({
|
|
9578
9736
|
projectId: Id128Schema.optional(),
|
|
9579
9737
|
orgId: Id128Schema.nullable().optional()
|
|
9580
9738
|
}).optional()).subscription(async function* ({ input }) {
|
|
@@ -9622,7 +9780,7 @@ var chatRouter = router({
|
|
|
9622
9780
|
* reachable where they were written, without leaking into every other
|
|
9623
9781
|
* organization's projects.
|
|
9624
9782
|
*/
|
|
9625
|
-
list: protectedProcedure.input(
|
|
9783
|
+
list: protectedProcedure.input(z17.object({
|
|
9626
9784
|
projectId: Id128Schema.optional(),
|
|
9627
9785
|
orgId: Id128Schema.nullable().optional()
|
|
9628
9786
|
}).optional()).query(async ({ input }) => {
|
|
@@ -9630,24 +9788,24 @@ var chatRouter = router({
|
|
|
9630
9788
|
if (!projectId) return conversationStore.list();
|
|
9631
9789
|
return conversationStore.listForProject({ id: projectId, orgId: input?.orgId });
|
|
9632
9790
|
}),
|
|
9633
|
-
get: protectedProcedure.input(
|
|
9791
|
+
get: protectedProcedure.input(z17.object({ id: Id128Schema })).query(async ({ input }) => {
|
|
9634
9792
|
const conv = await conversationStore.get(input.id);
|
|
9635
9793
|
if (!conv) throw new TRPCError12({ code: "NOT_FOUND", message: "Conversation not found" });
|
|
9636
9794
|
return conv;
|
|
9637
9795
|
}),
|
|
9638
|
-
create: protectedProcedure.input(
|
|
9796
|
+
create: protectedProcedure.input(z17.object({
|
|
9639
9797
|
title: ShortString200Schema.optional(),
|
|
9640
|
-
isCli:
|
|
9641
|
-
runner:
|
|
9798
|
+
isCli: z17.boolean().optional(),
|
|
9799
|
+
runner: z17.enum(["claude-code", "codex"]).optional(),
|
|
9642
9800
|
providerId: Id128Schema.optional(),
|
|
9643
9801
|
scenarioId: Id128Schema.optional(),
|
|
9644
|
-
scenarioInput:
|
|
9802
|
+
scenarioInput: z17.string().max(1e5).optional(),
|
|
9645
9803
|
kanbanBoardId: Id128Schema.optional(),
|
|
9646
9804
|
kanbanCardId: Id128Schema.optional(),
|
|
9647
9805
|
// The project the conversation is about: only the caller knows which
|
|
9648
9806
|
// one it is looking at.
|
|
9649
9807
|
projectId: Id128Schema.optional(),
|
|
9650
|
-
orgId:
|
|
9808
|
+
orgId: z17.string().max(128).nullable().optional()
|
|
9651
9809
|
})).mutation(async ({ input }) => {
|
|
9652
9810
|
let scenario = null;
|
|
9653
9811
|
if (input.scenarioId) {
|
|
@@ -9678,20 +9836,20 @@ var chatRouter = router({
|
|
|
9678
9836
|
}
|
|
9679
9837
|
return conv;
|
|
9680
9838
|
}),
|
|
9681
|
-
update: protectedProcedure.input(
|
|
9839
|
+
update: protectedProcedure.input(z17.object({
|
|
9682
9840
|
id: Id128Schema,
|
|
9683
9841
|
title: ShortString200Schema.optional(),
|
|
9684
|
-
messages:
|
|
9685
|
-
contextUsage:
|
|
9686
|
-
inputTokens:
|
|
9687
|
-
contextWindow:
|
|
9842
|
+
messages: z17.array(StoredMessageSchema).max(500).optional(),
|
|
9843
|
+
contextUsage: z17.object({
|
|
9844
|
+
inputTokens: z17.number().int().nonnegative(),
|
|
9845
|
+
contextWindow: z17.number().int().positive()
|
|
9688
9846
|
}).optional()
|
|
9689
9847
|
})).mutation(async ({ input }) => {
|
|
9690
9848
|
const conv = await conversationStore.update(input.id, { title: input.title, messages: input.messages, contextUsage: input.contextUsage });
|
|
9691
9849
|
if (!conv) throw new TRPCError12({ code: "NOT_FOUND", message: "Conversation not found" });
|
|
9692
9850
|
return conv;
|
|
9693
9851
|
}),
|
|
9694
|
-
delete: protectedProcedure.input(
|
|
9852
|
+
delete: protectedProcedure.input(z17.object({ id: Id128Schema })).mutation(async ({ input }) => {
|
|
9695
9853
|
const existing = await conversationStore.get(input.id);
|
|
9696
9854
|
if (!existing) throw new TRPCError12({ code: "NOT_FOUND", message: "Conversation not found" });
|
|
9697
9855
|
for (const agent of agentManager.listAgents()) {
|
|
@@ -9713,18 +9871,18 @@ var chatRouter = router({
|
|
|
9713
9871
|
(err) => console.error("[chat.delete] Image cleanup error:", err)
|
|
9714
9872
|
);
|
|
9715
9873
|
}),
|
|
9716
|
-
archive: protectedProcedure.input(
|
|
9874
|
+
archive: protectedProcedure.input(z17.object({ id: Id128Schema, archived: z17.boolean() })).mutation(async ({ input }) => {
|
|
9717
9875
|
const conv = await conversationStore.update(input.id, { archived: input.archived });
|
|
9718
9876
|
if (!conv) throw new TRPCError12({ code: "NOT_FOUND", message: "Conversation not found" });
|
|
9719
9877
|
return conv;
|
|
9720
9878
|
})
|
|
9721
9879
|
}),
|
|
9722
|
-
listModels: protectedProcedure.input(
|
|
9880
|
+
listModels: protectedProcedure.input(z17.object({
|
|
9723
9881
|
providerId: Id128Schema.optional(),
|
|
9724
9882
|
// Le projet dit de quelle organisation lire les fournisseurs ; absent,
|
|
9725
9883
|
// ce sont ceux du poste.
|
|
9726
9884
|
projectId: Id128Schema.optional(),
|
|
9727
|
-
orgId:
|
|
9885
|
+
orgId: z17.string().max(128).nullable().optional()
|
|
9728
9886
|
}).optional()).query(async ({ input }) => {
|
|
9729
9887
|
const active = await getActiveProvider(
|
|
9730
9888
|
input?.providerId,
|
|
@@ -9737,7 +9895,7 @@ var chatRouter = router({
|
|
|
9737
9895
|
return [];
|
|
9738
9896
|
}
|
|
9739
9897
|
}),
|
|
9740
|
-
checkCliAvailability: protectedProcedure.input(
|
|
9898
|
+
checkCliAvailability: protectedProcedure.input(z17.object({ agentId: Id128Schema.optional() }).optional()).query(async ({ input }) => {
|
|
9741
9899
|
if (input?.agentId) {
|
|
9742
9900
|
try {
|
|
9743
9901
|
const res = await agentManager.agentQuery(
|
|
@@ -9755,12 +9913,12 @@ var chatRouter = router({
|
|
|
9755
9913
|
]);
|
|
9756
9914
|
return { available: claudeOk, codexAvailable: codexOk };
|
|
9757
9915
|
}),
|
|
9758
|
-
enhanceScenarioPrompt: protectedProcedure.input(
|
|
9759
|
-
text:
|
|
9916
|
+
enhanceScenarioPrompt: protectedProcedure.input(z17.object({
|
|
9917
|
+
text: z17.string().max(1e4),
|
|
9760
9918
|
providerId: Id128Schema.optional(),
|
|
9761
|
-
model:
|
|
9919
|
+
model: z17.string().max(200).optional(),
|
|
9762
9920
|
projectId: Id128Schema.optional(),
|
|
9763
|
-
orgId:
|
|
9921
|
+
orgId: z17.string().max(128).nullable().optional()
|
|
9764
9922
|
})).mutation(async ({ input }) => {
|
|
9765
9923
|
const active = await getActiveProvider(
|
|
9766
9924
|
input.providerId,
|
|
@@ -9817,22 +9975,22 @@ Return ONLY the improved text, no explanation, no preamble.`;
|
|
|
9817
9975
|
}
|
|
9818
9976
|
}),
|
|
9819
9977
|
getStreamingStatus: protectedProcedure.query(() => activeSessionRegistry.listActive()),
|
|
9820
|
-
stopSession: protectedProcedure.input(
|
|
9978
|
+
stopSession: protectedProcedure.input(z17.object({ conversationId: ConversationIdSchema })).mutation(({ input }) => {
|
|
9821
9979
|
if (process.env.RUNEYA_DEBUG) console.log("[chat]: stopSession");
|
|
9822
9980
|
const killed = activeSessionRegistry.kill(input.conversationId);
|
|
9823
9981
|
if (!killed) throw new TRPCError12({ code: "NOT_FOUND", message: "No active session for this conversation" });
|
|
9824
9982
|
return { ok: true };
|
|
9825
9983
|
}),
|
|
9826
|
-
streamViaClaudeCode: protectedProcedure.input(
|
|
9984
|
+
streamViaClaudeCode: protectedProcedure.input(z17.object({
|
|
9827
9985
|
conversationId: ConversationIdSchema,
|
|
9828
|
-
prompt:
|
|
9829
|
-
contextNote:
|
|
9986
|
+
prompt: z17.string().max(1e5),
|
|
9987
|
+
contextNote: z17.string().max(2e5).optional(),
|
|
9830
9988
|
model: ShortString200Schema.optional(),
|
|
9831
|
-
effort:
|
|
9832
|
-
reconnect:
|
|
9989
|
+
effort: z17.enum(["low", "medium", "high"]).optional(),
|
|
9990
|
+
reconnect: z17.boolean().optional(),
|
|
9833
9991
|
agentId: Id128Schema.optional(),
|
|
9834
|
-
environmentId:
|
|
9835
|
-
imageIds:
|
|
9992
|
+
environmentId: z17.string().max(128).optional(),
|
|
9993
|
+
imageIds: z17.array(z17.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(),
|
|
9836
9994
|
imageParts: ImagePartsSchema
|
|
9837
9995
|
})).subscription(async function* ({ input, ctx, signal }) {
|
|
9838
9996
|
if (process.env.RUNEYA_DEBUG) console.log("[chat]: Reconnect");
|
|
@@ -9943,15 +10101,15 @@ ${imagePaths.map((p) => `Image: ${p}`).join("\n")}` : cliPrompt;
|
|
|
9943
10101
|
if (process.env.RUNEYA_DEBUG) console.log("[chat]: drainSession...");
|
|
9944
10102
|
yield* drainSession(session, signal, false);
|
|
9945
10103
|
}),
|
|
9946
|
-
streamViaCodex: protectedProcedure.input(
|
|
10104
|
+
streamViaCodex: protectedProcedure.input(z17.object({
|
|
9947
10105
|
conversationId: ConversationIdSchema,
|
|
9948
|
-
prompt:
|
|
9949
|
-
contextNote:
|
|
10106
|
+
prompt: z17.string().max(1e5),
|
|
10107
|
+
contextNote: z17.string().max(2e5).optional(),
|
|
9950
10108
|
model: ShortString200Schema.optional(),
|
|
9951
|
-
reconnect:
|
|
10109
|
+
reconnect: z17.boolean().optional(),
|
|
9952
10110
|
agentId: Id128Schema.optional(),
|
|
9953
|
-
environmentId:
|
|
9954
|
-
imageIds:
|
|
10111
|
+
environmentId: z17.string().max(128).optional(),
|
|
10112
|
+
imageIds: z17.array(z17.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(),
|
|
9955
10113
|
imageParts: ImagePartsSchema
|
|
9956
10114
|
})).subscription(async function* ({ input, ctx, signal }) {
|
|
9957
10115
|
const existingSession = activeSessionRegistry.get(input.conversationId);
|
|
@@ -10029,13 +10187,13 @@ ${input.prompt}` : input.prompt;
|
|
|
10029
10187
|
});
|
|
10030
10188
|
yield* drainSession(session, signal, false);
|
|
10031
10189
|
}),
|
|
10032
|
-
send: protectedProcedure.input(
|
|
10190
|
+
send: protectedProcedure.input(z17.object({
|
|
10033
10191
|
conversationId: ConversationIdSchema,
|
|
10034
|
-
messages:
|
|
10192
|
+
messages: z17.array(MessageSchema).min(0).max(100),
|
|
10035
10193
|
model: ShortString200Schema.optional(),
|
|
10036
|
-
contextNote:
|
|
10037
|
-
reconnect:
|
|
10038
|
-
imageIds:
|
|
10194
|
+
contextNote: z17.string().max(2e5).optional(),
|
|
10195
|
+
reconnect: z17.boolean().optional(),
|
|
10196
|
+
imageIds: z17.array(z17.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(),
|
|
10039
10197
|
imageParts: ImagePartsSchema
|
|
10040
10198
|
})).subscription(async function* ({ input, ctx, signal }) {
|
|
10041
10199
|
const existingSession = activeSessionRegistry.get(input.conversationId);
|
|
@@ -10153,25 +10311,25 @@ ${input.prompt}` : input.prompt;
|
|
|
10153
10311
|
// ── PTY passthrough (interactive Claude Code session) ────────────────────
|
|
10154
10312
|
pty: router({
|
|
10155
10313
|
/** Start a PTY session running `claude --resume <sessionId>` (or fresh). */
|
|
10156
|
-
start: protectedProcedure.input(
|
|
10157
|
-
agentId:
|
|
10158
|
-
sessionId:
|
|
10159
|
-
runner:
|
|
10160
|
-
resume:
|
|
10161
|
-
model:
|
|
10162
|
-
cwd:
|
|
10314
|
+
start: protectedProcedure.input(z17.object({
|
|
10315
|
+
agentId: z17.string().max(128).optional(),
|
|
10316
|
+
sessionId: z17.string().max(128).optional(),
|
|
10317
|
+
runner: z17.enum(["claude-code", "codex"]).default("claude-code"),
|
|
10318
|
+
resume: z17.boolean().default(false),
|
|
10319
|
+
model: z17.string().max(128).optional(),
|
|
10320
|
+
cwd: z17.string().max(4096).optional(),
|
|
10163
10321
|
/** Anchors the session when no explicit cwd is given. */
|
|
10164
|
-
serviceId:
|
|
10322
|
+
serviceId: z17.string().max(128).optional(),
|
|
10165
10323
|
projectId: Id128Schema.optional(),
|
|
10166
|
-
orgId:
|
|
10167
|
-
cols:
|
|
10168
|
-
rows:
|
|
10169
|
-
enableMcp:
|
|
10170
|
-
apiBaseUrl:
|
|
10171
|
-
environmentId:
|
|
10172
|
-
attachedContexts:
|
|
10173
|
-
label:
|
|
10174
|
-
text:
|
|
10324
|
+
orgId: z17.string().max(128).nullable().optional(),
|
|
10325
|
+
cols: z17.number().int().min(1).max(1e3).default(120),
|
|
10326
|
+
rows: z17.number().int().min(1).max(1e3).default(30),
|
|
10327
|
+
enableMcp: z17.boolean().default(false),
|
|
10328
|
+
apiBaseUrl: z17.string().max(512).optional(),
|
|
10329
|
+
environmentId: z17.string().max(128).optional(),
|
|
10330
|
+
attachedContexts: z17.array(z17.object({
|
|
10331
|
+
label: z17.string().max(200),
|
|
10332
|
+
text: z17.string().max(1e6)
|
|
10175
10333
|
})).max(20).optional()
|
|
10176
10334
|
})).mutation(async ({ input, ctx }) => {
|
|
10177
10335
|
const t0 = Date.now();
|
|
@@ -10330,10 +10488,10 @@ Context:
|
|
|
10330
10488
|
return { spawnId: res.spawnId, agentId, reattached: false };
|
|
10331
10489
|
}),
|
|
10332
10490
|
/** Subscribe to PTY output stream (raw text with ANSI). */
|
|
10333
|
-
stream: protectedProcedure.input(
|
|
10334
|
-
agentId:
|
|
10335
|
-
spawnId:
|
|
10336
|
-
fromOffset:
|
|
10491
|
+
stream: protectedProcedure.input(z17.object({
|
|
10492
|
+
agentId: z17.string().max(128).optional(),
|
|
10493
|
+
spawnId: z17.string().max(128),
|
|
10494
|
+
fromOffset: z17.number().int().min(0).default(0)
|
|
10337
10495
|
})).subscription(async function* ({ input, signal }) {
|
|
10338
10496
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10339
10497
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10385,10 +10543,10 @@ Context:
|
|
|
10385
10543
|
}
|
|
10386
10544
|
}),
|
|
10387
10545
|
/** Write input to a PTY session (keystrokes from xterm). */
|
|
10388
|
-
write: protectedProcedure.input(
|
|
10389
|
-
agentId:
|
|
10390
|
-
spawnId:
|
|
10391
|
-
data:
|
|
10546
|
+
write: protectedProcedure.input(z17.object({
|
|
10547
|
+
agentId: z17.string().max(128).optional(),
|
|
10548
|
+
spawnId: z17.string().max(128),
|
|
10549
|
+
data: z17.string().max(1e6)
|
|
10392
10550
|
})).mutation(async ({ input }) => {
|
|
10393
10551
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10394
10552
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10398,11 +10556,11 @@ Context:
|
|
|
10398
10556
|
});
|
|
10399
10557
|
}),
|
|
10400
10558
|
/** Resize a PTY session. */
|
|
10401
|
-
resize: protectedProcedure.input(
|
|
10402
|
-
agentId:
|
|
10403
|
-
spawnId:
|
|
10404
|
-
cols:
|
|
10405
|
-
rows:
|
|
10559
|
+
resize: protectedProcedure.input(z17.object({
|
|
10560
|
+
agentId: z17.string().max(128).optional(),
|
|
10561
|
+
spawnId: z17.string().max(128),
|
|
10562
|
+
cols: z17.number().int().min(1).max(1e3),
|
|
10563
|
+
rows: z17.number().int().min(1).max(1e3)
|
|
10406
10564
|
})).mutation(async ({ input }) => {
|
|
10407
10565
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10408
10566
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10418,11 +10576,11 @@ Context:
|
|
|
10418
10576
|
* picks it up. Returns the tmp path and which clipboard method succeeded
|
|
10419
10577
|
* (null if none — caller should inject `@<path>` instead of Ctrl+V).
|
|
10420
10578
|
*/
|
|
10421
|
-
pasteImage: protectedProcedure.input(
|
|
10422
|
-
agentId:
|
|
10423
|
-
sessionId:
|
|
10424
|
-
mimeType:
|
|
10425
|
-
base64:
|
|
10579
|
+
pasteImage: protectedProcedure.input(z17.object({
|
|
10580
|
+
agentId: z17.string().max(128).optional(),
|
|
10581
|
+
sessionId: z17.string().max(128).optional(),
|
|
10582
|
+
mimeType: z17.string().max(64),
|
|
10583
|
+
base64: z17.string().max(15e6)
|
|
10426
10584
|
})).mutation(async ({ input }) => {
|
|
10427
10585
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10428
10586
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10440,7 +10598,7 @@ Context:
|
|
|
10440
10598
|
* Read the transcript Claude Code stores on disk for a given session.
|
|
10441
10599
|
* Returns parsed JSONL entries (user / assistant messages, tool uses, etc.).
|
|
10442
10600
|
*/
|
|
10443
|
-
transcript: protectedProcedure.input(
|
|
10601
|
+
transcript: protectedProcedure.input(z17.object({ sessionId: z17.string().max(128) })).query(async ({ input }) => {
|
|
10444
10602
|
return readClaudeTranscript(input.sessionId);
|
|
10445
10603
|
}),
|
|
10446
10604
|
/**
|
|
@@ -10448,9 +10606,9 @@ Context:
|
|
|
10448
10606
|
* when was the transcript JSONL last touched? Used by the non-PTY view
|
|
10449
10607
|
* to show a "Claude is thinking…" indicator while output streams.
|
|
10450
10608
|
*/
|
|
10451
|
-
activity: protectedProcedure.input(
|
|
10452
|
-
agentId:
|
|
10453
|
-
sessionId:
|
|
10609
|
+
activity: protectedProcedure.input(z17.object({
|
|
10610
|
+
agentId: z17.string().max(128).optional(),
|
|
10611
|
+
sessionId: z17.string().max(128)
|
|
10454
10612
|
})).query(async ({ input }) => {
|
|
10455
10613
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10456
10614
|
let running = false;
|
|
@@ -10476,7 +10634,7 @@ Context:
|
|
|
10476
10634
|
* them on the conversation, so the non-PTY chat view stays in sync.
|
|
10477
10635
|
* Uses the conversation id as session id (PTY sessions are spawned that way).
|
|
10478
10636
|
*/
|
|
10479
|
-
syncTranscript: protectedProcedure.input(
|
|
10637
|
+
syncTranscript: protectedProcedure.input(z17.object({ conversationId: ConversationIdSchema })).mutation(async ({ input }) => {
|
|
10480
10638
|
const conv = await conversationStore.get(input.conversationId);
|
|
10481
10639
|
if (!conv) {
|
|
10482
10640
|
throw new TRPCError12({ code: "NOT_FOUND", message: `Conversation ${input.conversationId} not found` });
|
|
@@ -10490,14 +10648,14 @@ Context:
|
|
|
10490
10648
|
* with the given sessionId. Used to benchmark the PTY → tRPC → xterm.js
|
|
10491
10649
|
* pipeline. Open the conversation in PTY mode to attach to it.
|
|
10492
10650
|
*/
|
|
10493
|
-
debugStress: protectedProcedure.input(
|
|
10494
|
-
sessionId:
|
|
10495
|
-
agentId:
|
|
10496
|
-
bytesPerSec:
|
|
10497
|
-
chunkSize:
|
|
10498
|
-
durationMs:
|
|
10499
|
-
cols:
|
|
10500
|
-
rows:
|
|
10651
|
+
debugStress: protectedProcedure.input(z17.object({
|
|
10652
|
+
sessionId: z17.string().max(128),
|
|
10653
|
+
agentId: z17.string().max(128).optional(),
|
|
10654
|
+
bytesPerSec: z17.number().int().min(100).max(1e7).default(5e4),
|
|
10655
|
+
chunkSize: z17.number().int().min(1).max(65536).default(256),
|
|
10656
|
+
durationMs: z17.number().int().min(0).max(36e5).default(0),
|
|
10657
|
+
cols: z17.number().int().min(1).max(1e3).default(120),
|
|
10658
|
+
rows: z17.number().int().min(1).max(1e3).default(30)
|
|
10501
10659
|
})).mutation(async ({ input }) => {
|
|
10502
10660
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10503
10661
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10544,9 +10702,9 @@ Context:
|
|
|
10544
10702
|
return { spawnId: res.spawnId, agentId, stressSessionId };
|
|
10545
10703
|
}),
|
|
10546
10704
|
/** Kill a PTY session. */
|
|
10547
|
-
kill: protectedProcedure.input(
|
|
10548
|
-
agentId:
|
|
10549
|
-
spawnId:
|
|
10705
|
+
kill: protectedProcedure.input(z17.object({
|
|
10706
|
+
agentId: z17.string().max(128).optional(),
|
|
10707
|
+
spawnId: z17.string().max(128)
|
|
10550
10708
|
})).mutation(async ({ input }) => {
|
|
10551
10709
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10552
10710
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10558,16 +10716,16 @@ Context:
|
|
|
10558
10716
|
});
|
|
10559
10717
|
|
|
10560
10718
|
// ../server/src/trpc/routers/git.ts
|
|
10561
|
-
import { z as
|
|
10719
|
+
import { z as z18 } from "zod";
|
|
10562
10720
|
import { TRPCError as TRPCError13 } from "@trpc/server";
|
|
10563
10721
|
import Anthropic3 from "@anthropic-ai/sdk";
|
|
10564
10722
|
import OpenAI3 from "openai";
|
|
10565
|
-
var SERVICE_ID_SCHEMA =
|
|
10566
|
-
var SAFE_PATH_SCHEMA =
|
|
10723
|
+
var SERVICE_ID_SCHEMA = z18.string().max(128);
|
|
10724
|
+
var SAFE_PATH_SCHEMA = z18.string().min(1).max(4096).refine((p) => !p.startsWith("/") && !p.includes("../"), {
|
|
10567
10725
|
message: "Path must be relative and not traverse up"
|
|
10568
10726
|
});
|
|
10569
|
-
var REMOTE_SCHEMA =
|
|
10570
|
-
var BRANCH_SCHEMA =
|
|
10727
|
+
var REMOTE_SCHEMA = z18.string().min(1).max(128).regex(/^[a-zA-Z0-9_\-.]+$/);
|
|
10728
|
+
var BRANCH_SCHEMA = z18.string().min(1).max(256).regex(/^[a-zA-Z0-9._\-/]+$/);
|
|
10571
10729
|
async function resolveServiceContext(serviceId) {
|
|
10572
10730
|
const service = await serviceStore.get(serviceId);
|
|
10573
10731
|
if (!service) {
|
|
@@ -10581,11 +10739,11 @@ async function resolveServiceContext(serviceId) {
|
|
|
10581
10739
|
}
|
|
10582
10740
|
var gitTargetShape = {
|
|
10583
10741
|
serviceId: SERVICE_ID_SCHEMA.optional(),
|
|
10584
|
-
agentId:
|
|
10742
|
+
agentId: z18.string().max(128).optional(),
|
|
10585
10743
|
/** Anchors on a project when no service is targeted (e.g. from the AI chat). */
|
|
10586
|
-
projectId:
|
|
10744
|
+
projectId: z18.string().max(128).optional(),
|
|
10587
10745
|
/** Son organisation : un id de projet seul peut en nommer un par organisation. */
|
|
10588
|
-
orgId:
|
|
10746
|
+
orgId: z18.string().max(128).nullable().optional()
|
|
10589
10747
|
};
|
|
10590
10748
|
async function resolveGitContext(input) {
|
|
10591
10749
|
if (input.serviceId) return resolveServiceContext(input.serviceId);
|
|
@@ -10598,82 +10756,82 @@ async function resolveGitContext(input) {
|
|
|
10598
10756
|
}
|
|
10599
10757
|
var gitRouter = router({
|
|
10600
10758
|
/** Get full git status */
|
|
10601
|
-
status: protectedProcedure.input(
|
|
10759
|
+
status: protectedProcedure.input(z18.object({ ...gitTargetShape })).query(async ({ input }) => {
|
|
10602
10760
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10603
10761
|
return agentManager.agentQuery(agentId, "git.status", { cwd });
|
|
10604
10762
|
}),
|
|
10605
10763
|
/** Get commit log */
|
|
10606
|
-
log: protectedProcedure.input(
|
|
10764
|
+
log: protectedProcedure.input(z18.object({ ...gitTargetShape, limit: z18.number().int().min(1).max(200).default(50) })).query(async ({ input }) => {
|
|
10607
10765
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10608
10766
|
return agentManager.agentQuery(agentId, "git.log", { cwd, limit: input.limit });
|
|
10609
10767
|
}),
|
|
10610
10768
|
/** List local and remote branches */
|
|
10611
|
-
branches: protectedProcedure.input(
|
|
10769
|
+
branches: protectedProcedure.input(z18.object({ ...gitTargetShape })).query(async ({ input }) => {
|
|
10612
10770
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10613
10771
|
return agentManager.agentQuery(agentId, "git.branches", { cwd });
|
|
10614
10772
|
}),
|
|
10615
10773
|
/** Checkout a branch */
|
|
10616
|
-
checkout: protectedProcedure.input(
|
|
10774
|
+
checkout: protectedProcedure.input(z18.object({ ...gitTargetShape, branch: BRANCH_SCHEMA, create: z18.boolean().default(false) })).mutation(async ({ input }) => {
|
|
10617
10775
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10618
10776
|
return agentManager.agentMutation(agentId, "git.checkout", { cwd, branch: input.branch, create: input.create });
|
|
10619
10777
|
}),
|
|
10620
10778
|
/** Stage files */
|
|
10621
|
-
stage: protectedProcedure.input(
|
|
10779
|
+
stage: protectedProcedure.input(z18.object({ ...gitTargetShape, paths: z18.array(SAFE_PATH_SCHEMA).min(1).max(500) })).mutation(async ({ input }) => {
|
|
10622
10780
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10623
10781
|
return agentManager.agentMutation(agentId, "git.stage", { cwd, paths: input.paths });
|
|
10624
10782
|
}),
|
|
10625
10783
|
/** Stage all files */
|
|
10626
|
-
stageAll: protectedProcedure.input(
|
|
10784
|
+
stageAll: protectedProcedure.input(z18.object({ ...gitTargetShape })).mutation(async ({ input }) => {
|
|
10627
10785
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10628
10786
|
return agentManager.agentMutation(agentId, "git.stageAll", { cwd });
|
|
10629
10787
|
}),
|
|
10630
10788
|
/** Unstage files */
|
|
10631
|
-
unstage: protectedProcedure.input(
|
|
10789
|
+
unstage: protectedProcedure.input(z18.object({ ...gitTargetShape, paths: z18.array(SAFE_PATH_SCHEMA).min(1).max(500) })).mutation(async ({ input }) => {
|
|
10632
10790
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10633
10791
|
return agentManager.agentMutation(agentId, "git.unstage", { cwd, paths: input.paths });
|
|
10634
10792
|
}),
|
|
10635
10793
|
/** Unstage all files */
|
|
10636
|
-
unstageAll: protectedProcedure.input(
|
|
10794
|
+
unstageAll: protectedProcedure.input(z18.object({ ...gitTargetShape })).mutation(async ({ input }) => {
|
|
10637
10795
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10638
10796
|
return agentManager.agentMutation(agentId, "git.unstageAll", { cwd });
|
|
10639
10797
|
}),
|
|
10640
10798
|
/** Commit staged changes */
|
|
10641
|
-
commit: protectedProcedure.input(
|
|
10799
|
+
commit: protectedProcedure.input(z18.object({ ...gitTargetShape, message: z18.string().min(1).max(4096) })).mutation(async ({ input }) => {
|
|
10642
10800
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10643
10801
|
return agentManager.agentMutation(agentId, "git.commit", { cwd, message: input.message });
|
|
10644
10802
|
}),
|
|
10645
10803
|
/** Push to remote */
|
|
10646
|
-
push: protectedProcedure.input(
|
|
10804
|
+
push: protectedProcedure.input(z18.object({ ...gitTargetShape, remote: REMOTE_SCHEMA.default("origin"), setUpstream: z18.boolean().default(false) })).mutation(async ({ input }) => {
|
|
10647
10805
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10648
10806
|
return agentManager.agentMutation(agentId, "git.push", { cwd, remote: input.remote, setUpstream: input.setUpstream });
|
|
10649
10807
|
}),
|
|
10650
10808
|
/** Pull from remote */
|
|
10651
|
-
pull: protectedProcedure.input(
|
|
10809
|
+
pull: protectedProcedure.input(z18.object({ ...gitTargetShape, remote: REMOTE_SCHEMA.default("origin") })).mutation(async ({ input }) => {
|
|
10652
10810
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10653
10811
|
return agentManager.agentMutation(agentId, "git.pull", { cwd, remote: input.remote });
|
|
10654
10812
|
}),
|
|
10655
10813
|
/** Fetch from remote */
|
|
10656
|
-
fetch: protectedProcedure.input(
|
|
10814
|
+
fetch: protectedProcedure.input(z18.object({ ...gitTargetShape, remote: REMOTE_SCHEMA.default("origin") })).mutation(async ({ input }) => {
|
|
10657
10815
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10658
10816
|
return agentManager.agentMutation(agentId, "git.fetch", { cwd, remote: input.remote });
|
|
10659
10817
|
}),
|
|
10660
10818
|
/** Get diff for a file or the whole index */
|
|
10661
|
-
diff: protectedProcedure.input(
|
|
10819
|
+
diff: protectedProcedure.input(z18.object({
|
|
10662
10820
|
...gitTargetShape,
|
|
10663
|
-
path:
|
|
10664
|
-
staged:
|
|
10665
|
-
untracked:
|
|
10821
|
+
path: z18.string().max(4096).optional(),
|
|
10822
|
+
staged: z18.boolean().default(false),
|
|
10823
|
+
untracked: z18.boolean().default(false)
|
|
10666
10824
|
})).query(async ({ input }) => {
|
|
10667
10825
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10668
10826
|
return agentManager.agentQuery(agentId, "git.diff", { cwd, path: input.path, staged: input.staged, untracked: input.untracked });
|
|
10669
10827
|
}),
|
|
10670
10828
|
/** Discard changes to working tree files */
|
|
10671
|
-
discard: protectedProcedure.input(
|
|
10829
|
+
discard: protectedProcedure.input(z18.object({ ...gitTargetShape, paths: z18.array(SAFE_PATH_SCHEMA).min(1).max(500) })).mutation(async ({ input }) => {
|
|
10672
10830
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10673
10831
|
return agentManager.agentMutation(agentId, "git.discard", { cwd, paths: input.paths });
|
|
10674
10832
|
}),
|
|
10675
10833
|
/** Generate a commit message from staged diffs using AI (diff fetched from agent, AI runs on server) */
|
|
10676
|
-
generateCommitMessage: protectedProcedure.input(
|
|
10834
|
+
generateCommitMessage: protectedProcedure.input(z18.object({ ...gitTargetShape, providerId: OptionalProviderIdSchema, model: z18.string().max(200).optional() })).mutation(async ({ input }) => {
|
|
10677
10835
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10678
10836
|
const { diff } = await agentManager.agentQuery(agentId, "git.stagedDiff", { cwd });
|
|
10679
10837
|
if (!diff.trim()) {
|
|
@@ -10720,42 +10878,42 @@ Rules:
|
|
|
10720
10878
|
throw new TRPCError13({ code: "BAD_REQUEST", message: "Unsupported AI provider" });
|
|
10721
10879
|
}),
|
|
10722
10880
|
/** Merge a branch into the current branch */
|
|
10723
|
-
merge: protectedProcedure.input(
|
|
10881
|
+
merge: protectedProcedure.input(z18.object({ ...gitTargetShape, branch: BRANCH_SCHEMA, noFf: z18.boolean().default(false) })).mutation(async ({ input }) => {
|
|
10724
10882
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10725
10883
|
return agentManager.agentMutation(agentId, "git.merge", { cwd, branch: input.branch, noFf: input.noFf });
|
|
10726
10884
|
}),
|
|
10727
10885
|
/** Rebase current branch onto another branch */
|
|
10728
|
-
rebase: protectedProcedure.input(
|
|
10886
|
+
rebase: protectedProcedure.input(z18.object({ ...gitTargetShape, branch: BRANCH_SCHEMA })).mutation(async ({ input }) => {
|
|
10729
10887
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10730
10888
|
return agentManager.agentMutation(agentId, "git.rebase", { cwd, branch: input.branch });
|
|
10731
10889
|
}),
|
|
10732
10890
|
/** List stash entries */
|
|
10733
|
-
stashList: protectedProcedure.input(
|
|
10891
|
+
stashList: protectedProcedure.input(z18.object({ ...gitTargetShape })).query(async ({ input }) => {
|
|
10734
10892
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10735
10893
|
return agentManager.agentQuery(agentId, "git.stashList", { cwd });
|
|
10736
10894
|
}),
|
|
10737
10895
|
/** Stash current changes */
|
|
10738
|
-
stashPush: protectedProcedure.input(
|
|
10896
|
+
stashPush: protectedProcedure.input(z18.object({ ...gitTargetShape, message: z18.string().max(4096).optional(), includeUntracked: z18.boolean().default(true) })).mutation(async ({ input }) => {
|
|
10739
10897
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10740
10898
|
return agentManager.agentMutation(agentId, "git.stashPush", { cwd, message: input.message, includeUntracked: input.includeUntracked });
|
|
10741
10899
|
}),
|
|
10742
10900
|
/** Pop a stash entry */
|
|
10743
|
-
stashPop: protectedProcedure.input(
|
|
10901
|
+
stashPop: protectedProcedure.input(z18.object({ ...gitTargetShape, index: z18.number().int().min(0).max(1e3).default(0) })).mutation(async ({ input }) => {
|
|
10744
10902
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10745
10903
|
return agentManager.agentMutation(agentId, "git.stashPop", { cwd, index: input.index });
|
|
10746
10904
|
}),
|
|
10747
10905
|
/** Apply a stash entry without dropping it */
|
|
10748
|
-
stashApply: protectedProcedure.input(
|
|
10906
|
+
stashApply: protectedProcedure.input(z18.object({ ...gitTargetShape, index: z18.number().int().min(0).max(1e3).default(0) })).mutation(async ({ input }) => {
|
|
10749
10907
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10750
10908
|
return agentManager.agentMutation(agentId, "git.stashApply", { cwd, index: input.index });
|
|
10751
10909
|
}),
|
|
10752
10910
|
/** Drop a stash entry */
|
|
10753
|
-
stashDrop: protectedProcedure.input(
|
|
10911
|
+
stashDrop: protectedProcedure.input(z18.object({ ...gitTargetShape, index: z18.number().int().min(0).max(1e3).default(0) })).mutation(async ({ input }) => {
|
|
10754
10912
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10755
10913
|
return agentManager.agentMutation(agentId, "git.stashDrop", { cwd, index: input.index });
|
|
10756
10914
|
}),
|
|
10757
10915
|
/** Watch .git/ for changes and stream updated status */
|
|
10758
|
-
onStatusChange: protectedProcedure.input(
|
|
10916
|
+
onStatusChange: protectedProcedure.input(z18.object({ ...gitTargetShape })).subscription(async function* ({ input }) {
|
|
10759
10917
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10760
10918
|
const queue = [];
|
|
10761
10919
|
let resolve7 = null;
|
|
@@ -10802,7 +10960,7 @@ Rules:
|
|
|
10802
10960
|
}
|
|
10803
10961
|
}),
|
|
10804
10962
|
/** List remotes */
|
|
10805
|
-
remotes: protectedProcedure.input(
|
|
10963
|
+
remotes: protectedProcedure.input(z18.object({ ...gitTargetShape })).query(async ({ input }) => {
|
|
10806
10964
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10807
10965
|
return agentManager.agentQuery(agentId, "git.remotes", { cwd });
|
|
10808
10966
|
})
|
|
@@ -10811,7 +10969,7 @@ Rules:
|
|
|
10811
10969
|
// ../server/src/trpc/routers/scenario.ts
|
|
10812
10970
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
10813
10971
|
import { TRPCError as TRPCError16 } from "@trpc/server";
|
|
10814
|
-
import { z as
|
|
10972
|
+
import { z as z19 } from "zod";
|
|
10815
10973
|
|
|
10816
10974
|
// ../server/src/trpc/crud-procedure-utils.ts
|
|
10817
10975
|
import { TRPCError as TRPCError14 } from "@trpc/server";
|
|
@@ -10925,9 +11083,9 @@ async function* streamWithActiveProvider(opts) {
|
|
|
10925
11083
|
}
|
|
10926
11084
|
|
|
10927
11085
|
// ../server/src/services/scenario-runner.ts
|
|
10928
|
-
import { mkdir as
|
|
11086
|
+
import { mkdir as mkdir16 } from "fs/promises";
|
|
10929
11087
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
10930
|
-
import { join as
|
|
11088
|
+
import { join as join19 } from "path";
|
|
10931
11089
|
|
|
10932
11090
|
// ../server/src/services/scenario-presets.ts
|
|
10933
11091
|
var BUILT_IN_PRESETS = [
|
|
@@ -11707,7 +11865,7 @@ async function appendNodeOutput(conversationId, node, output) {
|
|
|
11707
11865
|
if (!dir) return;
|
|
11708
11866
|
const slug = node.label.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 60) || "member";
|
|
11709
11867
|
const safeId = node.id.replace(/[^a-z0-9_-]/gi, "-").slice(0, 80);
|
|
11710
|
-
const filePath =
|
|
11868
|
+
const filePath = join19(dir, `${slug}_${safeId}.md`);
|
|
11711
11869
|
const content = `## Output
|
|
11712
11870
|
|
|
11713
11871
|
${output}
|
|
@@ -11720,9 +11878,9 @@ async function appendToReadme(conversationId, bus, text) {
|
|
|
11720
11878
|
const line = `${text}
|
|
11721
11879
|
`;
|
|
11722
11880
|
try {
|
|
11723
|
-
await
|
|
11881
|
+
await mkdir16(dir, { recursive: true });
|
|
11724
11882
|
const { appendFile: appendFile2 } = await import("fs/promises");
|
|
11725
|
-
await appendFile2(
|
|
11883
|
+
await appendFile2(join19(dir, "README.md"), line, "utf-8");
|
|
11726
11884
|
} catch {
|
|
11727
11885
|
}
|
|
11728
11886
|
publishToBus(bus, { type: "readme_append", text: line });
|
|
@@ -11742,7 +11900,7 @@ async function writeFinalMd(conversationId, bus, userRequest, content) {
|
|
|
11742
11900
|
|
|
11743
11901
|
${content}
|
|
11744
11902
|
`;
|
|
11745
|
-
const filePath =
|
|
11903
|
+
const filePath = join19(dir, "FINAL.md");
|
|
11746
11904
|
await atomicWriteSecure(filePath, fullContent);
|
|
11747
11905
|
await appendToReadme(
|
|
11748
11906
|
conversationId,
|
|
@@ -12410,28 +12568,28 @@ Modify the scenario. Keep existing ids when possible.`;
|
|
|
12410
12568
|
return `Generate an scenario org-chart based on: ${userPrompt}`;
|
|
12411
12569
|
}
|
|
12412
12570
|
var ScopeShape2 = {
|
|
12413
|
-
orgId:
|
|
12571
|
+
orgId: z19.string().max(128).nullable().optional(),
|
|
12414
12572
|
projectId: Id128Schema.optional()
|
|
12415
12573
|
};
|
|
12416
12574
|
async function scopeOf2(input) {
|
|
12417
12575
|
return input?.orgId ?? await vaultOfProject(input?.projectId);
|
|
12418
12576
|
}
|
|
12419
12577
|
var scenarioRouter = router({
|
|
12420
|
-
list: protectedProcedure.input(
|
|
12421
|
-
get: protectedProcedure.input(
|
|
12578
|
+
list: protectedProcedure.input(z19.object(ScopeShape2).optional()).query(async ({ input }) => scenarioStore.list(await scopeOf2(input))),
|
|
12579
|
+
get: protectedProcedure.input(z19.object({ id: Id128Schema, ...ScopeShape2 })).query(async ({ input }) => getOrNotFound(
|
|
12422
12580
|
async () => scenarioStore.get(input.id, await scopeOf2(input)),
|
|
12423
12581
|
"Scenario not found"
|
|
12424
12582
|
)),
|
|
12425
|
-
create: protectedProcedure.input(
|
|
12583
|
+
create: protectedProcedure.input(z19.object({
|
|
12426
12584
|
name: NameSchema,
|
|
12427
|
-
icon:
|
|
12585
|
+
icon: z19.string().max(64).optional(),
|
|
12428
12586
|
description: DescriptionSchema.optional(),
|
|
12429
12587
|
leaderId: Id128Schema,
|
|
12430
|
-
groups:
|
|
12431
|
-
nodes:
|
|
12432
|
-
traversalMode:
|
|
12433
|
-
presetId:
|
|
12434
|
-
isPublished:
|
|
12588
|
+
groups: z19.array(ScenarioGroupSchema).max(100).optional(),
|
|
12589
|
+
nodes: z19.array(ScenarioNodeSchema).min(1).max(500),
|
|
12590
|
+
traversalMode: z19.enum(["hierarchical", "topological"]).optional(),
|
|
12591
|
+
presetId: z19.string().max(128).optional(),
|
|
12592
|
+
isPublished: z19.boolean().optional(),
|
|
12435
12593
|
...ScopeShape2
|
|
12436
12594
|
})).mutation(({ input }) => {
|
|
12437
12595
|
const now = Date.now();
|
|
@@ -12450,17 +12608,17 @@ var scenarioRouter = router({
|
|
|
12450
12608
|
updatedAt: now
|
|
12451
12609
|
}));
|
|
12452
12610
|
}),
|
|
12453
|
-
update: protectedProcedure.input(
|
|
12611
|
+
update: protectedProcedure.input(z19.object({
|
|
12454
12612
|
id: Id128Schema,
|
|
12455
12613
|
name: NameSchema.optional(),
|
|
12456
|
-
icon:
|
|
12614
|
+
icon: z19.string().max(64).optional(),
|
|
12457
12615
|
description: DescriptionSchema.optional(),
|
|
12458
12616
|
leaderId: Id128Schema.optional(),
|
|
12459
|
-
groups:
|
|
12460
|
-
nodes:
|
|
12461
|
-
traversalMode:
|
|
12462
|
-
presetId:
|
|
12463
|
-
isPublished:
|
|
12617
|
+
groups: z19.array(ScenarioGroupSchema).max(100).optional(),
|
|
12618
|
+
nodes: z19.array(ScenarioNodeSchema).min(1).max(500).optional(),
|
|
12619
|
+
traversalMode: z19.enum(["hierarchical", "topological"]).optional(),
|
|
12620
|
+
presetId: z19.string().max(128).optional(),
|
|
12621
|
+
isPublished: z19.boolean().optional(),
|
|
12464
12622
|
...ScopeShape2
|
|
12465
12623
|
})).mutation(({ input }) => updateOrThrow(
|
|
12466
12624
|
async () => scenarioStore.update(input.id, {
|
|
@@ -12477,22 +12635,22 @@ var scenarioRouter = router({
|
|
|
12477
12635
|
}, await scopeOf2(input)),
|
|
12478
12636
|
"Scenario not found"
|
|
12479
12637
|
)),
|
|
12480
|
-
delete: protectedProcedure.input(
|
|
12638
|
+
delete: protectedProcedure.input(z19.object({ id: Id128Schema, ...ScopeShape2 })).mutation(({ input }) => deleteOrNotFound(
|
|
12481
12639
|
async () => scenarioStore.delete(input.id, await scopeOf2(input)),
|
|
12482
12640
|
"Scenario not found"
|
|
12483
12641
|
)),
|
|
12484
|
-
run: protectedProcedure.input(
|
|
12642
|
+
run: protectedProcedure.input(z19.object({
|
|
12485
12643
|
conversationId: ConversationIdSchema,
|
|
12486
12644
|
scenarioId: Id128Schema,
|
|
12487
|
-
userRequest:
|
|
12488
|
-
runnerOverride:
|
|
12645
|
+
userRequest: z19.string().max(1e5),
|
|
12646
|
+
runnerOverride: z19.enum(["claude-code", "codex"]).optional(),
|
|
12489
12647
|
modelOverride: Id128Schema.optional(),
|
|
12490
12648
|
agentId: Id128Schema.optional(),
|
|
12491
12649
|
/** Anchors the run's working directory on the project it belongs to. */
|
|
12492
12650
|
projectId: Id128Schema.optional(),
|
|
12493
12651
|
/** Son organisation : sans elle, un id partagé désignerait un projet au hasard. */
|
|
12494
|
-
orgId:
|
|
12495
|
-
resume:
|
|
12652
|
+
orgId: z19.string().max(128).nullable().optional(),
|
|
12653
|
+
resume: z19.boolean().optional()
|
|
12496
12654
|
})).subscription(async function* ({ input, signal }) {
|
|
12497
12655
|
const scenario = await scenarioStore.get(input.scenarioId, await scopeOf2(input));
|
|
12498
12656
|
if (!scenario) throw new TRPCError16({ code: "NOT_FOUND", message: "Scenario not found" });
|
|
@@ -12512,41 +12670,41 @@ var scenarioRouter = router({
|
|
|
12512
12670
|
}
|
|
12513
12671
|
yield* tapBus(input.conversationId, signal ?? new AbortController().signal);
|
|
12514
12672
|
}),
|
|
12515
|
-
stop: protectedProcedure.input(
|
|
12673
|
+
stop: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).mutation(({ input }) => {
|
|
12516
12674
|
abortScenario(input.conversationId);
|
|
12517
12675
|
return { ok: true };
|
|
12518
12676
|
}),
|
|
12519
|
-
sendNodeInput: protectedProcedure.input(
|
|
12677
|
+
sendNodeInput: protectedProcedure.input(z19.object({
|
|
12520
12678
|
conversationId: ConversationIdSchema,
|
|
12521
12679
|
nodeId: Id128Schema,
|
|
12522
|
-
text:
|
|
12680
|
+
text: z19.string().min(1).max(1e5)
|
|
12523
12681
|
})).mutation(({ input }) => {
|
|
12524
12682
|
const resolved = resolveNodeInput(input.conversationId, input.nodeId, input.text);
|
|
12525
12683
|
if (!resolved) throw new TRPCError16({ code: "NOT_FOUND", message: "No pending input request for this node" });
|
|
12526
12684
|
return { ok: true };
|
|
12527
12685
|
}),
|
|
12528
|
-
isRunning: protectedProcedure.input(
|
|
12529
|
-
runState: protectedProcedure.input(
|
|
12686
|
+
isRunning: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).query(({ input }) => ({ running: isScenarioRunning(input.conversationId) })),
|
|
12687
|
+
runState: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).query(({ input }) => {
|
|
12530
12688
|
const runState = scenarioRunStore.getRunState(input.conversationId);
|
|
12531
12689
|
return runState ?? { nodeStates: {}, nodeOutputs: {}, activeNodeId: void 0 };
|
|
12532
12690
|
}),
|
|
12533
|
-
getPersistedRunState: protectedProcedure.input(
|
|
12691
|
+
getPersistedRunState: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).query(async ({ input }) => {
|
|
12534
12692
|
return await scenarioRunStore.loadPersistedRunState(input.conversationId);
|
|
12535
12693
|
}),
|
|
12536
|
-
getReadme: protectedProcedure.input(
|
|
12694
|
+
getReadme: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).query(async ({ input }) => {
|
|
12537
12695
|
return await scenarioRunStore.readReadme(input.conversationId);
|
|
12538
12696
|
}),
|
|
12539
|
-
getSnapshot: protectedProcedure.input(
|
|
12697
|
+
getSnapshot: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).query(async ({ input }) => {
|
|
12540
12698
|
return await scenarioRunStore.loadScenarioSnapshot(input.conversationId);
|
|
12541
12699
|
}),
|
|
12542
|
-
streamGenerateWithAI: protectedProcedure.input(
|
|
12543
|
-
prompt:
|
|
12700
|
+
streamGenerateWithAI: protectedProcedure.input(z19.object({
|
|
12701
|
+
prompt: z19.string().min(1).max(1e4),
|
|
12544
12702
|
providerId: OptionalProviderIdSchema,
|
|
12545
|
-
model:
|
|
12546
|
-
current:
|
|
12703
|
+
model: z19.string().max(200).optional(),
|
|
12704
|
+
current: z19.object({
|
|
12547
12705
|
leaderId: Id128Schema,
|
|
12548
|
-
groups:
|
|
12549
|
-
nodes:
|
|
12706
|
+
groups: z19.array(ScenarioGroupSchema).max(100),
|
|
12707
|
+
nodes: z19.array(ScenarioNodeSchema).max(500)
|
|
12550
12708
|
}).optional()
|
|
12551
12709
|
})).subscription(async function* ({ input, signal }) {
|
|
12552
12710
|
const userMessage = buildScenarioUserMessage(input.prompt, input.current);
|
|
@@ -12559,7 +12717,7 @@ var scenarioRouter = router({
|
|
|
12559
12717
|
signal: signal ?? void 0
|
|
12560
12718
|
});
|
|
12561
12719
|
}),
|
|
12562
|
-
streamRunEvents: protectedProcedure.input(
|
|
12720
|
+
streamRunEvents: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).subscription(async function* ({ input }) {
|
|
12563
12721
|
const convId = input.conversationId;
|
|
12564
12722
|
const runState = scenarioRunStore.getRunState(convId);
|
|
12565
12723
|
if (runState) {
|
|
@@ -12573,14 +12731,14 @@ var scenarioRouter = router({
|
|
|
12573
12731
|
* open a debug PTY with `claude --resume <sessionId>` on the right agent.
|
|
12574
12732
|
* Falls back to the persisted run-state for past nodes.
|
|
12575
12733
|
*/
|
|
12576
|
-
getNodeSession: protectedProcedure.input(
|
|
12734
|
+
getNodeSession: protectedProcedure.input(z19.object({
|
|
12577
12735
|
conversationId: ConversationIdSchema,
|
|
12578
12736
|
nodeId: Id128Schema
|
|
12579
12737
|
})).query(async ({ input }) => {
|
|
12580
12738
|
return await scenarioRunStore.getNodeSessionPersistent(input.conversationId, input.nodeId);
|
|
12581
12739
|
}),
|
|
12582
12740
|
listPresets: protectedProcedure.query(() => listPresets()),
|
|
12583
|
-
getPreset: protectedProcedure.input(
|
|
12741
|
+
getPreset: protectedProcedure.input(z19.object({ id: Id128Schema })).query(({ input }) => {
|
|
12584
12742
|
const preset = getPreset(input.id);
|
|
12585
12743
|
if (!preset) throw new TRPCError16({ code: "NOT_FOUND", message: "Preset not found" });
|
|
12586
12744
|
return preset;
|
|
@@ -12590,7 +12748,7 @@ var scenarioRouter = router({
|
|
|
12590
12748
|
// ../server/src/trpc/routers/debug.ts
|
|
12591
12749
|
import { randomUUID as randomUUID9 } from "crypto";
|
|
12592
12750
|
import { TRPCError as TRPCError17 } from "@trpc/server";
|
|
12593
|
-
import { z as
|
|
12751
|
+
import { z as z20 } from "zod";
|
|
12594
12752
|
var MAX_BUFFER3 = 300;
|
|
12595
12753
|
var jobs = /* @__PURE__ */ new Map();
|
|
12596
12754
|
function publish(job, event) {
|
|
@@ -12647,9 +12805,9 @@ async function* tapJob(job, signal) {
|
|
|
12647
12805
|
}
|
|
12648
12806
|
}
|
|
12649
12807
|
var debugRouter = router({
|
|
12650
|
-
startRandomJob: protectedProcedure.input(
|
|
12651
|
-
intervalMs:
|
|
12652
|
-
maxTicks:
|
|
12808
|
+
startRandomJob: protectedProcedure.input(z20.object({
|
|
12809
|
+
intervalMs: z20.number().int().min(100).max(5e3).optional(),
|
|
12810
|
+
maxTicks: z20.number().int().min(1).max(1e4).optional()
|
|
12653
12811
|
}).optional()).mutation(({ input }) => {
|
|
12654
12812
|
const jobId = randomUUID9();
|
|
12655
12813
|
const intervalMs = input?.intervalMs ?? 400;
|
|
@@ -12683,15 +12841,15 @@ var debugRouter = router({
|
|
|
12683
12841
|
jobs.set(jobId, job);
|
|
12684
12842
|
return { jobId, intervalMs, maxTicks, startedAt: job.startedAt };
|
|
12685
12843
|
}),
|
|
12686
|
-
streamRandomJob: protectedProcedure.input(
|
|
12844
|
+
streamRandomJob: protectedProcedure.input(z20.object({ jobId: z20.string().max(128) })).subscription(async function* ({ input, signal }) {
|
|
12687
12845
|
const job = jobs.get(input.jobId);
|
|
12688
12846
|
if (!job) {
|
|
12689
12847
|
throw new TRPCError17({ code: "NOT_FOUND", message: "Random job not found" });
|
|
12690
12848
|
}
|
|
12691
12849
|
yield* tapJob(job, signal ?? new AbortController().signal);
|
|
12692
12850
|
}),
|
|
12693
|
-
stopRandomJob: protectedProcedure.input(
|
|
12694
|
-
randomJobStatus: protectedProcedure.input(
|
|
12851
|
+
stopRandomJob: protectedProcedure.input(z20.object({ jobId: z20.string().max(128) })).mutation(({ input }) => ({ ok: stopJob(input.jobId, "stopped") })),
|
|
12852
|
+
randomJobStatus: protectedProcedure.input(z20.object({ jobId: z20.string().max(128) })).query(({ input }) => {
|
|
12695
12853
|
const job = jobs.get(input.jobId);
|
|
12696
12854
|
return {
|
|
12697
12855
|
running: !!job && !job.done,
|
|
@@ -12701,7 +12859,7 @@ var debugRouter = router({
|
|
|
12701
12859
|
});
|
|
12702
12860
|
|
|
12703
12861
|
// ../server/src/trpc/routers/diagnostics.ts
|
|
12704
|
-
import { z as
|
|
12862
|
+
import { z as z21 } from "zod";
|
|
12705
12863
|
import { TRPCError as TRPCError18 } from "@trpc/server";
|
|
12706
12864
|
|
|
12707
12865
|
// ../server/src/services/log-buffer.ts
|
|
@@ -12773,7 +12931,7 @@ function onEntry(listener) {
|
|
|
12773
12931
|
// ../server/src/trpc/routers/diagnostics.ts
|
|
12774
12932
|
var diagnosticsRouter = router({
|
|
12775
12933
|
/** Backlog for a client that just opened the panel. */
|
|
12776
|
-
recentLogs: protectedProcedure.input(
|
|
12934
|
+
recentLogs: protectedProcedure.input(z21.object({ limit: z21.number().int().min(1).max(2e3).default(500) }).optional()).query(({ input }) => recentEntries(input?.limit ?? 500)),
|
|
12777
12935
|
/**
|
|
12778
12936
|
* Live log stream.
|
|
12779
12937
|
*
|
|
@@ -12782,7 +12940,7 @@ var diagnosticsRouter = router({
|
|
|
12782
12940
|
* silently loses lines, which is precisely what someone watching a boot
|
|
12783
12941
|
* failure cannot afford.
|
|
12784
12942
|
*/
|
|
12785
|
-
streamLogs: protectedProcedure.input(
|
|
12943
|
+
streamLogs: protectedProcedure.input(z21.object({ afterSeq: z21.number().int().nonnegative().default(0) }).optional()).subscription(async function* ({ input, signal }) {
|
|
12786
12944
|
for (const entry of entriesSince(input?.afterSeq ?? 0)) yield entry;
|
|
12787
12945
|
const queue = [];
|
|
12788
12946
|
let wake = null;
|
|
@@ -12816,7 +12974,7 @@ var diagnosticsRouter = router({
|
|
|
12816
12974
|
* refused. That is what keeps this from being a way to signal arbitrary
|
|
12817
12975
|
* processes with the server's privileges.
|
|
12818
12976
|
*/
|
|
12819
|
-
killInstance: protectedProcedure.input(
|
|
12977
|
+
killInstance: protectedProcedure.input(z21.object({ pid: z21.number().int().positive() })).mutation(async ({ input }) => {
|
|
12820
12978
|
try {
|
|
12821
12979
|
return await killInstance(input.pid);
|
|
12822
12980
|
} catch (err) {
|
|
@@ -12829,11 +12987,46 @@ var diagnosticsRouter = router({
|
|
|
12829
12987
|
}
|
|
12830
12988
|
throw new TRPCError18({ code: "INTERNAL_SERVER_ERROR", message: reason });
|
|
12831
12989
|
}
|
|
12990
|
+
}),
|
|
12991
|
+
/**
|
|
12992
|
+
* Redémarrer une Runeya de cette machine : même exécutable, mêmes arguments,
|
|
12993
|
+
* même répertoire, mêmes `RUNEYA_*`.
|
|
12994
|
+
*
|
|
12995
|
+
* Deux chemins pour une même promesse. Une autre instance est arrêtée puis
|
|
12996
|
+
* relancée d'ici, et la réponse dit ce qui s'est passé. Celle-ci ne peut pas :
|
|
12997
|
+
* elle répond d'abord, pose un relanceur détaché, et part — d'où un résultat
|
|
12998
|
+
* qui annonce un redémarrage à venir plutôt qu'un redémarrage fait.
|
|
12999
|
+
*
|
|
13000
|
+
* Mêmes garde-fous que `killInstance` — le pid est un sélecteur cherché dans
|
|
13001
|
+
* la liste validée — plus un refus propre quand le lancement n'est pas
|
|
13002
|
+
* reproductible : instance trop ancienne pour avoir publié sa ligne de
|
|
13003
|
+
* commande, ou lancée avec un secret que le registre ne conserve pas.
|
|
13004
|
+
*/
|
|
13005
|
+
restartInstance: protectedProcedure.input(z21.object({ pid: z21.number().int().positive() })).mutation(async ({ input }) => {
|
|
13006
|
+
try {
|
|
13007
|
+
if (input.pid === process.pid) {
|
|
13008
|
+
const { relauncherPid, port } = await scheduleSelfRestart();
|
|
13009
|
+
return { self: true, relauncherPid, port };
|
|
13010
|
+
}
|
|
13011
|
+
return { self: false, ...await restartInstance(input.pid) };
|
|
13012
|
+
} catch (err) {
|
|
13013
|
+
const reason = err.message;
|
|
13014
|
+
if (reason === "instance-not-found") {
|
|
13015
|
+
throw new TRPCError18({ code: "NOT_FOUND", message: "No live Runeya instance with this pid." });
|
|
13016
|
+
}
|
|
13017
|
+
if (reason.startsWith("instance-not-restartable:")) {
|
|
13018
|
+
throw new TRPCError18({
|
|
13019
|
+
code: "BAD_REQUEST",
|
|
13020
|
+
message: `This instance cannot be restarted (${reason.split(":")[1]}).`
|
|
13021
|
+
});
|
|
13022
|
+
}
|
|
13023
|
+
throw new TRPCError18({ code: "INTERNAL_SERVER_ERROR", message: reason });
|
|
13024
|
+
}
|
|
12832
13025
|
})
|
|
12833
13026
|
});
|
|
12834
13027
|
|
|
12835
13028
|
// ../server/src/trpc/routers/kanban-queue.ts
|
|
12836
|
-
import { z as
|
|
13029
|
+
import { z as z22 } from "zod";
|
|
12837
13030
|
|
|
12838
13031
|
// ../server/src/services/kanban-queue.ts
|
|
12839
13032
|
import { randomUUID as randomUUID10 } from "crypto";
|
|
@@ -13021,36 +13214,36 @@ var kanbanQueue = new KanbanQueueService();
|
|
|
13021
13214
|
// ../server/src/trpc/routers/kanban-queue.ts
|
|
13022
13215
|
var kanbanQueueRouter = router({
|
|
13023
13216
|
getState: protectedProcedure.query(() => kanbanQueue.getState()),
|
|
13024
|
-
add: protectedProcedure.input(
|
|
13025
|
-
boardId:
|
|
13026
|
-
cardId:
|
|
13027
|
-
runner:
|
|
13028
|
-
model:
|
|
13029
|
-
scenarioId:
|
|
13217
|
+
add: protectedProcedure.input(z22.object({
|
|
13218
|
+
boardId: z22.string().max(128),
|
|
13219
|
+
cardId: z22.string().max(128),
|
|
13220
|
+
runner: z22.enum(["claude-code", "codex"]).optional(),
|
|
13221
|
+
model: z22.string().max(128).optional(),
|
|
13222
|
+
scenarioId: z22.string().max(128).optional(),
|
|
13030
13223
|
// Le projet ouvert quand la carte a été mise en file : la conversation
|
|
13031
13224
|
// qui en naîtra lui appartient, plutôt que de rester orpheline et de
|
|
13032
13225
|
// s'afficher dans tous les projets.
|
|
13033
|
-
projectId:
|
|
13034
|
-
orgId:
|
|
13226
|
+
projectId: z22.string().max(128).optional(),
|
|
13227
|
+
orgId: z22.string().max(128).nullable().optional()
|
|
13035
13228
|
})).mutation(({ input }) => kanbanQueue.add(input)),
|
|
13036
|
-
addColumn: protectedProcedure.input(
|
|
13037
|
-
boardId:
|
|
13038
|
-
columnId:
|
|
13039
|
-
runner:
|
|
13040
|
-
model:
|
|
13041
|
-
scenarioId:
|
|
13042
|
-
projectId:
|
|
13043
|
-
orgId:
|
|
13229
|
+
addColumn: protectedProcedure.input(z22.object({
|
|
13230
|
+
boardId: z22.string().max(128),
|
|
13231
|
+
columnId: z22.string().max(128),
|
|
13232
|
+
runner: z22.enum(["claude-code", "codex"]).optional(),
|
|
13233
|
+
model: z22.string().max(128).optional(),
|
|
13234
|
+
scenarioId: z22.string().max(128).optional(),
|
|
13235
|
+
projectId: z22.string().max(128).optional(),
|
|
13236
|
+
orgId: z22.string().max(128).nullable().optional()
|
|
13044
13237
|
})).mutation(async ({ input }) => {
|
|
13045
13238
|
const { boardId, columnId, ...options } = input;
|
|
13046
13239
|
return kanbanQueue.addColumn(boardId, columnId, options);
|
|
13047
13240
|
}),
|
|
13048
|
-
remove: protectedProcedure.input(
|
|
13241
|
+
remove: protectedProcedure.input(z22.object({ itemId: z22.string().max(128) })).mutation(({ input }) => ({ removed: kanbanQueue.remove(input.itemId) })),
|
|
13049
13242
|
stopAll: protectedProcedure.mutation(() => {
|
|
13050
13243
|
kanbanQueue.stopAll();
|
|
13051
13244
|
return { ok: true };
|
|
13052
13245
|
}),
|
|
13053
|
-
setMaxConcurrent: protectedProcedure.input(
|
|
13246
|
+
setMaxConcurrent: protectedProcedure.input(z22.object({ max: z22.number().int().min(1).max(20) })).mutation(({ input }) => {
|
|
13054
13247
|
kanbanQueue.setMaxConcurrent(input.max);
|
|
13055
13248
|
return kanbanQueue.getState();
|
|
13056
13249
|
}),
|
|
@@ -13084,11 +13277,11 @@ var kanbanQueueRouter = router({
|
|
|
13084
13277
|
});
|
|
13085
13278
|
|
|
13086
13279
|
// ../server/src/trpc/routers/kanban.ts
|
|
13087
|
-
import { mkdir as
|
|
13280
|
+
import { mkdir as mkdir17, readdir as readdir5, rm as rm3, stat as stat5, writeFile as writeFile15 } from "fs/promises";
|
|
13088
13281
|
import { createHash } from "crypto";
|
|
13089
13282
|
import { tmpdir } from "os";
|
|
13090
|
-
import { join as
|
|
13091
|
-
import { z as
|
|
13283
|
+
import { join as join20 } from "path";
|
|
13284
|
+
import { z as z23 } from "zod";
|
|
13092
13285
|
import { TRPCError as TRPCError19 } from "@trpc/server";
|
|
13093
13286
|
function summarizeCard(card, boardId, columnTitle) {
|
|
13094
13287
|
return {
|
|
@@ -13138,14 +13331,14 @@ function safeDecode(value) {
|
|
|
13138
13331
|
}
|
|
13139
13332
|
var MAX_ATTACHMENT_BYTES = 55 * 1024 * 1024;
|
|
13140
13333
|
function attachmentCacheDir() {
|
|
13141
|
-
return
|
|
13334
|
+
return join20(tmpdir(), "runeya-kanban-attachments");
|
|
13142
13335
|
}
|
|
13143
13336
|
var ATTACHMENT_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
13144
13337
|
async function purgeStaleAttachments(dir, ttlMs = ATTACHMENT_CACHE_TTL_MS) {
|
|
13145
13338
|
try {
|
|
13146
13339
|
const cutoff = Date.now() - ttlMs;
|
|
13147
13340
|
for (const name of await readdir5(dir)) {
|
|
13148
|
-
const path =
|
|
13341
|
+
const path = join20(dir, name);
|
|
13149
13342
|
const info = await stat5(path).catch(() => null);
|
|
13150
13343
|
if (info && info.mtimeMs < cutoff) await rm3(path, { force: true });
|
|
13151
13344
|
}
|
|
@@ -13153,15 +13346,15 @@ async function purgeStaleAttachments(dir, ttlMs = ATTACHMENT_CACHE_TTL_MS) {
|
|
|
13153
13346
|
}
|
|
13154
13347
|
}
|
|
13155
13348
|
function attachmentCacheDirs() {
|
|
13156
|
-
return [attachmentCacheDir(),
|
|
13349
|
+
return [attachmentCacheDir(), join20(machineRoot(), "kanban-attachments")];
|
|
13157
13350
|
}
|
|
13158
13351
|
async function storeAttachment(id, name, body, dirs = attachmentCacheDirs()) {
|
|
13159
13352
|
const refusals = [];
|
|
13160
13353
|
for (const dir of dirs) {
|
|
13161
13354
|
try {
|
|
13162
|
-
await
|
|
13163
|
-
const path =
|
|
13164
|
-
await
|
|
13355
|
+
await mkdir17(dir, { recursive: true });
|
|
13356
|
+
const path = join20(dir, safeLocalName(id, name));
|
|
13357
|
+
await writeFile15(path, body);
|
|
13165
13358
|
void purgeStaleAttachments(dir);
|
|
13166
13359
|
return path;
|
|
13167
13360
|
} catch (err) {
|
|
@@ -13184,9 +13377,9 @@ var kanbanRouter = router({
|
|
|
13184
13377
|
* card graph, so listing them in full would be megabytes to answer "which
|
|
13185
13378
|
* boards exist?". Use `getBoard` for the cards of one.
|
|
13186
13379
|
*/
|
|
13187
|
-
listBoards: protectedProcedure.input(
|
|
13188
|
-
includeArchived:
|
|
13189
|
-
organizationId:
|
|
13380
|
+
listBoards: protectedProcedure.input(z23.object({
|
|
13381
|
+
includeArchived: z23.boolean().optional(),
|
|
13382
|
+
organizationId: z23.string().max(128).optional()
|
|
13190
13383
|
}).optional()).query(async ({ input }) => {
|
|
13191
13384
|
const { organizationId, boards } = await kanbanStore.list(
|
|
13192
13385
|
input?.includeArchived ?? false,
|
|
@@ -13212,7 +13405,7 @@ var kanbanRouter = router({
|
|
|
13212
13405
|
};
|
|
13213
13406
|
}),
|
|
13214
13407
|
/** One board: its columns, and the cards in each. */
|
|
13215
|
-
getBoard: protectedProcedure.input(
|
|
13408
|
+
getBoard: protectedProcedure.input(z23.object({ boardId: z23.string().max(128) })).query(async ({ input }) => {
|
|
13216
13409
|
const board = await kanbanStore.get(input.boardId);
|
|
13217
13410
|
if (!board) return { board: null };
|
|
13218
13411
|
const { links } = await kanbanStore.cardLinks(input.boardId);
|
|
@@ -13251,11 +13444,11 @@ var kanbanRouter = router({
|
|
|
13251
13444
|
* organization — or one board when `boardId` is given. Archived boards are
|
|
13252
13445
|
* left out: they are what the team decided to stop looking at.
|
|
13253
13446
|
*/
|
|
13254
|
-
searchCards: protectedProcedure.input(
|
|
13255
|
-
query:
|
|
13256
|
-
boardId:
|
|
13257
|
-
limit:
|
|
13258
|
-
organizationId:
|
|
13447
|
+
searchCards: protectedProcedure.input(z23.object({
|
|
13448
|
+
query: z23.string().min(1).max(256),
|
|
13449
|
+
boardId: z23.string().max(128).optional(),
|
|
13450
|
+
limit: z23.number().int().min(1).max(100).optional(),
|
|
13451
|
+
organizationId: z23.string().max(128).optional()
|
|
13259
13452
|
})).query(async ({ input }) => {
|
|
13260
13453
|
const needle = normalize(input.query);
|
|
13261
13454
|
const ids = input.boardId ? [input.boardId] : (await kanbanStore.list(false, input.organizationId)).boards.map((b) => b.id);
|
|
@@ -13274,10 +13467,10 @@ var kanbanRouter = router({
|
|
|
13274
13467
|
* qu'un `commentCount`, et rien n'en donnait le texte. Cette route est la
|
|
13275
13468
|
* relecture, pour une seule carte : c'est le journal qui pèse, pas le reste.
|
|
13276
13469
|
*/
|
|
13277
|
-
getCardComments: protectedProcedure.input(
|
|
13278
|
-
boardId:
|
|
13279
|
-
cardId:
|
|
13280
|
-
limit:
|
|
13470
|
+
getCardComments: protectedProcedure.input(z23.object({
|
|
13471
|
+
boardId: z23.string().max(128),
|
|
13472
|
+
cardId: z23.string().max(128),
|
|
13473
|
+
limit: z23.number().int().min(1).max(200).optional()
|
|
13281
13474
|
})).query(async ({ input }) => {
|
|
13282
13475
|
const history = await kanbanStore.cardHistory(input.boardId, input.cardId);
|
|
13283
13476
|
const comments = history.filter((e) => e.type === "comment");
|
|
@@ -13306,18 +13499,18 @@ var kanbanRouter = router({
|
|
|
13306
13499
|
* `getBoard` en donne déjà l'essentiel carte par carte ; cette route sert
|
|
13307
13500
|
* quand c'est l'arbre lui-même qu'on veut, dates et auteurs compris.
|
|
13308
13501
|
*/
|
|
13309
|
-
getCardLinks: protectedProcedure.input(
|
|
13502
|
+
getCardLinks: protectedProcedure.input(z23.object({ boardId: z23.string().max(128) })).query(async ({ input }) => kanbanStore.cardLinks(input.boardId)),
|
|
13310
13503
|
/**
|
|
13311
13504
|
* Rattacher une carte à une carte parente, ou l'en détacher.
|
|
13312
13505
|
*
|
|
13313
13506
|
* Sans `parentCardId`, le lien est retiré. Le parent peut vivre sur un autre
|
|
13314
13507
|
* tableau : `parentBoardId` le désigne alors, sinon c'est celui de la carte.
|
|
13315
13508
|
*/
|
|
13316
|
-
setCardParent: protectedProcedure.input(
|
|
13317
|
-
boardId:
|
|
13318
|
-
cardId:
|
|
13319
|
-
parentCardId:
|
|
13320
|
-
parentBoardId:
|
|
13509
|
+
setCardParent: protectedProcedure.input(z23.object({
|
|
13510
|
+
boardId: z23.string().max(128),
|
|
13511
|
+
cardId: z23.string().max(128),
|
|
13512
|
+
parentCardId: z23.string().max(128).optional(),
|
|
13513
|
+
parentBoardId: z23.string().max(128).optional()
|
|
13321
13514
|
})).mutation(async ({ input }) => {
|
|
13322
13515
|
const ok = await kanbanStore.setCardParent(
|
|
13323
13516
|
input.boardId,
|
|
@@ -13329,31 +13522,31 @@ var kanbanRouter = router({
|
|
|
13329
13522
|
}
|
|
13330
13523
|
return { ok: true };
|
|
13331
13524
|
}),
|
|
13332
|
-
moveCard: protectedProcedure.input(
|
|
13333
|
-
boardId:
|
|
13334
|
-
cardId:
|
|
13335
|
-
targetColumn:
|
|
13525
|
+
moveCard: protectedProcedure.input(z23.object({
|
|
13526
|
+
boardId: z23.string().max(128),
|
|
13527
|
+
cardId: z23.string().max(128),
|
|
13528
|
+
targetColumn: z23.string().max(256)
|
|
13336
13529
|
})).mutation(async ({ input }) => {
|
|
13337
13530
|
await executeKanbanCommands(input.boardId, input.cardId, [
|
|
13338
13531
|
{ type: "move_card", columnTitle: input.targetColumn }
|
|
13339
13532
|
]);
|
|
13340
13533
|
return { ok: true };
|
|
13341
13534
|
}),
|
|
13342
|
-
addComment: protectedProcedure.input(
|
|
13343
|
-
boardId:
|
|
13344
|
-
cardId:
|
|
13345
|
-
comment:
|
|
13535
|
+
addComment: protectedProcedure.input(z23.object({
|
|
13536
|
+
boardId: z23.string().max(128),
|
|
13537
|
+
cardId: z23.string().max(128),
|
|
13538
|
+
comment: z23.string().max(2e4)
|
|
13346
13539
|
})).mutation(async ({ input }) => {
|
|
13347
13540
|
await executeKanbanCommands(input.boardId, input.cardId, [
|
|
13348
13541
|
{ type: "add_comment", comment: input.comment }
|
|
13349
13542
|
]);
|
|
13350
13543
|
return { ok: true };
|
|
13351
13544
|
}),
|
|
13352
|
-
addCard: protectedProcedure.input(
|
|
13353
|
-
boardId:
|
|
13354
|
-
column:
|
|
13355
|
-
title:
|
|
13356
|
-
content:
|
|
13545
|
+
addCard: protectedProcedure.input(z23.object({
|
|
13546
|
+
boardId: z23.string().max(128),
|
|
13547
|
+
column: z23.string().max(256),
|
|
13548
|
+
title: z23.string().max(512),
|
|
13549
|
+
content: z23.string().max(2e4).optional()
|
|
13357
13550
|
})).mutation(async ({ input }) => {
|
|
13358
13551
|
await executeKanbanBoardCommands(input.boardId, [
|
|
13359
13552
|
{ type: "add_card", columnTitle: input.column, cardTitle: input.title, cardContent: input.content }
|
|
@@ -13365,7 +13558,7 @@ var kanbanRouter = router({
|
|
|
13365
13558
|
* agent can open it with its own file tools. The bytes never go through the
|
|
13366
13559
|
* prompt: the card context lists the attachments, this returns a path.
|
|
13367
13560
|
*/
|
|
13368
|
-
downloadAttachment: protectedProcedure.input(
|
|
13561
|
+
downloadAttachment: protectedProcedure.input(z23.object({ attachmentId: z23.string().max(128) })).mutation(async ({ input }) => {
|
|
13369
13562
|
const id = input.attachmentId;
|
|
13370
13563
|
if (!ATTACHMENT_ID_REGEX.test(id)) {
|
|
13371
13564
|
throw new TRPCError19({ code: "BAD_REQUEST", message: "Invalid attachment id" });
|
|
@@ -13398,21 +13591,21 @@ var kanbanRouter = router({
|
|
|
13398
13591
|
});
|
|
13399
13592
|
|
|
13400
13593
|
// ../server/src/trpc/routers/terminal.ts
|
|
13401
|
-
import { z as
|
|
13594
|
+
import { z as z24 } from "zod";
|
|
13402
13595
|
import { TRPCError as TRPCError20 } from "@trpc/server";
|
|
13403
13596
|
var terminalRouter = router({
|
|
13404
13597
|
/** Create a PTY shell session on the target agent */
|
|
13405
|
-
create: protectedProcedure.input(
|
|
13406
|
-
agentId:
|
|
13407
|
-
cwd:
|
|
13598
|
+
create: protectedProcedure.input(z24.object({
|
|
13599
|
+
agentId: z24.string().max(128),
|
|
13600
|
+
cwd: z24.string().max(512).optional(),
|
|
13408
13601
|
/** Anchors the terminal when no explicit cwd is given. */
|
|
13409
|
-
serviceId:
|
|
13410
|
-
projectId:
|
|
13602
|
+
serviceId: z24.string().max(128).optional(),
|
|
13603
|
+
projectId: z24.string().max(128).optional(),
|
|
13411
13604
|
/** L'organisation du projet : un id seul peut en nommer un par organisation. */
|
|
13412
|
-
orgId:
|
|
13413
|
-
cols:
|
|
13414
|
-
rows:
|
|
13415
|
-
title:
|
|
13605
|
+
orgId: z24.string().max(128).nullable().optional(),
|
|
13606
|
+
cols: z24.number().int().min(1).max(512).optional(),
|
|
13607
|
+
rows: z24.number().int().min(1).max(256).optional(),
|
|
13608
|
+
title: z24.string().max(128).optional()
|
|
13416
13609
|
})).mutation(async ({ input }) => {
|
|
13417
13610
|
const result = await agentManager.agentMutation(
|
|
13418
13611
|
input.agentId,
|
|
@@ -13433,17 +13626,17 @@ var terminalRouter = router({
|
|
|
13433
13626
|
return result;
|
|
13434
13627
|
}),
|
|
13435
13628
|
/** Les sessions PTY encore vivantes sur l'agent (onglets à retrouver) */
|
|
13436
|
-
list: protectedProcedure.input(
|
|
13629
|
+
list: protectedProcedure.input(z24.object({ agentId: z24.string().max(128) })).query(async ({ input }) => {
|
|
13437
13630
|
return agentManager.agentQuery(
|
|
13438
13631
|
input.agentId,
|
|
13439
13632
|
"terminal.list"
|
|
13440
13633
|
);
|
|
13441
13634
|
}),
|
|
13442
13635
|
/** Renommer un onglet */
|
|
13443
|
-
rename: protectedProcedure.input(
|
|
13444
|
-
agentId:
|
|
13445
|
-
sessionId:
|
|
13446
|
-
title:
|
|
13636
|
+
rename: protectedProcedure.input(z24.object({
|
|
13637
|
+
agentId: z24.string().max(128),
|
|
13638
|
+
sessionId: z24.string().max(128),
|
|
13639
|
+
title: z24.string().max(128)
|
|
13447
13640
|
})).mutation(async ({ input }) => {
|
|
13448
13641
|
await agentManager.agentMutation(
|
|
13449
13642
|
input.agentId,
|
|
@@ -13453,10 +13646,10 @@ var terminalRouter = router({
|
|
|
13453
13646
|
return { ok: true };
|
|
13454
13647
|
}),
|
|
13455
13648
|
/** Send keystrokes / data to a PTY session */
|
|
13456
|
-
write: protectedProcedure.input(
|
|
13457
|
-
agentId:
|
|
13458
|
-
sessionId:
|
|
13459
|
-
data:
|
|
13649
|
+
write: protectedProcedure.input(z24.object({
|
|
13650
|
+
agentId: z24.string().max(128),
|
|
13651
|
+
sessionId: z24.string().max(128),
|
|
13652
|
+
data: z24.string().max(65536)
|
|
13460
13653
|
})).mutation(async ({ input }) => {
|
|
13461
13654
|
await agentManager.agentMutation(
|
|
13462
13655
|
input.agentId,
|
|
@@ -13466,11 +13659,11 @@ var terminalRouter = router({
|
|
|
13466
13659
|
return { ok: true };
|
|
13467
13660
|
}),
|
|
13468
13661
|
/** Resize the PTY */
|
|
13469
|
-
resize: protectedProcedure.input(
|
|
13470
|
-
agentId:
|
|
13471
|
-
sessionId:
|
|
13472
|
-
cols:
|
|
13473
|
-
rows:
|
|
13662
|
+
resize: protectedProcedure.input(z24.object({
|
|
13663
|
+
agentId: z24.string().max(128),
|
|
13664
|
+
sessionId: z24.string().max(128),
|
|
13665
|
+
cols: z24.number().int().min(1).max(512),
|
|
13666
|
+
rows: z24.number().int().min(1).max(256)
|
|
13474
13667
|
})).mutation(async ({ input }) => {
|
|
13475
13668
|
await agentManager.agentMutation(
|
|
13476
13669
|
input.agentId,
|
|
@@ -13480,9 +13673,9 @@ var terminalRouter = router({
|
|
|
13480
13673
|
return { ok: true };
|
|
13481
13674
|
}),
|
|
13482
13675
|
/** Destroy a PTY session */
|
|
13483
|
-
destroy: protectedProcedure.input(
|
|
13484
|
-
agentId:
|
|
13485
|
-
sessionId:
|
|
13676
|
+
destroy: protectedProcedure.input(z24.object({
|
|
13677
|
+
agentId: z24.string().max(128),
|
|
13678
|
+
sessionId: z24.string().max(128)
|
|
13486
13679
|
})).mutation(async ({ input }) => {
|
|
13487
13680
|
await agentManager.agentMutation(
|
|
13488
13681
|
input.agentId,
|
|
@@ -13492,11 +13685,11 @@ var terminalRouter = router({
|
|
|
13492
13685
|
return { ok: true };
|
|
13493
13686
|
}),
|
|
13494
13687
|
/** Stream PTY output — proxied via AgentWSBridge dynamic subscription */
|
|
13495
|
-
onData: protectedProcedure.input(
|
|
13496
|
-
agentId:
|
|
13497
|
-
sessionId:
|
|
13688
|
+
onData: protectedProcedure.input(z24.object({
|
|
13689
|
+
agentId: z24.string().max(128),
|
|
13690
|
+
sessionId: z24.string().max(128),
|
|
13498
13691
|
/** Rejouer l'historique de la session avant le flux temps réel. */
|
|
13499
|
-
replay:
|
|
13692
|
+
replay: z24.boolean().optional()
|
|
13500
13693
|
})).subscription(async function* ({ input }) {
|
|
13501
13694
|
const queue = [];
|
|
13502
13695
|
let resolve7 = null;
|
|
@@ -13545,11 +13738,11 @@ var terminalRouter = router({
|
|
|
13545
13738
|
});
|
|
13546
13739
|
|
|
13547
13740
|
// ../server/src/trpc/routers/utility.ts
|
|
13548
|
-
import { z as
|
|
13741
|
+
import { z as z25 } from "zod";
|
|
13549
13742
|
var MAX_WAIT_MS = 5 * 60 * 1e3;
|
|
13550
13743
|
var utilityRouter = router({
|
|
13551
|
-
wait: protectedProcedure.input(
|
|
13552
|
-
ms:
|
|
13744
|
+
wait: protectedProcedure.input(z25.object({
|
|
13745
|
+
ms: z25.number().int().min(0).max(MAX_WAIT_MS)
|
|
13553
13746
|
})).mutation(async ({ input }) => {
|
|
13554
13747
|
await new Promise((resolve7) => setTimeout(resolve7, input.ms));
|
|
13555
13748
|
return { waited: input.ms };
|
|
@@ -13557,15 +13750,15 @@ var utilityRouter = router({
|
|
|
13557
13750
|
});
|
|
13558
13751
|
|
|
13559
13752
|
// ../server/src/trpc/routers/wiki.ts
|
|
13560
|
-
import { z as
|
|
13753
|
+
import { z as z26 } from "zod";
|
|
13561
13754
|
import { TRPCError as TRPCError21 } from "@trpc/server";
|
|
13562
|
-
import { readFile as
|
|
13563
|
-
import { resolve as resolvePath, join as
|
|
13564
|
-
var SCOPE_SCHEMA =
|
|
13565
|
-
|
|
13566
|
-
|
|
13755
|
+
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";
|
|
13756
|
+
import { resolve as resolvePath, join as join21, relative, sep as sep3, dirname as dirname9 } from "path";
|
|
13757
|
+
var SCOPE_SCHEMA = z26.union([
|
|
13758
|
+
z26.literal("global"),
|
|
13759
|
+
z26.string().regex(/^service:[A-Za-z0-9_-]{1,128}$/, "Invalid service scope")
|
|
13567
13760
|
]);
|
|
13568
|
-
var REL_PATH_SCHEMA =
|
|
13761
|
+
var REL_PATH_SCHEMA = z26.string().min(1).max(512).regex(/^[A-Za-z0-9_./-]+$/).refine((p) => !p.includes("..") && !p.startsWith("/"), {
|
|
13569
13762
|
message: "Path must be a relative path without traversal"
|
|
13570
13763
|
});
|
|
13571
13764
|
var MAX_FILES = 500;
|
|
@@ -13585,9 +13778,9 @@ var IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
|
13585
13778
|
"target",
|
|
13586
13779
|
"out"
|
|
13587
13780
|
]);
|
|
13588
|
-
var DocsEntrySchema =
|
|
13589
|
-
|
|
13590
|
-
|
|
13781
|
+
var DocsEntrySchema = z26.lazy(() => z26.union([
|
|
13782
|
+
z26.object({ type: z26.literal("file"), name: z26.string(), path: z26.string() }),
|
|
13783
|
+
z26.object({ type: z26.literal("dir"), name: z26.string(), path: z26.string(), children: z26.array(DocsEntrySchema) })
|
|
13591
13784
|
]));
|
|
13592
13785
|
async function resolveScope(scope) {
|
|
13593
13786
|
if (scope === "global") {
|
|
@@ -13597,13 +13790,13 @@ async function resolveScope(scope) {
|
|
|
13597
13790
|
throw new TRPCError21({ code: "BAD_REQUEST", message: "Sous-chemin invalide" });
|
|
13598
13791
|
}
|
|
13599
13792
|
const dataDirAbs = resolvePath(env.DATA_DIR);
|
|
13600
|
-
await
|
|
13793
|
+
await mkdir18(dataDirAbs, { recursive: true });
|
|
13601
13794
|
const base = dirname9(await realpath(dataDirAbs));
|
|
13602
13795
|
const target = resolvePath(base, sub);
|
|
13603
13796
|
if (target !== base && !(target + sep3).startsWith(base + sep3)) {
|
|
13604
13797
|
throw new TRPCError21({ code: "FORBIDDEN", message: "Hors du dossier de donn\xE9es du serveur" });
|
|
13605
13798
|
}
|
|
13606
|
-
await
|
|
13799
|
+
await mkdir18(target, { recursive: true });
|
|
13607
13800
|
const root = await realpath(target);
|
|
13608
13801
|
if (root !== base && !(root + sep3).startsWith(base + sep3)) {
|
|
13609
13802
|
throw new TRPCError21({ code: "FORBIDDEN", message: "Le dossier wiki r\xE9sout hors du dossier de donn\xE9es" });
|
|
@@ -13630,7 +13823,7 @@ async function walkLocal(root, dir, depth, counter) {
|
|
|
13630
13823
|
for (const e of entries2) {
|
|
13631
13824
|
if (counter.n >= MAX_FILES) break;
|
|
13632
13825
|
if (e.name.startsWith(".") && e.name !== ".") continue;
|
|
13633
|
-
const abs =
|
|
13826
|
+
const abs = join21(dir, e.name);
|
|
13634
13827
|
const rel = relative(root, abs).split(sep3).join("/");
|
|
13635
13828
|
if (e.isDirectory()) {
|
|
13636
13829
|
if (IGNORED_DIRS.has(e.name)) continue;
|
|
@@ -13677,7 +13870,7 @@ async function resolveSafeLocal(root, relPath, requireExist) {
|
|
|
13677
13870
|
return resolvePath(realParent, target.slice(parent.length).replace(/^[\\/]+/, ""));
|
|
13678
13871
|
}
|
|
13679
13872
|
var wikiRouter = router({
|
|
13680
|
-
list: protectedProcedure.input(
|
|
13873
|
+
list: protectedProcedure.input(z26.object({ scope: SCOPE_SCHEMA })).output(z26.object({ root: z26.string(), entries: z26.array(DocsEntrySchema), truncated: z26.boolean() })).query(async ({ input }) => {
|
|
13681
13874
|
const target = await resolveScope(input.scope);
|
|
13682
13875
|
if (target.mode === "agent") {
|
|
13683
13876
|
return agentManager.agentQuery(target.agentId, "wiki.listRepoMarkdown", { cwd: target.cwd });
|
|
@@ -13686,7 +13879,7 @@ var wikiRouter = router({
|
|
|
13686
13879
|
const entries2 = await walkLocal(target.root, target.root, 0, counter);
|
|
13687
13880
|
return { root: target.root, entries: entries2, truncated: counter.n >= MAX_FILES };
|
|
13688
13881
|
}),
|
|
13689
|
-
read: protectedProcedure.input(
|
|
13882
|
+
read: protectedProcedure.input(z26.object({ scope: SCOPE_SCHEMA, path: REL_PATH_SCHEMA })).output(z26.object({ path: z26.string(), content: z26.string() })).query(async ({ input }) => {
|
|
13690
13883
|
if (!/\.(md|markdown)$/i.test(input.path)) {
|
|
13691
13884
|
throw new TRPCError21({ code: "BAD_REQUEST", message: "Seuls les .md/.markdown sont autoris\xE9s" });
|
|
13692
13885
|
}
|
|
@@ -13698,10 +13891,10 @@ var wikiRouter = router({
|
|
|
13698
13891
|
const s = await stat6(file);
|
|
13699
13892
|
if (!s.isFile()) throw new TRPCError21({ code: "BAD_REQUEST", message: "Pas un fichier" });
|
|
13700
13893
|
if (s.size > MAX_FILE_BYTES) throw new TRPCError21({ code: "PAYLOAD_TOO_LARGE", message: "Fichier trop volumineux" });
|
|
13701
|
-
const content = await
|
|
13894
|
+
const content = await readFile16(file, "utf-8");
|
|
13702
13895
|
return { path: input.path, content };
|
|
13703
13896
|
}),
|
|
13704
|
-
write: protectedProcedure.input(
|
|
13897
|
+
write: protectedProcedure.input(z26.object({ scope: SCOPE_SCHEMA, path: REL_PATH_SCHEMA, content: z26.string().max(5e6) })).mutation(async ({ input }) => {
|
|
13705
13898
|
if (!/\.(md|markdown)$/i.test(input.path)) {
|
|
13706
13899
|
throw new TRPCError21({ code: "BAD_REQUEST", message: "Seuls les .md/.markdown sont autoris\xE9s" });
|
|
13707
13900
|
}
|
|
@@ -13710,11 +13903,11 @@ var wikiRouter = router({
|
|
|
13710
13903
|
return agentManager.agentMutation(target.agentId, "wiki.writeMarkdown", { cwd: target.cwd, path: input.path, content: input.content });
|
|
13711
13904
|
}
|
|
13712
13905
|
const file = await resolveSafeLocal(target.root, input.path, false);
|
|
13713
|
-
await
|
|
13714
|
-
await
|
|
13906
|
+
await mkdir18(dirname9(file), { recursive: true });
|
|
13907
|
+
await writeFile16(file, input.content, "utf-8");
|
|
13715
13908
|
return { path: input.path, ok: true };
|
|
13716
13909
|
}),
|
|
13717
|
-
createFile: protectedProcedure.input(
|
|
13910
|
+
createFile: protectedProcedure.input(z26.object({ scope: SCOPE_SCHEMA, path: REL_PATH_SCHEMA })).mutation(async ({ input }) => {
|
|
13718
13911
|
if (!/\.(md|markdown)$/i.test(input.path)) {
|
|
13719
13912
|
throw new TRPCError21({ code: "BAD_REQUEST", message: "Seuls les .md/.markdown sont autoris\xE9s" });
|
|
13720
13913
|
}
|
|
@@ -13729,20 +13922,20 @@ var wikiRouter = router({
|
|
|
13729
13922
|
} catch (err) {
|
|
13730
13923
|
if (err instanceof TRPCError21) throw err;
|
|
13731
13924
|
}
|
|
13732
|
-
await
|
|
13733
|
-
await
|
|
13925
|
+
await mkdir18(dirname9(file), { recursive: true });
|
|
13926
|
+
await writeFile16(file, "", "utf-8");
|
|
13734
13927
|
return { path: input.path, ok: true };
|
|
13735
13928
|
}),
|
|
13736
|
-
createDir: protectedProcedure.input(
|
|
13929
|
+
createDir: protectedProcedure.input(z26.object({ scope: SCOPE_SCHEMA, path: REL_PATH_SCHEMA })).mutation(async ({ input }) => {
|
|
13737
13930
|
const target = await resolveScope(input.scope);
|
|
13738
13931
|
if (target.mode === "agent") {
|
|
13739
13932
|
return agentManager.agentMutation(target.agentId, "wiki.createDir", { cwd: target.cwd, path: input.path });
|
|
13740
13933
|
}
|
|
13741
13934
|
const dir = await resolveSafeLocal(target.root, input.path, false);
|
|
13742
|
-
await
|
|
13935
|
+
await mkdir18(dir, { recursive: true });
|
|
13743
13936
|
return { path: input.path, ok: true };
|
|
13744
13937
|
}),
|
|
13745
|
-
rename: protectedProcedure.input(
|
|
13938
|
+
rename: protectedProcedure.input(z26.object({ scope: SCOPE_SCHEMA, fromPath: REL_PATH_SCHEMA, toPath: REL_PATH_SCHEMA })).mutation(async ({ input }) => {
|
|
13746
13939
|
const target = await resolveScope(input.scope);
|
|
13747
13940
|
if (target.mode === "agent") {
|
|
13748
13941
|
return agentManager.agentMutation(target.agentId, "wiki.renamePath", { cwd: target.cwd, fromPath: input.fromPath, toPath: input.toPath });
|
|
@@ -13755,11 +13948,11 @@ var wikiRouter = router({
|
|
|
13755
13948
|
} catch (err) {
|
|
13756
13949
|
if (err instanceof TRPCError21) throw err;
|
|
13757
13950
|
}
|
|
13758
|
-
await
|
|
13759
|
-
await
|
|
13951
|
+
await mkdir18(dirname9(to), { recursive: true });
|
|
13952
|
+
await rename13(from, to);
|
|
13760
13953
|
return { fromPath: input.fromPath, toPath: input.toPath, ok: true };
|
|
13761
13954
|
}),
|
|
13762
|
-
ensureRoot: protectedProcedure.input(
|
|
13955
|
+
ensureRoot: protectedProcedure.input(z26.object({ scope: SCOPE_SCHEMA })).mutation(async ({ input }) => {
|
|
13763
13956
|
if (input.scope === "global") {
|
|
13764
13957
|
await resolveScope("global");
|
|
13765
13958
|
return { ok: true };
|
|
@@ -13772,7 +13965,7 @@ var wikiRouter = router({
|
|
|
13772
13965
|
const cwd = await resolveWorkspaceCwd({ serviceId, override: service.docsPath?.trim() || void 0 });
|
|
13773
13966
|
return agentManager.agentMutation(agentId, "wiki.ensureRoot", { cwd });
|
|
13774
13967
|
}),
|
|
13775
|
-
delete: protectedProcedure.input(
|
|
13968
|
+
delete: protectedProcedure.input(z26.object({ scope: SCOPE_SCHEMA, path: REL_PATH_SCHEMA })).mutation(async ({ input }) => {
|
|
13776
13969
|
const target = await resolveScope(input.scope);
|
|
13777
13970
|
if (target.mode === "agent") {
|
|
13778
13971
|
return agentManager.agentMutation(target.agentId, "wiki.deletePath", { cwd: target.cwd, path: input.path });
|
|
@@ -13798,14 +13991,14 @@ var configRouter = router({
|
|
|
13798
13991
|
});
|
|
13799
13992
|
|
|
13800
13993
|
// ../server/src/trpc/routers/cloud-sync.ts
|
|
13801
|
-
import { z as
|
|
13994
|
+
import { z as z27 } from "zod";
|
|
13802
13995
|
import { TRPCError as TRPCError22 } from "@trpc/server";
|
|
13803
13996
|
|
|
13804
13997
|
// ../server/src/services/org-sync-scope.ts
|
|
13805
13998
|
import { access as access2 } from "fs/promises";
|
|
13806
|
-
import { join as
|
|
13999
|
+
import { join as join22 } from "path";
|
|
13807
14000
|
async function isMaterialized(root) {
|
|
13808
|
-
return access2(
|
|
14001
|
+
return access2(join22(root, "project.json")).then(() => true, () => false);
|
|
13809
14002
|
}
|
|
13810
14003
|
async function orgsToSync() {
|
|
13811
14004
|
const cloudUrl = getCloudApiUrl();
|
|
@@ -13867,16 +14060,16 @@ async function reconcileOrgCanary(orgId) {
|
|
|
13867
14060
|
|
|
13868
14061
|
// ../server/src/services/cloud-sync-bridge.ts
|
|
13869
14062
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
13870
|
-
import { mkdir as
|
|
14063
|
+
import { mkdir as mkdir20, rm as rm5 } from "fs/promises";
|
|
13871
14064
|
import * as Y from "yjs";
|
|
13872
14065
|
|
|
13873
14066
|
// ../server/src/services/org-lock.ts
|
|
13874
|
-
import { open as open2, readFile as
|
|
14067
|
+
import { open as open2, readFile as readFile17, unlink as unlink4, mkdir as mkdir19 } from "fs/promises";
|
|
13875
14068
|
import { readFileSync, unlinkSync } from "fs";
|
|
13876
|
-
import { join as
|
|
14069
|
+
import { join as join23 } from "path";
|
|
13877
14070
|
var held = /* @__PURE__ */ new Set();
|
|
13878
14071
|
function lockPath(orgId) {
|
|
13879
|
-
return
|
|
14072
|
+
return join23(orgVaultRoot(orgId), "org.lock");
|
|
13880
14073
|
}
|
|
13881
14074
|
function isRunning(pid) {
|
|
13882
14075
|
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
@@ -13889,7 +14082,7 @@ function isRunning(pid) {
|
|
|
13889
14082
|
}
|
|
13890
14083
|
async function readLock(path) {
|
|
13891
14084
|
try {
|
|
13892
|
-
const parsed = JSON.parse(await
|
|
14085
|
+
const parsed = JSON.parse(await readFile17(path, "utf-8"));
|
|
13893
14086
|
return typeof parsed?.pid === "number" ? parsed : null;
|
|
13894
14087
|
} catch {
|
|
13895
14088
|
return null;
|
|
@@ -13897,7 +14090,7 @@ async function readLock(path) {
|
|
|
13897
14090
|
}
|
|
13898
14091
|
async function acquireOrgLock(orgId) {
|
|
13899
14092
|
const path = lockPath(orgId);
|
|
13900
|
-
await
|
|
14093
|
+
await mkdir19(orgVaultRoot(orgId), { recursive: true });
|
|
13901
14094
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
13902
14095
|
try {
|
|
13903
14096
|
const handle = await open2(path, "wx");
|
|
@@ -14308,7 +14501,7 @@ var OrgSyncConnection = class {
|
|
|
14308
14501
|
}
|
|
14309
14502
|
const isLocal = existing?.orgId === this.link.orgId;
|
|
14310
14503
|
if (!inDoc && !isLocal) return false;
|
|
14311
|
-
await
|
|
14504
|
+
await mkdir20(projectVaultRoot(this.link.orgId, projectId), { recursive: true });
|
|
14312
14505
|
this.tracked.add(projectId);
|
|
14313
14506
|
if (inDoc) await this.pullFromDoc([projectId]);
|
|
14314
14507
|
else await this.reconcileLocalToDoc();
|
|
@@ -14684,8 +14877,8 @@ var CloudSyncBridge = class {
|
|
|
14684
14877
|
var cloudSyncBridge = new CloudSyncBridge();
|
|
14685
14878
|
|
|
14686
14879
|
// ../server/src/services/key-adoption.ts
|
|
14687
|
-
import { readdir as readdir7, readFile as
|
|
14688
|
-
import { join as
|
|
14880
|
+
import { readdir as readdir7, readFile as readFile18, writeFile as writeFile17, mkdir as mkdir21, copyFile, rename as rename14, stat as stat7 } from "fs/promises";
|
|
14881
|
+
import { join as join24 } from "path";
|
|
14689
14882
|
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes5 } from "crypto";
|
|
14690
14883
|
var ALGORITHM = "aes-256-gcm";
|
|
14691
14884
|
function isAgentTriplet(value) {
|
|
@@ -14765,10 +14958,10 @@ async function adoptOrgKey(orgId, newKey, masterPassword, now) {
|
|
|
14765
14958
|
const touchedRoots = /* @__PURE__ */ new Set();
|
|
14766
14959
|
for (const vaultRoot of await rootsOfOrg(orgId)) {
|
|
14767
14960
|
for (const name of await jsonFilesIn(vaultRoot)) {
|
|
14768
|
-
const path =
|
|
14961
|
+
const path = join24(vaultRoot, name);
|
|
14769
14962
|
let parsed;
|
|
14770
14963
|
try {
|
|
14771
|
-
parsed = JSON.parse(await
|
|
14964
|
+
parsed = JSON.parse(await readFile18(path, "utf-8"));
|
|
14772
14965
|
} catch {
|
|
14773
14966
|
continue;
|
|
14774
14967
|
}
|
|
@@ -14782,22 +14975,22 @@ async function adoptOrgKey(orgId, newKey, masterPassword, now) {
|
|
|
14782
14975
|
const stamp = now.toISOString().replace(/[:.]/g, "-").substring(0, 19);
|
|
14783
14976
|
const backups = [];
|
|
14784
14977
|
for (const vaultRoot of touchedRoots) {
|
|
14785
|
-
const backupDir =
|
|
14786
|
-
await
|
|
14978
|
+
const backupDir = join24(vaultRoot, `backup-key-${stamp}`);
|
|
14979
|
+
await mkdir21(backupDir, { recursive: true });
|
|
14787
14980
|
for (const name of await jsonFilesIn(vaultRoot)) {
|
|
14788
|
-
await copyFile(
|
|
14981
|
+
await copyFile(join24(vaultRoot, name), join24(backupDir, name));
|
|
14789
14982
|
}
|
|
14790
14983
|
for (const name of [".encryption.key.enc", ".runeya-verify"]) {
|
|
14791
|
-
if (await exists(
|
|
14792
|
-
await copyFile(
|
|
14984
|
+
if (await exists(join24(vaultRoot, name))) {
|
|
14985
|
+
await copyFile(join24(vaultRoot, name), join24(backupDir, name));
|
|
14793
14986
|
}
|
|
14794
14987
|
}
|
|
14795
14988
|
backups.push(backupDir);
|
|
14796
14989
|
}
|
|
14797
14990
|
for (const item of pending) {
|
|
14798
14991
|
const tmp = item.path + ".tmp";
|
|
14799
|
-
await
|
|
14800
|
-
await
|
|
14992
|
+
await writeFile17(tmp, item.content, "utf-8");
|
|
14993
|
+
await rename14(tmp, item.path);
|
|
14801
14994
|
}
|
|
14802
14995
|
await installOrgKey(orgId, newKey, masterPassword);
|
|
14803
14996
|
clearVaultLock(orgId);
|
|
@@ -14858,10 +15051,10 @@ var cloudSyncRouter = router({
|
|
|
14858
15051
|
* "open this project" is the whole gesture.
|
|
14859
15052
|
*/
|
|
14860
15053
|
trackProject: protectedProcedure.input(
|
|
14861
|
-
|
|
14862
|
-
orgId:
|
|
14863
|
-
cloudUrl:
|
|
14864
|
-
projectId:
|
|
15054
|
+
z27.object({
|
|
15055
|
+
orgId: z27.string().min(1).max(128),
|
|
15056
|
+
cloudUrl: z27.string().url().max(2048),
|
|
15057
|
+
projectId: z27.string().min(1).max(128)
|
|
14865
15058
|
})
|
|
14866
15059
|
).mutation(async ({ input }) => {
|
|
14867
15060
|
await assertOrgReadable(input.orgId);
|
|
@@ -14895,10 +15088,10 @@ var cloudSyncRouter = router({
|
|
|
14895
15088
|
* fusionné.
|
|
14896
15089
|
*/
|
|
14897
15090
|
publishProject: protectedProcedure.input(
|
|
14898
|
-
|
|
14899
|
-
orgId:
|
|
14900
|
-
cloudUrl:
|
|
14901
|
-
projectId:
|
|
15091
|
+
z27.object({
|
|
15092
|
+
orgId: z27.string().min(1).max(128),
|
|
15093
|
+
cloudUrl: z27.string().url().max(2048),
|
|
15094
|
+
projectId: z27.string().min(1).max(128)
|
|
14902
15095
|
})
|
|
14903
15096
|
).mutation(async ({ input }) => {
|
|
14904
15097
|
const local = await projectStore.get({ id: input.projectId, orgId: null });
|
|
@@ -14939,9 +15132,9 @@ var cloudSyncRouter = router({
|
|
|
14939
15132
|
* publié. Le cloud, lui, ne peut pas répondre — il n'a que du chiffré sous
|
|
14940
15133
|
* les yeux — donc le canari est rapatrié et jugé ici.
|
|
14941
15134
|
*/
|
|
14942
|
-
checkOrgKey: protectedProcedure.input(
|
|
14943
|
-
orgId:
|
|
14944
|
-
keyHex:
|
|
15135
|
+
checkOrgKey: protectedProcedure.input(z27.object({
|
|
15136
|
+
orgId: z27.string().min(1).max(128),
|
|
15137
|
+
keyHex: z27.string().length(64).regex(/^[0-9a-f]+$/i)
|
|
14945
15138
|
})).query(async ({ input }) => {
|
|
14946
15139
|
const res = await cloudFetch2(
|
|
14947
15140
|
`/api/auth/organization/canary?organizationId=${encodeURIComponent(input.orgId)}`,
|
|
@@ -14964,10 +15157,10 @@ var cloudSyncRouter = router({
|
|
|
14964
15157
|
* Bornée au coffre de l'organisation et à ceux de ses projets : les autres
|
|
14965
15158
|
* organisations et la machine gardent leur clé.
|
|
14966
15159
|
*/
|
|
14967
|
-
adoptOrgKey: protectedProcedure.input(
|
|
14968
|
-
orgId:
|
|
14969
|
-
keyHex:
|
|
14970
|
-
masterPassword:
|
|
15160
|
+
adoptOrgKey: protectedProcedure.input(z27.object({
|
|
15161
|
+
orgId: z27.string().min(1).max(128),
|
|
15162
|
+
keyHex: z27.string().length(64).regex(/^[0-9a-f]+$/i),
|
|
15163
|
+
masterPassword: z27.string().min(1).max(1024)
|
|
14971
15164
|
})).mutation(async ({ input }) => {
|
|
14972
15165
|
const report = await adoptOrgKey(
|
|
14973
15166
|
input.orgId,
|
|
@@ -14991,7 +15184,7 @@ var cloudSyncRouter = router({
|
|
|
14991
15184
|
* Elle ne re-chiffre rien : ce qui a déjà été synchronisé sous l'ancienne clé
|
|
14992
15185
|
* reste illisible. L'interface le dit avant de la déclencher.
|
|
14993
15186
|
*/
|
|
14994
|
-
resetOrgKey: protectedProcedure.input(
|
|
15187
|
+
resetOrgKey: protectedProcedure.input(z27.object({ orgId: z27.string().min(1).max(128) })).mutation(async ({ input }) => {
|
|
14995
15188
|
const canary = await readVerifyFile(await keyRoot());
|
|
14996
15189
|
if (!canary) {
|
|
14997
15190
|
throw new TRPCError22({
|
|
@@ -15021,9 +15214,9 @@ var cloudSyncRouter = router({
|
|
|
15021
15214
|
* every other member and for this one on another machine.
|
|
15022
15215
|
*/
|
|
15023
15216
|
untrackProject: protectedProcedure.input(
|
|
15024
|
-
|
|
15025
|
-
orgId:
|
|
15026
|
-
projectId:
|
|
15217
|
+
z27.object({
|
|
15218
|
+
orgId: z27.string().min(1).max(128),
|
|
15219
|
+
projectId: z27.string().min(1).max(128)
|
|
15027
15220
|
})
|
|
15028
15221
|
).mutation(async ({ input }) => {
|
|
15029
15222
|
await cloudSyncBridge.unfollowProject(input.orgId, input.projectId);
|
|
@@ -15039,9 +15232,9 @@ var cloudSyncRouter = router({
|
|
|
15039
15232
|
* membre, ce qui évite d'effacer les fichiers si le cloud a refusé l'ordre.
|
|
15040
15233
|
*/
|
|
15041
15234
|
deleteProjectFromOrg: protectedProcedure.input(
|
|
15042
|
-
|
|
15043
|
-
orgId:
|
|
15044
|
-
projectId:
|
|
15235
|
+
z27.object({
|
|
15236
|
+
orgId: z27.string().min(1).max(128),
|
|
15237
|
+
projectId: z27.string().min(1).max(128)
|
|
15045
15238
|
})
|
|
15046
15239
|
).mutation(async ({ input }) => {
|
|
15047
15240
|
let res;
|
|
@@ -15085,10 +15278,10 @@ var cloudSyncRouter = router({
|
|
|
15085
15278
|
* afficher. Le nom est donc recopié dans le tampon du coffre au passage, là
|
|
15086
15279
|
* où il est déjà lu au démarrage suivant.
|
|
15087
15280
|
*/
|
|
15088
|
-
rememberOrgNames: protectedProcedure.input(
|
|
15089
|
-
orgs:
|
|
15090
|
-
orgId:
|
|
15091
|
-
name:
|
|
15281
|
+
rememberOrgNames: protectedProcedure.input(z27.object({
|
|
15282
|
+
orgs: z27.array(z27.object({
|
|
15283
|
+
orgId: z27.string().min(1).max(128),
|
|
15284
|
+
name: z27.string().min(1).max(100)
|
|
15092
15285
|
})).max(200)
|
|
15093
15286
|
})).mutation(async ({ input }) => {
|
|
15094
15287
|
for (const { orgId, name } of input.orgs) await rememberOrgName(orgId, name);
|
|
@@ -15124,13 +15317,13 @@ var cloudSyncRouter = router({
|
|
|
15124
15317
|
// ../server/src/trpc/routers/filesystem.ts
|
|
15125
15318
|
import { readdir as readdir8, stat as stat8 } from "fs/promises";
|
|
15126
15319
|
import { homedir as homedir5 } from "os";
|
|
15127
|
-
import { isAbsolute as isAbsolute4, join as
|
|
15128
|
-
import { z as
|
|
15320
|
+
import { isAbsolute as isAbsolute4, join as join25, resolve as resolve5, dirname as dirname10, basename as basename2 } from "path";
|
|
15321
|
+
import { z as z28 } from "zod";
|
|
15129
15322
|
var MAX_ENTRIES2 = 500;
|
|
15130
|
-
var PATH_SCHEMA =
|
|
15323
|
+
var PATH_SCHEMA = z28.string().min(1).max(4096);
|
|
15131
15324
|
function safeResolve(input) {
|
|
15132
15325
|
if (input.includes("\0")) throw new Error("Chemin invalide");
|
|
15133
|
-
const expanded = input.startsWith("~") ?
|
|
15326
|
+
const expanded = input.startsWith("~") ? join25(homedir5(), input.slice(1)) : input;
|
|
15134
15327
|
if (!isAbsolute4(expanded)) throw new Error("Le chemin doit \xEAtre absolu");
|
|
15135
15328
|
return resolve5(expanded);
|
|
15136
15329
|
}
|
|
@@ -15151,7 +15344,7 @@ var filesystemRouter = router({
|
|
|
15151
15344
|
* Hidden entries are skipped: they are noise for choosing a workspace, and
|
|
15152
15345
|
* `.runeya` itself would invite placing a project inside another's data.
|
|
15153
15346
|
*/
|
|
15154
|
-
listDirectories: protectedProcedure.input(
|
|
15347
|
+
listDirectories: protectedProcedure.input(z28.object({ path: PATH_SCHEMA })).query(async ({ input }) => {
|
|
15155
15348
|
const dir = safeResolve(input.path);
|
|
15156
15349
|
const info = await stat8(dir).catch(() => null);
|
|
15157
15350
|
if (!info?.isDirectory()) {
|
|
@@ -15166,7 +15359,7 @@ var filesystemRouter = router({
|
|
|
15166
15359
|
const truncated = names.length > MAX_ENTRIES2;
|
|
15167
15360
|
const entries2 = [];
|
|
15168
15361
|
for (const name of names.slice(0, MAX_ENTRIES2)) {
|
|
15169
|
-
const path =
|
|
15362
|
+
const path = join25(dir, name);
|
|
15170
15363
|
entries2.push({ name, path, hasRuneyaProject: await holdsRuneyaProject(path) });
|
|
15171
15364
|
}
|
|
15172
15365
|
return {
|
|
@@ -15185,10 +15378,10 @@ var filesystemRouter = router({
|
|
|
15185
15378
|
* Two projects in one directory is what makes services run against the wrong
|
|
15186
15379
|
* code, so a directory that already holds one is refused outright.
|
|
15187
15380
|
*/
|
|
15188
|
-
checkProjectTarget: protectedProcedure.input(
|
|
15381
|
+
checkProjectTarget: protectedProcedure.input(z28.object({
|
|
15189
15382
|
path: PATH_SCHEMA,
|
|
15190
|
-
projectId:
|
|
15191
|
-
orgId:
|
|
15383
|
+
projectId: z28.string().min(1).max(128),
|
|
15384
|
+
orgId: z28.string().max(128).nullable().optional()
|
|
15192
15385
|
})).query(async ({ input }) => {
|
|
15193
15386
|
const dir = safeResolve(input.path);
|
|
15194
15387
|
const info = await stat8(dir).catch(() => null);
|
|
@@ -15298,8 +15491,8 @@ async function ensureFilePermissions() {
|
|
|
15298
15491
|
}
|
|
15299
15492
|
|
|
15300
15493
|
// ../server/src/services/vault-migration.ts
|
|
15301
|
-
import { readdir as readdir9, readFile as
|
|
15302
|
-
import { join as
|
|
15494
|
+
import { readdir as readdir9, readFile as readFile19, writeFile as writeFile18, mkdir as mkdir22, copyFile as copyFile2, unlink as unlink5, rename as rename15, stat as stat10 } from "fs/promises";
|
|
15495
|
+
import { join as join26 } from "path";
|
|
15303
15496
|
var KEY_FILES = [".encryption.key.enc", ".runeya-verify"];
|
|
15304
15497
|
var MACHINE_FILES = [
|
|
15305
15498
|
"agents.json",
|
|
@@ -15329,17 +15522,17 @@ async function openLegacyVault(legacyRoot, masterPassword) {
|
|
|
15329
15522
|
}
|
|
15330
15523
|
async function migrateLegacyVault(legacyRoot, machineRootDir, legacyKey, machineKey, now) {
|
|
15331
15524
|
const stamp = now.toISOString().replace(/[:.]/g, "-").substring(0, 19);
|
|
15332
|
-
const backupDir =
|
|
15333
|
-
await
|
|
15525
|
+
const backupDir = join26(legacyRoot, `backup-${stamp}`);
|
|
15526
|
+
await mkdir22(backupDir, { recursive: true });
|
|
15334
15527
|
const jsonFiles = await vaultJsonFiles(legacyRoot);
|
|
15335
15528
|
for (const name of [...jsonFiles, ...KEY_FILES]) {
|
|
15336
|
-
if (await exists2(
|
|
15337
|
-
await copyFile2(
|
|
15529
|
+
if (await exists2(join26(legacyRoot, name))) {
|
|
15530
|
+
await copyFile2(join26(legacyRoot, name), join26(backupDir, name));
|
|
15338
15531
|
}
|
|
15339
15532
|
}
|
|
15340
15533
|
const rekeyed = [];
|
|
15341
15534
|
for (const name of jsonFiles) {
|
|
15342
|
-
const raw = await
|
|
15535
|
+
const raw = await readFile19(join26(legacyRoot, name), "utf-8");
|
|
15343
15536
|
let parsed;
|
|
15344
15537
|
try {
|
|
15345
15538
|
parsed = JSON.parse(raw);
|
|
@@ -15349,13 +15542,13 @@ async function migrateLegacyVault(legacyRoot, machineRootDir, legacyKey, machine
|
|
|
15349
15542
|
const counter = { n: 0 };
|
|
15350
15543
|
const converted = rekeyValue(parsed, legacyKey, machineKey, counter);
|
|
15351
15544
|
if (counter.n === 0) continue;
|
|
15352
|
-
const tmp =
|
|
15353
|
-
await
|
|
15354
|
-
await
|
|
15545
|
+
const tmp = join26(legacyRoot, `${name}.tmp`);
|
|
15546
|
+
await writeFile18(tmp, JSON.stringify(converted, null, 2), "utf-8");
|
|
15547
|
+
await rename15(tmp, join26(legacyRoot, name));
|
|
15355
15548
|
rekeyed.push({ file: name, values: counter.n });
|
|
15356
15549
|
}
|
|
15357
15550
|
for (const { file, values } of rekeyed) {
|
|
15358
|
-
const parsed = JSON.parse(await
|
|
15551
|
+
const parsed = JSON.parse(await readFile19(join26(legacyRoot, file), "utf-8"));
|
|
15359
15552
|
const check = { n: 0 };
|
|
15360
15553
|
rekeyValue(parsed, machineKey, machineKey, check);
|
|
15361
15554
|
if (check.n !== values) {
|
|
@@ -15364,13 +15557,13 @@ async function migrateLegacyVault(legacyRoot, machineRootDir, legacyKey, machine
|
|
|
15364
15557
|
);
|
|
15365
15558
|
}
|
|
15366
15559
|
}
|
|
15367
|
-
await
|
|
15560
|
+
await mkdir22(machineRootDir, { recursive: true });
|
|
15368
15561
|
const moved = [];
|
|
15369
15562
|
const skipped = [];
|
|
15370
15563
|
for (const name of MACHINE_FILES) {
|
|
15371
|
-
const from =
|
|
15564
|
+
const from = join26(legacyRoot, name);
|
|
15372
15565
|
if (!await exists2(from)) continue;
|
|
15373
|
-
const to =
|
|
15566
|
+
const to = join26(machineRootDir, name);
|
|
15374
15567
|
if (await exists2(to)) {
|
|
15375
15568
|
skipped.push(name);
|
|
15376
15569
|
continue;
|
|
@@ -15380,15 +15573,15 @@ async function migrateLegacyVault(legacyRoot, machineRootDir, legacyKey, machine
|
|
|
15380
15573
|
moved.push(name);
|
|
15381
15574
|
}
|
|
15382
15575
|
for (const name of KEY_FILES) {
|
|
15383
|
-
const path =
|
|
15576
|
+
const path = join26(legacyRoot, name);
|
|
15384
15577
|
if (await exists2(path)) await unlink5(path);
|
|
15385
15578
|
}
|
|
15386
15579
|
return { backupDir, rekeyed, moved, skipped };
|
|
15387
15580
|
}
|
|
15388
15581
|
|
|
15389
15582
|
// ../server/src/services/settings-migration.ts
|
|
15390
|
-
import { readFile as
|
|
15391
|
-
import { join as
|
|
15583
|
+
import { readFile as readFile20, writeFile as writeFile19, rename as rename16, unlink as unlink6, mkdir as mkdir23, chmod as chmod12, stat as stat11 } from "fs/promises";
|
|
15584
|
+
import { join as join27 } from "path";
|
|
15392
15585
|
var SETTINGS_FILE2 = "settings.json";
|
|
15393
15586
|
var SETTINGS_PRIVATE_FILE2 = "settings.private.json";
|
|
15394
15587
|
async function exists3(path) {
|
|
@@ -15401,12 +15594,12 @@ async function legacySource(filename) {
|
|
|
15401
15594
|
return null;
|
|
15402
15595
|
}
|
|
15403
15596
|
async function moveInto(root, filename, from) {
|
|
15404
|
-
await
|
|
15405
|
-
const to =
|
|
15406
|
-
const contents = await
|
|
15597
|
+
await mkdir23(root, { recursive: true });
|
|
15598
|
+
const to = join27(root, filename);
|
|
15599
|
+
const contents = await readFile20(from, "utf-8");
|
|
15407
15600
|
const tmp = to + ".tmp";
|
|
15408
|
-
await
|
|
15409
|
-
await
|
|
15601
|
+
await writeFile19(tmp, contents, "utf-8");
|
|
15602
|
+
await rename16(tmp, to);
|
|
15410
15603
|
await chmod12(to, 384);
|
|
15411
15604
|
await unlink6(from);
|
|
15412
15605
|
}
|
|
@@ -15427,7 +15620,7 @@ async function migrateSettingsIntoVaults() {
|
|
|
15427
15620
|
const orgId = orgs[0];
|
|
15428
15621
|
const root = orgVaultRoot(orgId);
|
|
15429
15622
|
for (const { filename, from } of sources) {
|
|
15430
|
-
if (await exists3(
|
|
15623
|
+
if (await exists3(join27(root, filename))) continue;
|
|
15431
15624
|
await moveInto(root, filename, from);
|
|
15432
15625
|
report.files.push(filename);
|
|
15433
15626
|
}
|
|
@@ -15443,14 +15636,14 @@ import { createRequire as createRequire2 } from "module";
|
|
|
15443
15636
|
import { randomBytes as randomBytes6, createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3 } from "crypto";
|
|
15444
15637
|
import { randomUUID as randomUUID12 } from "crypto";
|
|
15445
15638
|
import {
|
|
15446
|
-
readFile as
|
|
15447
|
-
writeFile as
|
|
15448
|
-
rename as
|
|
15449
|
-
mkdir as
|
|
15639
|
+
readFile as readFile21,
|
|
15640
|
+
writeFile as writeFile20,
|
|
15641
|
+
rename as rename17,
|
|
15642
|
+
mkdir as mkdir24,
|
|
15450
15643
|
access as access3,
|
|
15451
15644
|
readdir as readdir10
|
|
15452
15645
|
} from "fs/promises";
|
|
15453
|
-
import { join as
|
|
15646
|
+
import { join as join28, dirname as dirname11 } from "path";
|
|
15454
15647
|
var _require = createRequire2(import.meta.url);
|
|
15455
15648
|
var PARSER_ID_MAP = {
|
|
15456
15649
|
"stack-monitor-parser-jsons": "native:json",
|
|
@@ -15559,7 +15752,7 @@ async function getSodium() {
|
|
|
15559
15752
|
return _sodium;
|
|
15560
15753
|
}
|
|
15561
15754
|
async function decryptLegacyFile(filePath, key, sodium) {
|
|
15562
|
-
const raw = (await
|
|
15755
|
+
const raw = (await readFile21(filePath, "utf-8")).trim();
|
|
15563
15756
|
if (!raw || raw === "[]" || raw === "{}") {
|
|
15564
15757
|
try {
|
|
15565
15758
|
return JSON.parse(raw);
|
|
@@ -15579,12 +15772,12 @@ async function decryptLegacyFile(filePath, key, sodium) {
|
|
|
15579
15772
|
}
|
|
15580
15773
|
async function atomicWrite(path, data) {
|
|
15581
15774
|
const tmp = path + ".tmp";
|
|
15582
|
-
await
|
|
15583
|
-
await
|
|
15775
|
+
await writeFile20(tmp, JSON.stringify(data, null, 2), "utf-8");
|
|
15776
|
+
await rename17(tmp, path);
|
|
15584
15777
|
}
|
|
15585
15778
|
async function runLegacyMigration(dataDir) {
|
|
15586
15779
|
const legacyRoot = env.DATA_DIR;
|
|
15587
|
-
const legacyKeyPath =
|
|
15780
|
+
const legacyKeyPath = join28(legacyRoot, "dbs", "encryption-key.json");
|
|
15588
15781
|
try {
|
|
15589
15782
|
await access3(legacyKeyPath);
|
|
15590
15783
|
} catch {
|
|
@@ -15592,20 +15785,20 @@ async function runLegacyMigration(dataDir) {
|
|
|
15592
15785
|
}
|
|
15593
15786
|
console.log("[legacy-migration] Legacy Runeya data detected, starting migration\u2026");
|
|
15594
15787
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").substring(0, 19);
|
|
15595
|
-
const legacyTmp =
|
|
15596
|
-
await
|
|
15597
|
-
await
|
|
15598
|
-
const legacyOld =
|
|
15599
|
-
await
|
|
15788
|
+
const legacyTmp = join28(abCwd, ".runeya-tmp");
|
|
15789
|
+
await rename17(legacyRoot, legacyTmp);
|
|
15790
|
+
await mkdir24(dataDir, { recursive: true });
|
|
15791
|
+
const legacyOld = join28(dataDir, `backup-${timestamp}`);
|
|
15792
|
+
await rename17(legacyTmp, legacyOld);
|
|
15600
15793
|
console.log(`[legacy-migration] Legacy data backed up to ${legacyOld}`);
|
|
15601
|
-
const keyJson = JSON.parse(await
|
|
15794
|
+
const keyJson = JSON.parse(await readFile21(join28(legacyOld, "dbs", "encryption-key.json"), "utf-8"));
|
|
15602
15795
|
const sodium = await getSodium();
|
|
15603
15796
|
const sodiumKey = sodium.from_base64(keyJson.encryptionKey);
|
|
15604
15797
|
const keyBuffer = Buffer.from(sodiumKey);
|
|
15605
15798
|
const runyeaKeyHex = keyBuffer.toString("hex");
|
|
15606
15799
|
await setEncryptionKey(runyeaKeyHex);
|
|
15607
15800
|
console.log("[legacy-migration] Encryption key loaded in memory (temporary)");
|
|
15608
|
-
const dbsDir =
|
|
15801
|
+
const dbsDir = join28(legacyOld, "dbs");
|
|
15609
15802
|
async function readEncrypted(filePath) {
|
|
15610
15803
|
try {
|
|
15611
15804
|
return await decryptLegacyFile(filePath, sodiumKey, sodium);
|
|
@@ -15614,29 +15807,29 @@ async function runLegacyMigration(dataDir) {
|
|
|
15614
15807
|
return null;
|
|
15615
15808
|
}
|
|
15616
15809
|
}
|
|
15617
|
-
const envsDir =
|
|
15810
|
+
const envsDir = join28(dbsDir, "envs");
|
|
15618
15811
|
const envFiles = (await readdir10(envsDir).catch(() => [])).filter((f) => f.endsWith(".encrypted.json"));
|
|
15619
15812
|
const legacyEnvs = {};
|
|
15620
15813
|
for (const file of envFiles) {
|
|
15621
15814
|
const name = file.replace(".encrypted.json", "");
|
|
15622
|
-
legacyEnvs[name] = await readEncrypted(
|
|
15815
|
+
legacyEnvs[name] = await readEncrypted(join28(envsDir, file));
|
|
15623
15816
|
}
|
|
15624
|
-
const servicesDir =
|
|
15817
|
+
const servicesDir = join28(dbsDir, "services");
|
|
15625
15818
|
const serviceFiles = (await readdir10(servicesDir).catch(() => [])).filter((f) => f.endsWith(".encrypted.json"));
|
|
15626
15819
|
const legacyServices = {};
|
|
15627
15820
|
for (const file of serviceFiles) {
|
|
15628
15821
|
const name = file.replace(".encrypted.json", "");
|
|
15629
15822
|
if (!name) continue;
|
|
15630
|
-
const data = await readEncrypted(
|
|
15823
|
+
const data = await readEncrypted(join28(servicesDir, file));
|
|
15631
15824
|
if (data?.label) legacyServices[name] = data;
|
|
15632
15825
|
}
|
|
15633
|
-
const overridesDir =
|
|
15826
|
+
const overridesDir = join28(dbsDir, "overrides");
|
|
15634
15827
|
const overrideFiles = (await readdir10(overridesDir).catch(() => [])).filter((f) => f.endsWith(".encrypted.json"));
|
|
15635
15828
|
const legacyServiceOverrides = {};
|
|
15636
15829
|
const legacyEnvOverrides = {};
|
|
15637
15830
|
for (const file of overrideFiles) {
|
|
15638
15831
|
const baseName = file.replace(".encrypted.json", "");
|
|
15639
|
-
const data = await readEncrypted(
|
|
15832
|
+
const data = await readEncrypted(join28(overridesDir, file));
|
|
15640
15833
|
if (!data) continue;
|
|
15641
15834
|
if (baseName.endsWith("-envs")) {
|
|
15642
15835
|
legacyServiceOverrides[baseName.slice(0, -5)] = data;
|
|
@@ -15644,11 +15837,11 @@ async function runLegacyMigration(dataDir) {
|
|
|
15644
15837
|
legacyEnvOverrides[baseName.slice(0, -12)] = data;
|
|
15645
15838
|
}
|
|
15646
15839
|
}
|
|
15647
|
-
const parsersDir =
|
|
15840
|
+
const parsersDir = join28(dbsDir, "parsers");
|
|
15648
15841
|
const parserFiles = (await readdir10(parsersDir).catch(() => [])).filter((f) => f.endsWith(".encrypted.json"));
|
|
15649
15842
|
const legacyParsers = [];
|
|
15650
15843
|
for (const file of parserFiles) {
|
|
15651
|
-
const data = await readEncrypted(
|
|
15844
|
+
const data = await readEncrypted(join28(parsersDir, file));
|
|
15652
15845
|
if (data?.id) legacyParsers.push(data);
|
|
15653
15846
|
}
|
|
15654
15847
|
const projectMonoId = randomUUID12();
|
|
@@ -15989,7 +16182,7 @@ async function runLegacyMigration(dataDir) {
|
|
|
15989
16182
|
}
|
|
15990
16183
|
let existingSettings = {};
|
|
15991
16184
|
try {
|
|
15992
|
-
existingSettings = JSON.parse(await
|
|
16185
|
+
existingSettings = JSON.parse(await readFile21(join28(dataDir, "settings.json"), "utf-8"));
|
|
15993
16186
|
} catch {
|
|
15994
16187
|
}
|
|
15995
16188
|
const migratedParsers = legacyParsers.map((p) => ({
|
|
@@ -16010,11 +16203,11 @@ ${p.transform ?? ""}`,
|
|
|
16010
16203
|
...migratedParsers
|
|
16011
16204
|
]
|
|
16012
16205
|
};
|
|
16013
|
-
await atomicWrite(
|
|
16014
|
-
await atomicWrite(
|
|
16015
|
-
await atomicWrite(
|
|
16016
|
-
await atomicWrite(
|
|
16017
|
-
await atomicWrite(
|
|
16206
|
+
await atomicWrite(join28(dataDir, "projects.json"), runeProjects);
|
|
16207
|
+
await atomicWrite(join28(dataDir, "services.json"), runeServices);
|
|
16208
|
+
await atomicWrite(join28(dataDir, "environments.json"), runeEnvs);
|
|
16209
|
+
await atomicWrite(join28(dataDir, "environment-overrides.json"), flatOverrides);
|
|
16210
|
+
await atomicWrite(join28(dataDir, "settings.json"), newSettings);
|
|
16018
16211
|
const svcEnvCount = runeEnvs.filter((e) => e.scope === "service").length;
|
|
16019
16212
|
console.log(`[legacy-migration] Written: ${runeProjects.length} projects, ${runeServices.length} services, ${runeEnvs.length} environments (${svcEnvCount} service-scoped)`);
|
|
16020
16213
|
console.log(`[legacy-migration] Overrides: ${Object.keys(flatOverrides).length}, custom parsers: ${migratedParsers.length} (all disabled \u2014 rewrite required)`);
|
|
@@ -16028,9 +16221,9 @@ async function findLegacyKeyInBackup(dataDir) {
|
|
|
16028
16221
|
const entries2 = await readdir10(dataDir);
|
|
16029
16222
|
const backupDirs = entries2.filter((e) => e.startsWith("backup-")).sort((a, b) => a < b ? -1 : a > b ? 1 : 0).reverse();
|
|
16030
16223
|
for (const dir of backupDirs) {
|
|
16031
|
-
const keyJsonPath =
|
|
16224
|
+
const keyJsonPath = join28(dataDir, dir, "dbs", "encryption-key.json");
|
|
16032
16225
|
try {
|
|
16033
|
-
const raw = await
|
|
16226
|
+
const raw = await readFile21(keyJsonPath, "utf-8");
|
|
16034
16227
|
const parsed = JSON.parse(raw);
|
|
16035
16228
|
if (!parsed.encryptionKey) continue;
|
|
16036
16229
|
const sodium = await getSodium();
|
|
@@ -16051,8 +16244,8 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16051
16244
|
const { resolve: resolve7 } = await import("path");
|
|
16052
16245
|
const abDataDir = resolve7(dataDir);
|
|
16053
16246
|
const candidateDirs = [
|
|
16054
|
-
|
|
16055
|
-
|
|
16247
|
+
join28(dirname11(env.DATA_DIR), ".runeya", "dbs", "overrides"),
|
|
16248
|
+
join28(abDataDir, "dbs", "overrides")
|
|
16056
16249
|
];
|
|
16057
16250
|
let overridesDir = null;
|
|
16058
16251
|
let overrideFiles = [];
|
|
@@ -16068,7 +16261,7 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16068
16261
|
}
|
|
16069
16262
|
}
|
|
16070
16263
|
if (!overridesDir || overrideFiles.length === 0) return false;
|
|
16071
|
-
const legacyKeyPath =
|
|
16264
|
+
const legacyKeyPath = join28(overridesDir, "..", "encryption-key.json");
|
|
16072
16265
|
try {
|
|
16073
16266
|
await access3(legacyKeyPath);
|
|
16074
16267
|
return false;
|
|
@@ -16086,7 +16279,7 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16086
16279
|
const envNameToId = {};
|
|
16087
16280
|
let envsRaw;
|
|
16088
16281
|
try {
|
|
16089
|
-
envsRaw = JSON.parse(await
|
|
16282
|
+
envsRaw = JSON.parse(await readFile21(join28(abDataDir, "environments.json"), "utf-8"));
|
|
16090
16283
|
for (const _env of envsRaw) {
|
|
16091
16284
|
const env2 = _env;
|
|
16092
16285
|
if (env2["name"] && env2["id"]) {
|
|
@@ -16105,7 +16298,7 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16105
16298
|
let servicesRaw = [];
|
|
16106
16299
|
const serviceNameToId = {};
|
|
16107
16300
|
try {
|
|
16108
|
-
servicesRaw = JSON.parse(await
|
|
16301
|
+
servicesRaw = JSON.parse(await readFile21(join28(abDataDir, "services.json"), "utf-8"));
|
|
16109
16302
|
for (const _svc of servicesRaw) {
|
|
16110
16303
|
const svc = _svc;
|
|
16111
16304
|
if (svc["name"] && svc["id"]) serviceNameToId[svc["name"]] = svc["id"];
|
|
@@ -16122,7 +16315,7 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16122
16315
|
const envName = baseName.slice(0, -"-environment".length);
|
|
16123
16316
|
let data;
|
|
16124
16317
|
try {
|
|
16125
|
-
data = await decryptLegacyFile(
|
|
16318
|
+
data = await decryptLegacyFile(join28(overridesDir, file), sodiumKey, sodium);
|
|
16126
16319
|
} catch (err) {
|
|
16127
16320
|
console.warn(`[override-migration] Failed to decrypt ${file}: ${err.message}`);
|
|
16128
16321
|
continue;
|
|
@@ -16149,7 +16342,7 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16149
16342
|
}
|
|
16150
16343
|
}
|
|
16151
16344
|
if (Object.keys(flatOverrides).length > 0) {
|
|
16152
|
-
await atomicWrite(
|
|
16345
|
+
await atomicWrite(join28(abDataDir, "environment-overrides.json"), flatOverrides);
|
|
16153
16346
|
console.log(`[override-migration] Written ${Object.keys(flatOverrides).length} override(s) to environment-overrides.json`);
|
|
16154
16347
|
}
|
|
16155
16348
|
let envsModified = false;
|
|
@@ -16159,7 +16352,7 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16159
16352
|
const serviceName = baseName.slice(0, -"-envs".length);
|
|
16160
16353
|
let data;
|
|
16161
16354
|
try {
|
|
16162
|
-
data = await decryptLegacyFile(
|
|
16355
|
+
data = await decryptLegacyFile(join28(overridesDir, file), sodiumKey, sodium);
|
|
16163
16356
|
} catch (err) {
|
|
16164
16357
|
console.warn(`[override-migration] Failed to decrypt ${file}: ${err.message}`);
|
|
16165
16358
|
continue;
|
|
@@ -16218,12 +16411,12 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16218
16411
|
}
|
|
16219
16412
|
}
|
|
16220
16413
|
if (envsModified) {
|
|
16221
|
-
await atomicWrite(
|
|
16414
|
+
await atomicWrite(join28(abDataDir, "environments.json"), envsRaw);
|
|
16222
16415
|
console.log("[override-migration] Merged service overrides into environments.json");
|
|
16223
16416
|
}
|
|
16224
16417
|
const migratedDir = overridesDir.replace(/overrides$/, "overrides-migrated");
|
|
16225
16418
|
try {
|
|
16226
|
-
await
|
|
16419
|
+
await rename17(overridesDir, migratedDir);
|
|
16227
16420
|
console.log(`[override-migration] Moved overrides/ \u2192 overrides-migrated/`);
|
|
16228
16421
|
} catch (err) {
|
|
16229
16422
|
console.warn(`[override-migration] Could not rename overrides dir: ${err.message}`);
|
|
@@ -16233,7 +16426,7 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16233
16426
|
}
|
|
16234
16427
|
|
|
16235
16428
|
// ../server/src/services/server-state.ts
|
|
16236
|
-
import { join as
|
|
16429
|
+
import { join as join29 } from "path";
|
|
16237
16430
|
import { stat as stat12 } from "fs/promises";
|
|
16238
16431
|
var ENCRYPTED_KEY_FILENAME2 = ".encryption.key.enc";
|
|
16239
16432
|
var VERIFY_FILENAME2 = ".runeya-verify";
|
|
@@ -16243,22 +16436,22 @@ async function getServerState() {
|
|
|
16243
16436
|
let hasVerify = false;
|
|
16244
16437
|
let hasData = false;
|
|
16245
16438
|
try {
|
|
16246
|
-
await stat12(
|
|
16439
|
+
await stat12(join29(dataDir, ENCRYPTED_KEY_FILENAME2));
|
|
16247
16440
|
hasEncFile = true;
|
|
16248
16441
|
} catch {
|
|
16249
16442
|
}
|
|
16250
16443
|
try {
|
|
16251
|
-
await stat12(
|
|
16444
|
+
await stat12(join29(dataDir, VERIFY_FILENAME2));
|
|
16252
16445
|
hasVerify = true;
|
|
16253
16446
|
} catch {
|
|
16254
16447
|
}
|
|
16255
16448
|
try {
|
|
16256
|
-
await stat12(
|
|
16449
|
+
await stat12(join29(dataDir, "projects.json"));
|
|
16257
16450
|
hasData = true;
|
|
16258
16451
|
} catch {
|
|
16259
16452
|
}
|
|
16260
16453
|
try {
|
|
16261
|
-
await stat12(
|
|
16454
|
+
await stat12(join29(dataDir, "project.json"));
|
|
16262
16455
|
hasData = true;
|
|
16263
16456
|
} catch {
|
|
16264
16457
|
}
|
|
@@ -16671,6 +16864,7 @@ async function createLocalServer() {
|
|
|
16671
16864
|
await ensureDataGitignore(env.DATA_DIR);
|
|
16672
16865
|
}
|
|
16673
16866
|
await settingsManager.getSettings();
|
|
16867
|
+
await applyPersistedLanMode();
|
|
16674
16868
|
await migrationEngine.run();
|
|
16675
16869
|
await ensureFilePermissions();
|
|
16676
16870
|
auditService.cleanup().catch((err) => console.error("[server] Audit cleanup failed:", err));
|
|
@@ -17267,6 +17461,7 @@ async function createLocalServer() {
|
|
|
17267
17461
|
}));
|
|
17268
17462
|
app.use(errorHandler);
|
|
17269
17463
|
const server = createServer(app);
|
|
17464
|
+
registerHttpServer(server);
|
|
17270
17465
|
const wss = new WebSocketServer({ noServer: true });
|
|
17271
17466
|
applyWSSHandler({
|
|
17272
17467
|
wss,
|
|
@@ -17518,4 +17713,4 @@ export {
|
|
|
17518
17713
|
pullEnv,
|
|
17519
17714
|
registerInstance
|
|
17520
17715
|
};
|
|
17521
|
-
//# sourceMappingURL=src-
|
|
17716
|
+
//# sourceMappingURL=src-MY5W5AYS.js.map
|