specrails-desktop 2.26.2 → 2.28.0
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/client/dist/assets/{ActivityFeedPage-bDe4VitF.js → ActivityFeedPage-DcMmDAP3.js} +1 -1
- package/client/dist/assets/AgentBrowserCapture-CZ3oc1UL.js +1 -0
- package/client/dist/assets/AgentIntegrationsModal-DkqooCFn.js +1 -0
- package/client/dist/assets/{AgentModeCodePane-Ci39DcOo.js → AgentModeCodePane-CM77ljte.js} +2 -2
- package/client/dist/assets/AgentModeJobsPane-DbZzogbi.js +1 -0
- package/client/dist/assets/AgentsPage-BZIml7eL.js +86 -0
- package/client/dist/assets/{AnalyticsPage-Da21wWWw.js → AnalyticsPage-B4qflNxi.js} +1 -1
- package/client/dist/assets/{BarChart-BiLTq3uC.js → BarChart-Ckstq9fl.js} +1 -1
- package/client/dist/assets/CodePage-DFZXLbI1.js +2 -0
- package/client/dist/assets/{DesktopAnalyticsPage-COkzgMmd.js → DesktopAnalyticsPage-DbgMa8OO.js} +1 -1
- package/client/dist/assets/DocsDialog-BQc9Kwev.js +11 -0
- package/client/dist/assets/DocsPage-OsV44ECy.js +11 -0
- package/client/dist/assets/{ExportDropdown-DDhJH-Jr.js → ExportDropdown-a43XHO3Y.js} +1 -1
- package/client/dist/assets/IntegrationsPage-C3E8hZhB.js +1 -0
- package/client/dist/assets/InteractiveJobComposer-zj8SrOAl.js +19 -0
- package/client/dist/assets/JobDetailModal-Cm6ZeVoh.js +1 -0
- package/client/dist/assets/JobDetailPage-DN67LsdX.js +1 -0
- package/client/dist/assets/JobsPage-DF9wKGbw.js +1 -0
- package/client/dist/assets/{LoopBuilderPage-DsLLrtHa.js → LoopBuilderPage-RJ6GGjli.js} +2 -2
- package/client/dist/assets/{LoopPreviewModal-C-fDEgnu.js → LoopPreviewModal-B2wmifF6.js} +1 -1
- package/client/dist/assets/LoopsPage-DdlvH-dJ.js +1 -0
- package/client/dist/assets/PluginsPage-9DI0a6jI.js +2 -0
- package/client/dist/assets/ProjectSettingsDialog-dgy5hqPd.js +1 -0
- package/client/dist/assets/{TemplatePreviewModal-DcHFbLA8.js → TemplatePreviewModal-CERf1IYB.js} +1 -1
- package/client/dist/assets/agent-BRJCESkc2.js +1 -0
- package/client/dist/assets/agent-BuYz6fJd.js +1 -0
- package/client/dist/assets/agent-CxnRzL6Z.js +1 -0
- package/client/dist/assets/agent-D4JAuEGN2.js +1 -0
- package/client/dist/assets/agent-DNQlI8EN.js +1 -0
- package/client/dist/assets/agent-DyzUH89R.js +1 -0
- package/client/dist/assets/agent-MaTxBlg5.js +1 -0
- package/client/dist/assets/agent-ostmMYNz2.js +1 -0
- package/client/dist/assets/{brain-BBNUUrUI.js → brain-BPbhM1Jx.js} +1 -1
- package/client/dist/assets/dashboard-5C2FOZQX.js +1 -0
- package/client/dist/assets/{dashboard-C6w0rICe.js → dashboard-B6iQ-IL_.js} +1 -1
- package/client/dist/assets/dashboard-BFfnCtq52.js +1 -0
- package/client/dist/assets/dashboard-BIC8KtRf2.js +1 -0
- package/client/dist/assets/dashboard-CEgg9NAr.js +1 -0
- package/client/dist/assets/dashboard-CiOyDh9L.js +1 -0
- package/client/dist/assets/dashboard-D6x5OnNj2.js +1 -0
- package/client/dist/assets/dashboard-DBuLfWo9.js +1 -0
- package/client/dist/assets/{dist-js-BxjTIvdT.js → dist-js-Byjcju1W.js} +1 -1
- package/client/dist/assets/{dist-js-DdP_Gl3p.js → dist-js-Dh-9lbLD.js} +1 -1
- package/client/dist/assets/index-89SuhD4Y.js +158 -0
- package/client/dist/assets/index-DOGzWJhO.css +2 -0
- package/client/dist/assets/integrations-By80EBkf.js +1 -0
- package/client/dist/assets/integrations-CAjq5tdW2.js +1 -0
- package/client/dist/assets/integrations-CG2dp3Kd.js +1 -0
- package/client/dist/assets/integrations-CP_aiV_8.js +1 -0
- package/client/dist/assets/integrations-CUNe3t9l2.js +1 -0
- package/client/dist/assets/integrations-CWjh5VRk.js +1 -0
- package/client/dist/assets/integrations-JOHSCvB3.js +1 -0
- package/client/dist/assets/integrations-RJfzXkPx2.js +1 -0
- package/client/dist/assets/{lib-BviHZ_gK.js → lib-yKyTNJ1c.js} +1 -1
- package/client/dist/assets/nav-B2_ToNqS.js +1 -0
- package/client/dist/assets/nav-BAMkVEId.js +1 -0
- package/client/dist/assets/nav-BTg8s-cD.js +1 -0
- package/client/dist/assets/nav-BY_4EWRv.js +1 -0
- package/client/dist/assets/nav-CVXtv0wX2.js +1 -0
- package/client/dist/assets/nav-D0Erv9ZJ2.js +1 -0
- package/client/dist/assets/nav-DUuw9VIU2.js +1 -0
- package/client/dist/assets/nav-S4HM94vW.js +1 -0
- package/client/dist/assets/settings-BYCMtxOz.js +1 -0
- package/client/dist/assets/{settings-BHdPchJP.js → settings-B_v3zgJf.js} +1 -1
- package/client/dist/assets/{settings-BeCczBFS2.js → settings-BemR_e3F.js} +1 -1
- package/client/dist/assets/{settings-D54_cgl12.js → settings-Bp24JHlv2.js} +1 -1
- package/client/dist/assets/{settings-C_nY14Yz.js → settings-BvIwQ3A1.js} +1 -1
- package/client/dist/assets/{settings-BlLi719f.js → settings-Bx2ObkTR2.js} +1 -1
- package/client/dist/assets/{settings-CaZ26a0S.js → settings-C_T0-j9d.js} +1 -1
- package/client/dist/assets/{settings-cn0tbve62.js → settings-DhaFKpcw2.js} +1 -1
- package/client/dist/assets/{upload-CRuuzzvp.js → upload-Qh1NE3xi.js} +1 -1
- package/client/dist/assets/{value-CIr5hDMt.js → value-BMPeyInx.js} +1 -1
- package/client/dist/index.html +29 -29
- package/package.json +1 -1
- package/server/dist/agent-chat-router.js +2 -0
- package/server/dist/agent-operator-prompt.js +17 -1
- package/server/dist/db.js +51 -2
- package/server/dist/dev-ports.js +35 -0
- package/server/dist/global-plugins-router.js +62 -0
- package/server/dist/headroom-manager.js +971 -0
- package/server/dist/headroom-routing.js +53 -0
- package/server/dist/index.js +9 -6
- package/server/dist/mcp/guide.js +3 -0
- package/server/dist/mcp/tools/catalog.js +2 -0
- package/server/dist/mcp/tools/env.js +72 -0
- package/server/dist/mcp/tools/jobs.js +110 -2
- package/server/dist/path-resolver.js +84 -18
- package/server/dist/project-env.js +30 -0
- package/server/dist/project-registry.js +4 -2
- package/server/dist/project-router-jobs.js +126 -0
- package/server/dist/project-router-settings.js +10 -1
- package/server/dist/queue-manager.js +9 -1
- package/server/dist/rail-isolated-launch.js +5 -4
- package/server/dist/rail-pr-decision.js +27 -17
- package/server/dist/rail-pr-store.js +36 -0
- package/server/dist/rails-router.js +7 -1
- package/server/dist/setup-manager.js +32 -29
- package/server/dist/setup-prerequisites.js +3 -1
- package/server/dist/transient-children.js +266 -9
- package/server/dist/util/cli-prompt.js +3 -0
- package/server/dist/workspace-resolution.js +3 -3
- package/server/dist/worktree-env-discovery.js +172 -0
- package/client/dist/assets/AgentBrowserCapture-DQyeEm2V.js +0 -1
- package/client/dist/assets/AgentModeJobsPane-C-g1WNVG.js +0 -1
- package/client/dist/assets/AgentsPage-BWgglK7V.js +0 -86
- package/client/dist/assets/CodePage-BUcAp7SC.js +0 -2
- package/client/dist/assets/DocsDialog-PZHMN18B.js +0 -11
- package/client/dist/assets/DocsPage-D3fChfkj.js +0 -11
- package/client/dist/assets/IntegrationsPage-F87uxxVH.js +0 -3
- package/client/dist/assets/InteractiveJobComposer-DqDCiCa0.js +0 -19
- package/client/dist/assets/JobDetailModal-BWJR60fi.js +0 -1
- package/client/dist/assets/JobDetailPage-CjWE_jyd.js +0 -1
- package/client/dist/assets/JobsPage-LmnXkyCa.js +0 -1
- package/client/dist/assets/LoopsPage-DDNO9h9T.js +0 -1
- package/client/dist/assets/ProjectSettingsDialog-CX854C8e.js +0 -1
- package/client/dist/assets/agent-BI6vr-To.js +0 -1
- package/client/dist/assets/agent-BUGXI3Ok2.js +0 -1
- package/client/dist/assets/agent-Bph_-xt7.js +0 -1
- package/client/dist/assets/agent-Bvy2Csyd.js +0 -1
- package/client/dist/assets/agent-Bwkyg2oX2.js +0 -1
- package/client/dist/assets/agent-CLCyDaZh.js +0 -1
- package/client/dist/assets/agent-Cqs14QMr2.js +0 -1
- package/client/dist/assets/agent-DJ0EBUuP.js +0 -1
- package/client/dist/assets/dashboard-BjjS1OrL.js +0 -1
- package/client/dist/assets/dashboard-Bk6oSk1H2.js +0 -1
- package/client/dist/assets/dashboard-BrH-GdOg2.js +0 -1
- package/client/dist/assets/dashboard-BurhUI8_.js +0 -1
- package/client/dist/assets/dashboard-CAUnfDQL2.js +0 -1
- package/client/dist/assets/dashboard-C_ljpeYO.js +0 -1
- package/client/dist/assets/dashboard-D6OqDdj6.js +0 -1
- package/client/dist/assets/index-C695aPdV.css +0 -2
- package/client/dist/assets/index-Dw1N2-ci.js +0 -156
- package/client/dist/assets/integrations-4KZnYECp.js +0 -1
- package/client/dist/assets/integrations-7W266oqF2.js +0 -1
- package/client/dist/assets/integrations-BNuauK3o.js +0 -1
- package/client/dist/assets/integrations-CHy8tnpV.js +0 -1
- package/client/dist/assets/integrations-Cl_wD5AI.js +0 -1
- package/client/dist/assets/integrations-CuWnMR5L.js +0 -1
- package/client/dist/assets/integrations-Cy8nZ_dv2.js +0 -1
- package/client/dist/assets/integrations-zMqY4VU12.js +0 -1
- package/client/dist/assets/nav-40HzpIFb.js +0 -1
- package/client/dist/assets/nav-8yPhBn00.js +0 -1
- package/client/dist/assets/nav-B6PkGfTk2.js +0 -1
- package/client/dist/assets/nav-BHqMLrS72.js +0 -1
- package/client/dist/assets/nav-CGy4yx3C.js +0 -1
- package/client/dist/assets/nav-CXEDcRdv2.js +0 -1
- package/client/dist/assets/nav-CzKzuwH8.js +0 -1
- package/client/dist/assets/nav-EI_OhEAo.js +0 -1
- package/client/dist/assets/settings-D9bDDe2O.js +0 -1
- /package/client/dist/assets/{activity-BZNfOdiS.js → activity-BZZlEG3a.js} +0 -0
- /package/client/dist/assets/{activity--iN4Ad2R2.js → activity-BbWiDfn-2.js} +0 -0
- /package/client/dist/assets/{activity-CIOLxGvh.js → activity-D3Ic-HTS.js} +0 -0
- /package/client/dist/assets/{activity-DtxrAUMo2.js → activity-DFbvNqhE2.js} +0 -0
- /package/client/dist/assets/{activity-D8vQJrpW.js → activity-Dbl71S-E.js} +0 -0
- /package/client/dist/assets/{activity-BuVo5sPB.js → activity-DtzRy92x.js} +0 -0
- /package/client/dist/assets/{activity-6hM_ZSg9.js → activity-DvECTYGt.js} +0 -0
- /package/client/dist/assets/{activity-D2r2h3SE2.js → activity-FleOlK0l2.js} +0 -0
- /package/client/dist/assets/{addspec-D-JLDsUV.js → addspec-BKrH2Ucz.js} +0 -0
- /package/client/dist/assets/{addspec-DfhDbg5c.js → addspec-B_LQMHW3.js} +0 -0
- /package/client/dist/assets/{addspec-bsNDdqRm2.js → addspec-Bw_YQwo62.js} +0 -0
- /package/client/dist/assets/{addspec-BMtLZLW62.js → addspec-CFxGvmJR2.js} +0 -0
- /package/client/dist/assets/{addspec-mgPOt5q02.js → addspec-CR8MB5Fr2.js} +0 -0
- /package/client/dist/assets/{addspec-CP0HRuxY.js → addspec-DaA-CbTt.js} +0 -0
- /package/client/dist/assets/{addspec-DxW6oPsk.js → addspec-DrXqP8ip.js} +0 -0
- /package/client/dist/assets/{addspec-CRuvWn8d.js → addspec-NBbcTbLc.js} +0 -0
- /package/client/dist/assets/{agents-BpoUaoW92.js → agents-B9pFSJQI2.js} +0 -0
- /package/client/dist/assets/{agents-78bTZGZh.js → agents-BHgn--3j.js} +0 -0
- /package/client/dist/assets/{agents-BUdEi3-N.js → agents-B_qGaB0F.js} +0 -0
- /package/client/dist/assets/{agents-Cev2oFfX.js → agents-CGDn_3kB.js} +0 -0
- /package/client/dist/assets/{agents-bvyRLczL.js → agents-CP8_ezYG.js} +0 -0
- /package/client/dist/assets/{agents-BLhWCmDS2.js → agents-CV-_xBvX2.js} +0 -0
- /package/client/dist/assets/{agents-CWo-KyAB.js → agents-HFCqQH0Z.js} +0 -0
- /package/client/dist/assets/{agents-DDtCJ5M02.js → agents-VsyFhGOS2.js} +0 -0
- /package/client/dist/assets/{agentstudio-BMQxc_bz.js → agentstudio-BEp7Sb46.js} +0 -0
- /package/client/dist/assets/{agentstudio-Dtq3dGYk.js → agentstudio-BOjG6tgJ.js} +0 -0
- /package/client/dist/assets/{agentstudio-C_Jq8Tl4.js → agentstudio-Br3WD7Xs.js} +0 -0
- /package/client/dist/assets/{agentstudio-sI27TpBu2.js → agentstudio-CuTt3ZGe2.js} +0 -0
- /package/client/dist/assets/{agentstudio-CWgXG5W52.js → agentstudio-D2A5peWV2.js} +0 -0
- /package/client/dist/assets/{agentstudio-CZm2rOzt.js → agentstudio-Dxe_94PK.js} +0 -0
- /package/client/dist/assets/{agentstudio-COZriimI2.js → agentstudio-RfZavULt2.js} +0 -0
- /package/client/dist/assets/{agentstudio-jKMTdT70.js → agentstudio-RsxnZtUA.js} +0 -0
- /package/client/dist/assets/{aiedit-igmw-ZoZ2.js → aiedit-26p5A_HY2.js} +0 -0
- /package/client/dist/assets/{aiedit-6CHdb_iv2.js → aiedit-CV520D4W2.js} +0 -0
- /package/client/dist/assets/{aiedit-pc5JDUq1.js → aiedit-CcugGPbS.js} +0 -0
- /package/client/dist/assets/{aiedit-eMN4eQPF.js → aiedit-D0Syl-mC.js} +0 -0
- /package/client/dist/assets/{aiedit-hknZlly82.js → aiedit-DnBzjlVz2.js} +0 -0
- /package/client/dist/assets/{aiedit-B03pD_Na.js → aiedit-DrIjSojo.js} +0 -0
- /package/client/dist/assets/{aiedit-DYtnZU9H.js → aiedit-DrfHQnlz.js} +0 -0
- /package/client/dist/assets/{aiedit-BtRqRxML.js → aiedit-a-Z-g5iC.js} +0 -0
- /package/client/dist/assets/{analytics-C5dpiS0o.js → analytics-4-eskbtX.js} +0 -0
- /package/client/dist/assets/{analytics-CR1TJqUi2.js → analytics-4HvXb0Vn2.js} +0 -0
- /package/client/dist/assets/{analytics-rmHuJv0V.js → analytics-Bd9rHGjV.js} +0 -0
- /package/client/dist/assets/{analytics-BWMUZ2Pq2.js → analytics-Bpe41fnX2.js} +0 -0
- /package/client/dist/assets/{analytics-Bj-SmKHa.js → analytics-CpSTNfui.js} +0 -0
- /package/client/dist/assets/{analytics-Ce-sPORu.js → analytics-CxDYcBl9.js} +0 -0
- /package/client/dist/assets/{analytics-CCprAqk3.js → analytics-DEe5BMz8.js} +0 -0
- /package/client/dist/assets/{analytics-DfNdXR0y2.js → analytics-DcOITHla2.js} +0 -0
- /package/client/dist/assets/{attachments-BjyMmrwE.js → attachments-CA2f3qL3.js} +0 -0
- /package/client/dist/assets/{attachments-DCZOL1RU.js → attachments-CHDbhKeH.js} +0 -0
- /package/client/dist/assets/{attachments-rNn1ekRy2.js → attachments-CKAY5aYG2.js} +0 -0
- /package/client/dist/assets/{attachments-BgBNSqQd.js → attachments-CgOQ9K-6.js} +0 -0
- /package/client/dist/assets/{attachments-DPCmkFZu2.js → attachments-D2jwJXQ42.js} +0 -0
- /package/client/dist/assets/{attachments-C9GTTJsx2.js → attachments-DlEQu56g2.js} +0 -0
- /package/client/dist/assets/{attachments-Ci6_42Kh.js → attachments-DvxQbBTC.js} +0 -0
- /package/client/dist/assets/{attachments-DL-bPy9E.js → attachments-jVdKzAXn.js} +0 -0
- /package/client/dist/assets/{auth-Cvsb7-Ek.js → auth-DpZq5p1e.js} +0 -0
- /package/client/dist/assets/{browser-Cvg-QHvd2.js → browser-BQFDxrRq.js} +0 -0
- /package/client/dist/assets/{browser-rWKj-RR_2.js → browser-BbJ_q_OT2.js} +0 -0
- /package/client/dist/assets/{browser-Cc0iDqUi.js → browser-C4VJ5CW12.js} +0 -0
- /package/client/dist/assets/{browser-BPkhILSJ.js → browser-Cl-FwPXs.js} +0 -0
- /package/client/dist/assets/{browser-CdS6O1Qb.js → browser-DM8G151q.js} +0 -0
- /package/client/dist/assets/{browser-FRv8P02E.js → browser-Do2jf8_N.js} +0 -0
- /package/client/dist/assets/{browser-BqLqJVVT.js → browser-JsiohNmW.js} +0 -0
- /package/client/dist/assets/{browser-BijVYG0Y2.js → browser-kA31eYhu2.js} +0 -0
- /package/client/dist/assets/{chat-VMflhzxn.js → chat-0dg5hOo_.js} +0 -0
- /package/client/dist/assets/{chat-DdwZjT8K2.js → chat-BMWD_Rx12.js} +0 -0
- /package/client/dist/assets/{chat-Bom6bqK3.js → chat-BalviUAD.js} +0 -0
- /package/client/dist/assets/{chat-DsbwJhus.js → chat-CJddjN3D2.js} +0 -0
- /package/client/dist/assets/{chat-Dnwg-NpQ.js → chat-D5xEtsf3.js} +0 -0
- /package/client/dist/assets/{chat-vylxqR0P2.js → chat-Ds8GvCnv.js} +0 -0
- /package/client/dist/assets/{chat-BgL3zv6x2.js → chat-SaG-ng1x2.js} +0 -0
- /package/client/dist/assets/{chat-Bh3NdgJs.js → chat-n43nZGvn.js} +0 -0
- /package/client/dist/assets/{code-thSEptMx.js → code-B62fClk-.js} +0 -0
- /package/client/dist/assets/{code-DzC1rMk12.js → code-Bit_z2Xd2.js} +0 -0
- /package/client/dist/assets/{code-BRcDlze52.js → code-BotxM43N2.js} +0 -0
- /package/client/dist/assets/{code-UPVvmAKM2.js → code-C9U6M5-e2.js} +0 -0
- /package/client/dist/assets/{code-BdMy3Ffq.js → code-CIPmDEd0.js} +0 -0
- /package/client/dist/assets/{code-DgeHz9CB.js → code-DUe1Bouz.js} +0 -0
- /package/client/dist/assets/{code-CwnBPPyA.js → code-F_KjccGf.js} +0 -0
- /package/client/dist/assets/{code-CeQ0FZpC.js → code-HDK4P6Rx.js} +0 -0
- /package/client/dist/assets/{commands-DkU0qliq.js → commands-BFQZc9AG.js} +0 -0
- /package/client/dist/assets/{commands-u-4eEHCN.js → commands-BMkC5-ki.js} +0 -0
- /package/client/dist/assets/{commands-CSDs9q_2.js → commands-BllkJauO.js} +0 -0
- /package/client/dist/assets/{commands-xHDDGfcP2.js → commands-CWX9WmDX2.js} +0 -0
- /package/client/dist/assets/{commands-C4Y3C-PF2.js → commands-CzFSoIiq2.js} +0 -0
- /package/client/dist/assets/{commands-CckaBWdV.js → commands-DCJ-R9E4.js} +0 -0
- /package/client/dist/assets/{commands-JWMfGDmr.js → commands-KBbhsnw8.js} +0 -0
- /package/client/dist/assets/{commands-RHOchN4n2.js → commands-cKTaLwwV2.js} +0 -0
- /package/client/dist/assets/{common-DmqBPwZG.js → common-BfQD173j.js} +0 -0
- /package/client/dist/assets/{common-DhWTkocg.js → common-CF8iGXrG.js} +0 -0
- /package/client/dist/assets/{common-Bwafujnc2.js → common-Cfmwcrl52.js} +0 -0
- /package/client/dist/assets/{common-C-vU-j-I.js → common-D2cimsul.js} +0 -0
- /package/client/dist/assets/{common-C5HKSbbz.js → common-DH7fjyL1.js} +0 -0
- /package/client/dist/assets/{common-CYaT2yHp.js → common-DXrmj6WD.js} +0 -0
- /package/client/dist/assets/{common-BM3LFLCE2.js → common-DZbXlmq72.js} +0 -0
- /package/client/dist/assets/{common-DiPTT7V_2.js → common-DtXmzX2o2.js} +0 -0
- /package/client/dist/assets/{explore-UvW1jEMa.js → explore-BEpIs343.js} +0 -0
- /package/client/dist/assets/{explore-CNBzrEPS.js → explore-BO_OinBD.js} +0 -0
- /package/client/dist/assets/{explore-C0k8HrkN.js → explore-Bhy7WWXv.js} +0 -0
- /package/client/dist/assets/{explore-B7fblXBb2.js → explore-CAc8Qzu32.js} +0 -0
- /package/client/dist/assets/{explore-D_mWBYCS2.js → explore-DCZL9gRN2.js} +0 -0
- /package/client/dist/assets/{explore-Dahc1lOx.js → explore-DW_YTkQh.js} +0 -0
- /package/client/dist/assets/{explore-BHtEpoNN2.js → explore-ELbrSZyQ2.js} +0 -0
- /package/client/dist/assets/{explore-BKVV5JSu.js → explore-_XyU5e7R.js} +0 -0
- /package/client/dist/assets/{format-command-CuWuRvka.js → format-command-Db1viey1.js} +0 -0
- /package/client/dist/assets/{jira-uNH1gETL2.js → jira-B5wszJ1-2.js} +0 -0
- /package/client/dist/assets/{jira-BHAKtc4B.js → jira-C5UjxHE4.js} +0 -0
- /package/client/dist/assets/{jira-D5efgwp_.js → jira-CQ7mrZde.js} +0 -0
- /package/client/dist/assets/{jira-bDs7Im2C.js → jira-DIRkZk9U.js} +0 -0
- /package/client/dist/assets/{jira-CPpgA-5z2.js → jira-DTYu3hJi2.js} +0 -0
- /package/client/dist/assets/{jira-B3613-gj.js → jira-DeIjwCK3.js} +0 -0
- /package/client/dist/assets/{jira-DS7ownDy.js → jira-DtZpokjJ.js} +0 -0
- /package/client/dist/assets/{jira-Be369RIR2.js → jira-ZdKb-50F2.js} +0 -0
- /package/client/dist/assets/{jobs-CE8qeIYj.js → jobs-BFIdeDTw.js} +0 -0
- /package/client/dist/assets/{jobs-BgQzB0Sx2.js → jobs-BJ-Gcao22.js} +0 -0
- /package/client/dist/assets/{jobs-1GV2-4zd2.js → jobs-DAGiPVIS2.js} +0 -0
- /package/client/dist/assets/{jobs-26F9gGcE.js → jobs-DAU8C_tZ.js} +0 -0
- /package/client/dist/assets/{jobs-BqWui9_f.js → jobs-Da0GaaSc.js} +0 -0
- /package/client/dist/assets/{jobs-D5sZzgLs.js → jobs-DrYmsKy5.js} +0 -0
- /package/client/dist/assets/{jobs-Wh7dn28q2.js → jobs-P3unxtxo2.js} +0 -0
- /package/client/dist/assets/{jobs-DzeuASRf.js → jobs-p360zdf1.js} +0 -0
- /package/client/dist/assets/{loops-CvOWsi5r.js → loops-Bi4ywYGn.js} +0 -0
- /package/client/dist/assets/{loops-BvqQ-bHR2.js → loops-BjK8lmoZ2.js} +0 -0
- /package/client/dist/assets/{loops-Brnx4Fji.js → loops-CO6q75W8.js} +0 -0
- /package/client/dist/assets/{loops-K5_HXfJa.js → loops-D3wdUkZV.js} +0 -0
- /package/client/dist/assets/{loops-D6D3XHjj.js → loops-DDs4KPu_.js} +0 -0
- /package/client/dist/assets/{loops-LIgO_-eM.js → loops-DKzYFcq6.js} +0 -0
- /package/client/dist/assets/{loops-DJNhp17p2.js → loops-Du-bNVpc2.js} +0 -0
- /package/client/dist/assets/{loops-vhJdbcz92.js → loops-DvGbSfxw2.js} +0 -0
- /package/client/dist/assets/{mcp-XJNRfxVp2.js → mcp-BG-OCJca2.js} +0 -0
- /package/client/dist/assets/{mcp-DtbxuH3V2.js → mcp-CbJ04oFS2.js} +0 -0
- /package/client/dist/assets/{mcp-sRmWE8WJ.js → mcp-CrWdq5db.js} +0 -0
- /package/client/dist/assets/{mcp-H-gnQUdN.js → mcp-Dd844F5_.js} +0 -0
- /package/client/dist/assets/{mcp-Dcl-XxkR.js → mcp-DfmzoT5t.js} +0 -0
- /package/client/dist/assets/{mcp-CjVKXAhD2.js → mcp-DyULurYS2.js} +0 -0
- /package/client/dist/assets/{mcp-CIH0pH1K.js → mcp-HwBbQDk0.js} +0 -0
- /package/client/dist/assets/{mcp-N1nzp8oL.js → mcp-zSJ2TsJj.js} +0 -0
- /package/client/dist/assets/{setup-BuQNKztt2.js → setup-1vN48B-m2.js} +0 -0
- /package/client/dist/assets/{setup-BwMovM9z2.js → setup-BmJ0Kx16.js} +0 -0
- /package/client/dist/assets/{setup-RiUHzq7E.js → setup-D2CmgAro.js} +0 -0
- /package/client/dist/assets/{setup-BXpw07r-.js → setup-DQWsu2TR.js} +0 -0
- /package/client/dist/assets/{setup-D84y3wx-.js → setup-JeBwoXoM.js} +0 -0
- /package/client/dist/assets/{setup-DU0ULX8q2.js → setup-T_ApeQDV2.js} +0 -0
- /package/client/dist/assets/{setup-BiduSX9d.js → setup-mXnzww4f.js} +0 -0
- /package/client/dist/assets/{setup-7J8TjG4O.js → setup-q0wRHUp1.js} +0 -0
- /package/client/dist/assets/{specs-CWtKcVDC.js → specs-BGRKhM8t.js} +0 -0
- /package/client/dist/assets/{specs-CBDvEYKv.js → specs-C6J2zrLM.js} +0 -0
- /package/client/dist/assets/{specs-D2clrt2c2.js → specs-CT8exGOy2.js} +0 -0
- /package/client/dist/assets/{specs-C9Sd7BhH2.js → specs-Ce5y2iFc2.js} +0 -0
- /package/client/dist/assets/{specs-CIPr9reA2.js → specs-DZDoZsDq.js} +0 -0
- /package/client/dist/assets/{specs-PozUNhqb.js → specs-DbtIzV8a.js} +0 -0
- /package/client/dist/assets/{specs-DTplt2XM.js → specs-GkiL-snY.js} +0 -0
- /package/client/dist/assets/{specs-CmEZY57v.js → specs-PGIOzMtc.js} +0 -0
- /package/client/dist/assets/{terminal-xGbCZJHg.js → terminal-BNSg2lR7.js} +0 -0
- /package/client/dist/assets/{terminal-De2Brd23.js → terminal-BTpE7iki.js} +0 -0
- /package/client/dist/assets/{terminal-DFPNRLKp.js → terminal-CFt56A5f.js} +0 -0
- /package/client/dist/assets/{terminal-BRm03iFA2.js → terminal-Cvabyzm42.js} +0 -0
- /package/client/dist/assets/{terminal-DxQWCqSD2.js → terminal-D0z12_sJ2.js} +0 -0
- /package/client/dist/assets/{terminal-Z7KsDM_n.js → terminal-DDk_bTw0.js} +0 -0
- /package/client/dist/assets/{terminal-cqfd3EDV.js → terminal-DEyt0prF.js} +0 -0
- /package/client/dist/assets/{terminal-WSAvHXoU.js → terminal-a6Uq8B0p.js} +0 -0
- /package/client/dist/assets/{tickets-CkfbISuK.js → tickets-BHv3ewvq.js} +0 -0
- /package/client/dist/assets/{tickets-C3b8cHhd2.js → tickets-BIxU86j12.js} +0 -0
- /package/client/dist/assets/{tickets-SuX_HkK4.js → tickets-C2BhwzwR.js} +0 -0
- /package/client/dist/assets/{tickets-DTHo9c3C.js → tickets-D1IeX2EW.js} +0 -0
- /package/client/dist/assets/{tickets-BoXom7l8.js → tickets-DZut8Ryt.js} +0 -0
- /package/client/dist/assets/{tickets-CWYFvx1W2.js → tickets-LfK6LzKl2.js} +0 -0
- /package/client/dist/assets/{tickets-CFXnJsYF.js → tickets-dQfsc7Ph.js} +0 -0
- /package/client/dist/assets/{tickets-B7zT4IRf.js → tickets-sVun0I6v.js} +0 -0
|
@@ -3,9 +3,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BACKGROUND_LOG_RETENTION_MS = void 0;
|
|
6
7
|
exports.trackTransientChild = trackTransientChild;
|
|
7
8
|
exports.killTransientChildren = killTransientChildren;
|
|
9
|
+
exports.startBackgroundProcess = startBackgroundProcess;
|
|
10
|
+
exports.getBackgroundProcess = getBackgroundProcess;
|
|
11
|
+
exports.getBackgroundProcessLogs = getBackgroundProcessLogs;
|
|
12
|
+
exports.listBackgroundProcesses = listBackgroundProcesses;
|
|
13
|
+
exports.killBackgroundProcess = killBackgroundProcess;
|
|
14
|
+
exports.killOwnedBackgroundProcess = killOwnedBackgroundProcess;
|
|
15
|
+
exports.killBackgroundProcessesForChat = killBackgroundProcessesForChat;
|
|
8
16
|
const tree_kill_1 = __importDefault(require("tree-kill"));
|
|
17
|
+
const child_process_1 = require("child_process");
|
|
18
|
+
const readline_1 = __importDefault(require("readline"));
|
|
9
19
|
/**
|
|
10
20
|
* Registry of fire-and-forget child processes that are NOT owned by a long-lived
|
|
11
21
|
* manager (QueueManager / ChatManager / SetupManager track their own). The Quick
|
|
@@ -17,6 +27,35 @@ const tree_kill_1 = __importDefault(require("tree-kill"));
|
|
|
17
27
|
* app shuts down. Self-cleaning: each child is auto-unregistered on `close`.
|
|
18
28
|
*/
|
|
19
29
|
const byProject = new Map();
|
|
30
|
+
const backgroundByPid = new Map();
|
|
31
|
+
const finishedBackgroundByPid = new Map();
|
|
32
|
+
const backgroundTerminal = new Set(['exited', 'killed', 'failed']);
|
|
33
|
+
const BACKGROUND_KILL_GRACE_MS = 2500;
|
|
34
|
+
const BACKGROUND_OUTPUT_MAX_LINE_CHARS = 1000;
|
|
35
|
+
const BACKGROUND_OUTPUT_MAX_LINES_PER_SECOND = 20;
|
|
36
|
+
const BACKGROUND_LOG_MAX_LINES = 500;
|
|
37
|
+
exports.BACKGROUND_LOG_RETENTION_MS = 10 * 60 * 1000;
|
|
38
|
+
function treeKillSafe(pid, signal) {
|
|
39
|
+
try {
|
|
40
|
+
(0, tree_kill_1.default)(pid, signal, () => undefined);
|
|
41
|
+
}
|
|
42
|
+
catch { /* best-effort */ }
|
|
43
|
+
}
|
|
44
|
+
function treeKillWithEscalation(pid, isStillAlive = () => backgroundByPid.has(pid)) {
|
|
45
|
+
treeKillSafe(pid, 'SIGTERM');
|
|
46
|
+
const timer = setTimeout(() => {
|
|
47
|
+
if (isStillAlive())
|
|
48
|
+
treeKillSafe(pid, 'SIGKILL');
|
|
49
|
+
}, BACKGROUND_KILL_GRACE_MS);
|
|
50
|
+
timer.unref?.();
|
|
51
|
+
return timer;
|
|
52
|
+
}
|
|
53
|
+
function cloneProcess(process) {
|
|
54
|
+
return { ...process };
|
|
55
|
+
}
|
|
56
|
+
function cloneLogLine(line) {
|
|
57
|
+
return { ...line };
|
|
58
|
+
}
|
|
20
59
|
/** Track a child under a projectId; auto-removes itself on close. */
|
|
21
60
|
function trackTransientChild(projectId, child) {
|
|
22
61
|
let set = byProject.get(projectId);
|
|
@@ -36,18 +75,236 @@ function trackTransientChild(projectId, child) {
|
|
|
36
75
|
child.once('close', drop);
|
|
37
76
|
child.once('error', drop);
|
|
38
77
|
}
|
|
39
|
-
/** SIGTERM the whole subtree of every tracked child for a project, then
|
|
78
|
+
/** SIGTERM the whole subtree of every tracked child for a project, then escalate. */
|
|
40
79
|
function killTransientChildren(projectId) {
|
|
41
80
|
const set = byProject.get(projectId);
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
81
|
+
if (set)
|
|
82
|
+
for (const child of set) {
|
|
83
|
+
if (child.pid) {
|
|
84
|
+
if (backgroundByPid.has(child.pid))
|
|
85
|
+
continue;
|
|
86
|
+
let alive = true;
|
|
87
|
+
const timer = treeKillWithEscalation(child.pid, () => alive);
|
|
88
|
+
const clear = () => { alive = false; clearTimeout(timer); };
|
|
89
|
+
child.once('close', clear);
|
|
90
|
+
child.once('error', clear);
|
|
48
91
|
}
|
|
49
|
-
catch { /* best-effort */ }
|
|
50
92
|
}
|
|
51
|
-
}
|
|
52
93
|
byProject.delete(projectId);
|
|
94
|
+
for (const [pid, record] of [...backgroundByPid]) {
|
|
95
|
+
if (record.process.projectId !== projectId)
|
|
96
|
+
continue;
|
|
97
|
+
markTerminal(record, 'killed', null, 'SIGTERM');
|
|
98
|
+
terminateBackgroundRecord(record);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function startBackgroundProcess(command, cwd, chatId, projectId, hooks) {
|
|
102
|
+
const child = (0, child_process_1.spawn)(command, {
|
|
103
|
+
cwd,
|
|
104
|
+
shell: true,
|
|
105
|
+
detached: true,
|
|
106
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
107
|
+
});
|
|
108
|
+
if (!child.pid) {
|
|
109
|
+
throw new Error('background process failed to start: missing pid');
|
|
110
|
+
}
|
|
111
|
+
const process = {
|
|
112
|
+
pid: child.pid,
|
|
113
|
+
command,
|
|
114
|
+
cwd,
|
|
115
|
+
startedAt: Date.now(),
|
|
116
|
+
status: 'running',
|
|
117
|
+
chatId,
|
|
118
|
+
projectId,
|
|
119
|
+
};
|
|
120
|
+
const staleFinished = finishedBackgroundByPid.get(child.pid);
|
|
121
|
+
if (staleFinished) {
|
|
122
|
+
clearTimeout(staleFinished.cleanupTimer);
|
|
123
|
+
finishedBackgroundByPid.delete(child.pid);
|
|
124
|
+
}
|
|
125
|
+
const record = {
|
|
126
|
+
child,
|
|
127
|
+
process,
|
|
128
|
+
hooks: hooks ?? {},
|
|
129
|
+
outputLines: [],
|
|
130
|
+
droppedOutputLines: 0,
|
|
131
|
+
};
|
|
132
|
+
backgroundByPid.set(child.pid, record);
|
|
133
|
+
trackTransientChild(projectId, child);
|
|
134
|
+
attachOutput(child, 'stdout', record);
|
|
135
|
+
attachOutput(child, 'stderr', record);
|
|
136
|
+
child.once('error', () => {
|
|
137
|
+
markTerminal(record, process.status === 'killed' ? 'killed' : 'failed', null, null);
|
|
138
|
+
backgroundByPid.delete(process.pid);
|
|
139
|
+
retainFinishedRecord(record);
|
|
140
|
+
});
|
|
141
|
+
child.once('close', (code, signal) => {
|
|
142
|
+
const status = process.status === 'killed' ? 'killed' : code === 0 ? 'exited' : 'failed';
|
|
143
|
+
markTerminal(record, status, code, signal);
|
|
144
|
+
backgroundByPid.delete(process.pid);
|
|
145
|
+
retainFinishedRecord(record);
|
|
146
|
+
});
|
|
147
|
+
record.hooks.onStarted?.(cloneProcess(process));
|
|
148
|
+
return cloneProcess(process);
|
|
149
|
+
}
|
|
150
|
+
function attachOutput(child, source, record) {
|
|
151
|
+
const stream = source === 'stdout' ? child.stdout : child.stderr;
|
|
152
|
+
const rl = readline_1.default.createInterface({ input: stream });
|
|
153
|
+
let windowStart = Date.now();
|
|
154
|
+
let emittedInWindow = 0;
|
|
155
|
+
rl.on('line', (line) => {
|
|
156
|
+
const clipped = line.length > BACKGROUND_OUTPUT_MAX_LINE_CHARS ? `${line.slice(0, BACKGROUND_OUTPUT_MAX_LINE_CHARS)}...` : line;
|
|
157
|
+
appendOutputLine(record, source, clipped);
|
|
158
|
+
if (!record.hooks.onOutput)
|
|
159
|
+
return;
|
|
160
|
+
const now = Date.now();
|
|
161
|
+
if (now - windowStart >= 1000) {
|
|
162
|
+
windowStart = now;
|
|
163
|
+
emittedInWindow = 0;
|
|
164
|
+
}
|
|
165
|
+
if (emittedInWindow >= BACKGROUND_OUTPUT_MAX_LINES_PER_SECOND)
|
|
166
|
+
return;
|
|
167
|
+
emittedInWindow += 1;
|
|
168
|
+
record.hooks.onOutput?.({
|
|
169
|
+
pid: record.process.pid,
|
|
170
|
+
chatId: record.process.chatId,
|
|
171
|
+
projectId: record.process.projectId,
|
|
172
|
+
source,
|
|
173
|
+
line: clipped,
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
function appendOutputLine(record, source, line) {
|
|
178
|
+
record.outputLines.push({ at: Date.now(), source, line });
|
|
179
|
+
if (record.outputLines.length > BACKGROUND_LOG_MAX_LINES) {
|
|
180
|
+
const overflow = record.outputLines.length - BACKGROUND_LOG_MAX_LINES;
|
|
181
|
+
record.outputLines.splice(0, overflow);
|
|
182
|
+
record.droppedOutputLines += overflow;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function retainFinishedRecord(record) {
|
|
186
|
+
if (record.retained) {
|
|
187
|
+
const existing = finishedBackgroundByPid.get(record.process.pid);
|
|
188
|
+
if (existing) {
|
|
189
|
+
existing.process = cloneProcess(record.process);
|
|
190
|
+
existing.outputLines = record.outputLines.map(cloneLogLine);
|
|
191
|
+
existing.droppedOutputLines = record.droppedOutputLines;
|
|
192
|
+
}
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
record.retained = true;
|
|
196
|
+
const previous = finishedBackgroundByPid.get(record.process.pid);
|
|
197
|
+
if (previous)
|
|
198
|
+
clearTimeout(previous.cleanupTimer);
|
|
199
|
+
const cleanupTimer = setTimeout(() => {
|
|
200
|
+
finishedBackgroundByPid.delete(record.process.pid);
|
|
201
|
+
}, exports.BACKGROUND_LOG_RETENTION_MS);
|
|
202
|
+
cleanupTimer.unref?.();
|
|
203
|
+
finishedBackgroundByPid.set(record.process.pid, {
|
|
204
|
+
process: cloneProcess(record.process),
|
|
205
|
+
outputLines: record.outputLines.map(cloneLogLine),
|
|
206
|
+
droppedOutputLines: record.droppedOutputLines,
|
|
207
|
+
cleanupTimer,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
function markTerminal(record, status, exitCode, signal) {
|
|
211
|
+
if (record.killTimer)
|
|
212
|
+
clearTimeout(record.killTimer);
|
|
213
|
+
record.process.status = status;
|
|
214
|
+
record.process.exitCode = exitCode;
|
|
215
|
+
record.process.signal = signal;
|
|
216
|
+
if (record.terminalNotified)
|
|
217
|
+
return;
|
|
218
|
+
record.terminalNotified = true;
|
|
219
|
+
record.hooks.onExited?.(cloneProcess(record.process));
|
|
220
|
+
}
|
|
221
|
+
function getBackgroundProcess(pid) {
|
|
222
|
+
const record = backgroundByPid.get(pid);
|
|
223
|
+
if (record)
|
|
224
|
+
return cloneProcess(record.process);
|
|
225
|
+
const finished = finishedBackgroundByPid.get(pid);
|
|
226
|
+
return finished ? cloneProcess(finished.process) : null;
|
|
227
|
+
}
|
|
228
|
+
function getBackgroundProcessLogs(pid, filter = {}) {
|
|
229
|
+
const live = backgroundByPid.get(pid);
|
|
230
|
+
const record = live
|
|
231
|
+
? {
|
|
232
|
+
process: live.process,
|
|
233
|
+
outputLines: live.outputLines,
|
|
234
|
+
droppedOutputLines: live.droppedOutputLines,
|
|
235
|
+
}
|
|
236
|
+
: finishedBackgroundByPid.get(pid);
|
|
237
|
+
if (!record)
|
|
238
|
+
return null;
|
|
239
|
+
if (filter.projectId && record.process.projectId !== filter.projectId)
|
|
240
|
+
return null;
|
|
241
|
+
if (filter.chatId && record.process.chatId !== filter.chatId)
|
|
242
|
+
return null;
|
|
243
|
+
const limit = typeof filter.limit === 'number' && Number.isFinite(filter.limit)
|
|
244
|
+
? Math.max(1, Math.min(BACKGROUND_LOG_MAX_LINES, Math.floor(filter.limit)))
|
|
245
|
+
: BACKGROUND_LOG_MAX_LINES;
|
|
246
|
+
const start = Math.max(0, record.outputLines.length - limit);
|
|
247
|
+
const lines = record.outputLines.slice(start).map(cloneLogLine);
|
|
248
|
+
const droppedByLimit = record.outputLines.length - lines.length;
|
|
249
|
+
const droppedLines = record.droppedOutputLines + droppedByLimit;
|
|
250
|
+
return {
|
|
251
|
+
process: cloneProcess(record.process),
|
|
252
|
+
lines,
|
|
253
|
+
truncated: droppedLines > 0,
|
|
254
|
+
droppedLines,
|
|
255
|
+
maxLines: BACKGROUND_LOG_MAX_LINES,
|
|
256
|
+
maxLineChars: BACKGROUND_OUTPUT_MAX_LINE_CHARS,
|
|
257
|
+
retentionMs: exports.BACKGROUND_LOG_RETENTION_MS,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
function listBackgroundProcesses(filter = {}) {
|
|
261
|
+
const processes = [];
|
|
262
|
+
for (const record of backgroundByPid.values()) {
|
|
263
|
+
const process = record.process;
|
|
264
|
+
if (filter.projectId && process.projectId !== filter.projectId)
|
|
265
|
+
continue;
|
|
266
|
+
if (filter.chatId && process.chatId !== filter.chatId)
|
|
267
|
+
continue;
|
|
268
|
+
if (backgroundTerminal.has(process.status))
|
|
269
|
+
continue;
|
|
270
|
+
processes.push(cloneProcess(process));
|
|
271
|
+
}
|
|
272
|
+
return processes;
|
|
273
|
+
}
|
|
274
|
+
function killBackgroundProcess(pid) {
|
|
275
|
+
const record = backgroundByPid.get(pid);
|
|
276
|
+
if (!record)
|
|
277
|
+
return;
|
|
278
|
+
record.process.status = 'killed';
|
|
279
|
+
terminateBackgroundRecord(record);
|
|
280
|
+
}
|
|
281
|
+
function killOwnedBackgroundProcess(pid, owner) {
|
|
282
|
+
const record = backgroundByPid.get(pid);
|
|
283
|
+
if (!record)
|
|
284
|
+
return false;
|
|
285
|
+
if (record.process.projectId !== owner.projectId)
|
|
286
|
+
return false;
|
|
287
|
+
if (record.process.chatId !== owner.chatId)
|
|
288
|
+
return false;
|
|
289
|
+
killBackgroundProcess(pid);
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
292
|
+
function terminateBackgroundRecord(record) {
|
|
293
|
+
if (record.killTimer)
|
|
294
|
+
clearTimeout(record.killTimer);
|
|
295
|
+
record.killTimer = treeKillWithEscalation(record.process.pid);
|
|
296
|
+
}
|
|
297
|
+
function killBackgroundProcessesForChat(chatId, projectId) {
|
|
298
|
+
let killed = 0;
|
|
299
|
+
for (const record of backgroundByPid.values()) {
|
|
300
|
+
if (record.process.chatId !== chatId)
|
|
301
|
+
continue;
|
|
302
|
+
if (projectId && record.process.projectId !== projectId)
|
|
303
|
+
continue;
|
|
304
|
+
record.process.status = 'killed';
|
|
305
|
+
markTerminal(record, 'killed', null, 'SIGTERM');
|
|
306
|
+
terminateBackgroundRecord(record);
|
|
307
|
+
killed += 1;
|
|
308
|
+
}
|
|
309
|
+
return killed;
|
|
53
310
|
}
|
|
@@ -29,6 +29,7 @@ exports.spawnCodex = spawnCodex;
|
|
|
29
29
|
exports.spawnGemini = spawnGemini;
|
|
30
30
|
exports.spawnAiCli = spawnAiCli;
|
|
31
31
|
const win_spawn_1 = require("./win-spawn");
|
|
32
|
+
const headroom_routing_1 = require("../headroom-routing");
|
|
32
33
|
// Per-call (not a frozen module const) so a test can flip the platform with a
|
|
33
34
|
// `process.platform` spy without re-importing this module — which removes a
|
|
34
35
|
// flaky vi.doMock + resetModules + dynamic-import dance in the spawn tests.
|
|
@@ -147,6 +148,7 @@ function ensureStdinPipe(stdio) {
|
|
|
147
148
|
* survive. POSIX call is identical to `spawnCli('claude', args, options)`.
|
|
148
149
|
*/
|
|
149
150
|
function spawnClaude(args, options = {}) {
|
|
151
|
+
options = (0, headroom_routing_1.withHeadroomSpawnEnv)('claude', options);
|
|
150
152
|
if (!isWin()) {
|
|
151
153
|
return (0, win_spawn_1.spawnCli)('claude', args, options);
|
|
152
154
|
}
|
|
@@ -169,6 +171,7 @@ function spawnClaude(args, options = {}) {
|
|
|
169
171
|
* survive. POSIX call is identical to `spawnCli('codex', args, options)`.
|
|
170
172
|
*/
|
|
171
173
|
function spawnCodex(args, options = {}) {
|
|
174
|
+
options = (0, headroom_routing_1.withHeadroomSpawnEnv)('codex', options);
|
|
172
175
|
if (!isWin()) {
|
|
173
176
|
return (0, win_spawn_1.spawnCli)('codex', args, options);
|
|
174
177
|
}
|
|
@@ -147,12 +147,12 @@ function resolveProjectExecution(project, home) {
|
|
|
147
147
|
*
|
|
148
148
|
* Legacy projects return `process.env` untouched — byte-identical behaviour.
|
|
149
149
|
*/
|
|
150
|
-
function resolveLoopBaseEnv(project, home) {
|
|
150
|
+
function resolveLoopBaseEnv(project, home, baseEnv = process.env) {
|
|
151
151
|
const exec = resolveProjectExecution(project, home);
|
|
152
152
|
if (!exec.relocated)
|
|
153
|
-
return
|
|
153
|
+
return baseEnv;
|
|
154
154
|
const { SPECRAILS_REPO_DIR: _perRun, ...projectEnv } = exec.env;
|
|
155
|
-
return { ...
|
|
155
|
+
return { ...baseEnv, ...projectEnv };
|
|
156
156
|
}
|
|
157
157
|
/** Build the legacy (in-repo, byte-identical-to-today) execution. */
|
|
158
158
|
function legacyExecution(repoDir) {
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.scanWorktreeEnvRequirements = scanWorktreeEnvRequirements;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const db_1 = require("./db");
|
|
10
|
+
const MAX_FILES = 250;
|
|
11
|
+
const MAX_DEPTH = 4;
|
|
12
|
+
const MAX_FILE_BYTES = 512 * 1024;
|
|
13
|
+
const SCANNED_FILENAMES = new Set([
|
|
14
|
+
'.npmrc',
|
|
15
|
+
'.yarnrc.yml',
|
|
16
|
+
'.yarnrc',
|
|
17
|
+
'.pnpmrc',
|
|
18
|
+
'package.json',
|
|
19
|
+
'pnpm-workspace.yaml',
|
|
20
|
+
'npm-shrinkwrap.json',
|
|
21
|
+
]);
|
|
22
|
+
const SKIP_DIRS = new Set([
|
|
23
|
+
'.git',
|
|
24
|
+
'.hg',
|
|
25
|
+
'.svn',
|
|
26
|
+
'node_modules',
|
|
27
|
+
'dist',
|
|
28
|
+
'build',
|
|
29
|
+
'coverage',
|
|
30
|
+
'.next',
|
|
31
|
+
'.nuxt',
|
|
32
|
+
'.turbo',
|
|
33
|
+
'.cache',
|
|
34
|
+
'.specrails',
|
|
35
|
+
]);
|
|
36
|
+
const ENV_REF_RE = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}|process\.env\.([A-Za-z_][A-Za-z0-9_]*)|process\.env\[['"]([A-Za-z_][A-Za-z0-9_]*)['"]\]/g;
|
|
37
|
+
const COMMON_PUBLIC_NPM_SCOPES = new Set([
|
|
38
|
+
'@babel',
|
|
39
|
+
'@codemirror',
|
|
40
|
+
'@eslint',
|
|
41
|
+
'@modelcontextprotocol',
|
|
42
|
+
'@monaco-editor',
|
|
43
|
+
'@radix-ui',
|
|
44
|
+
'@rolldown',
|
|
45
|
+
'@rollup',
|
|
46
|
+
'@tailwindcss',
|
|
47
|
+
'@tauri-apps',
|
|
48
|
+
'@testing-library',
|
|
49
|
+
'@types',
|
|
50
|
+
'@typescript-eslint',
|
|
51
|
+
'@vitejs',
|
|
52
|
+
'@vitest',
|
|
53
|
+
'@xterm',
|
|
54
|
+
]);
|
|
55
|
+
function addCandidate(map, name, confidence, reason, file) {
|
|
56
|
+
if (!db_1.WORKTREE_ENV_NAME_RE.test(name))
|
|
57
|
+
return;
|
|
58
|
+
const existing = map.get(name);
|
|
59
|
+
if (!existing) {
|
|
60
|
+
map.set(name, { name, confidence, reasons: [reason], files: [file] });
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (confidence === 'high')
|
|
64
|
+
existing.confidence = 'high';
|
|
65
|
+
if (!existing.reasons.includes(reason))
|
|
66
|
+
existing.reasons.push(reason);
|
|
67
|
+
if (!existing.files.includes(file))
|
|
68
|
+
existing.files.push(file);
|
|
69
|
+
}
|
|
70
|
+
function walk(root) {
|
|
71
|
+
const files = [];
|
|
72
|
+
const skipped = [];
|
|
73
|
+
const visit = (dir, depth) => {
|
|
74
|
+
if (files.length >= MAX_FILES)
|
|
75
|
+
return;
|
|
76
|
+
let entries;
|
|
77
|
+
try {
|
|
78
|
+
entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
skipped.push(path_1.default.relative(root, dir) || '.');
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
for (const entry of entries) {
|
|
85
|
+
if (files.length >= MAX_FILES)
|
|
86
|
+
return;
|
|
87
|
+
const abs = path_1.default.join(dir, entry.name);
|
|
88
|
+
if (entry.isDirectory()) {
|
|
89
|
+
if (depth >= MAX_DEPTH || SKIP_DIRS.has(entry.name))
|
|
90
|
+
continue;
|
|
91
|
+
visit(abs, depth + 1);
|
|
92
|
+
}
|
|
93
|
+
else if (entry.isFile() && SCANNED_FILENAMES.has(entry.name)) {
|
|
94
|
+
files.push(abs);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
visit(root, 0);
|
|
99
|
+
return { files, skipped };
|
|
100
|
+
}
|
|
101
|
+
function readSmallText(file) {
|
|
102
|
+
try {
|
|
103
|
+
const st = fs_1.default.statSync(file);
|
|
104
|
+
if (st.size > MAX_FILE_BYTES)
|
|
105
|
+
return null;
|
|
106
|
+
return fs_1.default.readFileSync(file, 'utf8');
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function scanEnvReferences(raw, rel, candidates) {
|
|
113
|
+
for (const match of raw.matchAll(ENV_REF_RE)) {
|
|
114
|
+
const name = match[1] ?? match[2] ?? match[3];
|
|
115
|
+
if (!name)
|
|
116
|
+
continue;
|
|
117
|
+
addCandidate(candidates, name, 'high', 'Referenced explicitly by the repository configuration', rel);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function packageScopes(pkg) {
|
|
121
|
+
const scopes = new Set();
|
|
122
|
+
for (const key of ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']) {
|
|
123
|
+
const deps = pkg[key];
|
|
124
|
+
if (!deps || typeof deps !== 'object' || Array.isArray(deps))
|
|
125
|
+
continue;
|
|
126
|
+
for (const name of Object.keys(deps)) {
|
|
127
|
+
const m = /^(@[^/]+)\//.exec(name);
|
|
128
|
+
if (m)
|
|
129
|
+
scopes.add(m[1]);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return scopes;
|
|
133
|
+
}
|
|
134
|
+
function likelyPrivatePackageScopes(scopes) {
|
|
135
|
+
return Array.from(scopes).filter((scope) => !COMMON_PUBLIC_NPM_SCOPES.has(scope)).sort();
|
|
136
|
+
}
|
|
137
|
+
function scanPackageJson(raw, rel, candidates) {
|
|
138
|
+
let pkg;
|
|
139
|
+
try {
|
|
140
|
+
pkg = JSON.parse(raw);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const privateScopes = likelyPrivatePackageScopes(packageScopes(pkg));
|
|
146
|
+
if (privateScopes.length > 0) {
|
|
147
|
+
addCandidate(candidates, 'NODE_AUTH_TOKEN', 'medium', 'Package dependencies include scoped packages that may require npm auth', rel);
|
|
148
|
+
addCandidate(candidates, 'NPM_TOKEN', 'medium', 'Package dependencies include scoped packages that may require npm auth', rel);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function scanWorktreeEnvRequirements(repoDir) {
|
|
152
|
+
const { files, skipped } = walk(repoDir);
|
|
153
|
+
const candidates = new Map();
|
|
154
|
+
const scannedFiles = [];
|
|
155
|
+
for (const file of files) {
|
|
156
|
+
const raw = readSmallText(file);
|
|
157
|
+
if (raw === null) {
|
|
158
|
+
skipped.push(path_1.default.relative(repoDir, file) || path_1.default.basename(file));
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
const rel = path_1.default.relative(repoDir, file) || path_1.default.basename(file);
|
|
162
|
+
scannedFiles.push(rel);
|
|
163
|
+
scanEnvReferences(raw, rel, candidates);
|
|
164
|
+
if (path_1.default.basename(file) === 'package.json')
|
|
165
|
+
scanPackageJson(raw, rel, candidates);
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
candidates: Array.from(candidates.values()).sort((a, b) => a.name.localeCompare(b.name)),
|
|
169
|
+
scannedFiles,
|
|
170
|
+
skipped,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as e}from"./chunk-BNv3lrIs.js";import{Cn as t,F as n,Kn as r,Ln as i,Rn as a,n as o,s}from"./index-Dw1N2-ci.js";var c=e(r(),1);function l(e,t){let n=e.indexOf(`,`);if(!e.startsWith(`data:`)||n===-1)throw Error(`dataUrlToFile: not a data URL`);let r=e.slice(0,n),i=/^data:([^;,]+)/.exec(r)?.[1]||`application/octet-stream`,a=e.slice(n+1);if(/;base64$/i.test(r)){let e=atob(a),n=new Uint8Array(e.length);for(let t=0;t<e.length;t++)n[t]=e.charCodeAt(t);return new File([n],t,{type:i})}return new File([decodeURIComponent(a)],t,{type:i})}var u=t();function d({projectId:e,conversationId:t}){let{t:r}=a(`agent`),{closeBrowser:d,queueCapture:f}=o(),p=(0,c.useMemo)(()=>`agent-${t??`home`}-${Math.round(performance.now())}`,[t]),m=async e=>{if(!t){i.error(r(`workspace.requiresConversation`));return}try{f(await s(t,l(e.screenshotDataUrl,`capture-${Date.now()}.png`))),i.success(r(`workspace.browserCaptured`)),d()}catch(e){i.error(r(`workspace.uploadFailed`),{description:e instanceof Error?e.message:void 0})}};return(0,u.jsx)(n,{open:!0,onClose:d,projectId:e,pendingSpecId:p,confirmLabel:r(`workspace.browserConfirm`),onCaptured:e=>{m(e)}})}export{d as AgentBrowserCapture};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as e}from"./chunk-BNv3lrIs.js";import{Cn as t,Kn as n,Mt as r,Pt as i,Rn as a,Sn as o,at as s,b as c,bn as l,cn as u,jt as d,n as f,rt as p,tt as m,vn as h,wn as g,yn as _}from"./index-Dw1N2-ci.js";import{JobDetailModal as v}from"./JobDetailModal-BWJR60fi.js";import{t as y}from"./format-command-CuWuRvka.js";var b=e(n(),1),x=t(),S=360,C=480,w={running:`running`,completed:`success`,failed:`failed`,canceled:`canceled`,queued:`queued`};function T({projectId:e}){let{t}=a(`agent`),{t:n}=a(`jobs`),{closeJobsPane:T}=f(),{projects:E}=h(),D=E.find(t=>t.id===e)?.provider,[O,k]=(0,b.useState)(C),[A,j]=(0,b.useState)(!1),[M,N]=(0,b.useState)(null),{data:P,isFirstLoad:F,refresh:I}=_({namespace:`agent-jobs`,projectId:e,initialValue:[],fetcher:async()=>{let e=await fetch(`${g()}/jobs?limit=50`);return e.ok?(await e.json()).jobs:[]},pollInterval:5e3}),{registerHandler:L,unregisterHandler:R}=o(),z=(0,b.useRef)(e);z.current=e;let B=(0,b.useRef)(I);B.current=I,(0,b.useEffect)(()=>(L(`agent-jobs-pane`,e=>{let t=e;t.type===`queue`&&(t.projectId&&t.projectId!==z.current||B.current())}),()=>R(`agent-jobs-pane`)),[L,R]);let V=(0,b.useCallback)(e=>{let t=e.clientX,n=O,r=window.innerWidth-S;try{e.currentTarget.setPointerCapture(e.pointerId)}catch{}let i=e=>{k(Math.min(Math.max(n+(t-e.clientX),S),r))},a=()=>{window.removeEventListener(`pointermove`,i),window.removeEventListener(`pointerup`,a),window.removeEventListener(`pointercancel`,a)};window.addEventListener(`pointermove`,i),window.addEventListener(`pointerup`,a),window.addEventListener(`pointercancel`,a)},[O]);return(0,x.jsxs)(`div`,{className:p(`flex h-full flex-col overflow-hidden border-l border-border bg-background`,A&&`absolute inset-0 z-30 border-l-0`),style:A?void 0:{width:O,flexShrink:0},children:[(0,x.jsx)(`div`,{className:`relative flex items-center`,children:!A&&(0,x.jsx)(`div`,{role:`separator`,"aria-orientation":`vertical`,onPointerDown:V,className:`absolute left-0 top-0 h-full w-1.5 -translate-x-full cursor-col-resize select-none touch-none hover:bg-accent-primary/20`,title:t(`workspace.resizeJobs`)})}),(0,x.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-border/60 bg-surface/40 px-3 py-1.5`,children:[(0,x.jsx)(`span`,{className:`text-xs font-medium text-foreground/70`,children:t(`workspace.jobs`)}),(0,x.jsxs)(`div`,{className:`ml-auto flex items-center gap-1`,children:[(0,x.jsx)(`button`,{type:`button`,onClick:()=>j(e=>!e),"aria-label":t(A?`restore`:`maximize`),title:t(A?`restore`:`maximize`),className:`rounded-md p-1 text-foreground/60 hover:bg-surface hover:text-foreground`,children:A?(0,x.jsx)(d,{className:`h-4 w-4`}):(0,x.jsx)(r,{className:`h-4 w-4`})}),(0,x.jsx)(`button`,{type:`button`,onClick:T,"aria-label":t(`workspace.closeJobs`),title:t(`workspace.closeJobs`),className:`rounded-md p-1 text-foreground/60 hover:bg-surface hover:text-foreground`,children:(0,x.jsx)(s,{className:`h-4 w-4`})})]})]}),(0,x.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-2`,children:F?(0,x.jsx)(`div`,{className:`flex h-24 items-center justify-center text-muted-foreground`,children:(0,x.jsx)(i,{className:`h-4 w-4 animate-spin`})}):P.length===0?(0,x.jsxs)(`div`,{className:`flex h-full flex-col items-center justify-center gap-2 text-center text-muted-foreground`,children:[(0,x.jsx)(u,{className:`h-6 w-6 opacity-40`}),(0,x.jsx)(`p`,{className:`text-xs`,children:t(`workspace.noJobs`)})]}):(0,x.jsx)(`ul`,{className:`space-y-1`,children:P.map(e=>(0,x.jsx)(`li`,{children:(0,x.jsxs)(`button`,{type:`button`,onClick:()=>N(e.id),className:p(`flex w-full flex-col gap-1 rounded-lg border border-border/50 bg-surface/30 px-2.5 py-2 text-left transition-colors`,`hover:border-accent-primary/40 hover:bg-surface/60`),children:[(0,x.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,x.jsx)(m,{variant:w[e.status]??`queued`,children:n(`statusLabel.${e.status in w?e.status:`queued`}`)}),e.status===`running`&&(0,x.jsx)(i,{className:`h-3 w-3 animate-spin text-accent-primary`}),(0,x.jsx)(`span`,{className:`ml-auto text-[10px] text-muted-foreground`,children:c(new Date(e.started_at),{addSuffix:!0,locale:l()})})]}),(0,x.jsx)(`code`,{className:`truncate font-mono text-xs text-foreground/85`,children:y(e.command,D)})]})},e.id))})}),M&&(0,x.jsx)(v,{jobId:M,onClose:()=>N(null)})]})}export{T as AgentModeJobsPane};
|