@runeya/runeya 2.0.70 → 2.0.72
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 +260 -164
- package/agent/index.js.map +1 -1
- package/agent-manager-YDLSYZE3.js +7 -0
- package/{chunk-YSJ6OJGN.js → chunk-HPYBAUAH.js} +409 -18
- package/chunk-HPYBAUAH.js.map +1 -0
- package/index.js +3 -2
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/{src-6WVQ2FQV.js → src-53OQNM27.js} +735 -633
- package/src-53OQNM27.js.map +1 -0
- package/web/assets/AgentScalarChatInterface.vue-DdIfThmp.js +13 -0
- package/web/assets/AgentTerminalPage-BD2w4XRc.css +1 -0
- package/web/assets/AgentTerminalPage-v9fFc2Kd.js +1 -0
- package/web/assets/AiChatPage-BvrKlLxc.js +1 -0
- package/web/assets/AppLayout-CLzy-QOZ.js +1 -0
- package/web/assets/{AppLayout-BqXoW05V.css → AppLayout-Dj8VrBzz.css} +1 -1
- package/web/assets/AuditPage-DgJIcr0c.js +1 -0
- package/web/assets/CloudAccountPage-CoJV3YCA.js +1 -0
- package/web/assets/CloudAccountPage-DGtKCmXL.js +1 -0
- package/web/assets/CloudMessagingPage-Bql34zJU.js +2 -0
- package/web/assets/DashboardPage-BSvJxrcT.js +1 -0
- package/web/assets/DirectoryPickerDialog-BfLLfUQy.js +1 -0
- package/web/assets/{EditorIcon-DUDLTmUd.js → EditorIcon-BbilRWLq.js} +2 -2
- package/web/assets/EnvironmentForm-BIHXK18r.js +108 -0
- package/web/assets/EnvironmentFormPage-oLAwLJ1b.js +1 -0
- package/web/assets/EnvironmentListPage-tJfB0q_E.js +1 -0
- package/web/assets/KanbanBoardPage-DpyYe6jx.js +4 -0
- package/web/assets/KanbanListPage-DjXWjWgU.js +1 -0
- package/web/assets/LaunchProjectPage-Bqgsa2z1.js +1 -0
- package/web/assets/LaunchProjectPage-BrmWhutG.css +1 -0
- package/web/assets/LaunchServicesPage-BCNDSuuN.js +1 -0
- package/web/assets/LaunchServicesPage-CMxUWoNQ.css +1 -0
- package/web/assets/LogViewer-gTNzyao0.js +3 -0
- package/web/assets/OrgKeyPrompt-BdNV_cve.js +1 -0
- package/web/assets/{ProcessControls-DMxvJmDe.js → ProcessControls-BzMrd-2c.js} +1 -1
- package/web/assets/ProcessDetailPage-Rg5zyPYJ.js +1 -0
- package/web/assets/{ProcessMetrics-DK4Dgdb0.js → ProcessMetrics-hZWAa3gi.js} +2 -2
- package/web/assets/ProjectDetailPage-NbxG6AIr.js +1 -0
- package/web/assets/ProjectListPage-COMYMVbr.js +1 -0
- package/web/assets/RandomJobTestPage-DTK2RLln.js +2 -0
- package/web/assets/ScenarioEditorPage-DIx_Nzbh.js +14 -0
- package/web/assets/SendToChatDialog-BAalryU3.js +1 -0
- package/web/assets/ServiceControlsBar-CgR8yFZb.js +1 -0
- package/web/assets/ServiceDetailPage-Cvqftndf.js +2 -0
- package/web/assets/ServiceFormPage-CGgCwNM3.js +1 -0
- package/web/assets/{SettingsPage-uCS5lY2z.css → SettingsPage-ClUsbLPy.css} +1 -1
- package/web/assets/SettingsPage-Dx5xoAS7.js +2063 -0
- package/web/assets/UnlockPage-BkqsC0ML.css +1 -0
- package/web/assets/UnlockPage-Dlp8kXD-.js +1 -0
- package/web/assets/VariablesTable-Dr1C6hg4.js +1 -0
- package/web/assets/VaultMigrationPage-1zZCTKgS.js +1 -0
- package/web/assets/VaultMigrationPage-B20L2W_w.css +1 -0
- package/web/assets/VersionBadge-BiLjqi8I.js +1 -0
- package/web/assets/WikiPage-B51w0xOX.js +1 -0
- package/web/assets/WikiView-CGQrkGH4.js +1 -0
- package/web/assets/add-scalar-classes-ChVyhgpT.js +387 -0
- package/web/assets/auth-errors-BdfA61wA.js +1 -0
- package/web/assets/autocomplete-wqj_ORBH.js +308 -0
- package/web/assets/{basic-shape-diamond.svg-CacrbinE.js → basic-shape-diamond.svg-CWwnQ30s.js} +1 -1
- package/web/assets/{basic-shape-hexagon.svg-GGJ54oyX.js → basic-shape-hexagon.svg-C9JMDUIK.js} +1 -1
- package/web/assets/{basic-shape-primary-circle-ellipse-round.svg-CuWfwdJM.js → basic-shape-primary-circle-ellipse-round.svg-Do0Ewbp-.js} +1 -1
- package/web/assets/{basic-shape-primary-square-rectangle.svg-C2Bewjip.js → basic-shape-primary-square-rectangle.svg-CRq767cD.js} +1 -1
- package/web/assets/{basic-shape-shield.svg-DNtg0KuJ.js → basic-shape-shield.svg-BuxJBs70.js} +1 -1
- package/web/assets/{browser-XO2fm4BX.js → browser-BEEW2obM.js} +1 -1
- package/web/assets/{browser-5NN8ieli.js → browser-BhZAIVa8.js} +1 -1
- package/web/assets/browser-DNbnH79q.js +6 -0
- package/web/assets/card-C1iS2wAN.js +32 -0
- package/web/assets/{checkbox-iq9mU5eP.js → checkbox-CCU9xze9.js} +3 -3
- package/web/assets/{chip-BsccUnHb.js → chip-DsJBorBp.js} +2 -2
- package/web/assets/client-BFK39Zab.js +24 -0
- package/web/assets/cloud-chat.store-D39vo5xT.js +1 -0
- package/web/assets/cloud-session-B7G8xhKC.js +1 -0
- package/web/assets/column-CPU5Jg0n.js +907 -0
- package/web/assets/{computer-device-desktop-monitor.svg-DSwpF_ss.js → computer-device-desktop-monitor.svg-XWEWhL0y.js} +1 -1
- package/web/assets/{computer-device-desktop.svg-Caj_PZBV.js → computer-device-desktop.svg-COkZClBv.js} +1 -1
- package/web/assets/{computer-device-laptop.svg-Bv3ienI_.js → computer-device-laptop.svg-C4EfJUqO.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-android-samsung-back.svg-IWlhEKx_.js → computer-device-mobile-phone-android-samsung-back.svg-Bb2_2tyI.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-android-samsung.svg-CglQAFq2.js → computer-device-mobile-phone-android-samsung.svg-CEUhXP7K.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-iphone-x-back.svg-CgjNnTTw.js → computer-device-mobile-phone-iphone-x-back.svg-B3rxizbE.js} +1 -1
- package/web/assets/{computer-device-mobile-phone-iphone-x.svg-CotZ-4M5.js → computer-device-mobile-phone-iphone-x.svg-BSKpZFCN.js} +1 -1
- package/web/assets/{computer-device-mobile-tablet-touch.svg-B2cemd61.js → computer-device-mobile-tablet-touch.svg-CZvb3YX2.js} +1 -1
- package/web/assets/{computer-device-mobile-tablet.svg-8nPVs4u_.js → computer-device-mobile-tablet.svg-BM4_YZYi.js} +1 -1
- package/web/assets/{computer-device-network-ethernet-cat6.svg-Bl56Qw4v.js → computer-device-network-ethernet-cat6.svg-CK0v-Rjf.js} +1 -1
- package/web/assets/{computer-device-network-lan-www.svg-C_x6Rf8N.js → computer-device-network-lan-www.svg-DvhO71Lq.js} +1 -1
- package/web/assets/{computer-device-network-wifi-connection.svg-oz6dsDQB.js → computer-device-network-wifi-connection.svg--olUYsgv.js} +1 -1
- package/web/assets/{computer-device-network-wifi-router.svg-BciHU6Nj.js → computer-device-network-wifi-router.svg-D5HKSWTi.js} +1 -1
- package/web/assets/{cssMode-DSX5tYcm.js → cssMode-CTjKNOiX.js} +1 -1
- package/web/assets/{divider-DnPOdDs3.js → divider-VFAPax5_.js} +2 -2
- package/web/assets/docx-preview-gNYLz3FX.js +21 -0
- package/web/assets/{ecology-science-erlenmeyer-flask.svg-BzQP6y9L.js → ecology-science-erlenmeyer-flask.svg-THkDG-tj.js} +1 -1
- package/web/assets/{fieldset-D9lkV70l.js → fieldset-DZGy449H.js} +2 -2
- package/web/assets/{freemarker2-D9yXX9Vw.js → freemarker2-CNSvFpVF.js} +1 -1
- package/web/assets/{handlebars-BmcjEksL.js → handlebars-BeRu48NI.js} +1 -1
- package/web/assets/{html-BQF9vZLL.js → html-DrTiGPjE.js} +1 -1
- package/web/assets/{htmlMode-DxSRpgHE.js → htmlMode-DpbDpbjK.js} +1 -1
- package/web/assets/{image-flash-lightning.svg-DQX09uxo.js → image-flash-lightning.svg-DrkyfdIV.js} +1 -1
- package/web/assets/{image-picture-flower.svg-CUBdrnoc.js → image-picture-flower.svg-BqFj1xcR.js} +1 -1
- package/web/assets/{index-CICxLkjp.css → index-B___lI4D.css} +1 -1
- package/web/assets/{index-enuBsJBa.js → index-y5bguEQB.js} +299 -299
- package/web/assets/{interface-alert-exclamation-diamond.svg-DXQdQSvN.js → interface-alert-exclamation-diamond.svg-B40BfW6d.js} +1 -1
- package/web/assets/{interface-alert-exclamation-triangle-warning.svg-BoCeNIlU.js → interface-alert-exclamation-triangle-warning.svg-DeIlksL4.js} +1 -1
- package/web/assets/{interface-alert-information-circle.svg-BCA57JL2.js → interface-alert-information-circle.svg-SwVdV-Z6.js} +1 -1
- package/web/assets/{interface-award-crown.svg-B1hTlsb0.js → interface-award-crown.svg-DZHf0EHC.js} +1 -1
- package/web/assets/{interface-bookmark.svg-zf3cIGKM.js → interface-bookmark-tag.svg-CiaV2Cjo.js} +1 -1
- package/web/assets/{interface-bookmark-tag.svg-AosfQ0Ip.js → interface-bookmark.svg-DBEqa-8W.js} +1 -1
- package/web/assets/{interface-calendar-date-one.svg-D58WqPie.js → interface-calendar-date-one.svg-C_afKyyz.js} +1 -1
- package/web/assets/{interface-content-book-open-pages.svg-B74HWMlw.js → interface-content-book-open-pages.svg-D5d9ilSu.js} +1 -1
- package/web/assets/{interface-content-book-page.svg-C2QWk62-.js → interface-content-book-page.svg-B6hlaLP5.js} +1 -1
- package/web/assets/{interface-content-file.svg-xKu0qAOQ.js → interface-content-file.svg-COWMwejF.js} +1 -1
- package/web/assets/interface-content-folder.svg-BCIUgpD4.js +1 -0
- package/web/assets/{interface-content-folder.svg-ZkrY9WkQ.js → interface-content-folder.svg-K7DTqQH-.js} +1 -1
- package/web/assets/{interface-copy-clipboard.svg-BEkNG3vO.js → interface-copy-clipboard.svg-BFQ6eajI.js} +1 -1
- package/web/assets/{interface-edit-attachment.svg-5ztQ3WTq.js → interface-edit-attachment.svg-B-LsB4cM.js} +1 -1
- package/web/assets/{interface-edit-binocular.svg-CC9U1Gnc.js → interface-edit-binocular.svg-CnVjKyrn.js} +1 -1
- package/web/assets/{interface-edit-magic-wand.svg-CPl6ZoE9.js → interface-edit-magic-wand.svg-CUY6vVJT.js} +1 -1
- package/web/assets/{interface-edit-tool-paint-roller.svg-B85t7jG2.js → interface-edit-tool-paint-roller.svg-B1tSdIxN.js} +1 -1
- package/web/assets/{interface-edit-tool-pencil.svg-BSTdqWUg.js → interface-edit-tool-pencil.svg-BHFULT75.js} +1 -1
- package/web/assets/{interface-favorite-award.svg-DbPr_WKt.js → interface-favorite-award.svg-CcOLoF8I.js} +1 -1
- package/web/assets/{interface-favorite-flag.svg-CgKYXc7k.js → interface-favorite-flag.svg-CAW6LmLW.js} +1 -1
- package/web/assets/{interface-favorite-heart.svg-DfnXyJMg.js → interface-favorite-heart.svg-BEz4zlNs.js} +1 -1
- package/web/assets/{interface-favorite-star.svg-0sT7jJMK.js → interface-favorite-star.svg-DKFuvYge.js} +1 -1
- package/web/assets/{interface-favorite-stars-sparkles.svg-BcM2EXgn.js → interface-favorite-stars-sparkles.svg-BfzccoPz.js} +1 -1
- package/web/assets/{interface-hierarchy-flowchart.svg-BM62WcKt.js → interface-hierarchy-flowchart.svg-BT8QX161.js} +1 -1
- package/web/assets/{interface-home-house.svg-KqP7iMC4.js → interface-home-house.svg-B264pTPi.js} +1 -1
- package/web/assets/{interface-hyperlink.svg-DBKFbihR.js → interface-hyperlink.svg-DhUgNKkr.js} +1 -1
- package/web/assets/{interface-lighting-brightness.svg-DTkCS7PY.js → interface-lighting-brightness.svg-CPKb40uB.js} +1 -1
- package/web/assets/{interface-lock-closed.svg-Div5xlvI.js → interface-lock-closed.svg-CvXhgCtt.js} +1 -1
- package/web/assets/{interface-lock-open-unlock.svg-Du5L_iMV.js → interface-lock-open-unlock.svg-B0PMKRhP.js} +1 -1
- package/web/assets/{interface-login-key.svg-28TYVVzH.js → interface-login-key.svg-DJUm3vhg.js} +1 -1
- package/web/assets/{interface-search.svg-BS_owhIG.js → interface-search.svg-ByW98ez_.js} +1 -1
- package/web/assets/{interface-setting-cog.svg-afYc0TQv.js → interface-setting-cog.svg-DYOmJ9It.js} +1 -1
- package/web/assets/{interface-share-megaphone-bullhorn.svg-BnW8HhjG.js → interface-share-megaphone-bullhorn.svg-YOCUHa3i.js} +1 -1
- package/web/assets/{interface-share-rocket.svg-DvX_9178.js → interface-share-rocket.svg-C5kj5dSu.js} +1 -1
- package/web/assets/{interface-share-satellite.svg-B4nQqv6w.js → interface-share-satellite.svg-C0svPxG6.js} +1 -1
- package/web/assets/{interface-share-space-ship.svg-Ciol-6JO.js → interface-share-space-ship.svg-8Nw02n1Q.js} +1 -1
- package/web/assets/{interface-share.svg-COm1OVr8.js → interface-share.svg-eDW294tn.js} +1 -1
- package/web/assets/{interface-signal-square.svg-DXuF6sqG.js → interface-signal-square.svg-CxB5mcJQ.js} +1 -1
- package/web/assets/{interface-time-clock-circle.svg-CWLe4mcs.js → interface-time-clock-circle.svg-CEnlQi79.js} +1 -1
- package/web/assets/{interface-time-hour-glass.svg-DXz9wBiv.js → interface-time-hour-glass.svg-qL3_s19Q.js} +1 -1
- package/web/assets/{interface-users-multiple.svg-CXOw1J5l.js → interface-users-multiple.svg-Cz2iA33z.js} +1 -1
- package/web/assets/{interface-weather-moon.svg-B9H9xib3.js → interface-weather-moon.svg-BoT9GUK_.js} +1 -1
- package/web/assets/{javascript-BY1URXQK.js → javascript-DWdA0-HW.js} +1 -1
- package/web/assets/{jsonMode-CxipJdzJ.js → jsonMode-DxGrVlm0.js} +2 -2
- package/web/assets/{liquid-BbqI_ezD.js → liquid-COqLk0mR.js} +1 -1
- package/web/assets/{lspLanguageFeatures-BrbDxmfl.js → lspLanguageFeatures--0hj1ZV4.js} +3 -3
- package/web/assets/{mail-chat-bubble-square.svg-CAlBGAlW.js → mail-chat-bubble-square.svg-eiKzTBOv.js} +1 -1
- package/web/assets/{mail-send-email-paper-airplane.svg-BoNc-FEY.js → mail-send-email-paper-airplane.svg-CCI77Gk8.js} +1 -1
- package/web/assets/{mail-send-envelope.svg-CnMOSib5.js → mail-send-envelope.svg-ChM5k_N7.js} +1 -1
- package/web/assets/{mdx-C4PcQ_oe.js → mdx-CwXNREAO.js} +1 -1
- package/web/assets/{message-BWsbEnoG.js → message-CSxReshg.js} +2 -2
- package/web/assets/{minus-BpDIA3FO.js → minus-Cg0lH8Mn.js} +2 -2
- package/web/assets/modal-D3dkRJqD.js +1 -0
- package/web/assets/modal-ix4Amfqv.js +5 -0
- package/web/assets/{money-cashier-receipt.svg-DZQ9mrBZ.js → money-cashier-receipt.svg-WMIW7vxg.js} +1 -1
- package/web/assets/{money-currency-dollar-pay.svg-BCaw-GeJ.js → money-currency-dollar-pay.svg-qTcGSVX2.js} +1 -1
- package/web/assets/{money-graph-arrow-increase.svg-DZXh-i2p.js → money-graph-arrow-increase.svg-B-TQKOW-.js} +1 -1
- package/web/assets/{money-graph-bar-chart-increase.svg-j_1tUlGM.js → money-graph-bar-chart-increase.svg-CWCIjQcI.js} +1 -1
- package/web/assets/multiselect-C7U34xql.js +251 -0
- package/web/assets/{nature-ecology-leaf.svg-bajA57tM.js → nature-ecology-leaf.svg-CL26IBv2.js} +1 -1
- package/web/assets/{password-W9W3PSE2.js → password-ZOY0bqV1.js} +4 -4
- package/web/assets/{phone-telephone.svg-DD5MGHqV.js → phone-telephone.svg-BhzxDLVX.js} +1 -1
- package/web/assets/{plus-RuIcofM_.js → plus-DsBv8bgd.js} +6 -6
- package/web/assets/process.store-DPp7dk63.js +1 -0
- package/web/assets/{programming-bug.svg-CjtqBc8Z.js → programming-bug.svg-CBNm3E3F.js} +1 -1
- package/web/assets/{programming-cloud.svg-BXQ_h3dK.js → programming-cloud.svg-BrVRbl9B.js} +1 -1
- package/web/assets/{programming-computer-database-server.svg-D6TzOHsK.js → programming-computer-database-server.svg-LQp6n-du.js} +1 -1
- package/web/assets/{programming-computer-database.svg-Dmdh0lIx.js → programming-computer-database.svg-CSbhcIMU.js} +1 -1
- package/web/assets/{programming-module-four-layout.svg-CtGhpLhO.js → programming-module-four-layout.svg-DYEAcL2j.js} +1 -1
- package/web/assets/{programming-module-three.svg-hz_w8W7I.js → programming-module-three.svg-CCQXCU-e.js} +1 -1
- package/web/assets/{programming-module.svg-oDT_fQLn.js → programming-module.svg-Chrmf7k4.js} +1 -1
- package/web/assets/{programming-script-code.svg-CxHHTsaU.js → programming-script-code.svg-DPhhp3IW.js} +1 -1
- package/web/assets/{python-DH-AyaLR.js → python-B7ePhfsS.js} +1 -1
- package/web/assets/{razor-BUpT1gRX.js → razor-ChpzroOv.js} +1 -1
- package/web/assets/router-Df972Ysi.js +1 -0
- package/web/assets/settings-scope-CC3oHq2H.js +1 -0
- package/web/assets/settings.store-B31_cRNl.js +1 -0
- package/web/assets/{shopping-cart.svg-D1eK38-E.js → shopping-cart.svg-bmefzlOu.js} +1 -1
- package/web/assets/{shopping-gift-present.svg-CxSfFNAS.js → shopping-gift-present.svg-aUOleva0.js} +1 -1
- package/web/assets/{shopping-shipping-box-parcel-package.svg-M5Njo2qJ.js → shopping-shipping-box-parcel-package.svg-BLsRP4dg.js} +1 -1
- package/web/assets/{src-CEK4EPEJ.js → src-BPSr9dU2.js} +34 -34
- package/web/assets/src-Dt37H-VN.js +1 -0
- package/web/assets/tabpanel-DZQ_g__B.js +150 -0
- package/web/assets/{tag-new-circle.svg-v_Go3fcT.js → tag-new-circle.svg-kTMMMv-0.js} +1 -1
- package/web/assets/{toggleswitch-C4A0_850.js → toggleswitch-BWXDXl37.js} +2 -2
- package/web/assets/{travel-map-earth-globe.svg-Db2uRb3M.js → travel-map-earth-globe.svg-BdQmz8_b.js} +1 -1
- package/web/assets/trpc-aSS7b3jh.js +1 -0
- package/web/assets/{tsMode-CXB5XugS.js → tsMode-arHIUQbZ.js} +6 -6
- package/web/assets/{typescript-CHJkC9r6.js → typescript-Ds9kgbPd.js} +1 -1
- package/web/assets/useAiChatDrawer-C1xrMtLl.js +1 -0
- package/web/assets/useCloudOrg-BdpqnN19.css +1 -0
- package/web/assets/useCloudOrg-BexK510D.js +97 -0
- package/web/assets/{useProjectCatalog-DDm0I6sX.js → useProjectCatalog-BbSaTBSS.js} +1 -1
- package/web/assets/{xml-DB4EKWC9.js → xml-CO56TgpZ.js} +1 -1
- package/web/assets/{yaml-CqvLyuow.js → yaml-DueFV2-x.js} +1 -1
- package/web/index.html +2 -2
- package/agent-manager-74WZPMVQ.js +0 -7
- package/chunk-YSJ6OJGN.js.map +0 -1
- package/src-6WVQ2FQV.js.map +0 -1
- package/web/assets/AgentScalarChatInterface.vue-vU3z8Etw.js +0 -13
- package/web/assets/AgentTerminalPage-A8GIX6dZ.css +0 -1
- package/web/assets/AgentTerminalPage-DE3GUoXn.js +0 -1
- package/web/assets/AiChatPage-BIJczUeS.js +0 -1
- package/web/assets/AppLayout-CvkK_Pp3.js +0 -1
- package/web/assets/AuditPage-BZuVgUf1.js +0 -1
- package/web/assets/CloudAccountPage-B__2SGAw.js +0 -1
- package/web/assets/CloudAccountPage-MSWkg9Ke.js +0 -1
- package/web/assets/CloudMessagingPage-C5pD6Qsd.js +0 -2
- package/web/assets/DashboardPage-66q5K841.js +0 -1
- package/web/assets/DirectoryPickerDialog-wZYtGEZ9.js +0 -1
- package/web/assets/EnvironmentForm-C0Q1pRdW.js +0 -108
- package/web/assets/EnvironmentFormPage-LO-mwupn.js +0 -1
- package/web/assets/EnvironmentListPage-CvknyN3O.js +0 -1
- package/web/assets/KanbanBoardPage-DUsAyowy.js +0 -4
- package/web/assets/KanbanListPage-9RBCauSd.js +0 -1
- package/web/assets/LaunchProjectPage--S6EXtGb.css +0 -1
- package/web/assets/LaunchProjectPage-obaNCuEY.js +0 -1
- package/web/assets/LaunchServicesPage-CiWzQIyC.js +0 -1
- package/web/assets/LaunchServicesPage-pWREsZTD.css +0 -1
- package/web/assets/LogViewer-BiSD_TNt.js +0 -3
- package/web/assets/OrgKeyPrompt-zhMl_nTd.js +0 -1
- package/web/assets/ProcessDetailPage-CsCqQh2V.js +0 -1
- package/web/assets/ProjectDetailPage-B0vJySvH.js +0 -1
- package/web/assets/ProjectListPage-srxBmrbO.js +0 -1
- package/web/assets/RandomJobTestPage-jGfX-6W9.js +0 -2
- package/web/assets/ScenarioEditorPage-CxLy6gs7.js +0 -14
- package/web/assets/SendToChatDialog-AHkuFQjt.js +0 -1
- package/web/assets/ServiceControlsBar-C8P9_qWK.js +0 -1
- package/web/assets/ServiceDetailPage-DTBpQegV.js +0 -2
- package/web/assets/ServiceFormPage-CsPSMWdD.js +0 -1
- package/web/assets/SettingsPage-CmtRn6VJ.js +0 -2063
- package/web/assets/UnlockPage-Bkp_hR-F.js +0 -1
- package/web/assets/UnlockPage-DE_HJy8h.css +0 -1
- package/web/assets/VariablesTable-jo61MhbL.js +0 -1
- package/web/assets/VaultMigrationPage-BGJ2PP-7.css +0 -1
- package/web/assets/VaultMigrationPage-D-Dxg5xH.js +0 -1
- package/web/assets/VersionBadge-CwNZLgqN.js +0 -1
- package/web/assets/WikiPage-DZLKTPi3.js +0 -1
- package/web/assets/WikiView-BpJECJ2Y.js +0 -1
- package/web/assets/add-scalar-classes-CqLAxAGv.js +0 -387
- package/web/assets/auth-errors-BOjTx5eo.js +0 -1
- package/web/assets/autocomplete-CrMQ2sCk.js +0 -308
- package/web/assets/card-CjcU4SfX.js +0 -32
- package/web/assets/client-B9UJRQa-.js +0 -24
- package/web/assets/cloud-chat.store-Dw2lzuBY.js +0 -1
- package/web/assets/cloud-session-DIhbWyP5.js +0 -1
- package/web/assets/column-BGKYk6b6.js +0 -907
- package/web/assets/interface-content-folder.svg-DjEfXjEF.js +0 -1
- package/web/assets/modal-DZYAJM4x.js +0 -5
- package/web/assets/modal-Fe2dzlxp.js +0 -1
- package/web/assets/multiselect-CmjxW2sW.js +0 -251
- package/web/assets/process.store-COWqXNUm.js +0 -1
- package/web/assets/router-BIJ4goD-.js +0 -1
- package/web/assets/settings-scope-DGzA7Be-.js +0 -1
- package/web/assets/settings.store-Dj2nbYYG.js +0 -1
- package/web/assets/src-BTWvqafq.js +0 -1
- package/web/assets/tabpanel-CWwOXePg.js +0 -150
- package/web/assets/trpc-DfyQNjZd.js +0 -1
- package/web/assets/useAiChatDrawer-Cuhlc2BI.js +0 -1
- package/web/assets/useCloudOrg-DYOv1Oak.js +0 -93
- package/web/assets/useCloudOrg-Dc6yRgro.css +0 -1
- /package/{agent-manager-74WZPMVQ.js.map → agent-manager-YDLSYZE3.js.map} +0 -0
- /package/web/assets/{abap-Q7FyqTce.js → abap-BvxTqXT2.js} +0 -0
- /package/web/assets/{apex-DBNDq2a_.js → apex-CIPCCkBr.js} +0 -0
- /package/web/assets/{azcli-BHW8ozYN.js → azcli-Rs0NIwkA.js} +0 -0
- /package/web/assets/{bat-BL-_3Nfo.js → bat-BxAhM6gR.js} +0 -0
- /package/web/assets/{bicep-DR2vgumW.js → bicep-oV_ehPcG.js} +0 -0
- /package/web/assets/{cameligo-BCjoEAZU.js → cameligo-CJLaUyQs.js} +0 -0
- /package/web/assets/{clojure-zw1Irdul.js → clojure-CjvMureh.js} +0 -0
- /package/web/assets/{coffee-BdEjkiiW.js → coffee-motWC5XQ.js} +0 -0
- /package/web/assets/{cpp-DKUlBIAG.js → cpp-DiWIfYNM.js} +0 -0
- /package/web/assets/{csharp-BsNC4zVq.js → csharp-GBlGBeai.js} +0 -0
- /package/web/assets/{csp-X4Chv5_9.js → csp-tSyK5eO1.js} +0 -0
- /package/web/assets/{css-Dh0Dlycs.js → css-BkFK9HG_.js} +0 -0
- /package/web/assets/{cypher-BL_DRjGX.js → cypher-Bcp8PXr2.js} +0 -0
- /package/web/assets/{dart-DaM4j487.js → dart-uz9Rxe0M.js} +0 -0
- /package/web/assets/{dockerfile-Df5WJXAt.js → dockerfile-iJizx3Zp.js} +0 -0
- /package/web/assets/{ecl-BjUo3uTs.js → ecl-BalaS36Z.js} +0 -0
- /package/web/assets/{elixir-DrLHYSxt.js → elixir-D6CLrLGy.js} +0 -0
- /package/web/assets/{flow9-DKiuX7rg.js → flow9-CFt3-vVY.js} +0 -0
- /package/web/assets/{fsharp-CAN78557.js → fsharp-DGa7raxa.js} +0 -0
- /package/web/assets/{go-DGjr9vA5.js → go-wlqInk4z.js} +0 -0
- /package/web/assets/{graphql-CcoU3Cj2.js → graphql-CP1guigM.js} +0 -0
- /package/web/assets/{hcl-udfyCcTm.js → hcl-CK0UkKD0.js} +0 -0
- /package/web/assets/{ini-BVbXatjh.js → ini-Ch56nrUj.js} +0 -0
- /package/web/assets/{java-Drpmh61g.js → java-C9_WIayl.js} +0 -0
- /package/web/assets/{julia-asFGk-ZV.js → julia-Can2_mhR.js} +0 -0
- /package/web/assets/{kotlin-HmkKz1TT.js → kotlin-DUvGf_BX.js} +0 -0
- /package/web/assets/{less-C5i2m2Dn.js → less-DoTbG-rc.js} +0 -0
- /package/web/assets/{lexon-B3Xh2kL6.js → lexon-BFMO2_kL.js} +0 -0
- /package/web/assets/{lua-DnOtgOOu.js → lua-CC-QtBo7.js} +0 -0
- /package/web/assets/{m3-Brj4HNKq.js → m3-C51MyH5Q.js} +0 -0
- /package/web/assets/{markdown-C3-4Ntpz.js → markdown-CDwLHhgZ.js} +0 -0
- /package/web/assets/{mips-vFQKPHzn.js → mips-YuxZtPGU.js} +0 -0
- /package/web/assets/{msdax-D5MYLS2R.js → msdax-CJjWhmte.js} +0 -0
- /package/web/assets/{mysql-CRQHhUON.js → mysql-B1riwLaD.js} +0 -0
- /package/web/assets/{objective-c-8cZEp0HR.js → objective-c-drXT-gmc.js} +0 -0
- /package/web/assets/{pascal-BPn_2jro.js → pascal-KUYgrN-Z.js} +0 -0
- /package/web/assets/{pascaligo-L7QnU_8B.js → pascaligo-DQmQJP-r.js} +0 -0
- /package/web/assets/{perl-B9zSPnp3.js → perl-09XLBmCS.js} +0 -0
- /package/web/assets/{pgsql-DiRJukCJ.js → pgsql-BFj9IFFu.js} +0 -0
- /package/web/assets/{php-Dv4g8Lhr.js → php-UnC5BqwY.js} +0 -0
- /package/web/assets/{pla-CKAoz6vp.js → pla-BFuYrPHG.js} +0 -0
- /package/web/assets/{postiats-B_PYgUTS.js → postiats-n4ft3jnO.js} +0 -0
- /package/web/assets/{powerquery-CAagSyo-.js → powerquery-D-s-oFSc.js} +0 -0
- /package/web/assets/{powershell-Cj9BzLhS.js → powershell-CTboTf93.js} +0 -0
- /package/web/assets/{protobuf-DTRY4FFo.js → protobuf-Dt62GuJP.js} +0 -0
- /package/web/assets/{pug-qADGmCS8.js → pug-CEFWkUzw.js} +0 -0
- /package/web/assets/{qsharp-xkZT0ZOm.js → qsharp-B0DUmgPZ.js} +0 -0
- /package/web/assets/{r-C7wfNC2Z.js → r-BVnF0c4T.js} +0 -0
- /package/web/assets/{redis-BoccK80D.js → redis-DLl3KQXi.js} +0 -0
- /package/web/assets/{redshift-EL8PjTts.js → redshift-cif1I7h1.js} +0 -0
- /package/web/assets/{restructuredtext-CA6rgR7C.js → restructuredtext-PNfql36m.js} +0 -0
- /package/web/assets/{ruby-BymrInur.js → ruby-j3jxDjUN.js} +0 -0
- /package/web/assets/{rust-BTbPL-fg.js → rust-BaIO-mAt.js} +0 -0
- /package/web/assets/{sb-BTkOICcb.js → sb-D8XNVNUQ.js} +0 -0
- /package/web/assets/{scala-CzaUHeQF.js → scala-DiK9Ps90.js} +0 -0
- /package/web/assets/{scheme-DZe2DRuY.js → scheme-DPKqXHmF.js} +0 -0
- /package/web/assets/{scss-D5oFt9cg.js → scss-DpMwfP2H.js} +0 -0
- /package/web/assets/{shell-DCkIF5jZ.js → shell-Dw9mKVg2.js} +0 -0
- /package/web/assets/{solidity-CfOO4gXi.js → solidity-DTxo-7fe.js} +0 -0
- /package/web/assets/{sophia-0-sROOHR.js → sophia-BjA3Q87y.js} +0 -0
- /package/web/assets/{sparql-Dzzr9hol.js → sparql-q1EpMUqb.js} +0 -0
- /package/web/assets/{sql-DbXHiHh_.js → sql-CjcQ4wIr.js} +0 -0
- /package/web/assets/{st-DEaYV8xH.js → st-AuOpxVl7.js} +0 -0
- /package/web/assets/{swift-BQItveav.js → swift-BUWnv6f7.js} +0 -0
- /package/web/assets/{systemverilog-nE6YfGlx.js → systemverilog-FhXn-3OZ.js} +0 -0
- /package/web/assets/{tcl-Do7Q0SM0.js → tcl-B0lqcTtS.js} +0 -0
- /package/web/assets/{twig-B2CLZN2j.js → twig-B0OeGPVa.js} +0 -0
- /package/web/assets/{typespec-r9R1AgVi.js → typespec-Bmh6VX11.js} +0 -0
- /package/web/assets/{uuid-CXjA27vZ.js → uuid-FpfcaBnR.js} +0 -0
- /package/web/assets/{vb-DGnD02qr.js → vb-bmgX6veu.js} +0 -0
- /package/web/assets/{wgsl-C2fD4koY.js → wgsl-FflLnFqI.js} +0 -0
|
@@ -60,9 +60,11 @@ import {
|
|
|
60
60
|
isVaultLocked,
|
|
61
61
|
keyRoot,
|
|
62
62
|
keyedFilePath,
|
|
63
|
+
killInstance,
|
|
63
64
|
legacyMachineFilePath,
|
|
64
65
|
legacyVaultRoot,
|
|
65
66
|
listCloudVaults,
|
|
67
|
+
listInstances,
|
|
66
68
|
listOrgVaults,
|
|
67
69
|
loadFromEnv,
|
|
68
70
|
localVaultRoot,
|
|
@@ -79,11 +81,14 @@ import {
|
|
|
79
81
|
readOrgNames,
|
|
80
82
|
refOfProjectAmong,
|
|
81
83
|
refsOfProjectId,
|
|
84
|
+
registerInstance,
|
|
82
85
|
registerProjectLoader,
|
|
83
86
|
rememberFile,
|
|
84
87
|
rememberOrgName,
|
|
88
|
+
restartInstance,
|
|
85
89
|
rootOfProjectAmong,
|
|
86
90
|
rootOfProjectRef,
|
|
91
|
+
scheduleSelfRestart,
|
|
87
92
|
serviceStore,
|
|
88
93
|
setEncryptionKey,
|
|
89
94
|
setEncryptionKeyInMemory,
|
|
@@ -93,11 +98,12 @@ import {
|
|
|
93
98
|
stableEncryptValue,
|
|
94
99
|
stampOrgCloud,
|
|
95
100
|
traefikManager,
|
|
101
|
+
unregisterInstance,
|
|
96
102
|
vaultFor,
|
|
97
103
|
vaultIdOfRoot,
|
|
98
104
|
wasRead,
|
|
99
105
|
writeEntity
|
|
100
|
-
} from "./chunk-
|
|
106
|
+
} from "./chunk-HPYBAUAH.js";
|
|
101
107
|
|
|
102
108
|
// ../server/src/create-server.ts
|
|
103
109
|
import express from "express";
|
|
@@ -4372,7 +4378,7 @@ var environmentRouter = router({
|
|
|
4372
4378
|
|
|
4373
4379
|
// ../server/src/trpc/routers/settings.ts
|
|
4374
4380
|
import { promises as dns } from "dns";
|
|
4375
|
-
import { z as
|
|
4381
|
+
import { z as z11 } from "zod";
|
|
4376
4382
|
import { TRPCError as TRPCError8 } from "@trpc/server";
|
|
4377
4383
|
|
|
4378
4384
|
// ../server/src/services/settings-scope.ts
|
|
@@ -4384,6 +4390,122 @@ async function vaultOfProject(projectId) {
|
|
|
4384
4390
|
return refs[0]?.orgId ?? void 0;
|
|
4385
4391
|
}
|
|
4386
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
|
+
|
|
4387
4509
|
// ../server/src/trpc/routers/settings.ts
|
|
4388
4510
|
var NotificationPreferencesPatchSchema = NotificationPreferencesSchema.partial().strict();
|
|
4389
4511
|
function maskApiKey2(plaintext) {
|
|
@@ -4391,8 +4513,8 @@ function maskApiKey2(plaintext) {
|
|
|
4391
4513
|
return plaintext.slice(0, 4) + "****" + plaintext.slice(-4);
|
|
4392
4514
|
}
|
|
4393
4515
|
var ScopeShape = {
|
|
4394
|
-
orgId:
|
|
4395
|
-
projectId:
|
|
4516
|
+
orgId: z11.string().max(128).nullable().optional(),
|
|
4517
|
+
projectId: z11.string().max(128).optional()
|
|
4396
4518
|
};
|
|
4397
4519
|
async function scopeOf(input) {
|
|
4398
4520
|
return input?.orgId ?? await vaultOfProject(input?.projectId);
|
|
@@ -4419,6 +4541,27 @@ var settingsRouter = router({
|
|
|
4419
4541
|
// whichever directory the server happened to be started in.
|
|
4420
4542
|
machineDir: machineRoot()
|
|
4421
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
|
+
}),
|
|
4422
4565
|
/**
|
|
4423
4566
|
* Update settings (mode, cloudUrl)
|
|
4424
4567
|
*/
|
|
@@ -4434,7 +4577,7 @@ var settingsRouter = router({
|
|
|
4434
4577
|
/**
|
|
4435
4578
|
* Get notification preferences
|
|
4436
4579
|
*/
|
|
4437
|
-
getNotificationPreferences: protectedProcedure.input(
|
|
4580
|
+
getNotificationPreferences: protectedProcedure.input(z11.object(ScopeShape).optional()).query(async ({ input }) => {
|
|
4438
4581
|
const priv = await settingsManager.getPrivateSettings(await scopeOf(input));
|
|
4439
4582
|
return NotificationPreferencesSchema.parse(priv.notifications ?? {});
|
|
4440
4583
|
}),
|
|
@@ -4465,7 +4608,7 @@ var settingsRouter = router({
|
|
|
4465
4608
|
/**
|
|
4466
4609
|
* Get single parser by ID
|
|
4467
4610
|
*/
|
|
4468
|
-
getParser: protectedProcedure.input(
|
|
4611
|
+
getParser: protectedProcedure.input(z11.object({ id: z11.string().max(128) })).query(async ({ input }) => {
|
|
4469
4612
|
const settings = await settingsManager.getSettings();
|
|
4470
4613
|
const parser = (settings.logParsers || []).find((p) => p.id === input.id);
|
|
4471
4614
|
if (!parser) {
|
|
@@ -4540,7 +4683,7 @@ var settingsRouter = router({
|
|
|
4540
4683
|
/**
|
|
4541
4684
|
* Delete parser by ID
|
|
4542
4685
|
*/
|
|
4543
|
-
deleteParser: protectedProcedure.input(
|
|
4686
|
+
deleteParser: protectedProcedure.input(z11.object({ id: z11.string().max(128) })).mutation(async ({ input }) => {
|
|
4544
4687
|
const settings = await settingsManager.getSettings();
|
|
4545
4688
|
const newParsers = (settings.logParsers || []).filter(
|
|
4546
4689
|
(p) => p.id !== input.id
|
|
@@ -4563,7 +4706,7 @@ var settingsRouter = router({
|
|
|
4563
4706
|
/**
|
|
4564
4707
|
* List AI providers (API keys are masked)
|
|
4565
4708
|
*/
|
|
4566
|
-
listAIProviders: protectedProcedure.input(
|
|
4709
|
+
listAIProviders: protectedProcedure.input(z11.object(ScopeShape).optional()).query(async ({ input }) => {
|
|
4567
4710
|
const vault = await scopeOf(input);
|
|
4568
4711
|
const priv = await settingsManager.getPrivateSettings(vault);
|
|
4569
4712
|
return (priv.aiProviders ?? []).map((p) => {
|
|
@@ -4581,12 +4724,12 @@ var settingsRouter = router({
|
|
|
4581
4724
|
/**
|
|
4582
4725
|
* Create AI provider
|
|
4583
4726
|
*/
|
|
4584
|
-
createAIProvider: protectedProcedure.input(
|
|
4585
|
-
name:
|
|
4727
|
+
createAIProvider: protectedProcedure.input(z11.object({
|
|
4728
|
+
name: z11.string().min(1).max(200),
|
|
4586
4729
|
provider: AIProviderSchema.shape.provider,
|
|
4587
|
-
apiKey:
|
|
4730
|
+
apiKey: z11.string().max(500).optional(),
|
|
4588
4731
|
// optional for providers like Ollama
|
|
4589
|
-
model:
|
|
4732
|
+
model: z11.string().max(200).optional(),
|
|
4590
4733
|
...ScopeShape
|
|
4591
4734
|
})).mutation(async ({ input }) => {
|
|
4592
4735
|
if (input.provider !== "ollama" && !input.apiKey?.trim()) {
|
|
@@ -4619,12 +4762,12 @@ var settingsRouter = router({
|
|
|
4619
4762
|
/**
|
|
4620
4763
|
* Update AI provider (apiKey optional — omit to keep existing)
|
|
4621
4764
|
*/
|
|
4622
|
-
updateAIProvider: protectedProcedure.input(
|
|
4623
|
-
id:
|
|
4624
|
-
name:
|
|
4765
|
+
updateAIProvider: protectedProcedure.input(z11.object({
|
|
4766
|
+
id: z11.string().min(1).max(128),
|
|
4767
|
+
name: z11.string().min(1).max(200).optional(),
|
|
4625
4768
|
provider: AIProviderSchema.shape.provider.optional(),
|
|
4626
|
-
apiKey:
|
|
4627
|
-
model:
|
|
4769
|
+
apiKey: z11.string().min(1).max(500).optional(),
|
|
4770
|
+
model: z11.string().max(200).optional(),
|
|
4628
4771
|
...ScopeShape
|
|
4629
4772
|
})).mutation(async ({ input }) => {
|
|
4630
4773
|
const vault = await scopeOf(input);
|
|
@@ -4657,7 +4800,7 @@ var settingsRouter = router({
|
|
|
4657
4800
|
/**
|
|
4658
4801
|
* Delete AI provider
|
|
4659
4802
|
*/
|
|
4660
|
-
deleteAIProvider: protectedProcedure.input(
|
|
4803
|
+
deleteAIProvider: protectedProcedure.input(z11.object({ id: z11.string().min(1).max(128), ...ScopeShape })).mutation(async ({ input }) => {
|
|
4661
4804
|
const vault = await scopeOf(input);
|
|
4662
4805
|
const priv = await settingsManager.getPrivateSettings(vault);
|
|
4663
4806
|
const providers = priv.aiProviders ?? [];
|
|
@@ -4671,7 +4814,7 @@ var settingsRouter = router({
|
|
|
4671
4814
|
/**
|
|
4672
4815
|
* Set one provider as active (clears active flag on all others)
|
|
4673
4816
|
*/
|
|
4674
|
-
setActiveAIProvider: protectedProcedure.input(
|
|
4817
|
+
setActiveAIProvider: protectedProcedure.input(z11.object({ id: z11.string().min(1).max(128), ...ScopeShape })).mutation(async ({ input }) => {
|
|
4675
4818
|
const vault = await scopeOf(input);
|
|
4676
4819
|
const priv = await settingsManager.getPrivateSettings(vault);
|
|
4677
4820
|
const providers = priv.aiProviders ?? [];
|
|
@@ -4687,7 +4830,7 @@ var settingsRouter = router({
|
|
|
4687
4830
|
/**
|
|
4688
4831
|
* Get Traefik config for a specific agent (never returns credentials or cert key in plain text)
|
|
4689
4832
|
*/
|
|
4690
|
-
getAgentTraefikConfig: protectedProcedure.input(
|
|
4833
|
+
getAgentTraefikConfig: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).query(async ({ input }) => {
|
|
4691
4834
|
const raw = agentStore.getTraefikConfig(input.agentId);
|
|
4692
4835
|
const parsed = raw ? TraefikConfigSchema.safeParse(raw) : null;
|
|
4693
4836
|
const config = parsed?.success ? parsed.data : null;
|
|
@@ -4707,16 +4850,16 @@ var settingsRouter = router({
|
|
|
4707
4850
|
/**
|
|
4708
4851
|
* Update Traefik config for a specific agent (credentials are encrypted before saving)
|
|
4709
4852
|
*/
|
|
4710
|
-
updateAgentTraefikConfig: protectedProcedure.input(
|
|
4711
|
-
agentId:
|
|
4712
|
-
enabled:
|
|
4713
|
-
acmeEmail:
|
|
4714
|
-
wildcardDomain:
|
|
4715
|
-
httpPort:
|
|
4716
|
-
httpsPort:
|
|
4717
|
-
dnsProvider:
|
|
4718
|
-
dnsCredentials:
|
|
4719
|
-
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()
|
|
4720
4863
|
})).mutation(async ({ input }) => {
|
|
4721
4864
|
const { agentId, ...fields } = input;
|
|
4722
4865
|
const raw = agentStore.getTraefikConfig(agentId);
|
|
@@ -4745,13 +4888,13 @@ var settingsRouter = router({
|
|
|
4745
4888
|
/**
|
|
4746
4889
|
* Get Traefik config files content for a specific agent
|
|
4747
4890
|
*/
|
|
4748
|
-
getAgentTraefikConfigFiles: protectedProcedure.input(
|
|
4891
|
+
getAgentTraefikConfigFiles: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).query(async ({ input }) => {
|
|
4749
4892
|
return agentManager.agentQuery(
|
|
4750
4893
|
input.agentId,
|
|
4751
4894
|
"config.getTraefikConfigFiles"
|
|
4752
4895
|
);
|
|
4753
4896
|
}),
|
|
4754
|
-
getAgentTraefikFileTree: protectedProcedure.input(
|
|
4897
|
+
getAgentTraefikFileTree: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).query(async ({ input }) => {
|
|
4755
4898
|
return agentManager.agentQuery(
|
|
4756
4899
|
input.agentId,
|
|
4757
4900
|
"config.getTraefikFileTree"
|
|
@@ -4760,7 +4903,7 @@ var settingsRouter = router({
|
|
|
4760
4903
|
/**
|
|
4761
4904
|
* Get Traefik container logs for a specific agent (snapshot)
|
|
4762
4905
|
*/
|
|
4763
|
-
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 }) => {
|
|
4764
4907
|
const result = await agentManager.agentQuery(
|
|
4765
4908
|
input.agentId,
|
|
4766
4909
|
"config.getTraefikLogs",
|
|
@@ -4771,7 +4914,7 @@ var settingsRouter = router({
|
|
|
4771
4914
|
/**
|
|
4772
4915
|
* Stream Traefik logs in real-time (subscription, yields new lines every 500ms)
|
|
4773
4916
|
*/
|
|
4774
|
-
streamAgentTraefikLogs: protectedProcedure.input(
|
|
4917
|
+
streamAgentTraefikLogs: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).subscription(async function* ({ input, signal }) {
|
|
4775
4918
|
let seen = 0;
|
|
4776
4919
|
while (!signal?.aborted) {
|
|
4777
4920
|
try {
|
|
@@ -4794,7 +4937,7 @@ var settingsRouter = router({
|
|
|
4794
4937
|
/**
|
|
4795
4938
|
* Restart Traefik container on a specific agent (re-pushes config first to handle agent restarts)
|
|
4796
4939
|
*/
|
|
4797
|
-
restartAgentTraefik: protectedProcedure.input(
|
|
4940
|
+
restartAgentTraefik: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).mutation(async ({ input }) => {
|
|
4798
4941
|
const raw = agentStore.getTraefikConfig(input.agentId);
|
|
4799
4942
|
const parsed = raw ? TraefikConfigSchema.safeParse(raw) : null;
|
|
4800
4943
|
const config = parsed?.success ? parsed.data : null;
|
|
@@ -4807,7 +4950,7 @@ var settingsRouter = router({
|
|
|
4807
4950
|
/**
|
|
4808
4951
|
* Force certificate renewal for a specific agent (wipes acme.json + restarts container)
|
|
4809
4952
|
*/
|
|
4810
|
-
renewAgentTraefikCert: protectedProcedure.input(
|
|
4953
|
+
renewAgentTraefikCert: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).mutation(async ({ input }) => {
|
|
4811
4954
|
const raw = agentStore.getTraefikConfig(input.agentId);
|
|
4812
4955
|
const parsed = raw ? TraefikConfigSchema.safeParse(raw) : null;
|
|
4813
4956
|
const config = parsed?.success ? parsed.data : null;
|
|
@@ -4820,7 +4963,7 @@ var settingsRouter = router({
|
|
|
4820
4963
|
/**
|
|
4821
4964
|
* Validate Traefik configuration for a specific agent
|
|
4822
4965
|
*/
|
|
4823
|
-
validateAgentTraefikConfig: protectedProcedure.input(
|
|
4966
|
+
validateAgentTraefikConfig: protectedProcedure.input(z11.object({ agentId: z11.string().max(128) })).query(async ({ input }) => {
|
|
4824
4967
|
const raw = agentStore.getTraefikConfig(input.agentId);
|
|
4825
4968
|
const parsed = raw ? TraefikConfigSchema.safeParse(raw) : null;
|
|
4826
4969
|
const config = parsed?.success ? parsed.data : null;
|
|
@@ -4852,20 +4995,20 @@ var settingsRouter = router({
|
|
|
4852
4995
|
});
|
|
4853
4996
|
if (config?.wildcardDomain?.trim()) {
|
|
4854
4997
|
const sanitisedDomain = config.wildcardDomain.replace(/^\*\./, "").replace(/[^a-z0-9.-]/gi, "");
|
|
4855
|
-
const
|
|
4998
|
+
const probe = `probe.${sanitisedDomain}`;
|
|
4856
4999
|
try {
|
|
4857
|
-
const addresses = await dns.resolve4(
|
|
5000
|
+
const addresses = await dns.resolve4(probe);
|
|
4858
5001
|
const pointsToLocalhost = addresses.some((a) => a === "127.0.0.1");
|
|
4859
5002
|
checks.push({
|
|
4860
5003
|
id: "dns_resolution",
|
|
4861
5004
|
ok: pointsToLocalhost,
|
|
4862
|
-
message: pointsToLocalhost ? `${
|
|
5005
|
+
message: pointsToLocalhost ? `${probe} \u2192 127.0.0.1 \u2713` : `${probe} r\xE9sout vers ${addresses.join(", ")} (attendu : 127.0.0.1)`
|
|
4863
5006
|
});
|
|
4864
5007
|
} catch {
|
|
4865
5008
|
checks.push({
|
|
4866
5009
|
id: "dns_resolution",
|
|
4867
5010
|
ok: false,
|
|
4868
|
-
message: `${
|
|
5011
|
+
message: `${probe} ne r\xE9sout pas \u2014 v\xE9rifiez le DNS wildcard`
|
|
4869
5012
|
});
|
|
4870
5013
|
}
|
|
4871
5014
|
}
|
|
@@ -4922,12 +5065,12 @@ var settingsRouter = router({
|
|
|
4922
5065
|
* Test parser code: compile and run it against sample logs, return per-line results
|
|
4923
5066
|
*/
|
|
4924
5067
|
testParser: protectedProcedure.input(
|
|
4925
|
-
|
|
4926
|
-
code:
|
|
4927
|
-
sampleLogs:
|
|
4928
|
-
|
|
4929
|
-
raw:
|
|
4930
|
-
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"])
|
|
4931
5074
|
})
|
|
4932
5075
|
).max(100).default([])
|
|
4933
5076
|
})
|
|
@@ -4971,30 +5114,30 @@ var settingsRouter = router({
|
|
|
4971
5114
|
});
|
|
4972
5115
|
|
|
4973
5116
|
// ../server/src/trpc/routers/editor.ts
|
|
4974
|
-
import { z as
|
|
5117
|
+
import { z as z13 } from "zod";
|
|
4975
5118
|
import { TRPCError as TRPCError9 } from "@trpc/server";
|
|
4976
5119
|
import { execFile as execFile3, spawn as spawn2 } from "child_process";
|
|
4977
5120
|
import { stat as stat4 } from "fs/promises";
|
|
4978
|
-
import { resolve as resolve2, join as
|
|
5121
|
+
import { resolve as resolve2, join as join13 } from "path";
|
|
4979
5122
|
import { homedir as homedir2 } from "os";
|
|
4980
5123
|
|
|
4981
5124
|
// ../server/src/services/user-config-manager.ts
|
|
4982
|
-
import { readFile as
|
|
4983
|
-
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";
|
|
4984
5127
|
import { homedir } from "os";
|
|
4985
|
-
import { z as
|
|
4986
|
-
var CONFIG_DIR =
|
|
5128
|
+
import { z as z12 } from "zod";
|
|
5129
|
+
var CONFIG_DIR = join12(homedir(), ".runeya");
|
|
4987
5130
|
var CONFIG_FILE = "runeya.conf";
|
|
4988
|
-
var EditorPreferencesSchema =
|
|
4989
|
-
default:
|
|
4990
|
-
}).catchall(
|
|
4991
|
-
var ProjectSettingsSchema =
|
|
4992
|
-
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({
|
|
4993
5136
|
editors: EditorPreferencesSchema.optional()
|
|
4994
5137
|
}).optional()
|
|
4995
5138
|
});
|
|
4996
|
-
var UserConfigSchema =
|
|
4997
|
-
|
|
5139
|
+
var UserConfigSchema = z12.record(
|
|
5140
|
+
z12.string().max(128),
|
|
4998
5141
|
ProjectSettingsSchema
|
|
4999
5142
|
).refine((obj) => Object.keys(obj).length <= 100, "Too many projects in config");
|
|
5000
5143
|
function configKey(ref) {
|
|
@@ -5003,20 +5146,20 @@ function configKey(ref) {
|
|
|
5003
5146
|
var UserConfigManager = class {
|
|
5004
5147
|
config = null;
|
|
5005
5148
|
async ensureDir() {
|
|
5006
|
-
await
|
|
5149
|
+
await mkdir11(CONFIG_DIR, { recursive: true });
|
|
5007
5150
|
}
|
|
5008
5151
|
async atomicWrite(data) {
|
|
5009
5152
|
await this.ensureDir();
|
|
5010
|
-
const filePath =
|
|
5153
|
+
const filePath = join12(CONFIG_DIR, CONFIG_FILE);
|
|
5011
5154
|
const tmpPath = filePath + ".tmp";
|
|
5012
|
-
await
|
|
5013
|
-
await
|
|
5155
|
+
await writeFile11(tmpPath, JSON.stringify(data, null, 2), "utf-8");
|
|
5156
|
+
await rename11(tmpPath, filePath);
|
|
5014
5157
|
await chmod9(filePath, 384);
|
|
5015
5158
|
}
|
|
5016
5159
|
async getConfig() {
|
|
5017
5160
|
if (!this.config) {
|
|
5018
5161
|
try {
|
|
5019
|
-
const raw = await
|
|
5162
|
+
const raw = await readFile11(join12(CONFIG_DIR, CONFIG_FILE), "utf-8");
|
|
5020
5163
|
const parsed = UserConfigSchema.safeParse(JSON.parse(raw));
|
|
5021
5164
|
this.config = parsed.success ? parsed.data : {};
|
|
5022
5165
|
} catch {
|
|
@@ -5086,16 +5229,16 @@ var editorRouter = router({
|
|
|
5086
5229
|
);
|
|
5087
5230
|
return results;
|
|
5088
5231
|
}),
|
|
5089
|
-
getPreferences: protectedProcedure.input(
|
|
5090
|
-
projectId:
|
|
5091
|
-
orgId:
|
|
5232
|
+
getPreferences: protectedProcedure.input(z13.object({
|
|
5233
|
+
projectId: z13.string().max(128),
|
|
5234
|
+
orgId: z13.string().max(128).nullable().optional()
|
|
5092
5235
|
})).query(async ({ input }) => {
|
|
5093
5236
|
return userConfigManager.getEditorPreferences({ id: input.projectId, orgId: input.orgId });
|
|
5094
5237
|
}),
|
|
5095
|
-
setDefault: protectedProcedure.input(
|
|
5096
|
-
projectId:
|
|
5097
|
-
orgId:
|
|
5098
|
-
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)
|
|
5099
5242
|
})).mutation(async ({ input }) => {
|
|
5100
5243
|
if (!EDITOR_BY_KEY.has(input.editorKey)) {
|
|
5101
5244
|
throw new TRPCError9({ code: "BAD_REQUEST", message: `Unknown editor: ${input.editorKey}` });
|
|
@@ -5107,11 +5250,11 @@ var editorRouter = router({
|
|
|
5107
5250
|
);
|
|
5108
5251
|
return { success: true };
|
|
5109
5252
|
}),
|
|
5110
|
-
setServiceEditor: protectedProcedure.input(
|
|
5111
|
-
projectId:
|
|
5112
|
-
orgId:
|
|
5113
|
-
serviceId:
|
|
5114
|
-
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)
|
|
5115
5258
|
})).mutation(async ({ input }) => {
|
|
5116
5259
|
if (!EDITOR_BY_KEY.has(input.editorKey)) {
|
|
5117
5260
|
throw new TRPCError9({ code: "BAD_REQUEST", message: `Unknown editor: ${input.editorKey}` });
|
|
@@ -5123,10 +5266,10 @@ var editorRouter = router({
|
|
|
5123
5266
|
);
|
|
5124
5267
|
return { success: true };
|
|
5125
5268
|
}),
|
|
5126
|
-
removeServiceEditor: protectedProcedure.input(
|
|
5127
|
-
projectId:
|
|
5128
|
-
orgId:
|
|
5129
|
-
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)
|
|
5130
5273
|
})).mutation(async ({ input }) => {
|
|
5131
5274
|
await userConfigManager.removeEditorPreference(
|
|
5132
5275
|
{ id: input.projectId, orgId: input.orgId },
|
|
@@ -5134,9 +5277,9 @@ var editorRouter = router({
|
|
|
5134
5277
|
);
|
|
5135
5278
|
return { success: true };
|
|
5136
5279
|
}),
|
|
5137
|
-
open: protectedProcedure.input(
|
|
5138
|
-
editorKey:
|
|
5139
|
-
path:
|
|
5280
|
+
open: protectedProcedure.input(z13.object({
|
|
5281
|
+
editorKey: z13.string().max(64),
|
|
5282
|
+
path: z13.string().max(4096)
|
|
5140
5283
|
})).mutation(async ({ input }) => {
|
|
5141
5284
|
const editor = EDITOR_BY_KEY.get(input.editorKey);
|
|
5142
5285
|
if (!editor) {
|
|
@@ -5159,17 +5302,17 @@ var editorRouter = router({
|
|
|
5159
5302
|
child.unref();
|
|
5160
5303
|
return { success: true };
|
|
5161
5304
|
}),
|
|
5162
|
-
openFile: protectedProcedure.input(
|
|
5163
|
-
editorKey:
|
|
5164
|
-
serviceId:
|
|
5165
|
-
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)
|
|
5166
5309
|
})).mutation(async ({ input }) => {
|
|
5167
5310
|
const editor = EDITOR_BY_KEY.get(input.editorKey);
|
|
5168
5311
|
if (!editor) {
|
|
5169
5312
|
throw new TRPCError9({ code: "BAD_REQUEST", message: `Unknown editor: ${input.editorKey}` });
|
|
5170
5313
|
}
|
|
5171
5314
|
const cwd = await getServiceCwd(input.serviceId);
|
|
5172
|
-
const filePath =
|
|
5315
|
+
const filePath = join13(cwd, input.relativePath);
|
|
5173
5316
|
if (!filePath.startsWith(cwd)) {
|
|
5174
5317
|
throw new TRPCError9({ code: "BAD_REQUEST", message: "Path traversal not allowed" });
|
|
5175
5318
|
}
|
|
@@ -5190,65 +5333,65 @@ var editorRouter = router({
|
|
|
5190
5333
|
});
|
|
5191
5334
|
|
|
5192
5335
|
// ../server/src/trpc/routers/api-keys.ts
|
|
5193
|
-
import { z as
|
|
5336
|
+
import { z as z14 } from "zod";
|
|
5194
5337
|
import { TRPCError as TRPCError10 } from "@trpc/server";
|
|
5195
|
-
import { mkdir as
|
|
5196
|
-
import { join as
|
|
5338
|
+
import { mkdir as mkdir12, writeFile as writeFile12 } from "fs/promises";
|
|
5339
|
+
import { join as join14, dirname as dirname7 } from "path";
|
|
5197
5340
|
var ALLOWED_SKILL_PATHS = /* @__PURE__ */ new Set([
|
|
5198
5341
|
".claude/skills/runeya/SKILL.md",
|
|
5199
5342
|
".cursor/rules/runeya.mdc",
|
|
5200
5343
|
".windsurf/rules/runeya.md"
|
|
5201
5344
|
]);
|
|
5202
|
-
var KeyInputSchema =
|
|
5203
|
-
name:
|
|
5345
|
+
var KeyInputSchema = z14.object({
|
|
5346
|
+
name: z14.string().min(1).max(200),
|
|
5204
5347
|
scopes: ApiKeyScopeSchema,
|
|
5205
|
-
isPublic:
|
|
5348
|
+
isPublic: z14.boolean().default(false)
|
|
5206
5349
|
});
|
|
5207
5350
|
var apiKeysRouter = router({
|
|
5208
5351
|
list: protectedProcedure.query(() => apiKeyStore.list()),
|
|
5209
|
-
create: protectedProcedure.input(KeyInputSchema.extend({ orgId:
|
|
5352
|
+
create: protectedProcedure.input(KeyInputSchema.extend({ orgId: z14.string().min(1).max(128).nullable().optional() })).mutation(
|
|
5210
5353
|
({ input }) => apiKeyStore.create(input.name, input.scopes, input.isPublic, input.orgId ?? null)
|
|
5211
5354
|
),
|
|
5212
5355
|
/**
|
|
5213
5356
|
* Renvoie le secret d'une seule clé, sur demande explicite. `list` ne le
|
|
5214
5357
|
* contient pas : une clé ne doit jamais être re-servie en masse.
|
|
5215
5358
|
*/
|
|
5216
|
-
reveal: protectedProcedure.input(
|
|
5359
|
+
reveal: protectedProcedure.input(z14.object({ id: z14.string().max(128) })).query(async ({ input }) => {
|
|
5217
5360
|
const key = await apiKeyStore.reveal(input.id);
|
|
5218
5361
|
if (!key) throw new TRPCError10({ code: "NOT_FOUND", message: "API key not found" });
|
|
5219
5362
|
return { key };
|
|
5220
5363
|
}),
|
|
5221
|
-
update: protectedProcedure.input(KeyInputSchema.extend({ id:
|
|
5364
|
+
update: protectedProcedure.input(KeyInputSchema.extend({ id: z14.string().max(128) })).mutation(async ({ input }) => {
|
|
5222
5365
|
const updated = await apiKeyStore.update(input.id, input.name, input.scopes, input.isPublic);
|
|
5223
5366
|
if (!updated) throw new TRPCError10({ code: "NOT_FOUND", message: "API key not found" });
|
|
5224
5367
|
return maskApiKey(updated);
|
|
5225
5368
|
}),
|
|
5226
|
-
remove: protectedProcedure.input(
|
|
5369
|
+
remove: protectedProcedure.input(z14.object({ id: z14.string().max(128) })).mutation(async ({ input }) => {
|
|
5227
5370
|
const removed = await apiKeyStore.remove(input.id);
|
|
5228
5371
|
if (!removed) throw new TRPCError10({ code: "NOT_FOUND", message: "API key not found" });
|
|
5229
5372
|
return { success: true };
|
|
5230
5373
|
}),
|
|
5231
|
-
renewKey: protectedProcedure.input(
|
|
5374
|
+
renewKey: protectedProcedure.input(z14.object({ id: z14.string().max(128) })).mutation(async ({ input }) => {
|
|
5232
5375
|
const renewed = await apiKeyStore.renewKey(input.id);
|
|
5233
5376
|
if (!renewed) throw new TRPCError10({ code: "NOT_FOUND", message: "API key not found" });
|
|
5234
5377
|
return renewed;
|
|
5235
5378
|
}),
|
|
5236
|
-
writeSkillFile: protectedProcedure.input(
|
|
5237
|
-
relativePath:
|
|
5238
|
-
content:
|
|
5379
|
+
writeSkillFile: protectedProcedure.input(z14.object({
|
|
5380
|
+
relativePath: z14.string().max(256),
|
|
5381
|
+
content: z14.string().max(32768)
|
|
5239
5382
|
})).mutation(async ({ input }) => {
|
|
5240
5383
|
if (!ALLOWED_SKILL_PATHS.has(input.relativePath)) {
|
|
5241
5384
|
throw new TRPCError10({ code: "BAD_REQUEST", message: "Chemin non autoris\xE9" });
|
|
5242
5385
|
}
|
|
5243
|
-
const abs =
|
|
5244
|
-
await
|
|
5245
|
-
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 });
|
|
5246
5389
|
return { path: input.relativePath };
|
|
5247
5390
|
})
|
|
5248
5391
|
});
|
|
5249
5392
|
|
|
5250
5393
|
// ../server/src/trpc/routers/chat.ts
|
|
5251
|
-
import { z as
|
|
5394
|
+
import { z as z17 } from "zod";
|
|
5252
5395
|
import Anthropic2 from "@anthropic-ai/sdk";
|
|
5253
5396
|
import OpenAI2 from "openai";
|
|
5254
5397
|
import { execFile as execFile4 } from "child_process";
|
|
@@ -5602,11 +5745,11 @@ function buildApiDocs(apiBaseUrl, apiToken) {
|
|
|
5602
5745
|
}
|
|
5603
5746
|
|
|
5604
5747
|
// ../server/src/services/claude-transcript-sync.ts
|
|
5605
|
-
import { readdir as readdir2, access, readFile as
|
|
5748
|
+
import { readdir as readdir2, access, readFile as readFile12 } from "fs/promises";
|
|
5606
5749
|
import { watch } from "fs";
|
|
5607
5750
|
import { homedir as homedir3 } from "os";
|
|
5608
|
-
import { join as
|
|
5609
|
-
var PROJECTS_DIR =
|
|
5751
|
+
import { join as join15 } from "path";
|
|
5752
|
+
var PROJECTS_DIR = join15(homedir3(), ".claude", "projects");
|
|
5610
5753
|
var DEFAULT_TITLES = /* @__PURE__ */ new Set(["", "New conversation", "Nouvelle conversation"]);
|
|
5611
5754
|
async function findClaudeSessionFile(sessionId) {
|
|
5612
5755
|
let entries2;
|
|
@@ -5617,7 +5760,7 @@ async function findClaudeSessionFile(sessionId) {
|
|
|
5617
5760
|
}
|
|
5618
5761
|
const filename = `${sessionId}.jsonl`;
|
|
5619
5762
|
for (const dir of entries2) {
|
|
5620
|
-
const candidate =
|
|
5763
|
+
const candidate = join15(PROJECTS_DIR, dir, filename);
|
|
5621
5764
|
try {
|
|
5622
5765
|
await access(candidate);
|
|
5623
5766
|
return candidate;
|
|
@@ -5632,7 +5775,7 @@ async function claudeSessionExists(sessionId) {
|
|
|
5632
5775
|
async function readClaudeTranscript(sessionId) {
|
|
5633
5776
|
const path = await findClaudeSessionFile(sessionId);
|
|
5634
5777
|
if (!path) return { found: false, path: null, entries: [] };
|
|
5635
|
-
const raw = await
|
|
5778
|
+
const raw = await readFile12(path, "utf-8");
|
|
5636
5779
|
const entries2 = [];
|
|
5637
5780
|
for (const line of raw.split("\n")) {
|
|
5638
5781
|
if (!line.trim()) continue;
|
|
@@ -5780,7 +5923,7 @@ async function startClaudeTranscriptWatcher() {
|
|
|
5780
5923
|
}
|
|
5781
5924
|
for (const dir of topLevel) {
|
|
5782
5925
|
try {
|
|
5783
|
-
const w = watch(
|
|
5926
|
+
const w = watch(join15(PROJECTS_DIR, dir), (_event, filename) => {
|
|
5784
5927
|
handleFsEvent(filename ? filename.toString() : null);
|
|
5785
5928
|
});
|
|
5786
5929
|
w.on("error", () => {
|
|
@@ -5806,8 +5949,8 @@ function stopClaudeTranscriptWatcher() {
|
|
|
5806
5949
|
// ../server/src/services/codex-sessions.ts
|
|
5807
5950
|
import { readdir as readdir3 } from "fs/promises";
|
|
5808
5951
|
import { homedir as homedir4 } from "os";
|
|
5809
|
-
import { join as
|
|
5810
|
-
var SESSIONS_DIR =
|
|
5952
|
+
import { join as join16 } from "path";
|
|
5953
|
+
var SESSIONS_DIR = join16(homedir4(), ".codex", "sessions");
|
|
5811
5954
|
async function findCodexSessionFile(sessionId) {
|
|
5812
5955
|
const suffix = `-${sessionId}.jsonl`;
|
|
5813
5956
|
async function walk(dir) {
|
|
@@ -5818,7 +5961,7 @@ async function findCodexSessionFile(sessionId) {
|
|
|
5818
5961
|
return null;
|
|
5819
5962
|
}
|
|
5820
5963
|
for (const entry of entries2) {
|
|
5821
|
-
const full =
|
|
5964
|
+
const full = join16(dir, entry.name);
|
|
5822
5965
|
if (entry.isDirectory()) {
|
|
5823
5966
|
const found = await walk(full);
|
|
5824
5967
|
if (found) return found;
|
|
@@ -5838,12 +5981,12 @@ async function codexSessionExists(sessionId) {
|
|
|
5838
5981
|
import { TRPCError as TRPCError12 } from "@trpc/server";
|
|
5839
5982
|
|
|
5840
5983
|
// ../server/src/trpc/shared-schemas.ts
|
|
5841
|
-
import { z as
|
|
5842
|
-
var Id128Schema =
|
|
5843
|
-
var ConversationIdSchema =
|
|
5844
|
-
var NameSchema =
|
|
5845
|
-
var ShortString200Schema =
|
|
5846
|
-
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);
|
|
5847
5990
|
var OptionalProviderIdSchema = Id128Schema.optional();
|
|
5848
5991
|
|
|
5849
5992
|
// ../server/src/services/llms-txt-generator.ts
|
|
@@ -6778,11 +6921,11 @@ var ScenarioStore = class {
|
|
|
6778
6921
|
var scenarioStore = new ScenarioStore();
|
|
6779
6922
|
|
|
6780
6923
|
// ../server/src/services/scenario-run-store.ts
|
|
6781
|
-
import { mkdir as
|
|
6782
|
-
import { join as
|
|
6924
|
+
import { mkdir as mkdir14, rm as rm2, readFile as readFile14 } from "fs/promises";
|
|
6925
|
+
import { join as join17 } from "path";
|
|
6783
6926
|
|
|
6784
6927
|
// ../server/src/services/run-store-utils.ts
|
|
6785
|
-
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";
|
|
6786
6929
|
import { dirname as dirname8, resolve as resolve3, sep } from "path";
|
|
6787
6930
|
var SAFE_PATH_SEGMENT_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/;
|
|
6788
6931
|
function resolveConversationRunDir(rootDirName, conversationId) {
|
|
@@ -6797,10 +6940,10 @@ function resolveConversationRunDir(rootDirName, conversationId) {
|
|
|
6797
6940
|
return dir;
|
|
6798
6941
|
}
|
|
6799
6942
|
async function atomicWriteSecure(filePath, content) {
|
|
6800
|
-
await
|
|
6943
|
+
await mkdir13(dirname8(filePath), { recursive: true });
|
|
6801
6944
|
const tmpPath = `${filePath}.tmp`;
|
|
6802
|
-
await
|
|
6803
|
-
await
|
|
6945
|
+
await writeFile13(tmpPath, content, "utf-8");
|
|
6946
|
+
await rename12(tmpPath, filePath);
|
|
6804
6947
|
await chmod10(filePath, 384);
|
|
6805
6948
|
}
|
|
6806
6949
|
async function atomicWriteJsonSecure(filePath, data, pretty = false) {
|
|
@@ -6808,7 +6951,7 @@ async function atomicWriteJsonSecure(filePath, data, pretty = false) {
|
|
|
6808
6951
|
}
|
|
6809
6952
|
async function readJsonFileSafe(filePath) {
|
|
6810
6953
|
try {
|
|
6811
|
-
const raw = await
|
|
6954
|
+
const raw = await readFile13(filePath, "utf-8");
|
|
6812
6955
|
return JSON.parse(raw);
|
|
6813
6956
|
} catch {
|
|
6814
6957
|
return null;
|
|
@@ -6831,7 +6974,7 @@ var ScenarioRunStore = class _ScenarioRunStore {
|
|
|
6831
6974
|
}
|
|
6832
6975
|
async initializeConversationWorkspace(conversationId, scenario, userInput) {
|
|
6833
6976
|
const dir = this.getRunDir(conversationId);
|
|
6834
|
-
await
|
|
6977
|
+
await mkdir14(dir, { recursive: true });
|
|
6835
6978
|
await this.saveScenarioSnapshot(conversationId, scenario);
|
|
6836
6979
|
const nodesById = new Map(scenario.nodes.map((p) => [p.id, p]));
|
|
6837
6980
|
const teamMap = new Map(scenario.groups.map((t2) => [t2.id, t2.name]));
|
|
@@ -6856,8 +6999,8 @@ var ScenarioRunStore = class _ScenarioRunStore {
|
|
|
6856
6999
|
"- Use read-only references from linked upstream files as context.",
|
|
6857
7000
|
""
|
|
6858
7001
|
].join("\n");
|
|
6859
|
-
await atomicWriteSecure(
|
|
6860
|
-
await atomicWriteSecure(
|
|
7002
|
+
await atomicWriteSecure(join17(dir, "README.md"), overview);
|
|
7003
|
+
await atomicWriteSecure(join17(dir, "USER_REQUEST.md"), `# User request
|
|
6861
7004
|
|
|
6862
7005
|
${userInput.trim() || "(empty)"}
|
|
6863
7006
|
`);
|
|
@@ -6883,7 +7026,7 @@ ${userInput.trim() || "(empty)"}
|
|
|
6883
7026
|
"- Waiting for assignment.",
|
|
6884
7027
|
""
|
|
6885
7028
|
].join("\n");
|
|
6886
|
-
await atomicWriteSecure(
|
|
7029
|
+
await atomicWriteSecure(join17(dir, fileName), content);
|
|
6887
7030
|
}
|
|
6888
7031
|
}
|
|
6889
7032
|
async deleteRunDir(conversationId) {
|
|
@@ -6943,7 +7086,7 @@ ${userInput.trim() || "(empty)"}
|
|
|
6943
7086
|
if (!runState) return;
|
|
6944
7087
|
try {
|
|
6945
7088
|
const dir = this.getRunDir(conversationId);
|
|
6946
|
-
await
|
|
7089
|
+
await mkdir14(dir, { recursive: true });
|
|
6947
7090
|
const data = {
|
|
6948
7091
|
nodeStates: { ...runState.nodeStates },
|
|
6949
7092
|
nodeOutputs: { ...runState.nodeOutputs },
|
|
@@ -6951,18 +7094,18 @@ ${userInput.trim() || "(empty)"}
|
|
|
6951
7094
|
...Object.keys(runState.nodeAgentIds).length > 0 ? { nodeAgentIds: { ...runState.nodeAgentIds } } : {},
|
|
6952
7095
|
...Object.keys(runState.waitingInputs).length > 0 ? { waitingInputs: { ...runState.waitingInputs } } : {}
|
|
6953
7096
|
};
|
|
6954
|
-
await atomicWriteJsonSecure(
|
|
7097
|
+
await atomicWriteJsonSecure(join17(dir, "run-state.json"), data);
|
|
6955
7098
|
} catch {
|
|
6956
7099
|
}
|
|
6957
7100
|
}
|
|
6958
7101
|
async loadPersistedRunState(conversationId) {
|
|
6959
7102
|
const dir = this.getRunDir(conversationId);
|
|
6960
|
-
return readJsonFileSafe(
|
|
7103
|
+
return readJsonFileSafe(join17(dir, "run-state.json"));
|
|
6961
7104
|
}
|
|
6962
7105
|
async readUserRequest(conversationId) {
|
|
6963
7106
|
try {
|
|
6964
7107
|
const dir = this.getRunDir(conversationId);
|
|
6965
|
-
const content = await
|
|
7108
|
+
const content = await readFile14(join17(dir, "USER_REQUEST.md"), "utf-8");
|
|
6966
7109
|
return content.replace(/^#\s*User request\s*\n+/, "").trim() || null;
|
|
6967
7110
|
} catch {
|
|
6968
7111
|
return null;
|
|
@@ -6971,23 +7114,23 @@ ${userInput.trim() || "(empty)"}
|
|
|
6971
7114
|
async readReadme(conversationId) {
|
|
6972
7115
|
try {
|
|
6973
7116
|
const dir = this.getRunDir(conversationId);
|
|
6974
|
-
return await
|
|
7117
|
+
return await readFile14(join17(dir, "README.md"), "utf-8");
|
|
6975
7118
|
} catch {
|
|
6976
7119
|
return null;
|
|
6977
7120
|
}
|
|
6978
7121
|
}
|
|
6979
7122
|
async saveScenarioSnapshot(conversationId, scenario) {
|
|
6980
7123
|
const dir = this.getRunDir(conversationId);
|
|
6981
|
-
await
|
|
7124
|
+
await mkdir14(dir, { recursive: true });
|
|
6982
7125
|
await atomicWriteJsonSecure(
|
|
6983
|
-
|
|
7126
|
+
join17(dir, _ScenarioRunStore.SCENARIO_SNAPSHOT_FILE),
|
|
6984
7127
|
scenario,
|
|
6985
7128
|
true
|
|
6986
7129
|
);
|
|
6987
7130
|
}
|
|
6988
7131
|
async loadScenarioSnapshot(conversationId) {
|
|
6989
7132
|
const dir = this.getRunDir(conversationId);
|
|
6990
|
-
return readJsonFileSafe(
|
|
7133
|
+
return readJsonFileSafe(join17(dir, _ScenarioRunStore.SCENARIO_SNAPSHOT_FILE));
|
|
6991
7134
|
}
|
|
6992
7135
|
};
|
|
6993
7136
|
var scenarioRunStore = new ScenarioRunStore();
|
|
@@ -7033,9 +7176,9 @@ async function fetchProviderModels(provider, plaintextKey) {
|
|
|
7033
7176
|
|
|
7034
7177
|
// ../server/src/services/image-storage.service.ts
|
|
7035
7178
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
7036
|
-
import { mkdir as
|
|
7179
|
+
import { mkdir as mkdir15, writeFile as writeFile14, readFile as readFile15, unlink as unlink3, readdir as readdir4 } from "fs/promises";
|
|
7037
7180
|
import { existsSync as existsSync2 } from "fs";
|
|
7038
|
-
import { join as
|
|
7181
|
+
import { join as join18, extname, resolve as resolve4, sep as sep2 } from "path";
|
|
7039
7182
|
var ALLOWED_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
7040
7183
|
"image/png",
|
|
7041
7184
|
"image/jpeg",
|
|
@@ -7052,7 +7195,7 @@ var ImageStorageService = class {
|
|
|
7052
7195
|
this.dir = dir;
|
|
7053
7196
|
}
|
|
7054
7197
|
async ensureTmpDir() {
|
|
7055
|
-
await
|
|
7198
|
+
await mkdir15(this.dir, { recursive: true, mode: 448 });
|
|
7056
7199
|
}
|
|
7057
7200
|
async saveImage(buffer, originalName, mimeType, contextId) {
|
|
7058
7201
|
if (!ALLOWED_MIME_TYPES.has(mimeType)) {
|
|
@@ -7072,15 +7215,15 @@ var ImageStorageService = class {
|
|
|
7072
7215
|
const imageId = randomUUID4();
|
|
7073
7216
|
const safeExt = ext.replace(/[^a-z.]/g, "");
|
|
7074
7217
|
const fileName = `${imageId}${safeExt}`;
|
|
7075
|
-
const filePath =
|
|
7218
|
+
const filePath = join18(this.dir, fileName);
|
|
7076
7219
|
const resolvedPath = resolve4(filePath);
|
|
7077
7220
|
const resolvedDir = resolve4(this.dir);
|
|
7078
7221
|
if (resolvedPath !== resolvedDir && !resolvedPath.startsWith(resolvedDir + sep2)) {
|
|
7079
7222
|
throw new Error("Invalid file path");
|
|
7080
7223
|
}
|
|
7081
|
-
await
|
|
7224
|
+
await writeFile14(filePath, buffer, { mode: 384 });
|
|
7082
7225
|
const meta = { imageId, filePath, mimeType, originalName, createdAt: Date.now(), contextId };
|
|
7083
|
-
await
|
|
7226
|
+
await writeFile14(`${filePath}.meta.json`, JSON.stringify(meta), { encoding: "utf-8", mode: 384 });
|
|
7084
7227
|
return meta;
|
|
7085
7228
|
}
|
|
7086
7229
|
/**
|
|
@@ -7098,7 +7241,7 @@ var ImageStorageService = class {
|
|
|
7098
7241
|
const files = await readdir4(this.dir);
|
|
7099
7242
|
const metaFile = files.find((f) => f.startsWith(imageId) && f.endsWith(".meta.json"));
|
|
7100
7243
|
if (!metaFile) return null;
|
|
7101
|
-
const raw = JSON.parse(await
|
|
7244
|
+
const raw = JSON.parse(await readFile15(join18(this.dir, metaFile), "utf-8"));
|
|
7102
7245
|
if (expectedContextId !== void 0 && raw.contextId !== expectedContextId) return null;
|
|
7103
7246
|
if (!existsSync2(raw.filePath)) return null;
|
|
7104
7247
|
return { filePath: raw.filePath, mimeType: raw.mimeType, contextId: raw.contextId };
|
|
@@ -7124,7 +7267,7 @@ var ImageStorageService = class {
|
|
|
7124
7267
|
await Promise.all(
|
|
7125
7268
|
files.filter((f) => f.endsWith(".meta.json")).map(async (file) => {
|
|
7126
7269
|
try {
|
|
7127
|
-
const raw = JSON.parse(await
|
|
7270
|
+
const raw = JSON.parse(await readFile15(join18(this.dir, file), "utf-8"));
|
|
7128
7271
|
if (raw.contextId === contextId) {
|
|
7129
7272
|
await unlink3(raw.filePath).catch(() => {
|
|
7130
7273
|
});
|
|
@@ -7139,7 +7282,7 @@ var ImageStorageService = class {
|
|
|
7139
7282
|
async readImageAsBase64(imageId, expectedContextId) {
|
|
7140
7283
|
const result = await this.getImagePath(imageId, expectedContextId);
|
|
7141
7284
|
if (!result) return null;
|
|
7142
|
-
const buffer = await
|
|
7285
|
+
const buffer = await readFile15(result.filePath);
|
|
7143
7286
|
return { base64: buffer.toString("base64"), mimeType: result.mimeType };
|
|
7144
7287
|
}
|
|
7145
7288
|
async listExpiredImages(ttlMs = IMAGE_TTL_MS) {
|
|
@@ -7154,7 +7297,7 @@ var ImageStorageService = class {
|
|
|
7154
7297
|
for (const file of files) {
|
|
7155
7298
|
if (!file.endsWith(".meta.json")) continue;
|
|
7156
7299
|
try {
|
|
7157
|
-
const raw = JSON.parse(await
|
|
7300
|
+
const raw = JSON.parse(await readFile15(join18(this.dir, file), "utf-8"));
|
|
7158
7301
|
if (now - raw.createdAt > ttlMs) expired.push(raw);
|
|
7159
7302
|
} catch {
|
|
7160
7303
|
}
|
|
@@ -7216,11 +7359,8 @@ async function resolveImagesToBase64(images, contextId) {
|
|
|
7216
7359
|
return results.filter((r) => r !== null);
|
|
7217
7360
|
}
|
|
7218
7361
|
|
|
7219
|
-
// ../server/src/services/kanban-commands.ts
|
|
7220
|
-
import { randomUUID as randomUUID5 } from "crypto";
|
|
7221
|
-
|
|
7222
7362
|
// ../server/src/trpc/routers/cloud-auth.ts
|
|
7223
|
-
import { z as
|
|
7363
|
+
import { z as z16 } from "zod";
|
|
7224
7364
|
import { hostname } from "os";
|
|
7225
7365
|
import { basename } from "path";
|
|
7226
7366
|
import { TRPCError as TRPCError11 } from "@trpc/server";
|
|
@@ -7255,7 +7395,7 @@ function isAllowedProxyPath(path) {
|
|
|
7255
7395
|
}
|
|
7256
7396
|
var cloudAuthRouter = router({
|
|
7257
7397
|
/** Build the cloud authorization URL to open in the browser. */
|
|
7258
|
-
startLogin: protectedProcedure.input(
|
|
7398
|
+
startLogin: protectedProcedure.input(z16.object({ returnTo: z16.string().url().max(2048) })).mutation(async ({ input }) => {
|
|
7259
7399
|
if (!isLocalOrigin(input.returnTo)) {
|
|
7260
7400
|
throw new TRPCError11({ code: "BAD_REQUEST", message: "returnTo must be a local origin." });
|
|
7261
7401
|
}
|
|
@@ -7300,7 +7440,7 @@ var cloudAuthRouter = router({
|
|
|
7300
7440
|
* drops the session, and the local token is dropped here too, so nothing is
|
|
7301
7441
|
* left holding a dead credential.
|
|
7302
7442
|
*/
|
|
7303
|
-
revokeDevice: protectedProcedure.input(
|
|
7443
|
+
revokeDevice: protectedProcedure.input(z16.object({ id: z16.string().min(1).max(128) })).mutation(async ({ input }) => {
|
|
7304
7444
|
const res = await cloudFetch2("/api/auth/device/revoke", { method: "POST", body: { id: input.id } });
|
|
7305
7445
|
if (!res.ok) {
|
|
7306
7446
|
if (res.status === 401) await cloudSessionStore.clear();
|
|
@@ -7317,11 +7457,11 @@ var cloudAuthRouter = router({
|
|
|
7317
7457
|
* the cloud: the web UI asks its own server, which holds the credential.
|
|
7318
7458
|
*/
|
|
7319
7459
|
proxy: protectedProcedure.input(
|
|
7320
|
-
|
|
7321
|
-
path:
|
|
7322
|
-
method:
|
|
7323
|
-
query:
|
|
7324
|
-
body:
|
|
7460
|
+
z16.object({
|
|
7461
|
+
path: z16.string().min(1).max(512),
|
|
7462
|
+
method: z16.enum(["GET", "POST"]).default("GET"),
|
|
7463
|
+
query: z16.record(z16.string().max(128), z16.string().max(2048)).optional(),
|
|
7464
|
+
body: z16.unknown().optional()
|
|
7325
7465
|
})
|
|
7326
7466
|
).mutation(async ({ input }) => {
|
|
7327
7467
|
if (!isAllowedProxyPath(input.path)) {
|
|
@@ -7466,6 +7606,20 @@ var KanbanStore = class {
|
|
|
7466
7606
|
});
|
|
7467
7607
|
return res.ok;
|
|
7468
7608
|
}
|
|
7609
|
+
/**
|
|
7610
|
+
* Ajouter une carte, sans réécrire le tableau.
|
|
7611
|
+
*
|
|
7612
|
+
* La colonne se nomme par son titre : c'est ce que connaît une IA qui lit un
|
|
7613
|
+
* tableau, et le cloud le résout. Deux ajouts qui se croisent se rangent tous
|
|
7614
|
+
* les deux, ce qu'une sauvegarde de tableau entier ne garantissait pas.
|
|
7615
|
+
*/
|
|
7616
|
+
async addCard(boardId, input) {
|
|
7617
|
+
const res = await callCloud("/kanban/card/add", {
|
|
7618
|
+
method: "POST",
|
|
7619
|
+
body: { boardId, ...input }
|
|
7620
|
+
});
|
|
7621
|
+
return res.data?.card ?? null;
|
|
7622
|
+
}
|
|
7469
7623
|
/** Déplacer une carte, sans réécrire le tableau. */
|
|
7470
7624
|
async moveCard(boardId, cardId, toColumnId) {
|
|
7471
7625
|
const res = await callCloud("/kanban/card/move", {
|
|
@@ -7558,7 +7712,6 @@ async function executeKanbanCommands(boardId, cardId, commands, conversationId)
|
|
|
7558
7712
|
return;
|
|
7559
7713
|
}
|
|
7560
7714
|
}
|
|
7561
|
-
let pendingBoardWrite = false;
|
|
7562
7715
|
for (const cmd of commands) {
|
|
7563
7716
|
if (cmd.type === "move_card" && cmd.columnTitle) {
|
|
7564
7717
|
const target = board.columns.find(
|
|
@@ -7574,11 +7727,14 @@ async function executeKanbanCommands(boardId, cardId, commands, conversationId)
|
|
|
7574
7727
|
const ok = await kanbanStore.addComment(board.id, cardId, cmd.comment, conversationId);
|
|
7575
7728
|
if (!ok) console.warn(`[kanban-commands] add_comment failed: card=${cardId}`);
|
|
7576
7729
|
} else if (cmd.type === "add_card" && cmd.columnTitle && cmd.cardTitle) {
|
|
7577
|
-
|
|
7578
|
-
|
|
7730
|
+
const card = await kanbanStore.addCard(board.id, {
|
|
7731
|
+
column: cmd.columnTitle,
|
|
7732
|
+
title: cmd.cardTitle,
|
|
7733
|
+
markdown: cmd.cardContent
|
|
7734
|
+
});
|
|
7735
|
+
if (!card) console.warn(`[kanban-commands] add_card failed: column="${cmd.columnTitle}"`);
|
|
7579
7736
|
}
|
|
7580
7737
|
}
|
|
7581
|
-
if (pendingBoardWrite) await kanbanStore.update({ id: board.id, columns: board.columns });
|
|
7582
7738
|
}
|
|
7583
7739
|
async function executeKanbanBoardCommands(boardId, commands) {
|
|
7584
7740
|
if (commands.length === 0) return;
|
|
@@ -7586,30 +7742,14 @@ async function executeKanbanBoardCommands(boardId, commands) {
|
|
|
7586
7742
|
if (!board) return;
|
|
7587
7743
|
for (const cmd of commands) {
|
|
7588
7744
|
if (cmd.type === "add_card" && cmd.columnTitle && cmd.cardTitle) {
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
}
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
7598
|
-
const card = {
|
|
7599
|
-
id: randomUUID5(),
|
|
7600
|
-
title: cardTitle,
|
|
7601
|
-
markdown: cardContent ?? "",
|
|
7602
|
-
images: [],
|
|
7603
|
-
// `.default([])` on the schema makes these optional on the wire but required
|
|
7604
|
-
// on the inferred type — a card built by hand has to supply them.
|
|
7605
|
-
attachments: [],
|
|
7606
|
-
assignees: [],
|
|
7607
|
-
order: col.cards.length,
|
|
7608
|
-
history: [{ type: "created", timestamp: now, detail: `AI \u2014 In column "${col.title}"` }],
|
|
7609
|
-
createdAt: now,
|
|
7610
|
-
updatedAt: now
|
|
7611
|
-
};
|
|
7612
|
-
col.cards.push(card);
|
|
7745
|
+
const card = await kanbanStore.addCard(board.id, {
|
|
7746
|
+
column: cmd.columnTitle,
|
|
7747
|
+
title: cmd.cardTitle,
|
|
7748
|
+
markdown: cmd.cardContent
|
|
7749
|
+
});
|
|
7750
|
+
if (!card) console.warn(`[kanban-commands] add_card failed: column="${cmd.columnTitle}"`);
|
|
7751
|
+
}
|
|
7752
|
+
}
|
|
7613
7753
|
}
|
|
7614
7754
|
function formatSize(bytes) {
|
|
7615
7755
|
if (bytes < 1024) return `${bytes} o`;
|
|
@@ -7835,7 +7975,7 @@ Ne jamais omettre ce tag. Il doit \xEAtre la toute derni\xE8re ligne de ta r\xE9
|
|
|
7835
7975
|
`.trim();
|
|
7836
7976
|
|
|
7837
7977
|
// ../server/src/services/ai-runners/claude-pty-runner.ts
|
|
7838
|
-
import { randomUUID as
|
|
7978
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
7839
7979
|
|
|
7840
7980
|
// ../server/src/services/ai-runners/claude-pty-tail.ts
|
|
7841
7981
|
import { open } from "fs/promises";
|
|
@@ -7959,7 +8099,7 @@ function tailTranscript(opts) {
|
|
|
7959
8099
|
|
|
7960
8100
|
// ../server/src/services/ai-runners/claude-pty-runner.ts
|
|
7961
8101
|
async function getAgentManager() {
|
|
7962
|
-
const { agentManager: agentManager2 } = await import("./agent-manager-
|
|
8102
|
+
const { agentManager: agentManager2 } = await import("./agent-manager-YDLSYZE3.js");
|
|
7963
8103
|
return agentManager2;
|
|
7964
8104
|
}
|
|
7965
8105
|
function buildPtyArgs(params, sessionId, opts) {
|
|
@@ -8029,7 +8169,7 @@ function dispatchEntry(entry, state, cbs) {
|
|
|
8029
8169
|
async function runClaudeViaPty(params) {
|
|
8030
8170
|
const { agentId, signal, skipTokenInstructions } = params;
|
|
8031
8171
|
if (!agentId) throw new Error("runClaudeViaPty requires an agentId");
|
|
8032
|
-
const sessionId = params.sessionId && params.sessionId.length > 0 ? params.sessionId :
|
|
8172
|
+
const sessionId = params.sessionId && params.sessionId.length > 0 ? params.sessionId : randomUUID5();
|
|
8033
8173
|
const args = buildPtyArgs(params, sessionId, { excludeMcp: true });
|
|
8034
8174
|
const agentMgr = await getAgentManager();
|
|
8035
8175
|
const displayArgs = args.map((a) => {
|
|
@@ -8700,7 +8840,7 @@ async function shutdownCodexAppServer() {
|
|
|
8700
8840
|
}
|
|
8701
8841
|
}
|
|
8702
8842
|
async function getAgentManager2() {
|
|
8703
|
-
const { agentManager: agentManager2 } = await import("./agent-manager-
|
|
8843
|
+
const { agentManager: agentManager2 } = await import("./agent-manager-YDLSYZE3.js");
|
|
8704
8844
|
return agentManager2;
|
|
8705
8845
|
}
|
|
8706
8846
|
function parseRuneyaCurlCommand(command) {
|
|
@@ -9141,18 +9281,18 @@ ${prompt}`;
|
|
|
9141
9281
|
|
|
9142
9282
|
// ../server/src/trpc/routers/chat.ts
|
|
9143
9283
|
var execFileAsync3 = promisify3(execFile4);
|
|
9144
|
-
var MessageSchema =
|
|
9145
|
-
role:
|
|
9146
|
-
content:
|
|
9284
|
+
var MessageSchema = z17.object({
|
|
9285
|
+
role: z17.enum(["user", "assistant"]),
|
|
9286
|
+
content: z17.string().max(1e5)
|
|
9147
9287
|
});
|
|
9148
|
-
var ImagePartSchema =
|
|
9149
|
-
type:
|
|
9150
|
-
imageId:
|
|
9151
|
-
url:
|
|
9152
|
-
mimeType:
|
|
9153
|
-
altText:
|
|
9288
|
+
var ImagePartSchema = z17.object({
|
|
9289
|
+
type: z17.literal("image"),
|
|
9290
|
+
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),
|
|
9291
|
+
url: z17.string().max(500),
|
|
9292
|
+
mimeType: z17.string().max(100),
|
|
9293
|
+
altText: z17.string().max(500).optional()
|
|
9154
9294
|
});
|
|
9155
|
-
var ImagePartsSchema =
|
|
9295
|
+
var ImagePartsSchema = z17.array(ImagePartSchema).max(5).optional();
|
|
9156
9296
|
var LANGUAGE_INSTRUCTION = "Always respond in the same language the user writes in.";
|
|
9157
9297
|
async function buildSystemPrompt(apiKey) {
|
|
9158
9298
|
const allServices = await serviceStore.list();
|
|
@@ -9539,24 +9679,24 @@ async function startCodexSession(convId, prompt, opts = {}) {
|
|
|
9539
9679
|
});
|
|
9540
9680
|
return { session, done };
|
|
9541
9681
|
}
|
|
9542
|
-
var MessagePartSchema =
|
|
9543
|
-
|
|
9544
|
-
|
|
9545
|
-
|
|
9546
|
-
type:
|
|
9682
|
+
var MessagePartSchema = z17.discriminatedUnion("type", [
|
|
9683
|
+
z17.object({ type: z17.literal("thinking"), text: z17.string().max(1e5) }),
|
|
9684
|
+
z17.object({ type: z17.literal("text"), text: z17.string().max(1e5) }),
|
|
9685
|
+
z17.object({
|
|
9686
|
+
type: z17.literal("tool"),
|
|
9547
9687
|
id: Id128Schema,
|
|
9548
9688
|
name: Id128Schema,
|
|
9549
|
-
input:
|
|
9550
|
-
rawInput:
|
|
9551
|
-
result:
|
|
9552
|
-
isError:
|
|
9553
|
-
pending:
|
|
9689
|
+
input: z17.record(z17.string(), z17.unknown()).optional(),
|
|
9690
|
+
rawInput: z17.string().max(1e4).optional(),
|
|
9691
|
+
result: z17.unknown().optional(),
|
|
9692
|
+
isError: z17.boolean().optional(),
|
|
9693
|
+
pending: z17.boolean()
|
|
9554
9694
|
})
|
|
9555
9695
|
]);
|
|
9556
|
-
var StoredMessageSchema =
|
|
9557
|
-
role:
|
|
9558
|
-
content:
|
|
9559
|
-
parts:
|
|
9696
|
+
var StoredMessageSchema = z17.object({
|
|
9697
|
+
role: z17.enum(["user", "assistant"]),
|
|
9698
|
+
content: z17.string().max(1e5),
|
|
9699
|
+
parts: z17.array(MessagePartSchema).max(200).optional()
|
|
9560
9700
|
});
|
|
9561
9701
|
async function conversationCwd(conv) {
|
|
9562
9702
|
return resolveConversationCwd(conv.id);
|
|
@@ -9570,7 +9710,7 @@ var chatRouter = router({
|
|
|
9570
9710
|
* et sans le même filtre il y reversait toutes les conversations de la
|
|
9571
9711
|
* machine, une seconde après un chargement pourtant filtré.
|
|
9572
9712
|
*/
|
|
9573
|
-
onChanged: protectedProcedure.input(
|
|
9713
|
+
onChanged: protectedProcedure.input(z17.object({
|
|
9574
9714
|
projectId: Id128Schema.optional(),
|
|
9575
9715
|
orgId: Id128Schema.nullable().optional()
|
|
9576
9716
|
}).optional()).subscription(async function* ({ input }) {
|
|
@@ -9618,7 +9758,7 @@ var chatRouter = router({
|
|
|
9618
9758
|
* reachable where they were written, without leaking into every other
|
|
9619
9759
|
* organization's projects.
|
|
9620
9760
|
*/
|
|
9621
|
-
list: protectedProcedure.input(
|
|
9761
|
+
list: protectedProcedure.input(z17.object({
|
|
9622
9762
|
projectId: Id128Schema.optional(),
|
|
9623
9763
|
orgId: Id128Schema.nullable().optional()
|
|
9624
9764
|
}).optional()).query(async ({ input }) => {
|
|
@@ -9626,24 +9766,24 @@ var chatRouter = router({
|
|
|
9626
9766
|
if (!projectId) return conversationStore.list();
|
|
9627
9767
|
return conversationStore.listForProject({ id: projectId, orgId: input?.orgId });
|
|
9628
9768
|
}),
|
|
9629
|
-
get: protectedProcedure.input(
|
|
9769
|
+
get: protectedProcedure.input(z17.object({ id: Id128Schema })).query(async ({ input }) => {
|
|
9630
9770
|
const conv = await conversationStore.get(input.id);
|
|
9631
9771
|
if (!conv) throw new TRPCError12({ code: "NOT_FOUND", message: "Conversation not found" });
|
|
9632
9772
|
return conv;
|
|
9633
9773
|
}),
|
|
9634
|
-
create: protectedProcedure.input(
|
|
9774
|
+
create: protectedProcedure.input(z17.object({
|
|
9635
9775
|
title: ShortString200Schema.optional(),
|
|
9636
|
-
isCli:
|
|
9637
|
-
runner:
|
|
9776
|
+
isCli: z17.boolean().optional(),
|
|
9777
|
+
runner: z17.enum(["claude-code", "codex"]).optional(),
|
|
9638
9778
|
providerId: Id128Schema.optional(),
|
|
9639
9779
|
scenarioId: Id128Schema.optional(),
|
|
9640
|
-
scenarioInput:
|
|
9780
|
+
scenarioInput: z17.string().max(1e5).optional(),
|
|
9641
9781
|
kanbanBoardId: Id128Schema.optional(),
|
|
9642
9782
|
kanbanCardId: Id128Schema.optional(),
|
|
9643
9783
|
// The project the conversation is about: only the caller knows which
|
|
9644
9784
|
// one it is looking at.
|
|
9645
9785
|
projectId: Id128Schema.optional(),
|
|
9646
|
-
orgId:
|
|
9786
|
+
orgId: z17.string().max(128).nullable().optional()
|
|
9647
9787
|
})).mutation(async ({ input }) => {
|
|
9648
9788
|
let scenario = null;
|
|
9649
9789
|
if (input.scenarioId) {
|
|
@@ -9674,20 +9814,20 @@ var chatRouter = router({
|
|
|
9674
9814
|
}
|
|
9675
9815
|
return conv;
|
|
9676
9816
|
}),
|
|
9677
|
-
update: protectedProcedure.input(
|
|
9817
|
+
update: protectedProcedure.input(z17.object({
|
|
9678
9818
|
id: Id128Schema,
|
|
9679
9819
|
title: ShortString200Schema.optional(),
|
|
9680
|
-
messages:
|
|
9681
|
-
contextUsage:
|
|
9682
|
-
inputTokens:
|
|
9683
|
-
contextWindow:
|
|
9820
|
+
messages: z17.array(StoredMessageSchema).max(500).optional(),
|
|
9821
|
+
contextUsage: z17.object({
|
|
9822
|
+
inputTokens: z17.number().int().nonnegative(),
|
|
9823
|
+
contextWindow: z17.number().int().positive()
|
|
9684
9824
|
}).optional()
|
|
9685
9825
|
})).mutation(async ({ input }) => {
|
|
9686
9826
|
const conv = await conversationStore.update(input.id, { title: input.title, messages: input.messages, contextUsage: input.contextUsage });
|
|
9687
9827
|
if (!conv) throw new TRPCError12({ code: "NOT_FOUND", message: "Conversation not found" });
|
|
9688
9828
|
return conv;
|
|
9689
9829
|
}),
|
|
9690
|
-
delete: protectedProcedure.input(
|
|
9830
|
+
delete: protectedProcedure.input(z17.object({ id: Id128Schema })).mutation(async ({ input }) => {
|
|
9691
9831
|
const existing = await conversationStore.get(input.id);
|
|
9692
9832
|
if (!existing) throw new TRPCError12({ code: "NOT_FOUND", message: "Conversation not found" });
|
|
9693
9833
|
for (const agent of agentManager.listAgents()) {
|
|
@@ -9709,18 +9849,18 @@ var chatRouter = router({
|
|
|
9709
9849
|
(err) => console.error("[chat.delete] Image cleanup error:", err)
|
|
9710
9850
|
);
|
|
9711
9851
|
}),
|
|
9712
|
-
archive: protectedProcedure.input(
|
|
9852
|
+
archive: protectedProcedure.input(z17.object({ id: Id128Schema, archived: z17.boolean() })).mutation(async ({ input }) => {
|
|
9713
9853
|
const conv = await conversationStore.update(input.id, { archived: input.archived });
|
|
9714
9854
|
if (!conv) throw new TRPCError12({ code: "NOT_FOUND", message: "Conversation not found" });
|
|
9715
9855
|
return conv;
|
|
9716
9856
|
})
|
|
9717
9857
|
}),
|
|
9718
|
-
listModels: protectedProcedure.input(
|
|
9858
|
+
listModels: protectedProcedure.input(z17.object({
|
|
9719
9859
|
providerId: Id128Schema.optional(),
|
|
9720
9860
|
// Le projet dit de quelle organisation lire les fournisseurs ; absent,
|
|
9721
9861
|
// ce sont ceux du poste.
|
|
9722
9862
|
projectId: Id128Schema.optional(),
|
|
9723
|
-
orgId:
|
|
9863
|
+
orgId: z17.string().max(128).nullable().optional()
|
|
9724
9864
|
}).optional()).query(async ({ input }) => {
|
|
9725
9865
|
const active = await getActiveProvider(
|
|
9726
9866
|
input?.providerId,
|
|
@@ -9733,7 +9873,7 @@ var chatRouter = router({
|
|
|
9733
9873
|
return [];
|
|
9734
9874
|
}
|
|
9735
9875
|
}),
|
|
9736
|
-
checkCliAvailability: protectedProcedure.input(
|
|
9876
|
+
checkCliAvailability: protectedProcedure.input(z17.object({ agentId: Id128Schema.optional() }).optional()).query(async ({ input }) => {
|
|
9737
9877
|
if (input?.agentId) {
|
|
9738
9878
|
try {
|
|
9739
9879
|
const res = await agentManager.agentQuery(
|
|
@@ -9751,12 +9891,12 @@ var chatRouter = router({
|
|
|
9751
9891
|
]);
|
|
9752
9892
|
return { available: claudeOk, codexAvailable: codexOk };
|
|
9753
9893
|
}),
|
|
9754
|
-
enhanceScenarioPrompt: protectedProcedure.input(
|
|
9755
|
-
text:
|
|
9894
|
+
enhanceScenarioPrompt: protectedProcedure.input(z17.object({
|
|
9895
|
+
text: z17.string().max(1e4),
|
|
9756
9896
|
providerId: Id128Schema.optional(),
|
|
9757
|
-
model:
|
|
9897
|
+
model: z17.string().max(200).optional(),
|
|
9758
9898
|
projectId: Id128Schema.optional(),
|
|
9759
|
-
orgId:
|
|
9899
|
+
orgId: z17.string().max(128).nullable().optional()
|
|
9760
9900
|
})).mutation(async ({ input }) => {
|
|
9761
9901
|
const active = await getActiveProvider(
|
|
9762
9902
|
input.providerId,
|
|
@@ -9813,22 +9953,22 @@ Return ONLY the improved text, no explanation, no preamble.`;
|
|
|
9813
9953
|
}
|
|
9814
9954
|
}),
|
|
9815
9955
|
getStreamingStatus: protectedProcedure.query(() => activeSessionRegistry.listActive()),
|
|
9816
|
-
stopSession: protectedProcedure.input(
|
|
9956
|
+
stopSession: protectedProcedure.input(z17.object({ conversationId: ConversationIdSchema })).mutation(({ input }) => {
|
|
9817
9957
|
if (process.env.RUNEYA_DEBUG) console.log("[chat]: stopSession");
|
|
9818
9958
|
const killed = activeSessionRegistry.kill(input.conversationId);
|
|
9819
9959
|
if (!killed) throw new TRPCError12({ code: "NOT_FOUND", message: "No active session for this conversation" });
|
|
9820
9960
|
return { ok: true };
|
|
9821
9961
|
}),
|
|
9822
|
-
streamViaClaudeCode: protectedProcedure.input(
|
|
9962
|
+
streamViaClaudeCode: protectedProcedure.input(z17.object({
|
|
9823
9963
|
conversationId: ConversationIdSchema,
|
|
9824
|
-
prompt:
|
|
9825
|
-
contextNote:
|
|
9964
|
+
prompt: z17.string().max(1e5),
|
|
9965
|
+
contextNote: z17.string().max(2e5).optional(),
|
|
9826
9966
|
model: ShortString200Schema.optional(),
|
|
9827
|
-
effort:
|
|
9828
|
-
reconnect:
|
|
9967
|
+
effort: z17.enum(["low", "medium", "high"]).optional(),
|
|
9968
|
+
reconnect: z17.boolean().optional(),
|
|
9829
9969
|
agentId: Id128Schema.optional(),
|
|
9830
|
-
environmentId:
|
|
9831
|
-
imageIds:
|
|
9970
|
+
environmentId: z17.string().max(128).optional(),
|
|
9971
|
+
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(),
|
|
9832
9972
|
imageParts: ImagePartsSchema
|
|
9833
9973
|
})).subscription(async function* ({ input, ctx, signal }) {
|
|
9834
9974
|
if (process.env.RUNEYA_DEBUG) console.log("[chat]: Reconnect");
|
|
@@ -9939,15 +10079,15 @@ ${imagePaths.map((p) => `Image: ${p}`).join("\n")}` : cliPrompt;
|
|
|
9939
10079
|
if (process.env.RUNEYA_DEBUG) console.log("[chat]: drainSession...");
|
|
9940
10080
|
yield* drainSession(session, signal, false);
|
|
9941
10081
|
}),
|
|
9942
|
-
streamViaCodex: protectedProcedure.input(
|
|
10082
|
+
streamViaCodex: protectedProcedure.input(z17.object({
|
|
9943
10083
|
conversationId: ConversationIdSchema,
|
|
9944
|
-
prompt:
|
|
9945
|
-
contextNote:
|
|
10084
|
+
prompt: z17.string().max(1e5),
|
|
10085
|
+
contextNote: z17.string().max(2e5).optional(),
|
|
9946
10086
|
model: ShortString200Schema.optional(),
|
|
9947
|
-
reconnect:
|
|
10087
|
+
reconnect: z17.boolean().optional(),
|
|
9948
10088
|
agentId: Id128Schema.optional(),
|
|
9949
|
-
environmentId:
|
|
9950
|
-
imageIds:
|
|
10089
|
+
environmentId: z17.string().max(128).optional(),
|
|
10090
|
+
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(),
|
|
9951
10091
|
imageParts: ImagePartsSchema
|
|
9952
10092
|
})).subscription(async function* ({ input, ctx, signal }) {
|
|
9953
10093
|
const existingSession = activeSessionRegistry.get(input.conversationId);
|
|
@@ -10025,13 +10165,13 @@ ${input.prompt}` : input.prompt;
|
|
|
10025
10165
|
});
|
|
10026
10166
|
yield* drainSession(session, signal, false);
|
|
10027
10167
|
}),
|
|
10028
|
-
send: protectedProcedure.input(
|
|
10168
|
+
send: protectedProcedure.input(z17.object({
|
|
10029
10169
|
conversationId: ConversationIdSchema,
|
|
10030
|
-
messages:
|
|
10170
|
+
messages: z17.array(MessageSchema).min(0).max(100),
|
|
10031
10171
|
model: ShortString200Schema.optional(),
|
|
10032
|
-
contextNote:
|
|
10033
|
-
reconnect:
|
|
10034
|
-
imageIds:
|
|
10172
|
+
contextNote: z17.string().max(2e5).optional(),
|
|
10173
|
+
reconnect: z17.boolean().optional(),
|
|
10174
|
+
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(),
|
|
10035
10175
|
imageParts: ImagePartsSchema
|
|
10036
10176
|
})).subscription(async function* ({ input, ctx, signal }) {
|
|
10037
10177
|
const existingSession = activeSessionRegistry.get(input.conversationId);
|
|
@@ -10149,25 +10289,25 @@ ${input.prompt}` : input.prompt;
|
|
|
10149
10289
|
// ── PTY passthrough (interactive Claude Code session) ────────────────────
|
|
10150
10290
|
pty: router({
|
|
10151
10291
|
/** Start a PTY session running `claude --resume <sessionId>` (or fresh). */
|
|
10152
|
-
start: protectedProcedure.input(
|
|
10153
|
-
agentId:
|
|
10154
|
-
sessionId:
|
|
10155
|
-
runner:
|
|
10156
|
-
resume:
|
|
10157
|
-
model:
|
|
10158
|
-
cwd:
|
|
10292
|
+
start: protectedProcedure.input(z17.object({
|
|
10293
|
+
agentId: z17.string().max(128).optional(),
|
|
10294
|
+
sessionId: z17.string().max(128).optional(),
|
|
10295
|
+
runner: z17.enum(["claude-code", "codex"]).default("claude-code"),
|
|
10296
|
+
resume: z17.boolean().default(false),
|
|
10297
|
+
model: z17.string().max(128).optional(),
|
|
10298
|
+
cwd: z17.string().max(4096).optional(),
|
|
10159
10299
|
/** Anchors the session when no explicit cwd is given. */
|
|
10160
|
-
serviceId:
|
|
10300
|
+
serviceId: z17.string().max(128).optional(),
|
|
10161
10301
|
projectId: Id128Schema.optional(),
|
|
10162
|
-
orgId:
|
|
10163
|
-
cols:
|
|
10164
|
-
rows:
|
|
10165
|
-
enableMcp:
|
|
10166
|
-
apiBaseUrl:
|
|
10167
|
-
environmentId:
|
|
10168
|
-
attachedContexts:
|
|
10169
|
-
label:
|
|
10170
|
-
text:
|
|
10302
|
+
orgId: z17.string().max(128).nullable().optional(),
|
|
10303
|
+
cols: z17.number().int().min(1).max(1e3).default(120),
|
|
10304
|
+
rows: z17.number().int().min(1).max(1e3).default(30),
|
|
10305
|
+
enableMcp: z17.boolean().default(false),
|
|
10306
|
+
apiBaseUrl: z17.string().max(512).optional(),
|
|
10307
|
+
environmentId: z17.string().max(128).optional(),
|
|
10308
|
+
attachedContexts: z17.array(z17.object({
|
|
10309
|
+
label: z17.string().max(200),
|
|
10310
|
+
text: z17.string().max(1e6)
|
|
10171
10311
|
})).max(20).optional()
|
|
10172
10312
|
})).mutation(async ({ input, ctx }) => {
|
|
10173
10313
|
const t0 = Date.now();
|
|
@@ -10326,10 +10466,10 @@ Context:
|
|
|
10326
10466
|
return { spawnId: res.spawnId, agentId, reattached: false };
|
|
10327
10467
|
}),
|
|
10328
10468
|
/** Subscribe to PTY output stream (raw text with ANSI). */
|
|
10329
|
-
stream: protectedProcedure.input(
|
|
10330
|
-
agentId:
|
|
10331
|
-
spawnId:
|
|
10332
|
-
fromOffset:
|
|
10469
|
+
stream: protectedProcedure.input(z17.object({
|
|
10470
|
+
agentId: z17.string().max(128).optional(),
|
|
10471
|
+
spawnId: z17.string().max(128),
|
|
10472
|
+
fromOffset: z17.number().int().min(0).default(0)
|
|
10333
10473
|
})).subscription(async function* ({ input, signal }) {
|
|
10334
10474
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10335
10475
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10381,10 +10521,10 @@ Context:
|
|
|
10381
10521
|
}
|
|
10382
10522
|
}),
|
|
10383
10523
|
/** Write input to a PTY session (keystrokes from xterm). */
|
|
10384
|
-
write: protectedProcedure.input(
|
|
10385
|
-
agentId:
|
|
10386
|
-
spawnId:
|
|
10387
|
-
data:
|
|
10524
|
+
write: protectedProcedure.input(z17.object({
|
|
10525
|
+
agentId: z17.string().max(128).optional(),
|
|
10526
|
+
spawnId: z17.string().max(128),
|
|
10527
|
+
data: z17.string().max(1e6)
|
|
10388
10528
|
})).mutation(async ({ input }) => {
|
|
10389
10529
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10390
10530
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10394,11 +10534,11 @@ Context:
|
|
|
10394
10534
|
});
|
|
10395
10535
|
}),
|
|
10396
10536
|
/** Resize a PTY session. */
|
|
10397
|
-
resize: protectedProcedure.input(
|
|
10398
|
-
agentId:
|
|
10399
|
-
spawnId:
|
|
10400
|
-
cols:
|
|
10401
|
-
rows:
|
|
10537
|
+
resize: protectedProcedure.input(z17.object({
|
|
10538
|
+
agentId: z17.string().max(128).optional(),
|
|
10539
|
+
spawnId: z17.string().max(128),
|
|
10540
|
+
cols: z17.number().int().min(1).max(1e3),
|
|
10541
|
+
rows: z17.number().int().min(1).max(1e3)
|
|
10402
10542
|
})).mutation(async ({ input }) => {
|
|
10403
10543
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10404
10544
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10414,11 +10554,11 @@ Context:
|
|
|
10414
10554
|
* picks it up. Returns the tmp path and which clipboard method succeeded
|
|
10415
10555
|
* (null if none — caller should inject `@<path>` instead of Ctrl+V).
|
|
10416
10556
|
*/
|
|
10417
|
-
pasteImage: protectedProcedure.input(
|
|
10418
|
-
agentId:
|
|
10419
|
-
sessionId:
|
|
10420
|
-
mimeType:
|
|
10421
|
-
base64:
|
|
10557
|
+
pasteImage: protectedProcedure.input(z17.object({
|
|
10558
|
+
agentId: z17.string().max(128).optional(),
|
|
10559
|
+
sessionId: z17.string().max(128).optional(),
|
|
10560
|
+
mimeType: z17.string().max(64),
|
|
10561
|
+
base64: z17.string().max(15e6)
|
|
10422
10562
|
})).mutation(async ({ input }) => {
|
|
10423
10563
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10424
10564
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10436,7 +10576,7 @@ Context:
|
|
|
10436
10576
|
* Read the transcript Claude Code stores on disk for a given session.
|
|
10437
10577
|
* Returns parsed JSONL entries (user / assistant messages, tool uses, etc.).
|
|
10438
10578
|
*/
|
|
10439
|
-
transcript: protectedProcedure.input(
|
|
10579
|
+
transcript: protectedProcedure.input(z17.object({ sessionId: z17.string().max(128) })).query(async ({ input }) => {
|
|
10440
10580
|
return readClaudeTranscript(input.sessionId);
|
|
10441
10581
|
}),
|
|
10442
10582
|
/**
|
|
@@ -10444,9 +10584,9 @@ Context:
|
|
|
10444
10584
|
* when was the transcript JSONL last touched? Used by the non-PTY view
|
|
10445
10585
|
* to show a "Claude is thinking…" indicator while output streams.
|
|
10446
10586
|
*/
|
|
10447
|
-
activity: protectedProcedure.input(
|
|
10448
|
-
agentId:
|
|
10449
|
-
sessionId:
|
|
10587
|
+
activity: protectedProcedure.input(z17.object({
|
|
10588
|
+
agentId: z17.string().max(128).optional(),
|
|
10589
|
+
sessionId: z17.string().max(128)
|
|
10450
10590
|
})).query(async ({ input }) => {
|
|
10451
10591
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10452
10592
|
let running = false;
|
|
@@ -10472,7 +10612,7 @@ Context:
|
|
|
10472
10612
|
* them on the conversation, so the non-PTY chat view stays in sync.
|
|
10473
10613
|
* Uses the conversation id as session id (PTY sessions are spawned that way).
|
|
10474
10614
|
*/
|
|
10475
|
-
syncTranscript: protectedProcedure.input(
|
|
10615
|
+
syncTranscript: protectedProcedure.input(z17.object({ conversationId: ConversationIdSchema })).mutation(async ({ input }) => {
|
|
10476
10616
|
const conv = await conversationStore.get(input.conversationId);
|
|
10477
10617
|
if (!conv) {
|
|
10478
10618
|
throw new TRPCError12({ code: "NOT_FOUND", message: `Conversation ${input.conversationId} not found` });
|
|
@@ -10486,14 +10626,14 @@ Context:
|
|
|
10486
10626
|
* with the given sessionId. Used to benchmark the PTY → tRPC → xterm.js
|
|
10487
10627
|
* pipeline. Open the conversation in PTY mode to attach to it.
|
|
10488
10628
|
*/
|
|
10489
|
-
debugStress: protectedProcedure.input(
|
|
10490
|
-
sessionId:
|
|
10491
|
-
agentId:
|
|
10492
|
-
bytesPerSec:
|
|
10493
|
-
chunkSize:
|
|
10494
|
-
durationMs:
|
|
10495
|
-
cols:
|
|
10496
|
-
rows:
|
|
10629
|
+
debugStress: protectedProcedure.input(z17.object({
|
|
10630
|
+
sessionId: z17.string().max(128),
|
|
10631
|
+
agentId: z17.string().max(128).optional(),
|
|
10632
|
+
bytesPerSec: z17.number().int().min(100).max(1e7).default(5e4),
|
|
10633
|
+
chunkSize: z17.number().int().min(1).max(65536).default(256),
|
|
10634
|
+
durationMs: z17.number().int().min(0).max(36e5).default(0),
|
|
10635
|
+
cols: z17.number().int().min(1).max(1e3).default(120),
|
|
10636
|
+
rows: z17.number().int().min(1).max(1e3).default(30)
|
|
10497
10637
|
})).mutation(async ({ input }) => {
|
|
10498
10638
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10499
10639
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10540,9 +10680,9 @@ Context:
|
|
|
10540
10680
|
return { spawnId: res.spawnId, agentId, stressSessionId };
|
|
10541
10681
|
}),
|
|
10542
10682
|
/** Kill a PTY session. */
|
|
10543
|
-
kill: protectedProcedure.input(
|
|
10544
|
-
agentId:
|
|
10545
|
-
spawnId:
|
|
10683
|
+
kill: protectedProcedure.input(z17.object({
|
|
10684
|
+
agentId: z17.string().max(128).optional(),
|
|
10685
|
+
spawnId: z17.string().max(128)
|
|
10546
10686
|
})).mutation(async ({ input }) => {
|
|
10547
10687
|
const agentId = input.agentId ?? agentManager.getDefaultAgentId();
|
|
10548
10688
|
if (!agentId) throw new TRPCError12({ code: "PRECONDITION_FAILED", message: "No agent available" });
|
|
@@ -10554,16 +10694,16 @@ Context:
|
|
|
10554
10694
|
});
|
|
10555
10695
|
|
|
10556
10696
|
// ../server/src/trpc/routers/git.ts
|
|
10557
|
-
import { z as
|
|
10697
|
+
import { z as z18 } from "zod";
|
|
10558
10698
|
import { TRPCError as TRPCError13 } from "@trpc/server";
|
|
10559
10699
|
import Anthropic3 from "@anthropic-ai/sdk";
|
|
10560
10700
|
import OpenAI3 from "openai";
|
|
10561
|
-
var SERVICE_ID_SCHEMA =
|
|
10562
|
-
var SAFE_PATH_SCHEMA =
|
|
10701
|
+
var SERVICE_ID_SCHEMA = z18.string().max(128);
|
|
10702
|
+
var SAFE_PATH_SCHEMA = z18.string().min(1).max(4096).refine((p) => !p.startsWith("/") && !p.includes("../"), {
|
|
10563
10703
|
message: "Path must be relative and not traverse up"
|
|
10564
10704
|
});
|
|
10565
|
-
var REMOTE_SCHEMA =
|
|
10566
|
-
var BRANCH_SCHEMA =
|
|
10705
|
+
var REMOTE_SCHEMA = z18.string().min(1).max(128).regex(/^[a-zA-Z0-9_\-.]+$/);
|
|
10706
|
+
var BRANCH_SCHEMA = z18.string().min(1).max(256).regex(/^[a-zA-Z0-9._\-/]+$/);
|
|
10567
10707
|
async function resolveServiceContext(serviceId) {
|
|
10568
10708
|
const service = await serviceStore.get(serviceId);
|
|
10569
10709
|
if (!service) {
|
|
@@ -10577,11 +10717,11 @@ async function resolveServiceContext(serviceId) {
|
|
|
10577
10717
|
}
|
|
10578
10718
|
var gitTargetShape = {
|
|
10579
10719
|
serviceId: SERVICE_ID_SCHEMA.optional(),
|
|
10580
|
-
agentId:
|
|
10720
|
+
agentId: z18.string().max(128).optional(),
|
|
10581
10721
|
/** Anchors on a project when no service is targeted (e.g. from the AI chat). */
|
|
10582
|
-
projectId:
|
|
10722
|
+
projectId: z18.string().max(128).optional(),
|
|
10583
10723
|
/** Son organisation : un id de projet seul peut en nommer un par organisation. */
|
|
10584
|
-
orgId:
|
|
10724
|
+
orgId: z18.string().max(128).nullable().optional()
|
|
10585
10725
|
};
|
|
10586
10726
|
async function resolveGitContext(input) {
|
|
10587
10727
|
if (input.serviceId) return resolveServiceContext(input.serviceId);
|
|
@@ -10594,82 +10734,82 @@ async function resolveGitContext(input) {
|
|
|
10594
10734
|
}
|
|
10595
10735
|
var gitRouter = router({
|
|
10596
10736
|
/** Get full git status */
|
|
10597
|
-
status: protectedProcedure.input(
|
|
10737
|
+
status: protectedProcedure.input(z18.object({ ...gitTargetShape })).query(async ({ input }) => {
|
|
10598
10738
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10599
10739
|
return agentManager.agentQuery(agentId, "git.status", { cwd });
|
|
10600
10740
|
}),
|
|
10601
10741
|
/** Get commit log */
|
|
10602
|
-
log: protectedProcedure.input(
|
|
10742
|
+
log: protectedProcedure.input(z18.object({ ...gitTargetShape, limit: z18.number().int().min(1).max(200).default(50) })).query(async ({ input }) => {
|
|
10603
10743
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10604
10744
|
return agentManager.agentQuery(agentId, "git.log", { cwd, limit: input.limit });
|
|
10605
10745
|
}),
|
|
10606
10746
|
/** List local and remote branches */
|
|
10607
|
-
branches: protectedProcedure.input(
|
|
10747
|
+
branches: protectedProcedure.input(z18.object({ ...gitTargetShape })).query(async ({ input }) => {
|
|
10608
10748
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10609
10749
|
return agentManager.agentQuery(agentId, "git.branches", { cwd });
|
|
10610
10750
|
}),
|
|
10611
10751
|
/** Checkout a branch */
|
|
10612
|
-
checkout: protectedProcedure.input(
|
|
10752
|
+
checkout: protectedProcedure.input(z18.object({ ...gitTargetShape, branch: BRANCH_SCHEMA, create: z18.boolean().default(false) })).mutation(async ({ input }) => {
|
|
10613
10753
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10614
10754
|
return agentManager.agentMutation(agentId, "git.checkout", { cwd, branch: input.branch, create: input.create });
|
|
10615
10755
|
}),
|
|
10616
10756
|
/** Stage files */
|
|
10617
|
-
stage: protectedProcedure.input(
|
|
10757
|
+
stage: protectedProcedure.input(z18.object({ ...gitTargetShape, paths: z18.array(SAFE_PATH_SCHEMA).min(1).max(500) })).mutation(async ({ input }) => {
|
|
10618
10758
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10619
10759
|
return agentManager.agentMutation(agentId, "git.stage", { cwd, paths: input.paths });
|
|
10620
10760
|
}),
|
|
10621
10761
|
/** Stage all files */
|
|
10622
|
-
stageAll: protectedProcedure.input(
|
|
10762
|
+
stageAll: protectedProcedure.input(z18.object({ ...gitTargetShape })).mutation(async ({ input }) => {
|
|
10623
10763
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10624
10764
|
return agentManager.agentMutation(agentId, "git.stageAll", { cwd });
|
|
10625
10765
|
}),
|
|
10626
10766
|
/** Unstage files */
|
|
10627
|
-
unstage: protectedProcedure.input(
|
|
10767
|
+
unstage: protectedProcedure.input(z18.object({ ...gitTargetShape, paths: z18.array(SAFE_PATH_SCHEMA).min(1).max(500) })).mutation(async ({ input }) => {
|
|
10628
10768
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10629
10769
|
return agentManager.agentMutation(agentId, "git.unstage", { cwd, paths: input.paths });
|
|
10630
10770
|
}),
|
|
10631
10771
|
/** Unstage all files */
|
|
10632
|
-
unstageAll: protectedProcedure.input(
|
|
10772
|
+
unstageAll: protectedProcedure.input(z18.object({ ...gitTargetShape })).mutation(async ({ input }) => {
|
|
10633
10773
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10634
10774
|
return agentManager.agentMutation(agentId, "git.unstageAll", { cwd });
|
|
10635
10775
|
}),
|
|
10636
10776
|
/** Commit staged changes */
|
|
10637
|
-
commit: protectedProcedure.input(
|
|
10777
|
+
commit: protectedProcedure.input(z18.object({ ...gitTargetShape, message: z18.string().min(1).max(4096) })).mutation(async ({ input }) => {
|
|
10638
10778
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10639
10779
|
return agentManager.agentMutation(agentId, "git.commit", { cwd, message: input.message });
|
|
10640
10780
|
}),
|
|
10641
10781
|
/** Push to remote */
|
|
10642
|
-
push: protectedProcedure.input(
|
|
10782
|
+
push: protectedProcedure.input(z18.object({ ...gitTargetShape, remote: REMOTE_SCHEMA.default("origin"), setUpstream: z18.boolean().default(false) })).mutation(async ({ input }) => {
|
|
10643
10783
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10644
10784
|
return agentManager.agentMutation(agentId, "git.push", { cwd, remote: input.remote, setUpstream: input.setUpstream });
|
|
10645
10785
|
}),
|
|
10646
10786
|
/** Pull from remote */
|
|
10647
|
-
pull: protectedProcedure.input(
|
|
10787
|
+
pull: protectedProcedure.input(z18.object({ ...gitTargetShape, remote: REMOTE_SCHEMA.default("origin") })).mutation(async ({ input }) => {
|
|
10648
10788
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10649
10789
|
return agentManager.agentMutation(agentId, "git.pull", { cwd, remote: input.remote });
|
|
10650
10790
|
}),
|
|
10651
10791
|
/** Fetch from remote */
|
|
10652
|
-
fetch: protectedProcedure.input(
|
|
10792
|
+
fetch: protectedProcedure.input(z18.object({ ...gitTargetShape, remote: REMOTE_SCHEMA.default("origin") })).mutation(async ({ input }) => {
|
|
10653
10793
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10654
10794
|
return agentManager.agentMutation(agentId, "git.fetch", { cwd, remote: input.remote });
|
|
10655
10795
|
}),
|
|
10656
10796
|
/** Get diff for a file or the whole index */
|
|
10657
|
-
diff: protectedProcedure.input(
|
|
10797
|
+
diff: protectedProcedure.input(z18.object({
|
|
10658
10798
|
...gitTargetShape,
|
|
10659
|
-
path:
|
|
10660
|
-
staged:
|
|
10661
|
-
untracked:
|
|
10799
|
+
path: z18.string().max(4096).optional(),
|
|
10800
|
+
staged: z18.boolean().default(false),
|
|
10801
|
+
untracked: z18.boolean().default(false)
|
|
10662
10802
|
})).query(async ({ input }) => {
|
|
10663
10803
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10664
10804
|
return agentManager.agentQuery(agentId, "git.diff", { cwd, path: input.path, staged: input.staged, untracked: input.untracked });
|
|
10665
10805
|
}),
|
|
10666
10806
|
/** Discard changes to working tree files */
|
|
10667
|
-
discard: protectedProcedure.input(
|
|
10807
|
+
discard: protectedProcedure.input(z18.object({ ...gitTargetShape, paths: z18.array(SAFE_PATH_SCHEMA).min(1).max(500) })).mutation(async ({ input }) => {
|
|
10668
10808
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10669
10809
|
return agentManager.agentMutation(agentId, "git.discard", { cwd, paths: input.paths });
|
|
10670
10810
|
}),
|
|
10671
10811
|
/** Generate a commit message from staged diffs using AI (diff fetched from agent, AI runs on server) */
|
|
10672
|
-
generateCommitMessage: protectedProcedure.input(
|
|
10812
|
+
generateCommitMessage: protectedProcedure.input(z18.object({ ...gitTargetShape, providerId: OptionalProviderIdSchema, model: z18.string().max(200).optional() })).mutation(async ({ input }) => {
|
|
10673
10813
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10674
10814
|
const { diff } = await agentManager.agentQuery(agentId, "git.stagedDiff", { cwd });
|
|
10675
10815
|
if (!diff.trim()) {
|
|
@@ -10716,42 +10856,42 @@ Rules:
|
|
|
10716
10856
|
throw new TRPCError13({ code: "BAD_REQUEST", message: "Unsupported AI provider" });
|
|
10717
10857
|
}),
|
|
10718
10858
|
/** Merge a branch into the current branch */
|
|
10719
|
-
merge: protectedProcedure.input(
|
|
10859
|
+
merge: protectedProcedure.input(z18.object({ ...gitTargetShape, branch: BRANCH_SCHEMA, noFf: z18.boolean().default(false) })).mutation(async ({ input }) => {
|
|
10720
10860
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10721
10861
|
return agentManager.agentMutation(agentId, "git.merge", { cwd, branch: input.branch, noFf: input.noFf });
|
|
10722
10862
|
}),
|
|
10723
10863
|
/** Rebase current branch onto another branch */
|
|
10724
|
-
rebase: protectedProcedure.input(
|
|
10864
|
+
rebase: protectedProcedure.input(z18.object({ ...gitTargetShape, branch: BRANCH_SCHEMA })).mutation(async ({ input }) => {
|
|
10725
10865
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10726
10866
|
return agentManager.agentMutation(agentId, "git.rebase", { cwd, branch: input.branch });
|
|
10727
10867
|
}),
|
|
10728
10868
|
/** List stash entries */
|
|
10729
|
-
stashList: protectedProcedure.input(
|
|
10869
|
+
stashList: protectedProcedure.input(z18.object({ ...gitTargetShape })).query(async ({ input }) => {
|
|
10730
10870
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10731
10871
|
return agentManager.agentQuery(agentId, "git.stashList", { cwd });
|
|
10732
10872
|
}),
|
|
10733
10873
|
/** Stash current changes */
|
|
10734
|
-
stashPush: protectedProcedure.input(
|
|
10874
|
+
stashPush: protectedProcedure.input(z18.object({ ...gitTargetShape, message: z18.string().max(4096).optional(), includeUntracked: z18.boolean().default(true) })).mutation(async ({ input }) => {
|
|
10735
10875
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10736
10876
|
return agentManager.agentMutation(agentId, "git.stashPush", { cwd, message: input.message, includeUntracked: input.includeUntracked });
|
|
10737
10877
|
}),
|
|
10738
10878
|
/** Pop a stash entry */
|
|
10739
|
-
stashPop: protectedProcedure.input(
|
|
10879
|
+
stashPop: protectedProcedure.input(z18.object({ ...gitTargetShape, index: z18.number().int().min(0).max(1e3).default(0) })).mutation(async ({ input }) => {
|
|
10740
10880
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10741
10881
|
return agentManager.agentMutation(agentId, "git.stashPop", { cwd, index: input.index });
|
|
10742
10882
|
}),
|
|
10743
10883
|
/** Apply a stash entry without dropping it */
|
|
10744
|
-
stashApply: protectedProcedure.input(
|
|
10884
|
+
stashApply: protectedProcedure.input(z18.object({ ...gitTargetShape, index: z18.number().int().min(0).max(1e3).default(0) })).mutation(async ({ input }) => {
|
|
10745
10885
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10746
10886
|
return agentManager.agentMutation(agentId, "git.stashApply", { cwd, index: input.index });
|
|
10747
10887
|
}),
|
|
10748
10888
|
/** Drop a stash entry */
|
|
10749
|
-
stashDrop: protectedProcedure.input(
|
|
10889
|
+
stashDrop: protectedProcedure.input(z18.object({ ...gitTargetShape, index: z18.number().int().min(0).max(1e3).default(0) })).mutation(async ({ input }) => {
|
|
10750
10890
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10751
10891
|
return agentManager.agentMutation(agentId, "git.stashDrop", { cwd, index: input.index });
|
|
10752
10892
|
}),
|
|
10753
10893
|
/** Watch .git/ for changes and stream updated status */
|
|
10754
|
-
onStatusChange: protectedProcedure.input(
|
|
10894
|
+
onStatusChange: protectedProcedure.input(z18.object({ ...gitTargetShape })).subscription(async function* ({ input }) {
|
|
10755
10895
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10756
10896
|
const queue = [];
|
|
10757
10897
|
let resolve7 = null;
|
|
@@ -10798,16 +10938,16 @@ Rules:
|
|
|
10798
10938
|
}
|
|
10799
10939
|
}),
|
|
10800
10940
|
/** List remotes */
|
|
10801
|
-
remotes: protectedProcedure.input(
|
|
10941
|
+
remotes: protectedProcedure.input(z18.object({ ...gitTargetShape })).query(async ({ input }) => {
|
|
10802
10942
|
const { agentId, cwd } = await resolveGitContext(input);
|
|
10803
10943
|
return agentManager.agentQuery(agentId, "git.remotes", { cwd });
|
|
10804
10944
|
})
|
|
10805
10945
|
});
|
|
10806
10946
|
|
|
10807
10947
|
// ../server/src/trpc/routers/scenario.ts
|
|
10808
|
-
import { randomUUID as
|
|
10948
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
10809
10949
|
import { TRPCError as TRPCError16 } from "@trpc/server";
|
|
10810
|
-
import { z as
|
|
10950
|
+
import { z as z19 } from "zod";
|
|
10811
10951
|
|
|
10812
10952
|
// ../server/src/trpc/crud-procedure-utils.ts
|
|
10813
10953
|
import { TRPCError as TRPCError14 } from "@trpc/server";
|
|
@@ -10921,9 +11061,9 @@ async function* streamWithActiveProvider(opts) {
|
|
|
10921
11061
|
}
|
|
10922
11062
|
|
|
10923
11063
|
// ../server/src/services/scenario-runner.ts
|
|
10924
|
-
import { mkdir as
|
|
10925
|
-
import { randomUUID as
|
|
10926
|
-
import { join as
|
|
11064
|
+
import { mkdir as mkdir16 } from "fs/promises";
|
|
11065
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
11066
|
+
import { join as join19 } from "path";
|
|
10927
11067
|
|
|
10928
11068
|
// ../server/src/services/scenario-presets.ts
|
|
10929
11069
|
var BUILT_IN_PRESETS = [
|
|
@@ -11264,7 +11404,7 @@ function applyHireDirectivesFromOutput(manager, scenario, output) {
|
|
|
11264
11404
|
}
|
|
11265
11405
|
const hired = [];
|
|
11266
11406
|
for (const payload of hireDirectives) {
|
|
11267
|
-
const id = `hire-${
|
|
11407
|
+
const id = `hire-${randomUUID6().slice(0, 8)}`;
|
|
11268
11408
|
const position = computeHirePosition(manager, scenario.nodes);
|
|
11269
11409
|
ensureGroupCanContainNode(scenario, manager.groupId ?? null, position);
|
|
11270
11410
|
const node = {
|
|
@@ -11703,7 +11843,7 @@ async function appendNodeOutput(conversationId, node, output) {
|
|
|
11703
11843
|
if (!dir) return;
|
|
11704
11844
|
const slug = node.label.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 60) || "member";
|
|
11705
11845
|
const safeId = node.id.replace(/[^a-z0-9_-]/gi, "-").slice(0, 80);
|
|
11706
|
-
const filePath =
|
|
11846
|
+
const filePath = join19(dir, `${slug}_${safeId}.md`);
|
|
11707
11847
|
const content = `## Output
|
|
11708
11848
|
|
|
11709
11849
|
${output}
|
|
@@ -11716,9 +11856,9 @@ async function appendToReadme(conversationId, bus, text) {
|
|
|
11716
11856
|
const line = `${text}
|
|
11717
11857
|
`;
|
|
11718
11858
|
try {
|
|
11719
|
-
await
|
|
11859
|
+
await mkdir16(dir, { recursive: true });
|
|
11720
11860
|
const { appendFile: appendFile2 } = await import("fs/promises");
|
|
11721
|
-
await appendFile2(
|
|
11861
|
+
await appendFile2(join19(dir, "README.md"), line, "utf-8");
|
|
11722
11862
|
} catch {
|
|
11723
11863
|
}
|
|
11724
11864
|
publishToBus(bus, { type: "readme_append", text: line });
|
|
@@ -11738,7 +11878,7 @@ async function writeFinalMd(conversationId, bus, userRequest, content) {
|
|
|
11738
11878
|
|
|
11739
11879
|
${content}
|
|
11740
11880
|
`;
|
|
11741
|
-
const filePath =
|
|
11881
|
+
const filePath = join19(dir, "FINAL.md");
|
|
11742
11882
|
await atomicWriteSecure(filePath, fullContent);
|
|
11743
11883
|
await appendToReadme(
|
|
11744
11884
|
conversationId,
|
|
@@ -12406,33 +12546,33 @@ Modify the scenario. Keep existing ids when possible.`;
|
|
|
12406
12546
|
return `Generate an scenario org-chart based on: ${userPrompt}`;
|
|
12407
12547
|
}
|
|
12408
12548
|
var ScopeShape2 = {
|
|
12409
|
-
orgId:
|
|
12549
|
+
orgId: z19.string().max(128).nullable().optional(),
|
|
12410
12550
|
projectId: Id128Schema.optional()
|
|
12411
12551
|
};
|
|
12412
12552
|
async function scopeOf2(input) {
|
|
12413
12553
|
return input?.orgId ?? await vaultOfProject(input?.projectId);
|
|
12414
12554
|
}
|
|
12415
12555
|
var scenarioRouter = router({
|
|
12416
|
-
list: protectedProcedure.input(
|
|
12417
|
-
get: protectedProcedure.input(
|
|
12556
|
+
list: protectedProcedure.input(z19.object(ScopeShape2).optional()).query(async ({ input }) => scenarioStore.list(await scopeOf2(input))),
|
|
12557
|
+
get: protectedProcedure.input(z19.object({ id: Id128Schema, ...ScopeShape2 })).query(async ({ input }) => getOrNotFound(
|
|
12418
12558
|
async () => scenarioStore.get(input.id, await scopeOf2(input)),
|
|
12419
12559
|
"Scenario not found"
|
|
12420
12560
|
)),
|
|
12421
|
-
create: protectedProcedure.input(
|
|
12561
|
+
create: protectedProcedure.input(z19.object({
|
|
12422
12562
|
name: NameSchema,
|
|
12423
|
-
icon:
|
|
12563
|
+
icon: z19.string().max(64).optional(),
|
|
12424
12564
|
description: DescriptionSchema.optional(),
|
|
12425
12565
|
leaderId: Id128Schema,
|
|
12426
|
-
groups:
|
|
12427
|
-
nodes:
|
|
12428
|
-
traversalMode:
|
|
12429
|
-
presetId:
|
|
12430
|
-
isPublished:
|
|
12566
|
+
groups: z19.array(ScenarioGroupSchema).max(100).optional(),
|
|
12567
|
+
nodes: z19.array(ScenarioNodeSchema).min(1).max(500),
|
|
12568
|
+
traversalMode: z19.enum(["hierarchical", "topological"]).optional(),
|
|
12569
|
+
presetId: z19.string().max(128).optional(),
|
|
12570
|
+
isPublished: z19.boolean().optional(),
|
|
12431
12571
|
...ScopeShape2
|
|
12432
12572
|
})).mutation(({ input }) => {
|
|
12433
12573
|
const now = Date.now();
|
|
12434
12574
|
return createOrBadRequest(async () => scenarioStore.create({
|
|
12435
|
-
id:
|
|
12575
|
+
id: randomUUID7(),
|
|
12436
12576
|
name: input.name,
|
|
12437
12577
|
icon: input.icon,
|
|
12438
12578
|
description: input.description,
|
|
@@ -12446,17 +12586,17 @@ var scenarioRouter = router({
|
|
|
12446
12586
|
updatedAt: now
|
|
12447
12587
|
}));
|
|
12448
12588
|
}),
|
|
12449
|
-
update: protectedProcedure.input(
|
|
12589
|
+
update: protectedProcedure.input(z19.object({
|
|
12450
12590
|
id: Id128Schema,
|
|
12451
12591
|
name: NameSchema.optional(),
|
|
12452
|
-
icon:
|
|
12592
|
+
icon: z19.string().max(64).optional(),
|
|
12453
12593
|
description: DescriptionSchema.optional(),
|
|
12454
12594
|
leaderId: Id128Schema.optional(),
|
|
12455
|
-
groups:
|
|
12456
|
-
nodes:
|
|
12457
|
-
traversalMode:
|
|
12458
|
-
presetId:
|
|
12459
|
-
isPublished:
|
|
12595
|
+
groups: z19.array(ScenarioGroupSchema).max(100).optional(),
|
|
12596
|
+
nodes: z19.array(ScenarioNodeSchema).min(1).max(500).optional(),
|
|
12597
|
+
traversalMode: z19.enum(["hierarchical", "topological"]).optional(),
|
|
12598
|
+
presetId: z19.string().max(128).optional(),
|
|
12599
|
+
isPublished: z19.boolean().optional(),
|
|
12460
12600
|
...ScopeShape2
|
|
12461
12601
|
})).mutation(({ input }) => updateOrThrow(
|
|
12462
12602
|
async () => scenarioStore.update(input.id, {
|
|
@@ -12473,22 +12613,22 @@ var scenarioRouter = router({
|
|
|
12473
12613
|
}, await scopeOf2(input)),
|
|
12474
12614
|
"Scenario not found"
|
|
12475
12615
|
)),
|
|
12476
|
-
delete: protectedProcedure.input(
|
|
12616
|
+
delete: protectedProcedure.input(z19.object({ id: Id128Schema, ...ScopeShape2 })).mutation(({ input }) => deleteOrNotFound(
|
|
12477
12617
|
async () => scenarioStore.delete(input.id, await scopeOf2(input)),
|
|
12478
12618
|
"Scenario not found"
|
|
12479
12619
|
)),
|
|
12480
|
-
run: protectedProcedure.input(
|
|
12620
|
+
run: protectedProcedure.input(z19.object({
|
|
12481
12621
|
conversationId: ConversationIdSchema,
|
|
12482
12622
|
scenarioId: Id128Schema,
|
|
12483
|
-
userRequest:
|
|
12484
|
-
runnerOverride:
|
|
12623
|
+
userRequest: z19.string().max(1e5),
|
|
12624
|
+
runnerOverride: z19.enum(["claude-code", "codex"]).optional(),
|
|
12485
12625
|
modelOverride: Id128Schema.optional(),
|
|
12486
12626
|
agentId: Id128Schema.optional(),
|
|
12487
12627
|
/** Anchors the run's working directory on the project it belongs to. */
|
|
12488
12628
|
projectId: Id128Schema.optional(),
|
|
12489
12629
|
/** Son organisation : sans elle, un id partagé désignerait un projet au hasard. */
|
|
12490
|
-
orgId:
|
|
12491
|
-
resume:
|
|
12630
|
+
orgId: z19.string().max(128).nullable().optional(),
|
|
12631
|
+
resume: z19.boolean().optional()
|
|
12492
12632
|
})).subscription(async function* ({ input, signal }) {
|
|
12493
12633
|
const scenario = await scenarioStore.get(input.scenarioId, await scopeOf2(input));
|
|
12494
12634
|
if (!scenario) throw new TRPCError16({ code: "NOT_FOUND", message: "Scenario not found" });
|
|
@@ -12508,41 +12648,41 @@ var scenarioRouter = router({
|
|
|
12508
12648
|
}
|
|
12509
12649
|
yield* tapBus(input.conversationId, signal ?? new AbortController().signal);
|
|
12510
12650
|
}),
|
|
12511
|
-
stop: protectedProcedure.input(
|
|
12651
|
+
stop: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).mutation(({ input }) => {
|
|
12512
12652
|
abortScenario(input.conversationId);
|
|
12513
12653
|
return { ok: true };
|
|
12514
12654
|
}),
|
|
12515
|
-
sendNodeInput: protectedProcedure.input(
|
|
12655
|
+
sendNodeInput: protectedProcedure.input(z19.object({
|
|
12516
12656
|
conversationId: ConversationIdSchema,
|
|
12517
12657
|
nodeId: Id128Schema,
|
|
12518
|
-
text:
|
|
12658
|
+
text: z19.string().min(1).max(1e5)
|
|
12519
12659
|
})).mutation(({ input }) => {
|
|
12520
12660
|
const resolved = resolveNodeInput(input.conversationId, input.nodeId, input.text);
|
|
12521
12661
|
if (!resolved) throw new TRPCError16({ code: "NOT_FOUND", message: "No pending input request for this node" });
|
|
12522
12662
|
return { ok: true };
|
|
12523
12663
|
}),
|
|
12524
|
-
isRunning: protectedProcedure.input(
|
|
12525
|
-
runState: protectedProcedure.input(
|
|
12664
|
+
isRunning: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).query(({ input }) => ({ running: isScenarioRunning(input.conversationId) })),
|
|
12665
|
+
runState: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).query(({ input }) => {
|
|
12526
12666
|
const runState = scenarioRunStore.getRunState(input.conversationId);
|
|
12527
12667
|
return runState ?? { nodeStates: {}, nodeOutputs: {}, activeNodeId: void 0 };
|
|
12528
12668
|
}),
|
|
12529
|
-
getPersistedRunState: protectedProcedure.input(
|
|
12669
|
+
getPersistedRunState: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).query(async ({ input }) => {
|
|
12530
12670
|
return await scenarioRunStore.loadPersistedRunState(input.conversationId);
|
|
12531
12671
|
}),
|
|
12532
|
-
getReadme: protectedProcedure.input(
|
|
12672
|
+
getReadme: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).query(async ({ input }) => {
|
|
12533
12673
|
return await scenarioRunStore.readReadme(input.conversationId);
|
|
12534
12674
|
}),
|
|
12535
|
-
getSnapshot: protectedProcedure.input(
|
|
12675
|
+
getSnapshot: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).query(async ({ input }) => {
|
|
12536
12676
|
return await scenarioRunStore.loadScenarioSnapshot(input.conversationId);
|
|
12537
12677
|
}),
|
|
12538
|
-
streamGenerateWithAI: protectedProcedure.input(
|
|
12539
|
-
prompt:
|
|
12678
|
+
streamGenerateWithAI: protectedProcedure.input(z19.object({
|
|
12679
|
+
prompt: z19.string().min(1).max(1e4),
|
|
12540
12680
|
providerId: OptionalProviderIdSchema,
|
|
12541
|
-
model:
|
|
12542
|
-
current:
|
|
12681
|
+
model: z19.string().max(200).optional(),
|
|
12682
|
+
current: z19.object({
|
|
12543
12683
|
leaderId: Id128Schema,
|
|
12544
|
-
groups:
|
|
12545
|
-
nodes:
|
|
12684
|
+
groups: z19.array(ScenarioGroupSchema).max(100),
|
|
12685
|
+
nodes: z19.array(ScenarioNodeSchema).max(500)
|
|
12546
12686
|
}).optional()
|
|
12547
12687
|
})).subscription(async function* ({ input, signal }) {
|
|
12548
12688
|
const userMessage = buildScenarioUserMessage(input.prompt, input.current);
|
|
@@ -12555,7 +12695,7 @@ var scenarioRouter = router({
|
|
|
12555
12695
|
signal: signal ?? void 0
|
|
12556
12696
|
});
|
|
12557
12697
|
}),
|
|
12558
|
-
streamRunEvents: protectedProcedure.input(
|
|
12698
|
+
streamRunEvents: protectedProcedure.input(z19.object({ conversationId: ConversationIdSchema })).subscription(async function* ({ input }) {
|
|
12559
12699
|
const convId = input.conversationId;
|
|
12560
12700
|
const runState = scenarioRunStore.getRunState(convId);
|
|
12561
12701
|
if (runState) {
|
|
@@ -12569,14 +12709,14 @@ var scenarioRouter = router({
|
|
|
12569
12709
|
* open a debug PTY with `claude --resume <sessionId>` on the right agent.
|
|
12570
12710
|
* Falls back to the persisted run-state for past nodes.
|
|
12571
12711
|
*/
|
|
12572
|
-
getNodeSession: protectedProcedure.input(
|
|
12712
|
+
getNodeSession: protectedProcedure.input(z19.object({
|
|
12573
12713
|
conversationId: ConversationIdSchema,
|
|
12574
12714
|
nodeId: Id128Schema
|
|
12575
12715
|
})).query(async ({ input }) => {
|
|
12576
12716
|
return await scenarioRunStore.getNodeSessionPersistent(input.conversationId, input.nodeId);
|
|
12577
12717
|
}),
|
|
12578
12718
|
listPresets: protectedProcedure.query(() => listPresets()),
|
|
12579
|
-
getPreset: protectedProcedure.input(
|
|
12719
|
+
getPreset: protectedProcedure.input(z19.object({ id: Id128Schema })).query(({ input }) => {
|
|
12580
12720
|
const preset = getPreset(input.id);
|
|
12581
12721
|
if (!preset) throw new TRPCError16({ code: "NOT_FOUND", message: "Preset not found" });
|
|
12582
12722
|
return preset;
|
|
@@ -12584,9 +12724,9 @@ var scenarioRouter = router({
|
|
|
12584
12724
|
});
|
|
12585
12725
|
|
|
12586
12726
|
// ../server/src/trpc/routers/debug.ts
|
|
12587
|
-
import { randomUUID as
|
|
12727
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
12588
12728
|
import { TRPCError as TRPCError17 } from "@trpc/server";
|
|
12589
|
-
import { z as
|
|
12729
|
+
import { z as z20 } from "zod";
|
|
12590
12730
|
var MAX_BUFFER3 = 300;
|
|
12591
12731
|
var jobs = /* @__PURE__ */ new Map();
|
|
12592
12732
|
function publish(job, event) {
|
|
@@ -12643,11 +12783,11 @@ async function* tapJob(job, signal) {
|
|
|
12643
12783
|
}
|
|
12644
12784
|
}
|
|
12645
12785
|
var debugRouter = router({
|
|
12646
|
-
startRandomJob: protectedProcedure.input(
|
|
12647
|
-
intervalMs:
|
|
12648
|
-
maxTicks:
|
|
12786
|
+
startRandomJob: protectedProcedure.input(z20.object({
|
|
12787
|
+
intervalMs: z20.number().int().min(100).max(5e3).optional(),
|
|
12788
|
+
maxTicks: z20.number().int().min(1).max(1e4).optional()
|
|
12649
12789
|
}).optional()).mutation(({ input }) => {
|
|
12650
|
-
const jobId =
|
|
12790
|
+
const jobId = randomUUID8();
|
|
12651
12791
|
const intervalMs = input?.intervalMs ?? 400;
|
|
12652
12792
|
const maxTicks = input?.maxTicks ?? 500;
|
|
12653
12793
|
const job = {
|
|
@@ -12679,15 +12819,15 @@ var debugRouter = router({
|
|
|
12679
12819
|
jobs.set(jobId, job);
|
|
12680
12820
|
return { jobId, intervalMs, maxTicks, startedAt: job.startedAt };
|
|
12681
12821
|
}),
|
|
12682
|
-
streamRandomJob: protectedProcedure.input(
|
|
12822
|
+
streamRandomJob: protectedProcedure.input(z20.object({ jobId: z20.string().max(128) })).subscription(async function* ({ input, signal }) {
|
|
12683
12823
|
const job = jobs.get(input.jobId);
|
|
12684
12824
|
if (!job) {
|
|
12685
12825
|
throw new TRPCError17({ code: "NOT_FOUND", message: "Random job not found" });
|
|
12686
12826
|
}
|
|
12687
12827
|
yield* tapJob(job, signal ?? new AbortController().signal);
|
|
12688
12828
|
}),
|
|
12689
|
-
stopRandomJob: protectedProcedure.input(
|
|
12690
|
-
randomJobStatus: protectedProcedure.input(
|
|
12829
|
+
stopRandomJob: protectedProcedure.input(z20.object({ jobId: z20.string().max(128) })).mutation(({ input }) => ({ ok: stopJob(input.jobId, "stopped") })),
|
|
12830
|
+
randomJobStatus: protectedProcedure.input(z20.object({ jobId: z20.string().max(128) })).query(({ input }) => {
|
|
12691
12831
|
const job = jobs.get(input.jobId);
|
|
12692
12832
|
return {
|
|
12693
12833
|
running: !!job && !job.done,
|
|
@@ -12698,6 +12838,7 @@ var debugRouter = router({
|
|
|
12698
12838
|
|
|
12699
12839
|
// ../server/src/trpc/routers/diagnostics.ts
|
|
12700
12840
|
import { z as z21 } from "zod";
|
|
12841
|
+
import { TRPCError as TRPCError18 } from "@trpc/server";
|
|
12701
12842
|
|
|
12702
12843
|
// ../server/src/services/log-buffer.ts
|
|
12703
12844
|
import { EventEmitter as EventEmitter4 } from "events";
|
|
@@ -12765,128 +12906,6 @@ function onEntry(listener) {
|
|
|
12765
12906
|
return () => emitter.off("entry", listener);
|
|
12766
12907
|
}
|
|
12767
12908
|
|
|
12768
|
-
// ../server/src/services/instance-registry.ts
|
|
12769
|
-
import { mkdir as mkdir16, readdir as readdir5, readFile as readFile15, writeFile as writeFile14, rm as rm3 } from "fs/promises";
|
|
12770
|
-
import { join as join19 } from "path";
|
|
12771
|
-
import { z as z20 } from "zod";
|
|
12772
|
-
var InstanceFileSchema = z20.object({
|
|
12773
|
-
pid: z20.number().int().positive(),
|
|
12774
|
-
port: z20.number().int().min(1).max(65535),
|
|
12775
|
-
agentPort: z20.number().int().min(1).max(65535),
|
|
12776
|
-
cwd: z20.string().max(4096),
|
|
12777
|
-
dataDir: z20.string().max(4096),
|
|
12778
|
-
version: z20.string().max(64),
|
|
12779
|
-
fromDesktop: z20.boolean(),
|
|
12780
|
-
startedAt: z20.number().int().nonnegative()
|
|
12781
|
-
});
|
|
12782
|
-
function registryDir() {
|
|
12783
|
-
return join19(machineRoot(), "instances");
|
|
12784
|
-
}
|
|
12785
|
-
function fileFor(pid) {
|
|
12786
|
-
return join19(registryDir(), `${pid}.json`);
|
|
12787
|
-
}
|
|
12788
|
-
function selfRecord() {
|
|
12789
|
-
return {
|
|
12790
|
-
pid: process.pid,
|
|
12791
|
-
port: env.PORT,
|
|
12792
|
-
agentPort: env.RUNEYA_AGENT_PORT,
|
|
12793
|
-
cwd: process.cwd(),
|
|
12794
|
-
dataDir: env.DATA_DIR,
|
|
12795
|
-
version: process.env["RUNEYA_VERSION"] ?? "unknown",
|
|
12796
|
-
fromDesktop: env.FROM_DESKTOP,
|
|
12797
|
-
startedAt: Date.now()
|
|
12798
|
-
};
|
|
12799
|
-
}
|
|
12800
|
-
async function registerInstance() {
|
|
12801
|
-
try {
|
|
12802
|
-
await mkdir16(registryDir(), { recursive: true });
|
|
12803
|
-
await writeFile14(fileFor(process.pid), JSON.stringify(selfRecord(), null, 2));
|
|
12804
|
-
} catch (err) {
|
|
12805
|
-
console.log("[instances] Could not register this instance:", err.message);
|
|
12806
|
-
}
|
|
12807
|
-
}
|
|
12808
|
-
async function unregisterInstance() {
|
|
12809
|
-
await rm3(fileFor(process.pid), { force: true }).catch(() => {
|
|
12810
|
-
});
|
|
12811
|
-
}
|
|
12812
|
-
function isProcessAlive(pid) {
|
|
12813
|
-
try {
|
|
12814
|
-
process.kill(pid, 0);
|
|
12815
|
-
return true;
|
|
12816
|
-
} catch (err) {
|
|
12817
|
-
return err.code === "EPERM";
|
|
12818
|
-
}
|
|
12819
|
-
}
|
|
12820
|
-
async function probe(port) {
|
|
12821
|
-
try {
|
|
12822
|
-
const res = await fetch(`http://127.0.0.1:${port}/api/trpc/health.check`, {
|
|
12823
|
-
signal: AbortSignal.timeout(1500)
|
|
12824
|
-
});
|
|
12825
|
-
if (!res.ok) return { ok: false, uptimeMs: null, version: null };
|
|
12826
|
-
const body = await res.json();
|
|
12827
|
-
const data = body.result?.data;
|
|
12828
|
-
return { ok: true, uptimeMs: data?.uptime ?? null, version: data?.version ?? null };
|
|
12829
|
-
} catch {
|
|
12830
|
-
return { ok: false, uptimeMs: null, version: null };
|
|
12831
|
-
}
|
|
12832
|
-
}
|
|
12833
|
-
async function listInstances() {
|
|
12834
|
-
let files;
|
|
12835
|
-
try {
|
|
12836
|
-
files = await readdir5(registryDir());
|
|
12837
|
-
} catch {
|
|
12838
|
-
return [];
|
|
12839
|
-
}
|
|
12840
|
-
const found = await Promise.all(
|
|
12841
|
-
files.filter((f) => f.endsWith(".json")).map(async (name) => {
|
|
12842
|
-
const path = join19(registryDir(), name);
|
|
12843
|
-
let record;
|
|
12844
|
-
try {
|
|
12845
|
-
const parsed = InstanceFileSchema.safeParse(JSON.parse(await readFile15(path, "utf8")));
|
|
12846
|
-
if (!parsed.success) {
|
|
12847
|
-
await rm3(path, { force: true }).catch(() => {
|
|
12848
|
-
});
|
|
12849
|
-
return null;
|
|
12850
|
-
}
|
|
12851
|
-
record = parsed.data;
|
|
12852
|
-
} catch {
|
|
12853
|
-
return null;
|
|
12854
|
-
}
|
|
12855
|
-
if (!isProcessAlive(record.pid)) {
|
|
12856
|
-
await rm3(path, { force: true }).catch(() => {
|
|
12857
|
-
});
|
|
12858
|
-
return null;
|
|
12859
|
-
}
|
|
12860
|
-
const { ok, uptimeMs, version } = await probe(record.port);
|
|
12861
|
-
if (!ok) {
|
|
12862
|
-
await rm3(path, { force: true }).catch(() => {
|
|
12863
|
-
});
|
|
12864
|
-
return null;
|
|
12865
|
-
}
|
|
12866
|
-
return {
|
|
12867
|
-
...record,
|
|
12868
|
-
// Trust the live answer over the file: the file was written at boot
|
|
12869
|
-
// and an upgraded instance would keep claiming its old version.
|
|
12870
|
-
version: version ?? record.version,
|
|
12871
|
-
reachable: true,
|
|
12872
|
-
current: record.pid === process.pid,
|
|
12873
|
-
uptimeMs
|
|
12874
|
-
};
|
|
12875
|
-
})
|
|
12876
|
-
);
|
|
12877
|
-
return dedupeByPort(found.filter((i) => i !== null)).sort((a, b) => Number(b.current) - Number(a.current) || a.port - b.port);
|
|
12878
|
-
}
|
|
12879
|
-
function dedupeByPort(instances) {
|
|
12880
|
-
const byPort = /* @__PURE__ */ new Map();
|
|
12881
|
-
for (const instance of instances) {
|
|
12882
|
-
const kept = byPort.get(instance.port);
|
|
12883
|
-
if (!kept || instance.current || !kept.current && instance.startedAt > kept.startedAt) {
|
|
12884
|
-
byPort.set(instance.port, instance);
|
|
12885
|
-
}
|
|
12886
|
-
}
|
|
12887
|
-
return [...byPort.values()];
|
|
12888
|
-
}
|
|
12889
|
-
|
|
12890
12909
|
// ../server/src/trpc/routers/diagnostics.ts
|
|
12891
12910
|
var diagnosticsRouter = router({
|
|
12892
12911
|
/** Backlog for a client that just opened the panel. */
|
|
@@ -12924,14 +12943,71 @@ var diagnosticsRouter = router({
|
|
|
12924
12943
|
}
|
|
12925
12944
|
}),
|
|
12926
12945
|
/** Every Runeya answering on this machine, this one included. */
|
|
12927
|
-
instances: protectedProcedure.query(() => listInstances())
|
|
12946
|
+
instances: protectedProcedure.query(() => listInstances()),
|
|
12947
|
+
/**
|
|
12948
|
+
* Stop another Runeya on this machine — its agent first, then its server.
|
|
12949
|
+
*
|
|
12950
|
+
* The pid is a *selector*, not an instruction: it is looked up in the list
|
|
12951
|
+
* `listInstances()` has just vouched for, and anything absent from it is
|
|
12952
|
+
* refused. That is what keeps this from being a way to signal arbitrary
|
|
12953
|
+
* processes with the server's privileges.
|
|
12954
|
+
*/
|
|
12955
|
+
killInstance: protectedProcedure.input(z21.object({ pid: z21.number().int().positive() })).mutation(async ({ input }) => {
|
|
12956
|
+
try {
|
|
12957
|
+
return await killInstance(input.pid);
|
|
12958
|
+
} catch (err) {
|
|
12959
|
+
const reason = err.message;
|
|
12960
|
+
if (reason === "instance-not-found") {
|
|
12961
|
+
throw new TRPCError18({ code: "NOT_FOUND", message: "No live Runeya instance with this pid." });
|
|
12962
|
+
}
|
|
12963
|
+
if (reason === "instance-is-current") {
|
|
12964
|
+
throw new TRPCError18({ code: "BAD_REQUEST", message: "This instance cannot stop itself." });
|
|
12965
|
+
}
|
|
12966
|
+
throw new TRPCError18({ code: "INTERNAL_SERVER_ERROR", message: reason });
|
|
12967
|
+
}
|
|
12968
|
+
}),
|
|
12969
|
+
/**
|
|
12970
|
+
* Redémarrer une Runeya de cette machine : même exécutable, mêmes arguments,
|
|
12971
|
+
* même répertoire, mêmes `RUNEYA_*`.
|
|
12972
|
+
*
|
|
12973
|
+
* Deux chemins pour une même promesse. Une autre instance est arrêtée puis
|
|
12974
|
+
* relancée d'ici, et la réponse dit ce qui s'est passé. Celle-ci ne peut pas :
|
|
12975
|
+
* elle répond d'abord, pose un relanceur détaché, et part — d'où un résultat
|
|
12976
|
+
* qui annonce un redémarrage à venir plutôt qu'un redémarrage fait.
|
|
12977
|
+
*
|
|
12978
|
+
* Mêmes garde-fous que `killInstance` — le pid est un sélecteur cherché dans
|
|
12979
|
+
* la liste validée — plus un refus propre quand le lancement n'est pas
|
|
12980
|
+
* reproductible : instance trop ancienne pour avoir publié sa ligne de
|
|
12981
|
+
* commande, ou lancée avec un secret que le registre ne conserve pas.
|
|
12982
|
+
*/
|
|
12983
|
+
restartInstance: protectedProcedure.input(z21.object({ pid: z21.number().int().positive() })).mutation(async ({ input }) => {
|
|
12984
|
+
try {
|
|
12985
|
+
if (input.pid === process.pid) {
|
|
12986
|
+
const { relauncherPid, port } = await scheduleSelfRestart();
|
|
12987
|
+
return { self: true, relauncherPid, port };
|
|
12988
|
+
}
|
|
12989
|
+
return { self: false, ...await restartInstance(input.pid) };
|
|
12990
|
+
} catch (err) {
|
|
12991
|
+
const reason = err.message;
|
|
12992
|
+
if (reason === "instance-not-found") {
|
|
12993
|
+
throw new TRPCError18({ code: "NOT_FOUND", message: "No live Runeya instance with this pid." });
|
|
12994
|
+
}
|
|
12995
|
+
if (reason.startsWith("instance-not-restartable:")) {
|
|
12996
|
+
throw new TRPCError18({
|
|
12997
|
+
code: "BAD_REQUEST",
|
|
12998
|
+
message: `This instance cannot be restarted (${reason.split(":")[1]}).`
|
|
12999
|
+
});
|
|
13000
|
+
}
|
|
13001
|
+
throw new TRPCError18({ code: "INTERNAL_SERVER_ERROR", message: reason });
|
|
13002
|
+
}
|
|
13003
|
+
})
|
|
12928
13004
|
});
|
|
12929
13005
|
|
|
12930
13006
|
// ../server/src/trpc/routers/kanban-queue.ts
|
|
12931
13007
|
import { z as z22 } from "zod";
|
|
12932
13008
|
|
|
12933
13009
|
// ../server/src/services/kanban-queue.ts
|
|
12934
|
-
import { randomUUID as
|
|
13010
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
12935
13011
|
import { EventEmitter as EventEmitter5 } from "events";
|
|
12936
13012
|
var KanbanQueueService = class extends EventEmitter5 {
|
|
12937
13013
|
items = [];
|
|
@@ -12959,7 +13035,7 @@ var KanbanQueueService = class extends EventEmitter5 {
|
|
|
12959
13035
|
return { id: alreadyRunning.id, addedAt: alreadyRunning.startedAt, ...item };
|
|
12960
13036
|
}
|
|
12961
13037
|
const queueItem = {
|
|
12962
|
-
id:
|
|
13038
|
+
id: randomUUID9(),
|
|
12963
13039
|
...item,
|
|
12964
13040
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12965
13041
|
};
|
|
@@ -13179,12 +13255,12 @@ var kanbanQueueRouter = router({
|
|
|
13179
13255
|
});
|
|
13180
13256
|
|
|
13181
13257
|
// ../server/src/trpc/routers/kanban.ts
|
|
13182
|
-
import { mkdir as mkdir17, readdir as
|
|
13258
|
+
import { mkdir as mkdir17, readdir as readdir5, rm as rm3, stat as stat5, writeFile as writeFile15 } from "fs/promises";
|
|
13183
13259
|
import { createHash } from "crypto";
|
|
13184
13260
|
import { tmpdir } from "os";
|
|
13185
13261
|
import { join as join20 } from "path";
|
|
13186
13262
|
import { z as z23 } from "zod";
|
|
13187
|
-
import { TRPCError as
|
|
13263
|
+
import { TRPCError as TRPCError19 } from "@trpc/server";
|
|
13188
13264
|
function summarizeCard(card, boardId, columnTitle) {
|
|
13189
13265
|
return {
|
|
13190
13266
|
boardId,
|
|
@@ -13239,10 +13315,10 @@ var ATTACHMENT_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
|
13239
13315
|
async function purgeStaleAttachments(dir, ttlMs = ATTACHMENT_CACHE_TTL_MS) {
|
|
13240
13316
|
try {
|
|
13241
13317
|
const cutoff = Date.now() - ttlMs;
|
|
13242
|
-
for (const name of await
|
|
13318
|
+
for (const name of await readdir5(dir)) {
|
|
13243
13319
|
const path = join20(dir, name);
|
|
13244
13320
|
const info = await stat5(path).catch(() => null);
|
|
13245
|
-
if (info && info.mtimeMs < cutoff) await
|
|
13321
|
+
if (info && info.mtimeMs < cutoff) await rm3(path, { force: true });
|
|
13246
13322
|
}
|
|
13247
13323
|
} catch {
|
|
13248
13324
|
}
|
|
@@ -13263,7 +13339,7 @@ async function storeAttachment(id, name, body, dirs = attachmentCacheDirs()) {
|
|
|
13263
13339
|
refusals.push(`${dir} (${err instanceof Error ? err.message : String(err)})`);
|
|
13264
13340
|
}
|
|
13265
13341
|
}
|
|
13266
|
-
throw new
|
|
13342
|
+
throw new TRPCError19({
|
|
13267
13343
|
code: "INTERNAL_SERVER_ERROR",
|
|
13268
13344
|
message: `Impossible d'\xE9crire la pi\xE8ce jointe sur cette machine. Emplacements essay\xE9s : ${refusals.join(" ; ")}. V\xE9rifiez les droits d'\xE9criture, ou l'espace disque.`
|
|
13269
13345
|
});
|
|
@@ -13420,7 +13496,7 @@ var kanbanRouter = router({
|
|
|
13420
13496
|
input.parentCardId ? { boardId: input.parentBoardId ?? input.boardId, cardId: input.parentCardId } : null
|
|
13421
13497
|
);
|
|
13422
13498
|
if (!ok) {
|
|
13423
|
-
throw new
|
|
13499
|
+
throw new TRPCError19({ code: "BAD_REQUEST", message: "The cloud refused the link (unknown card, or a cycle)." });
|
|
13424
13500
|
}
|
|
13425
13501
|
return { ok: true };
|
|
13426
13502
|
}),
|
|
@@ -13463,25 +13539,25 @@ var kanbanRouter = router({
|
|
|
13463
13539
|
downloadAttachment: protectedProcedure.input(z23.object({ attachmentId: z23.string().max(128) })).mutation(async ({ input }) => {
|
|
13464
13540
|
const id = input.attachmentId;
|
|
13465
13541
|
if (!ATTACHMENT_ID_REGEX.test(id)) {
|
|
13466
|
-
throw new
|
|
13542
|
+
throw new TRPCError19({ code: "BAD_REQUEST", message: "Invalid attachment id" });
|
|
13467
13543
|
}
|
|
13468
13544
|
const res = await cloudFetch2(`/api/kanban/file/${id}`, { timeoutMs: 12e4 });
|
|
13469
13545
|
if (res.status === 404) {
|
|
13470
|
-
throw new
|
|
13546
|
+
throw new TRPCError19({ code: "NOT_FOUND", message: `Attachment ${id} not found` });
|
|
13471
13547
|
}
|
|
13472
13548
|
if (!res.ok) {
|
|
13473
|
-
throw new
|
|
13549
|
+
throw new TRPCError19({
|
|
13474
13550
|
code: res.status === 403 ? "FORBIDDEN" : "INTERNAL_SERVER_ERROR",
|
|
13475
13551
|
message: `Cloud refused the attachment (HTTP ${res.status})`
|
|
13476
13552
|
});
|
|
13477
13553
|
}
|
|
13478
13554
|
const declared = Number(res.headers.get("content-length") ?? 0);
|
|
13479
13555
|
if (declared > MAX_ATTACHMENT_BYTES) {
|
|
13480
|
-
throw new
|
|
13556
|
+
throw new TRPCError19({ code: "PAYLOAD_TOO_LARGE", message: "Attachment too large to download" });
|
|
13481
13557
|
}
|
|
13482
13558
|
const body = Buffer.from(await res.arrayBuffer());
|
|
13483
13559
|
if (body.length > MAX_ATTACHMENT_BYTES) {
|
|
13484
|
-
throw new
|
|
13560
|
+
throw new TRPCError19({ code: "PAYLOAD_TOO_LARGE", message: "Attachment too large to download" });
|
|
13485
13561
|
}
|
|
13486
13562
|
const contentType = res.headers.get("content-type") ?? "application/octet-stream";
|
|
13487
13563
|
const disposition = res.headers.get("content-disposition") ?? "";
|
|
@@ -13494,7 +13570,7 @@ var kanbanRouter = router({
|
|
|
13494
13570
|
|
|
13495
13571
|
// ../server/src/trpc/routers/terminal.ts
|
|
13496
13572
|
import { z as z24 } from "zod";
|
|
13497
|
-
import { TRPCError as
|
|
13573
|
+
import { TRPCError as TRPCError20 } from "@trpc/server";
|
|
13498
13574
|
var terminalRouter = router({
|
|
13499
13575
|
/** Create a PTY shell session on the target agent */
|
|
13500
13576
|
create: protectedProcedure.input(z24.object({
|
|
@@ -13506,7 +13582,8 @@ var terminalRouter = router({
|
|
|
13506
13582
|
/** L'organisation du projet : un id seul peut en nommer un par organisation. */
|
|
13507
13583
|
orgId: z24.string().max(128).nullable().optional(),
|
|
13508
13584
|
cols: z24.number().int().min(1).max(512).optional(),
|
|
13509
|
-
rows: z24.number().int().min(1).max(256).optional()
|
|
13585
|
+
rows: z24.number().int().min(1).max(256).optional(),
|
|
13586
|
+
title: z24.string().max(128).optional()
|
|
13510
13587
|
})).mutation(async ({ input }) => {
|
|
13511
13588
|
const result = await agentManager.agentMutation(
|
|
13512
13589
|
input.agentId,
|
|
@@ -13520,11 +13597,32 @@ var terminalRouter = router({
|
|
|
13520
13597
|
orgId: input.orgId
|
|
13521
13598
|
}),
|
|
13522
13599
|
cols: input.cols,
|
|
13523
|
-
rows: input.rows
|
|
13600
|
+
rows: input.rows,
|
|
13601
|
+
title: input.title
|
|
13524
13602
|
}
|
|
13525
13603
|
);
|
|
13526
13604
|
return result;
|
|
13527
13605
|
}),
|
|
13606
|
+
/** Les sessions PTY encore vivantes sur l'agent (onglets à retrouver) */
|
|
13607
|
+
list: protectedProcedure.input(z24.object({ agentId: z24.string().max(128) })).query(async ({ input }) => {
|
|
13608
|
+
return agentManager.agentQuery(
|
|
13609
|
+
input.agentId,
|
|
13610
|
+
"terminal.list"
|
|
13611
|
+
);
|
|
13612
|
+
}),
|
|
13613
|
+
/** Renommer un onglet */
|
|
13614
|
+
rename: protectedProcedure.input(z24.object({
|
|
13615
|
+
agentId: z24.string().max(128),
|
|
13616
|
+
sessionId: z24.string().max(128),
|
|
13617
|
+
title: z24.string().max(128)
|
|
13618
|
+
})).mutation(async ({ input }) => {
|
|
13619
|
+
await agentManager.agentMutation(
|
|
13620
|
+
input.agentId,
|
|
13621
|
+
"terminal.rename",
|
|
13622
|
+
{ sessionId: input.sessionId, title: input.title }
|
|
13623
|
+
);
|
|
13624
|
+
return { ok: true };
|
|
13625
|
+
}),
|
|
13528
13626
|
/** Send keystrokes / data to a PTY session */
|
|
13529
13627
|
write: protectedProcedure.input(z24.object({
|
|
13530
13628
|
agentId: z24.string().max(128),
|
|
@@ -13567,7 +13665,9 @@ var terminalRouter = router({
|
|
|
13567
13665
|
/** Stream PTY output — proxied via AgentWSBridge dynamic subscription */
|
|
13568
13666
|
onData: protectedProcedure.input(z24.object({
|
|
13569
13667
|
agentId: z24.string().max(128),
|
|
13570
|
-
sessionId: z24.string().max(128)
|
|
13668
|
+
sessionId: z24.string().max(128),
|
|
13669
|
+
/** Rejouer l'historique de la session avant le flux temps réel. */
|
|
13670
|
+
replay: z24.boolean().optional()
|
|
13571
13671
|
})).subscription(async function* ({ input }) {
|
|
13572
13672
|
const queue = [];
|
|
13573
13673
|
let resolve7 = null;
|
|
@@ -13577,7 +13677,7 @@ var terminalRouter = router({
|
|
|
13577
13677
|
unsubscribe = agentManager.agentSubscribe(
|
|
13578
13678
|
input.agentId,
|
|
13579
13679
|
"terminal.onData",
|
|
13580
|
-
{ sessionId: input.sessionId },
|
|
13680
|
+
{ sessionId: input.sessionId, replay: input.replay },
|
|
13581
13681
|
(data) => {
|
|
13582
13682
|
if (typeof data === "string") queue.push(data);
|
|
13583
13683
|
if (resolve7) {
|
|
@@ -13594,7 +13694,7 @@ var terminalRouter = router({
|
|
|
13594
13694
|
}
|
|
13595
13695
|
);
|
|
13596
13696
|
} catch (err) {
|
|
13597
|
-
throw new
|
|
13697
|
+
throw new TRPCError20({
|
|
13598
13698
|
code: "BAD_REQUEST",
|
|
13599
13699
|
message: `Cannot subscribe to terminal: ${err.message}`
|
|
13600
13700
|
});
|
|
@@ -13629,8 +13729,8 @@ var utilityRouter = router({
|
|
|
13629
13729
|
|
|
13630
13730
|
// ../server/src/trpc/routers/wiki.ts
|
|
13631
13731
|
import { z as z26 } from "zod";
|
|
13632
|
-
import { TRPCError as
|
|
13633
|
-
import { readFile as readFile16, readdir as
|
|
13732
|
+
import { TRPCError as TRPCError21 } from "@trpc/server";
|
|
13733
|
+
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";
|
|
13634
13734
|
import { resolve as resolvePath, join as join21, relative, sep as sep3, dirname as dirname9 } from "path";
|
|
13635
13735
|
var SCOPE_SCHEMA = z26.union([
|
|
13636
13736
|
z26.literal("global"),
|
|
@@ -13665,27 +13765,27 @@ async function resolveScope(scope) {
|
|
|
13665
13765
|
const settings = await settingsManager.getSettings();
|
|
13666
13766
|
const sub = (settings.globalDocsPath?.trim() || "wiki").replace(/^[\\/]+|[\\/]+$/g, "");
|
|
13667
13767
|
if (sub.includes("..") || sub.includes("\0")) {
|
|
13668
|
-
throw new
|
|
13768
|
+
throw new TRPCError21({ code: "BAD_REQUEST", message: "Sous-chemin invalide" });
|
|
13669
13769
|
}
|
|
13670
13770
|
const dataDirAbs = resolvePath(env.DATA_DIR);
|
|
13671
13771
|
await mkdir18(dataDirAbs, { recursive: true });
|
|
13672
13772
|
const base = dirname9(await realpath(dataDirAbs));
|
|
13673
13773
|
const target = resolvePath(base, sub);
|
|
13674
13774
|
if (target !== base && !(target + sep3).startsWith(base + sep3)) {
|
|
13675
|
-
throw new
|
|
13775
|
+
throw new TRPCError21({ code: "FORBIDDEN", message: "Hors du dossier de donn\xE9es du serveur" });
|
|
13676
13776
|
}
|
|
13677
13777
|
await mkdir18(target, { recursive: true });
|
|
13678
13778
|
const root = await realpath(target);
|
|
13679
13779
|
if (root !== base && !(root + sep3).startsWith(base + sep3)) {
|
|
13680
|
-
throw new
|
|
13780
|
+
throw new TRPCError21({ code: "FORBIDDEN", message: "Le dossier wiki r\xE9sout hors du dossier de donn\xE9es" });
|
|
13681
13781
|
}
|
|
13682
13782
|
return { mode: "local", root };
|
|
13683
13783
|
}
|
|
13684
13784
|
const serviceId = scope.slice("service:".length);
|
|
13685
13785
|
const service = await serviceStore.get(serviceId);
|
|
13686
|
-
if (!service) throw new
|
|
13786
|
+
if (!service) throw new TRPCError21({ code: "NOT_FOUND", message: "Service introuvable" });
|
|
13687
13787
|
const agentId = await resolveEffectiveAgentId(service);
|
|
13688
|
-
if (!agentId) throw new
|
|
13788
|
+
if (!agentId) throw new TRPCError21({ code: "BAD_REQUEST", message: "Aucun agent configur\xE9 pour ce service" });
|
|
13689
13789
|
const cwd = await resolveWorkspaceCwd({ serviceId, override: service.docsPath?.trim() || void 0 });
|
|
13690
13790
|
return { mode: "agent", agentId, cwd };
|
|
13691
13791
|
}
|
|
@@ -13693,7 +13793,7 @@ async function walkLocal(root, dir, depth, counter) {
|
|
|
13693
13793
|
if (depth > MAX_DEPTH || counter.n >= MAX_FILES) return [];
|
|
13694
13794
|
let entries2;
|
|
13695
13795
|
try {
|
|
13696
|
-
entries2 = await
|
|
13796
|
+
entries2 = await readdir6(dir, { withFileTypes: true });
|
|
13697
13797
|
} catch {
|
|
13698
13798
|
return [];
|
|
13699
13799
|
}
|
|
@@ -13720,7 +13820,7 @@ async function walkLocal(root, dir, depth, counter) {
|
|
|
13720
13820
|
}
|
|
13721
13821
|
async function resolveSafeLocal(root, relPath, requireExist) {
|
|
13722
13822
|
if (relPath.includes("..") || relPath.startsWith("/")) {
|
|
13723
|
-
throw new
|
|
13823
|
+
throw new TRPCError21({ code: "BAD_REQUEST", message: "Chemin invalide" });
|
|
13724
13824
|
}
|
|
13725
13825
|
const target = resolvePath(root, relPath);
|
|
13726
13826
|
if (requireExist) {
|
|
@@ -13728,10 +13828,10 @@ async function resolveSafeLocal(root, relPath, requireExist) {
|
|
|
13728
13828
|
try {
|
|
13729
13829
|
real = await realpath(target);
|
|
13730
13830
|
} catch {
|
|
13731
|
-
throw new
|
|
13831
|
+
throw new TRPCError21({ code: "NOT_FOUND", message: "Chemin introuvable" });
|
|
13732
13832
|
}
|
|
13733
13833
|
if (real !== root && !(real + sep3).startsWith(root + sep3)) {
|
|
13734
|
-
throw new
|
|
13834
|
+
throw new TRPCError21({ code: "FORBIDDEN", message: "Hors du dossier autoris\xE9" });
|
|
13735
13835
|
}
|
|
13736
13836
|
return real;
|
|
13737
13837
|
}
|
|
@@ -13743,7 +13843,7 @@ async function resolveSafeLocal(root, relPath, requireExist) {
|
|
|
13743
13843
|
realParent = parent;
|
|
13744
13844
|
}
|
|
13745
13845
|
if (realParent !== root && !(realParent + sep3).startsWith(root + sep3)) {
|
|
13746
|
-
throw new
|
|
13846
|
+
throw new TRPCError21({ code: "FORBIDDEN", message: "Hors du dossier autoris\xE9" });
|
|
13747
13847
|
}
|
|
13748
13848
|
return resolvePath(realParent, target.slice(parent.length).replace(/^[\\/]+/, ""));
|
|
13749
13849
|
}
|
|
@@ -13759,7 +13859,7 @@ var wikiRouter = router({
|
|
|
13759
13859
|
}),
|
|
13760
13860
|
read: protectedProcedure.input(z26.object({ scope: SCOPE_SCHEMA, path: REL_PATH_SCHEMA })).output(z26.object({ path: z26.string(), content: z26.string() })).query(async ({ input }) => {
|
|
13761
13861
|
if (!/\.(md|markdown)$/i.test(input.path)) {
|
|
13762
|
-
throw new
|
|
13862
|
+
throw new TRPCError21({ code: "BAD_REQUEST", message: "Seuls les .md/.markdown sont autoris\xE9s" });
|
|
13763
13863
|
}
|
|
13764
13864
|
const target = await resolveScope(input.scope);
|
|
13765
13865
|
if (target.mode === "agent") {
|
|
@@ -13767,14 +13867,14 @@ var wikiRouter = router({
|
|
|
13767
13867
|
}
|
|
13768
13868
|
const file = await resolveSafeLocal(target.root, input.path, true);
|
|
13769
13869
|
const s = await stat6(file);
|
|
13770
|
-
if (!s.isFile()) throw new
|
|
13771
|
-
if (s.size > MAX_FILE_BYTES) throw new
|
|
13870
|
+
if (!s.isFile()) throw new TRPCError21({ code: "BAD_REQUEST", message: "Pas un fichier" });
|
|
13871
|
+
if (s.size > MAX_FILE_BYTES) throw new TRPCError21({ code: "PAYLOAD_TOO_LARGE", message: "Fichier trop volumineux" });
|
|
13772
13872
|
const content = await readFile16(file, "utf-8");
|
|
13773
13873
|
return { path: input.path, content };
|
|
13774
13874
|
}),
|
|
13775
13875
|
write: protectedProcedure.input(z26.object({ scope: SCOPE_SCHEMA, path: REL_PATH_SCHEMA, content: z26.string().max(5e6) })).mutation(async ({ input }) => {
|
|
13776
13876
|
if (!/\.(md|markdown)$/i.test(input.path)) {
|
|
13777
|
-
throw new
|
|
13877
|
+
throw new TRPCError21({ code: "BAD_REQUEST", message: "Seuls les .md/.markdown sont autoris\xE9s" });
|
|
13778
13878
|
}
|
|
13779
13879
|
const target = await resolveScope(input.scope);
|
|
13780
13880
|
if (target.mode === "agent") {
|
|
@@ -13787,7 +13887,7 @@ var wikiRouter = router({
|
|
|
13787
13887
|
}),
|
|
13788
13888
|
createFile: protectedProcedure.input(z26.object({ scope: SCOPE_SCHEMA, path: REL_PATH_SCHEMA })).mutation(async ({ input }) => {
|
|
13789
13889
|
if (!/\.(md|markdown)$/i.test(input.path)) {
|
|
13790
|
-
throw new
|
|
13890
|
+
throw new TRPCError21({ code: "BAD_REQUEST", message: "Seuls les .md/.markdown sont autoris\xE9s" });
|
|
13791
13891
|
}
|
|
13792
13892
|
const target = await resolveScope(input.scope);
|
|
13793
13893
|
if (target.mode === "agent") {
|
|
@@ -13796,9 +13896,9 @@ var wikiRouter = router({
|
|
|
13796
13896
|
const file = await resolveSafeLocal(target.root, input.path, false);
|
|
13797
13897
|
try {
|
|
13798
13898
|
await stat6(file);
|
|
13799
|
-
throw new
|
|
13899
|
+
throw new TRPCError21({ code: "CONFLICT", message: "Fichier d\xE9j\xE0 existant" });
|
|
13800
13900
|
} catch (err) {
|
|
13801
|
-
if (err instanceof
|
|
13901
|
+
if (err instanceof TRPCError21) throw err;
|
|
13802
13902
|
}
|
|
13803
13903
|
await mkdir18(dirname9(file), { recursive: true });
|
|
13804
13904
|
await writeFile16(file, "", "utf-8");
|
|
@@ -13822,12 +13922,12 @@ var wikiRouter = router({
|
|
|
13822
13922
|
const to = await resolveSafeLocal(target.root, input.toPath, false);
|
|
13823
13923
|
try {
|
|
13824
13924
|
await stat6(to);
|
|
13825
|
-
throw new
|
|
13925
|
+
throw new TRPCError21({ code: "CONFLICT", message: "La cible existe d\xE9j\xE0" });
|
|
13826
13926
|
} catch (err) {
|
|
13827
|
-
if (err instanceof
|
|
13927
|
+
if (err instanceof TRPCError21) throw err;
|
|
13828
13928
|
}
|
|
13829
13929
|
await mkdir18(dirname9(to), { recursive: true });
|
|
13830
|
-
await
|
|
13930
|
+
await rename13(from, to);
|
|
13831
13931
|
return { fromPath: input.fromPath, toPath: input.toPath, ok: true };
|
|
13832
13932
|
}),
|
|
13833
13933
|
ensureRoot: protectedProcedure.input(z26.object({ scope: SCOPE_SCHEMA })).mutation(async ({ input }) => {
|
|
@@ -13837,9 +13937,9 @@ var wikiRouter = router({
|
|
|
13837
13937
|
}
|
|
13838
13938
|
const serviceId = input.scope.slice("service:".length);
|
|
13839
13939
|
const service = await serviceStore.get(serviceId);
|
|
13840
|
-
if (!service) throw new
|
|
13940
|
+
if (!service) throw new TRPCError21({ code: "NOT_FOUND", message: "Service introuvable" });
|
|
13841
13941
|
const agentId = await resolveEffectiveAgentId(service);
|
|
13842
|
-
if (!agentId) throw new
|
|
13942
|
+
if (!agentId) throw new TRPCError21({ code: "BAD_REQUEST", message: "Aucun agent configur\xE9" });
|
|
13843
13943
|
const cwd = await resolveWorkspaceCwd({ serviceId, override: service.docsPath?.trim() || void 0 });
|
|
13844
13944
|
return agentManager.agentMutation(agentId, "wiki.ensureRoot", { cwd });
|
|
13845
13945
|
}),
|
|
@@ -13849,8 +13949,8 @@ var wikiRouter = router({
|
|
|
13849
13949
|
return agentManager.agentMutation(target.agentId, "wiki.deletePath", { cwd: target.cwd, path: input.path });
|
|
13850
13950
|
}
|
|
13851
13951
|
const fp = await resolveSafeLocal(target.root, input.path, true);
|
|
13852
|
-
if (fp === target.root) throw new
|
|
13853
|
-
await
|
|
13952
|
+
if (fp === target.root) throw new TRPCError21({ code: "FORBIDDEN", message: "Impossible de supprimer la racine" });
|
|
13953
|
+
await rm4(fp, { recursive: true, force: true });
|
|
13854
13954
|
return { path: input.path, ok: true };
|
|
13855
13955
|
})
|
|
13856
13956
|
});
|
|
@@ -13870,7 +13970,7 @@ var configRouter = router({
|
|
|
13870
13970
|
|
|
13871
13971
|
// ../server/src/trpc/routers/cloud-sync.ts
|
|
13872
13972
|
import { z as z27 } from "zod";
|
|
13873
|
-
import { TRPCError as
|
|
13973
|
+
import { TRPCError as TRPCError22 } from "@trpc/server";
|
|
13874
13974
|
|
|
13875
13975
|
// ../server/src/services/org-sync-scope.ts
|
|
13876
13976
|
import { access as access2 } from "fs/promises";
|
|
@@ -13937,8 +14037,8 @@ async function reconcileOrgCanary(orgId) {
|
|
|
13937
14037
|
}
|
|
13938
14038
|
|
|
13939
14039
|
// ../server/src/services/cloud-sync-bridge.ts
|
|
13940
|
-
import { randomUUID as
|
|
13941
|
-
import { mkdir as mkdir20, rm as
|
|
14040
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
14041
|
+
import { mkdir as mkdir20, rm as rm5 } from "fs/promises";
|
|
13942
14042
|
import * as Y from "yjs";
|
|
13943
14043
|
|
|
13944
14044
|
// ../server/src/services/org-lock.ts
|
|
@@ -14051,7 +14151,7 @@ var OrgSyncConnection = class {
|
|
|
14051
14151
|
projects = getCollection(this.doc, "projects");
|
|
14052
14152
|
services = getCollection(this.doc, "services");
|
|
14053
14153
|
environments = getCollection(this.doc, "environments");
|
|
14054
|
-
conn =
|
|
14154
|
+
conn = randomUUID10();
|
|
14055
14155
|
link;
|
|
14056
14156
|
stopped = false;
|
|
14057
14157
|
initializing = true;
|
|
@@ -14395,7 +14495,7 @@ var OrgSyncConnection = class {
|
|
|
14395
14495
|
async unfollowProject(projectId) {
|
|
14396
14496
|
this.tracked.delete(projectId);
|
|
14397
14497
|
await projectStore.forgetLocally({ id: projectId, orgId: this.link.orgId });
|
|
14398
|
-
await
|
|
14498
|
+
await rm5(projectVaultRoot(this.link.orgId, projectId), { recursive: true, force: true }).catch(() => {
|
|
14399
14499
|
});
|
|
14400
14500
|
}
|
|
14401
14501
|
/**
|
|
@@ -14755,7 +14855,7 @@ var CloudSyncBridge = class {
|
|
|
14755
14855
|
var cloudSyncBridge = new CloudSyncBridge();
|
|
14756
14856
|
|
|
14757
14857
|
// ../server/src/services/key-adoption.ts
|
|
14758
|
-
import { readdir as
|
|
14858
|
+
import { readdir as readdir7, readFile as readFile18, writeFile as writeFile17, mkdir as mkdir21, copyFile, rename as rename14, stat as stat7 } from "fs/promises";
|
|
14759
14859
|
import { join as join24 } from "path";
|
|
14760
14860
|
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes5 } from "crypto";
|
|
14761
14861
|
var ALGORITHM = "aes-256-gcm";
|
|
@@ -14813,7 +14913,7 @@ async function rootsOfOrg(orgId) {
|
|
|
14813
14913
|
}
|
|
14814
14914
|
async function jsonFilesIn(root) {
|
|
14815
14915
|
try {
|
|
14816
|
-
const entries2 = await
|
|
14916
|
+
const entries2 = await readdir7(root, { withFileTypes: true });
|
|
14817
14917
|
return entries2.filter((e) => e.isFile() && e.name.endsWith(".json")).map((e) => e.name);
|
|
14818
14918
|
} catch {
|
|
14819
14919
|
return [];
|
|
@@ -14868,7 +14968,7 @@ async function adoptOrgKey(orgId, newKey, masterPassword, now) {
|
|
|
14868
14968
|
for (const item of pending) {
|
|
14869
14969
|
const tmp = item.path + ".tmp";
|
|
14870
14970
|
await writeFile17(tmp, item.content, "utf-8");
|
|
14871
|
-
await
|
|
14971
|
+
await rename14(tmp, item.path);
|
|
14872
14972
|
}
|
|
14873
14973
|
await installOrgKey(orgId, newKey, masterPassword);
|
|
14874
14974
|
clearVaultLock(orgId);
|
|
@@ -14899,7 +14999,7 @@ async function assertOrgReadable(orgId) {
|
|
|
14899
14999
|
await assertOrgVaultReadable(orgId);
|
|
14900
15000
|
} catch (err) {
|
|
14901
15001
|
if (err instanceof OrgVaultUnreadableError) {
|
|
14902
|
-
throw new
|
|
15002
|
+
throw new TRPCError22({ code: "FORBIDDEN", message: err.message });
|
|
14903
15003
|
}
|
|
14904
15004
|
throw err;
|
|
14905
15005
|
}
|
|
@@ -14909,10 +15009,10 @@ async function assertOrgKey(orgId) {
|
|
|
14909
15009
|
await reconcileOrgCanary(orgId);
|
|
14910
15010
|
} catch (err) {
|
|
14911
15011
|
if (err instanceof OrgKeyMismatchError) {
|
|
14912
|
-
throw new
|
|
15012
|
+
throw new TRPCError22({ code: "FORBIDDEN", message: err.message });
|
|
14913
15013
|
}
|
|
14914
15014
|
if (err instanceof CanaryUnavailableError) {
|
|
14915
|
-
throw new
|
|
15015
|
+
throw new TRPCError22({ code: "PRECONDITION_FAILED", message: err.message });
|
|
14916
15016
|
}
|
|
14917
15017
|
throw err;
|
|
14918
15018
|
}
|
|
@@ -14947,7 +15047,7 @@ var cloudSyncRouter = router({
|
|
|
14947
15047
|
return { pulled, state: syncState(input.orgId) };
|
|
14948
15048
|
} catch (err) {
|
|
14949
15049
|
if (err instanceof ProjectHeldElsewhereError) {
|
|
14950
|
-
throw new
|
|
15050
|
+
throw new TRPCError22({ code: "CONFLICT", message: err.code, cause: err });
|
|
14951
15051
|
}
|
|
14952
15052
|
throw err;
|
|
14953
15053
|
}
|
|
@@ -14974,10 +15074,10 @@ var cloudSyncRouter = router({
|
|
|
14974
15074
|
).mutation(async ({ input }) => {
|
|
14975
15075
|
const local = await projectStore.get({ id: input.projectId, orgId: null });
|
|
14976
15076
|
if (!local) {
|
|
14977
|
-
throw new
|
|
15077
|
+
throw new TRPCError22({ code: "NOT_FOUND", message: "PROJECT_NOT_LOCAL" });
|
|
14978
15078
|
}
|
|
14979
15079
|
if (await projectStore.get({ id: input.projectId, orgId: input.orgId })) {
|
|
14980
|
-
throw new
|
|
15080
|
+
throw new TRPCError22({ code: "CONFLICT", message: "PROJECT_ALREADY_IN_ORG" });
|
|
14981
15081
|
}
|
|
14982
15082
|
await assertOrgReadable(input.orgId);
|
|
14983
15083
|
const connected = cloudSyncBridge.states().some((s) => s.orgId === input.orgId);
|
|
@@ -14996,7 +15096,7 @@ var cloudSyncRouter = router({
|
|
|
14996
15096
|
await cloudSyncBridge.followProject(input.orgId, input.projectId);
|
|
14997
15097
|
} catch (err) {
|
|
14998
15098
|
if (err instanceof ProjectHeldElsewhereError) {
|
|
14999
|
-
throw new
|
|
15099
|
+
throw new TRPCError22({ code: "CONFLICT", message: err.code, cause: err });
|
|
15000
15100
|
}
|
|
15001
15101
|
throw err;
|
|
15002
15102
|
}
|
|
@@ -15019,7 +15119,7 @@ var cloudSyncRouter = router({
|
|
|
15019
15119
|
{ method: "GET" }
|
|
15020
15120
|
);
|
|
15021
15121
|
if (!res.ok) {
|
|
15022
|
-
throw new
|
|
15122
|
+
throw new TRPCError22({ code: "BAD_GATEWAY", message: await cloudMessage(res) || `CANARY_READ_FAILED (${res.status})` });
|
|
15023
15123
|
}
|
|
15024
15124
|
const { canary } = await res.json();
|
|
15025
15125
|
if (typeof canary !== "string") return { matches: false, published: false };
|
|
@@ -15065,7 +15165,7 @@ var cloudSyncRouter = router({
|
|
|
15065
15165
|
resetOrgKey: protectedProcedure.input(z27.object({ orgId: z27.string().min(1).max(128) })).mutation(async ({ input }) => {
|
|
15066
15166
|
const canary = await readVerifyFile(await keyRoot());
|
|
15067
15167
|
if (!canary) {
|
|
15068
|
-
throw new
|
|
15168
|
+
throw new TRPCError22({
|
|
15069
15169
|
code: "PRECONDITION_FAILED",
|
|
15070
15170
|
message: "Cette machine n'a pas encore de cl\xE9 de chiffrement."
|
|
15071
15171
|
});
|
|
@@ -15076,7 +15176,7 @@ var cloudSyncRouter = router({
|
|
|
15076
15176
|
});
|
|
15077
15177
|
if (!res.ok) {
|
|
15078
15178
|
const detail = await cloudMessage(res);
|
|
15079
|
-
throw new
|
|
15179
|
+
throw new TRPCError22({
|
|
15080
15180
|
code: res.status === 403 ? "FORBIDDEN" : "BAD_GATEWAY",
|
|
15081
15181
|
message: detail || `ORG_KEY_RESET_FAILED (${res.status})`
|
|
15082
15182
|
});
|
|
@@ -15122,8 +15222,8 @@ var cloudSyncRouter = router({
|
|
|
15122
15222
|
body: { organizationId: input.orgId, projectId: input.projectId }
|
|
15123
15223
|
});
|
|
15124
15224
|
} catch (err) {
|
|
15125
|
-
if (err instanceof
|
|
15126
|
-
throw new
|
|
15225
|
+
if (err instanceof TRPCError22 && err.code === "PRECONDITION_FAILED") {
|
|
15226
|
+
throw new TRPCError22({ code: "PRECONDITION_FAILED", message: "CLOUD_NOT_LINKED" });
|
|
15127
15227
|
}
|
|
15128
15228
|
throw err;
|
|
15129
15229
|
}
|
|
@@ -15131,12 +15231,12 @@ var cloudSyncRouter = router({
|
|
|
15131
15231
|
const detail = await cloudMessage(res);
|
|
15132
15232
|
if (res.status === 403) {
|
|
15133
15233
|
const code = /not a member/i.test(detail) ? "PROJECT_NOT_MEMBER" : "PROJECT_DELETE_FORBIDDEN";
|
|
15134
|
-
throw new
|
|
15234
|
+
throw new TRPCError22({ code: "FORBIDDEN", message: code, cause: new Error(detail) });
|
|
15135
15235
|
}
|
|
15136
15236
|
if (res.status === 404) {
|
|
15137
|
-
throw new
|
|
15237
|
+
throw new TRPCError22({ code: "NOT_FOUND", message: "PROJECT_NOT_IN_ORG", cause: new Error(detail) });
|
|
15138
15238
|
}
|
|
15139
|
-
throw new
|
|
15239
|
+
throw new TRPCError22({
|
|
15140
15240
|
code: "BAD_GATEWAY",
|
|
15141
15241
|
message: detail || `PROJECT_DELETE_FAILED (${res.status})`
|
|
15142
15242
|
});
|
|
@@ -15193,7 +15293,7 @@ var cloudSyncRouter = router({
|
|
|
15193
15293
|
});
|
|
15194
15294
|
|
|
15195
15295
|
// ../server/src/trpc/routers/filesystem.ts
|
|
15196
|
-
import { readdir as
|
|
15296
|
+
import { readdir as readdir8, stat as stat8 } from "fs/promises";
|
|
15197
15297
|
import { homedir as homedir5 } from "os";
|
|
15198
15298
|
import { isAbsolute as isAbsolute4, join as join25, resolve as resolve5, dirname as dirname10, basename as basename2 } from "path";
|
|
15199
15299
|
import { z as z28 } from "zod";
|
|
@@ -15230,7 +15330,7 @@ var filesystemRouter = router({
|
|
|
15230
15330
|
}
|
|
15231
15331
|
let names;
|
|
15232
15332
|
try {
|
|
15233
|
-
names = (await
|
|
15333
|
+
names = (await readdir8(dir, { withFileTypes: true })).filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name).sort((a, b) => a.localeCompare(b));
|
|
15234
15334
|
} catch {
|
|
15235
15335
|
throw new Error(`R\xE9pertoire illisible : ${dir}`);
|
|
15236
15336
|
}
|
|
@@ -15369,7 +15469,7 @@ async function ensureFilePermissions() {
|
|
|
15369
15469
|
}
|
|
15370
15470
|
|
|
15371
15471
|
// ../server/src/services/vault-migration.ts
|
|
15372
|
-
import { readdir as
|
|
15472
|
+
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";
|
|
15373
15473
|
import { join as join26 } from "path";
|
|
15374
15474
|
var KEY_FILES = [".encryption.key.enc", ".runeya-verify"];
|
|
15375
15475
|
var MACHINE_FILES = [
|
|
@@ -15382,7 +15482,7 @@ var MACHINE_FILES = [
|
|
|
15382
15482
|
];
|
|
15383
15483
|
var rekeyValue = rekeyJsonValue;
|
|
15384
15484
|
async function vaultJsonFiles(root) {
|
|
15385
|
-
const entries2 = await
|
|
15485
|
+
const entries2 = await readdir9(root, { withFileTypes: true });
|
|
15386
15486
|
return entries2.filter((e) => e.isFile() && e.name.endsWith(".json")).map((e) => e.name);
|
|
15387
15487
|
}
|
|
15388
15488
|
async function exists2(path) {
|
|
@@ -15422,7 +15522,7 @@ async function migrateLegacyVault(legacyRoot, machineRootDir, legacyKey, machine
|
|
|
15422
15522
|
if (counter.n === 0) continue;
|
|
15423
15523
|
const tmp = join26(legacyRoot, `${name}.tmp`);
|
|
15424
15524
|
await writeFile18(tmp, JSON.stringify(converted, null, 2), "utf-8");
|
|
15425
|
-
await
|
|
15525
|
+
await rename15(tmp, join26(legacyRoot, name));
|
|
15426
15526
|
rekeyed.push({ file: name, values: counter.n });
|
|
15427
15527
|
}
|
|
15428
15528
|
for (const { file, values } of rekeyed) {
|
|
@@ -15458,7 +15558,7 @@ async function migrateLegacyVault(legacyRoot, machineRootDir, legacyKey, machine
|
|
|
15458
15558
|
}
|
|
15459
15559
|
|
|
15460
15560
|
// ../server/src/services/settings-migration.ts
|
|
15461
|
-
import { readFile as readFile20, writeFile as writeFile19, rename as
|
|
15561
|
+
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";
|
|
15462
15562
|
import { join as join27 } from "path";
|
|
15463
15563
|
var SETTINGS_FILE2 = "settings.json";
|
|
15464
15564
|
var SETTINGS_PRIVATE_FILE2 = "settings.private.json";
|
|
@@ -15477,7 +15577,7 @@ async function moveInto(root, filename, from) {
|
|
|
15477
15577
|
const contents = await readFile20(from, "utf-8");
|
|
15478
15578
|
const tmp = to + ".tmp";
|
|
15479
15579
|
await writeFile19(tmp, contents, "utf-8");
|
|
15480
|
-
await
|
|
15580
|
+
await rename16(tmp, to);
|
|
15481
15581
|
await chmod12(to, 384);
|
|
15482
15582
|
await unlink6(from);
|
|
15483
15583
|
}
|
|
@@ -15512,14 +15612,14 @@ async function migrateSettingsIntoVaults() {
|
|
|
15512
15612
|
// ../server/src/migrations/migrate-from-legacy.ts
|
|
15513
15613
|
import { createRequire as createRequire2 } from "module";
|
|
15514
15614
|
import { randomBytes as randomBytes6, createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3 } from "crypto";
|
|
15515
|
-
import { randomUUID as
|
|
15615
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
15516
15616
|
import {
|
|
15517
15617
|
readFile as readFile21,
|
|
15518
15618
|
writeFile as writeFile20,
|
|
15519
|
-
rename as
|
|
15619
|
+
rename as rename17,
|
|
15520
15620
|
mkdir as mkdir24,
|
|
15521
15621
|
access as access3,
|
|
15522
|
-
readdir as
|
|
15622
|
+
readdir as readdir10
|
|
15523
15623
|
} from "fs/promises";
|
|
15524
15624
|
import { join as join28, dirname as dirname11 } from "path";
|
|
15525
15625
|
var _require = createRequire2(import.meta.url);
|
|
@@ -15651,7 +15751,7 @@ async function decryptLegacyFile(filePath, key, sodium) {
|
|
|
15651
15751
|
async function atomicWrite(path, data) {
|
|
15652
15752
|
const tmp = path + ".tmp";
|
|
15653
15753
|
await writeFile20(tmp, JSON.stringify(data, null, 2), "utf-8");
|
|
15654
|
-
await
|
|
15754
|
+
await rename17(tmp, path);
|
|
15655
15755
|
}
|
|
15656
15756
|
async function runLegacyMigration(dataDir) {
|
|
15657
15757
|
const legacyRoot = env.DATA_DIR;
|
|
@@ -15664,10 +15764,10 @@ async function runLegacyMigration(dataDir) {
|
|
|
15664
15764
|
console.log("[legacy-migration] Legacy Runeya data detected, starting migration\u2026");
|
|
15665
15765
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").substring(0, 19);
|
|
15666
15766
|
const legacyTmp = join28(abCwd, ".runeya-tmp");
|
|
15667
|
-
await
|
|
15767
|
+
await rename17(legacyRoot, legacyTmp);
|
|
15668
15768
|
await mkdir24(dataDir, { recursive: true });
|
|
15669
15769
|
const legacyOld = join28(dataDir, `backup-${timestamp}`);
|
|
15670
|
-
await
|
|
15770
|
+
await rename17(legacyTmp, legacyOld);
|
|
15671
15771
|
console.log(`[legacy-migration] Legacy data backed up to ${legacyOld}`);
|
|
15672
15772
|
const keyJson = JSON.parse(await readFile21(join28(legacyOld, "dbs", "encryption-key.json"), "utf-8"));
|
|
15673
15773
|
const sodium = await getSodium();
|
|
@@ -15686,14 +15786,14 @@ async function runLegacyMigration(dataDir) {
|
|
|
15686
15786
|
}
|
|
15687
15787
|
}
|
|
15688
15788
|
const envsDir = join28(dbsDir, "envs");
|
|
15689
|
-
const envFiles = (await
|
|
15789
|
+
const envFiles = (await readdir10(envsDir).catch(() => [])).filter((f) => f.endsWith(".encrypted.json"));
|
|
15690
15790
|
const legacyEnvs = {};
|
|
15691
15791
|
for (const file of envFiles) {
|
|
15692
15792
|
const name = file.replace(".encrypted.json", "");
|
|
15693
15793
|
legacyEnvs[name] = await readEncrypted(join28(envsDir, file));
|
|
15694
15794
|
}
|
|
15695
15795
|
const servicesDir = join28(dbsDir, "services");
|
|
15696
|
-
const serviceFiles = (await
|
|
15796
|
+
const serviceFiles = (await readdir10(servicesDir).catch(() => [])).filter((f) => f.endsWith(".encrypted.json"));
|
|
15697
15797
|
const legacyServices = {};
|
|
15698
15798
|
for (const file of serviceFiles) {
|
|
15699
15799
|
const name = file.replace(".encrypted.json", "");
|
|
@@ -15702,7 +15802,7 @@ async function runLegacyMigration(dataDir) {
|
|
|
15702
15802
|
if (data?.label) legacyServices[name] = data;
|
|
15703
15803
|
}
|
|
15704
15804
|
const overridesDir = join28(dbsDir, "overrides");
|
|
15705
|
-
const overrideFiles = (await
|
|
15805
|
+
const overrideFiles = (await readdir10(overridesDir).catch(() => [])).filter((f) => f.endsWith(".encrypted.json"));
|
|
15706
15806
|
const legacyServiceOverrides = {};
|
|
15707
15807
|
const legacyEnvOverrides = {};
|
|
15708
15808
|
for (const file of overrideFiles) {
|
|
@@ -15716,17 +15816,17 @@ async function runLegacyMigration(dataDir) {
|
|
|
15716
15816
|
}
|
|
15717
15817
|
}
|
|
15718
15818
|
const parsersDir = join28(dbsDir, "parsers");
|
|
15719
|
-
const parserFiles = (await
|
|
15819
|
+
const parserFiles = (await readdir10(parsersDir).catch(() => [])).filter((f) => f.endsWith(".encrypted.json"));
|
|
15720
15820
|
const legacyParsers = [];
|
|
15721
15821
|
for (const file of parserFiles) {
|
|
15722
15822
|
const data = await readEncrypted(join28(parsersDir, file));
|
|
15723
15823
|
if (data?.id) legacyParsers.push(data);
|
|
15724
15824
|
}
|
|
15725
|
-
const projectMonoId =
|
|
15825
|
+
const projectMonoId = randomUUID11();
|
|
15726
15826
|
const envIdMap = {};
|
|
15727
15827
|
const labelToKey = {};
|
|
15728
15828
|
for (const [name, legacyEnv] of Object.entries(legacyEnvs)) {
|
|
15729
|
-
envIdMap[name] =
|
|
15829
|
+
envIdMap[name] = randomUUID11();
|
|
15730
15830
|
if (legacyEnv?.label) labelToKey[legacyEnv.label] = name;
|
|
15731
15831
|
}
|
|
15732
15832
|
const runeEnvs = [];
|
|
@@ -15751,7 +15851,7 @@ async function runLegacyMigration(dataDir) {
|
|
|
15751
15851
|
if (hasInvalidInterpolation(value)) continue;
|
|
15752
15852
|
const cleaned = cleanVarKey(key);
|
|
15753
15853
|
if (inheritedVars[cleaned] === value) continue;
|
|
15754
|
-
const varId =
|
|
15854
|
+
const varId = randomUUID11();
|
|
15755
15855
|
variables[varId] = makeVariable(cleaned, value);
|
|
15756
15856
|
varIdLookup.set(`${envIdMap[name]}:${cleaned}`, varId);
|
|
15757
15857
|
}
|
|
@@ -15772,7 +15872,7 @@ async function runLegacyMigration(dataDir) {
|
|
|
15772
15872
|
const serviceIdMap = {};
|
|
15773
15873
|
const runeServices = [];
|
|
15774
15874
|
for (const [name, legacy] of Object.entries(legacyServices)) {
|
|
15775
|
-
const id =
|
|
15875
|
+
const id = randomUUID11();
|
|
15776
15876
|
serviceIdMap[name] = id;
|
|
15777
15877
|
const rootPath = legacy.rootPath || "";
|
|
15778
15878
|
const rootPathCwd = rootPath && rootPath !== "." ? rootPath : "";
|
|
@@ -15781,7 +15881,7 @@ async function runLegacyMigration(dataDir) {
|
|
|
15781
15881
|
const parts = [cmd.spawnCmd, ...cmd.spawnArgs || []].filter(Boolean);
|
|
15782
15882
|
if (!parts.length) continue;
|
|
15783
15883
|
commands.push({
|
|
15784
|
-
id: cmd.id ||
|
|
15884
|
+
id: cmd.id || randomUUID11(),
|
|
15785
15885
|
label: "Launch",
|
|
15786
15886
|
command: parts.join(" "),
|
|
15787
15887
|
cwd: cmd.spawnOptions?.cwd || "",
|
|
@@ -15842,7 +15942,7 @@ async function runLegacyMigration(dataDir) {
|
|
|
15842
15942
|
const legacyBootstrapCmds = container.bootstrap?.commands || [];
|
|
15843
15943
|
if (legacyBootstrapCmds.length > 0) {
|
|
15844
15944
|
dockerConfig.bootstrapCommands = legacyBootstrapCmds.filter((bs) => bs.cmd || bs.entrypoint).map((bs, idx) => ({
|
|
15845
|
-
id: bs.id ||
|
|
15945
|
+
id: bs.id || randomUUID11(),
|
|
15846
15946
|
label: bs.label || `Bootstrap ${idx + 1}`,
|
|
15847
15947
|
command: bs.cmd || "",
|
|
15848
15948
|
...bs.entrypoint ? { entrypoint: bs.entrypoint } : {},
|
|
@@ -15890,7 +15990,7 @@ async function runLegacyMigration(dataDir) {
|
|
|
15890
15990
|
cwd: serviceCwd,
|
|
15891
15991
|
runner: dockerConfig ? "docker" : "native",
|
|
15892
15992
|
shortcuts: (legacy.shortcuts || []).filter((s) => s.spawnCmd || s.label).map((s) => ({
|
|
15893
|
-
id: s.id ||
|
|
15993
|
+
id: s.id || randomUUID11(),
|
|
15894
15994
|
label: s.label || s.spawnCmd || "",
|
|
15895
15995
|
command: [s.spawnCmd, ...s.spawnArgs || []].filter(Boolean).join(" "),
|
|
15896
15996
|
...s.spawnOptions?.cwd ? { cwd: s.spawnOptions.cwd } : {}
|
|
@@ -15930,7 +16030,7 @@ async function runLegacyMigration(dataDir) {
|
|
|
15930
16030
|
);
|
|
15931
16031
|
if (!svcScopedEnv) {
|
|
15932
16032
|
svcScopedEnv = {
|
|
15933
|
-
id:
|
|
16033
|
+
id: randomUUID11(),
|
|
15934
16034
|
projectId: projectMonoId,
|
|
15935
16035
|
name: `${service?.name || name} (${globalEnv.name})`,
|
|
15936
16036
|
scope: "service",
|
|
@@ -15954,7 +16054,7 @@ async function runLegacyMigration(dataDir) {
|
|
|
15954
16054
|
const varPost = typeof varData === "object" ? String(varData.suffix ?? "") : "";
|
|
15955
16055
|
if (!varKey || existingKeys.has(cleanVarKey(varKey))) continue;
|
|
15956
16056
|
const cleaned = cleanVarKey(varKey);
|
|
15957
|
-
const varId =
|
|
16057
|
+
const varId = randomUUID11();
|
|
15958
16058
|
svcScopedEnv.variables[varId] = makeVariable(cleaned, varValue, varPre, varPost);
|
|
15959
16059
|
existingKeys.add(cleaned);
|
|
15960
16060
|
}
|
|
@@ -15974,7 +16074,7 @@ async function runLegacyMigration(dataDir) {
|
|
|
15974
16074
|
);
|
|
15975
16075
|
if (!svcScopedEnv) {
|
|
15976
16076
|
svcScopedEnv = {
|
|
15977
|
-
id:
|
|
16077
|
+
id: randomUUID11(),
|
|
15978
16078
|
projectId: projectMonoId,
|
|
15979
16079
|
name: `${service?.name || serviceName} (${globalEnv.name})`,
|
|
15980
16080
|
scope: "service",
|
|
@@ -15995,7 +16095,7 @@ async function runLegacyMigration(dataDir) {
|
|
|
15995
16095
|
const baseEntry = Object.entries(svcScopedEnv.variables).find(([, v]) => v.key === cleaned);
|
|
15996
16096
|
let varId = baseEntry?.[0];
|
|
15997
16097
|
if (!varId) {
|
|
15998
|
-
varId =
|
|
16098
|
+
varId = randomUUID11();
|
|
15999
16099
|
svcScopedEnv.variables[varId] = {
|
|
16000
16100
|
key: cleaned,
|
|
16001
16101
|
value: { value: "", pre: "", post: "", isSecret: false, injectIntoAi: false }
|
|
@@ -16025,13 +16125,13 @@ async function runLegacyMigration(dataDir) {
|
|
|
16025
16125
|
flatOverrides[varId] = makeVariable(cleaned, value);
|
|
16026
16126
|
}
|
|
16027
16127
|
} else {
|
|
16028
|
-
flatOverrides[
|
|
16128
|
+
flatOverrides[randomUUID11()] = makeVariable(cleaned, value);
|
|
16029
16129
|
}
|
|
16030
16130
|
} else {
|
|
16031
16131
|
const cleaned = cleanVarKey(key);
|
|
16032
16132
|
const existingVarId = Object.entries(env2.variables).find(([, v]) => v.key === cleaned)?.[0];
|
|
16033
16133
|
if (!existingVarId) {
|
|
16034
|
-
const varId =
|
|
16134
|
+
const varId = randomUUID11();
|
|
16035
16135
|
env2.variables[varId] = makeVariable(cleaned, value);
|
|
16036
16136
|
varIdLookup.set(`${envId}:${cleaned}`, varId);
|
|
16037
16137
|
}
|
|
@@ -16096,7 +16196,7 @@ ${p.transform ?? ""}`,
|
|
|
16096
16196
|
}
|
|
16097
16197
|
async function findLegacyKeyInBackup(dataDir) {
|
|
16098
16198
|
try {
|
|
16099
|
-
const entries2 = await
|
|
16199
|
+
const entries2 = await readdir10(dataDir);
|
|
16100
16200
|
const backupDirs = entries2.filter((e) => e.startsWith("backup-")).sort((a, b) => a < b ? -1 : a > b ? 1 : 0).reverse();
|
|
16101
16201
|
for (const dir of backupDirs) {
|
|
16102
16202
|
const keyJsonPath = join28(dataDir, dir, "dbs", "encryption-key.json");
|
|
@@ -16129,7 +16229,7 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16129
16229
|
let overrideFiles = [];
|
|
16130
16230
|
for (const dir of candidateDirs) {
|
|
16131
16231
|
try {
|
|
16132
|
-
const files = (await
|
|
16232
|
+
const files = (await readdir10(dir)).filter((f) => f.endsWith(".encrypted.json"));
|
|
16133
16233
|
if (files.length > 0) {
|
|
16134
16234
|
overridesDir = dir;
|
|
16135
16235
|
overrideFiles = files;
|
|
@@ -16215,7 +16315,7 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16215
16315
|
if (isSameAsBase(value, baseVar)) continue;
|
|
16216
16316
|
flatOverrides[varId] = makeVariable(cleaned, value);
|
|
16217
16317
|
} else {
|
|
16218
|
-
flatOverrides[
|
|
16318
|
+
flatOverrides[randomUUID11()] = makeVariable(cleaned, value);
|
|
16219
16319
|
}
|
|
16220
16320
|
}
|
|
16221
16321
|
}
|
|
@@ -16252,7 +16352,7 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16252
16352
|
);
|
|
16253
16353
|
if (!svcScopedEnv) {
|
|
16254
16354
|
svcScopedEnv = {
|
|
16255
|
-
id:
|
|
16355
|
+
id: randomUUID11(),
|
|
16256
16356
|
projectId: globalEnv["projectId"],
|
|
16257
16357
|
name: `${service?.["name"] || serviceName} (${globalEnv["name"]})`,
|
|
16258
16358
|
scope: "service",
|
|
@@ -16274,7 +16374,7 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16274
16374
|
const baseEntry = Object.entries(svcScopedEnv["variables"]).find(([, v]) => v.key === cleaned);
|
|
16275
16375
|
let varId = baseEntry?.[0];
|
|
16276
16376
|
if (!varId) {
|
|
16277
|
-
varId =
|
|
16377
|
+
varId = randomUUID11();
|
|
16278
16378
|
svcScopedEnv["variables"][varId] = {
|
|
16279
16379
|
key: cleaned,
|
|
16280
16380
|
value: { value: "", pre: "", post: "", isSecret: false, injectIntoAi: false }
|
|
@@ -16294,7 +16394,7 @@ async function runOverrideOnlyMigration(dataDir) {
|
|
|
16294
16394
|
}
|
|
16295
16395
|
const migratedDir = overridesDir.replace(/overrides$/, "overrides-migrated");
|
|
16296
16396
|
try {
|
|
16297
|
-
await
|
|
16397
|
+
await rename17(overridesDir, migratedDir);
|
|
16298
16398
|
console.log(`[override-migration] Moved overrides/ \u2192 overrides-migrated/`);
|
|
16299
16399
|
} catch (err) {
|
|
16300
16400
|
console.warn(`[override-migration] Could not rename overrides dir: ${err.message}`);
|
|
@@ -16742,6 +16842,7 @@ async function createLocalServer() {
|
|
|
16742
16842
|
await ensureDataGitignore(env.DATA_DIR);
|
|
16743
16843
|
}
|
|
16744
16844
|
await settingsManager.getSettings();
|
|
16845
|
+
await applyPersistedLanMode();
|
|
16745
16846
|
await migrationEngine.run();
|
|
16746
16847
|
await ensureFilePermissions();
|
|
16747
16848
|
auditService.cleanup().catch((err) => console.error("[server] Audit cleanup failed:", err));
|
|
@@ -17338,6 +17439,7 @@ async function createLocalServer() {
|
|
|
17338
17439
|
}));
|
|
17339
17440
|
app.use(errorHandler);
|
|
17340
17441
|
const server = createServer(app);
|
|
17442
|
+
registerHttpServer(server);
|
|
17341
17443
|
const wss = new WebSocketServer({ noServer: true });
|
|
17342
17444
|
applyWSSHandler({
|
|
17343
17445
|
wss,
|
|
@@ -17589,4 +17691,4 @@ export {
|
|
|
17589
17691
|
pullEnv,
|
|
17590
17692
|
registerInstance
|
|
17591
17693
|
};
|
|
17592
|
-
//# sourceMappingURL=src-
|
|
17694
|
+
//# sourceMappingURL=src-53OQNM27.js.map
|