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
|
@@ -12,6 +12,7 @@ const providers_1 = require("./providers");
|
|
|
12
12
|
const agent_tier_1 = require("./agent-tier");
|
|
13
13
|
const attachment_manager_1 = require("./attachment-manager");
|
|
14
14
|
const agent_store_1 = require("./agent-store");
|
|
15
|
+
const transient_children_1 = require("./transient-children");
|
|
15
16
|
function isAgentChatEnabled() {
|
|
16
17
|
return process.env.SPECRAILS_AGENT_CHAT !== 'false';
|
|
17
18
|
}
|
|
@@ -235,6 +236,7 @@ function createAgentChatRouter(deps) {
|
|
|
235
236
|
router.delete('/conversations/:id', (req, res) => {
|
|
236
237
|
const id = String(req.params.id);
|
|
237
238
|
manager.abort(id);
|
|
239
|
+
(0, transient_children_1.killBackgroundProcessesForChat)(id);
|
|
238
240
|
(0, agent_store_1.deleteAgentConversation)(desktopDb, id);
|
|
239
241
|
// Cascade-remove the conversation's attachment directory (best-effort).
|
|
240
242
|
void attachment_manager_1.attachmentManager.deleteAllAgent(id).catch((e) => console.error('[agent-chat] attachment cleanup failed:', e));
|
|
@@ -161,6 +161,7 @@ never try to work around the refusal. When you are about to propose an action
|
|
|
161
161
|
above the current level, say so up front.
|
|
162
162
|
|
|
163
163
|
- NEVER call an ai-spawn action (rails launch, jobs spawn/interactive_turn,
|
|
164
|
+
jobs background_start,
|
|
164
165
|
specs create/generate/ai_edit/contract_refine/smash, chat send, agents
|
|
165
166
|
generate/test/refine, code regenerate_summary) without first proposing it in
|
|
166
167
|
plain words — what runs, on which project, which engine/model, roughly how
|
|
@@ -401,6 +402,21 @@ summary later.
|
|
|
401
402
|
- \`specrails_jobs(spawn, command)\` bypasses rails to enqueue an arbitrary
|
|
402
403
|
slash-command job (e.g. \`/specrails:implement #5 --yes\`). Use rails for
|
|
403
404
|
normal implement flows; spawn for advanced one-offs.
|
|
405
|
+
- **Long-running shell commands get chips.** When the user asks you to run a
|
|
406
|
+
server/watch/tail command that should keep running (for example \`npm run dev\`,
|
|
407
|
+
\`vite --host\`, \`tail -f\`, or a local service), propose
|
|
408
|
+
\`specrails_jobs(background_start)\` with the command, project and cwd, wait for
|
|
409
|
+
explicit yes, then call that tool with \`confirmed:true\`. Do NOT use a raw shell/background-task
|
|
410
|
+
runner for these requests: only \`background_start\` emits the app events that
|
|
411
|
+
create the killable chip above this agent chat's composer. You normally do not
|
|
412
|
+
need to pass \`chatId\`; the in-app MCP origin conversation owns it. If a
|
|
413
|
+
job/loop is still running, do not pass \`allowWhileBusy:true\` unless the user
|
|
414
|
+
explicitly confirms running concurrently.
|
|
415
|
+
- **Diagnose background chip failures from logs.** If user asks whether
|
|
416
|
+
background chip command failed or why it stopped, call
|
|
417
|
+
\`specrails_jobs(background_logs, pid)\` for that PID before asking
|
|
418
|
+
to relaunch. Explain from captured stdout/stderr tail; only say logs
|
|
419
|
+
unavailable if PID unknown/expired or captured output empty.
|
|
404
420
|
- **Launch, then release the turn.** When a rail launch or job spawn is
|
|
405
421
|
accepted (202), report the returned jobId(s)/ids VERBATIM and END YOUR REPLY
|
|
406
422
|
immediately — do NOT sit on the turn watching the run. Progress streams live
|
|
@@ -471,4 +487,4 @@ When the user has no projects yet, or asks to add one:
|
|
|
471
487
|
Setup is QUICK-only (fast, offline). Do NOT offer, mention, or attempt a "full"
|
|
472
488
|
or "enrich" install — that flow is deprecated and not available through you.
|
|
473
489
|
`;
|
|
474
|
-
exports.OPERATOR_SYSTEM_PROMPT = `You are the Specrails operator agent, embedded inside the Specrails Desktop app; drive it on the user's behalf using the specrails_* MCP tools. Your full operator manual is the CLAUDE.md auto-loaded from your working directory — follow it. Non-negotiables: target a project with specrails_select_project or the projectId argument, and ask rather than guess when none is pinned; support/troubleshooting/install/usage/job-failure questions use specrails_support first and never become specs unless the user pivots to product work; missing agents/skills/slash commands concern the app-global specrails-core framework, never project-owned files — never say agents/skills/commands live inside the project; project setup checkpoints are not a core health signal, so pending/0 agents/0 commands must not trigger specrails_setup(install) or a project repair recommendation; offer core_update_check/core_update_apply only for global core updates, and if global core is current ask for the concrete job error/diagnostic; an on_review spec with an open PR, including a published pr_ready card, can be relaunched to continue that PR branch — do not require publish/discard/merge first; short async 202 ops (spec generation, ai-edit) may be awaited with specrails_watch (projectId required), but after a rail/job LAUNCH is accepted end your reply immediately — progress streams live in the conversation's run card and the app; watch a launched run only when the user explicitly asks you to wait, with a bounded untilMs; never claim success from a 202 acceptance alone — verify from a terminal event or a domain read (e.g. specrails_jobs get); call the free-form autonomous rail mode Freestyle in prose — freestyle/factory:freestyle/{{cmd:freestyle}} are canonical API/id/token values for that same capability; respect the cumulative permission ladder observe / edit / operate / autonomous — if a tool is refused, name the level the user must Shift+Tab to, never work around it; when refining a spec, ground it in the real codebase FIRST (specrails_code tree/read_file/summary + specrails_specs list) and show the evolving draft as one fenced spec-draft JSON block (title, description, labels, priority, acceptanceCriteria) at the end of each turn that changed it — the app renders it as a live card; persist the refined spec with specrails_specs commit_draft (no conversationId) — never route it through create/generate, which regenerate the content with AI; commit_draft appends a Contract Layer by default via one short background AI pass — pass contractRefine false when the user declines it; report tool outputs faithfully, including failures. Format replies for easy reading: short paragraphs separated by blank lines, bullet lists for enumerations. When asking the user to pick between concrete choices, end the reply with a fenced options code block containing a JSON array of the 2-6 choice labels (rendered as clickable chips); never use that block otherwise.`;
|
|
490
|
+
exports.OPERATOR_SYSTEM_PROMPT = `You are the Specrails operator agent, embedded inside the Specrails Desktop app; drive it on the user's behalf using the specrails_* MCP tools. Your full operator manual is the CLAUDE.md auto-loaded from your working directory — follow it. Non-negotiables: target a project with specrails_select_project or the projectId argument, and ask rather than guess when none is pinned; support/troubleshooting/install/usage/job-failure questions use specrails_support first and never become specs unless the user pivots to product work; missing agents/skills/slash commands concern the app-global specrails-core framework, never project-owned files — never say agents/skills/commands live inside the project; project setup checkpoints are not a core health signal, so pending/0 agents/0 commands must not trigger specrails_setup(install) or a project repair recommendation; offer core_update_check/core_update_apply only for global core updates, and if global core is current ask for the concrete job error/diagnostic; an on_review spec with an open PR, including a published pr_ready card, can be relaunched to continue that PR branch — do not require publish/discard/merge first; run long-lived server/watch/tail shell commands with specrails_jobs background_start and confirmed:true after explicit user confirmation, not a raw shell runner, so the app can show the killable background chip in this chat; if a background chip exits/fails, use specrails_jobs background_logs for its pid before asking to relaunch; if a job/loop is still running, pass allowWhileBusy:true only after explicit concurrent confirmation; short async 202 ops (spec generation, ai-edit) may be awaited with specrails_watch (projectId required), but after a rail/job LAUNCH is accepted end your reply immediately — progress streams live in the conversation's run card and the app; watch a launched run only when the user explicitly asks you to wait, with a bounded untilMs; never claim success from a 202 acceptance alone — verify from a terminal event or a domain read (e.g. specrails_jobs get); call the free-form autonomous rail mode Freestyle in prose — freestyle/factory:freestyle/{{cmd:freestyle}} are canonical API/id/token values for that same capability; respect the cumulative permission ladder observe / edit / operate / autonomous — if a tool is refused, name the level the user must Shift+Tab to, never work around it; when refining a spec, ground it in the real codebase FIRST (specrails_code tree/read_file/summary + specrails_specs list) and show the evolving draft as one fenced spec-draft JSON block (title, description, labels, priority, acceptanceCriteria) at the end of each turn that changed it — the app renders it as a live card; persist the refined spec with specrails_specs commit_draft (no conversationId) — never route it through create/generate, which regenerate the content with AI; commit_draft appends a Contract Layer by default via one short background AI pass — pass contractRefine false when the user declines it; report tool outputs faithfully, including failures. Format replies for easy reading: short paragraphs separated by blank lines, bullet lists for enumerations. When asking the user to pick between concrete choices, end the reply with a fenced options code block containing a JSON array of the 2-6 choice labels (rendered as clickable chips); never use that block otherwise.`;
|
package/server/dist/db.js
CHANGED
|
@@ -3,7 +3,7 @@ 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.DEFAULT_FREESTYLE_PRE_PROMPT = void 0;
|
|
6
|
+
exports.WORKTREE_ENV_NAME_RE = exports.DEFAULT_FREESTYLE_PRE_PROMPT = void 0;
|
|
7
7
|
exports.initDb = initDb;
|
|
8
8
|
exports.createJob = createJob;
|
|
9
9
|
exports.markJobInteractive = markJobInteractive;
|
|
@@ -38,6 +38,7 @@ exports.deleteTemplate = deleteTemplate;
|
|
|
38
38
|
exports.skipJob = skipJob;
|
|
39
39
|
exports.getPipelineJobs = getPipelineJobs;
|
|
40
40
|
exports.getStats = getStats;
|
|
41
|
+
exports.normalizeWorktreeEnvPassthrough = normalizeWorktreeEnvPassthrough;
|
|
41
42
|
exports.getProjectSettings = getProjectSettings;
|
|
42
43
|
exports.getFreestylePrePrompt = getFreestylePrePrompt;
|
|
43
44
|
exports.updateProjectSettings = updateProjectSettings;
|
|
@@ -722,7 +723,7 @@ const MIGRATIONS = [
|
|
|
722
723
|
},
|
|
723
724
|
// Migration 36: rail_pr_deliveries — one row per isolated rail LAUNCH tracking
|
|
724
725
|
// the ask-first PR decision lifecycle (building → on_review → pr_draft →
|
|
725
|
-
// pr_ready → merged | discarded | pr_failed). The durable single source of
|
|
726
|
+
// pr_ready → merged | discarded | implementation_failed | pr_failed). The durable single source of
|
|
726
727
|
// truth both decision surfaces (rail row + agent chat) read and write, so a
|
|
727
728
|
// refresh/restart never loses a pending PR decision. `branches` captures the
|
|
728
729
|
// per-unit DeliverBranch records at build-settle (deferred deliverRailAsPr
|
|
@@ -1238,18 +1239,57 @@ exports.DEFAULT_FREESTYLE_PRE_PROMPT = [
|
|
|
1238
1239
|
'Do NOT follow any structured architect/developer/reviewer pipeline — use your own judgement and the repo conventions.',
|
|
1239
1240
|
'Never ask for confirmation; there is no human to answer. Choose the recommended option and proceed.',
|
|
1240
1241
|
].join('\n');
|
|
1242
|
+
exports.WORKTREE_ENV_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
1243
|
+
const WORKTREE_ENV_MAX_NAMES = 64;
|
|
1244
|
+
const WORKTREE_ENV_MAX_NAME_LENGTH = 128;
|
|
1245
|
+
function normalizeWorktreeEnvPassthrough(value) {
|
|
1246
|
+
if (!Array.isArray(value))
|
|
1247
|
+
throw new Error('worktreeEnvPassthrough must be an array of environment variable names');
|
|
1248
|
+
const out = [];
|
|
1249
|
+
const seen = new Set();
|
|
1250
|
+
for (const raw of value) {
|
|
1251
|
+
if (typeof raw !== 'string')
|
|
1252
|
+
throw new Error('worktreeEnvPassthrough entries must be strings');
|
|
1253
|
+
const name = raw.trim();
|
|
1254
|
+
if (!name)
|
|
1255
|
+
continue;
|
|
1256
|
+
if (name.length > WORKTREE_ENV_MAX_NAME_LENGTH)
|
|
1257
|
+
throw new Error(`environment variable name is too long: ${name.slice(0, 24)}...`);
|
|
1258
|
+
if (!exports.WORKTREE_ENV_NAME_RE.test(name))
|
|
1259
|
+
throw new Error(`invalid environment variable name: ${name}`);
|
|
1260
|
+
if (seen.has(name))
|
|
1261
|
+
continue;
|
|
1262
|
+
seen.add(name);
|
|
1263
|
+
out.push(name);
|
|
1264
|
+
if (out.length > WORKTREE_ENV_MAX_NAMES)
|
|
1265
|
+
throw new Error(`worktreeEnvPassthrough can contain at most ${WORKTREE_ENV_MAX_NAMES} names`);
|
|
1266
|
+
}
|
|
1267
|
+
return out;
|
|
1268
|
+
}
|
|
1269
|
+
function parseWorktreeEnvPassthrough(raw) {
|
|
1270
|
+
if (!raw)
|
|
1271
|
+
return [];
|
|
1272
|
+
try {
|
|
1273
|
+
return normalizeWorktreeEnvPassthrough(JSON.parse(raw));
|
|
1274
|
+
}
|
|
1275
|
+
catch {
|
|
1276
|
+
return [];
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1241
1279
|
function getProjectSettings(db) {
|
|
1242
1280
|
const telemetryRow = db.prepare(`SELECT value FROM queue_state WHERE key = 'config.pipeline_telemetry_enabled'`).get();
|
|
1243
1281
|
const modelRow = db.prepare(`SELECT value FROM queue_state WHERE key = 'config.orchestrator_model'`).get();
|
|
1244
1282
|
const prePromptRow = db.prepare(`SELECT value FROM queue_state WHERE key = 'config.pre_prompt'`).get();
|
|
1245
1283
|
const freestylePrePromptRow = db.prepare(`SELECT value FROM queue_state WHERE key = 'config.freestyle_pre_prompt'`).get();
|
|
1246
1284
|
const integrationBranchRow = db.prepare(`SELECT value FROM queue_state WHERE key = 'config.integration_branch'`).get();
|
|
1285
|
+
const worktreeEnvPassthroughRow = db.prepare(`SELECT value FROM queue_state WHERE key = 'config.worktree_env_passthrough'`).get();
|
|
1247
1286
|
return {
|
|
1248
1287
|
pipelineTelemetryEnabled: telemetryRow?.value === 'true',
|
|
1249
1288
|
orchestratorModel: modelRow?.value ?? 'sonnet',
|
|
1250
1289
|
prePrompt: prePromptRow?.value ?? '',
|
|
1251
1290
|
freestylePrePrompt: freestylePrePromptRow?.value ?? '',
|
|
1252
1291
|
integrationBranch: integrationBranchRow?.value ?? '',
|
|
1292
|
+
worktreeEnvPassthrough: parseWorktreeEnvPassthrough(worktreeEnvPassthroughRow?.value),
|
|
1253
1293
|
};
|
|
1254
1294
|
}
|
|
1255
1295
|
/** Resolve the effective Freestyle pre-prompt: the per-project override when
|
|
@@ -1289,6 +1329,15 @@ function updateProjectSettings(db, patch) {
|
|
|
1289
1329
|
db.prepare(`INSERT OR REPLACE INTO queue_state (key, value) VALUES ('config.integration_branch', ?)`).run(patch.integrationBranch.trim());
|
|
1290
1330
|
}
|
|
1291
1331
|
}
|
|
1332
|
+
if (patch.worktreeEnvPassthrough !== undefined) {
|
|
1333
|
+
const names = normalizeWorktreeEnvPassthrough(patch.worktreeEnvPassthrough);
|
|
1334
|
+
if (names.length === 0) {
|
|
1335
|
+
db.prepare(`DELETE FROM queue_state WHERE key = 'config.worktree_env_passthrough'`).run();
|
|
1336
|
+
}
|
|
1337
|
+
else {
|
|
1338
|
+
db.prepare(`INSERT OR REPLACE INTO queue_state (key, value) VALUES ('config.worktree_env_passthrough', ?)`).run(JSON.stringify(names));
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1292
1341
|
}
|
|
1293
1342
|
// ─── Explore Spec acceleration ────────────────────────────────────────────────
|
|
1294
1343
|
/**
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_DEV_CLIENT_PORT = exports.DEFAULT_DEV_SERVER_PORT = void 0;
|
|
4
|
+
exports.parseDevPort = parseDevPort;
|
|
5
|
+
exports.resolveServerPort = resolveServerPort;
|
|
6
|
+
exports.resolveWebDevPorts = resolveWebDevPorts;
|
|
7
|
+
exports.DEFAULT_DEV_SERVER_PORT = 4200;
|
|
8
|
+
exports.DEFAULT_DEV_CLIENT_PORT = 4201;
|
|
9
|
+
function parseDevPort(value, fallback) {
|
|
10
|
+
if (value == null || value.trim() === '')
|
|
11
|
+
return fallback;
|
|
12
|
+
const port = Number(value);
|
|
13
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535)
|
|
14
|
+
return fallback;
|
|
15
|
+
return port;
|
|
16
|
+
}
|
|
17
|
+
function resolveServerPort(argv, env = process.env) {
|
|
18
|
+
let port = parseDevPort(env.SPECRAILS_DEV_SERVER_PORT ?? env.SPECRAILS_PORT, exports.DEFAULT_DEV_SERVER_PORT);
|
|
19
|
+
for (let i = 2; i < argv.length; i++) {
|
|
20
|
+
if (argv[i] === '--port' && argv[i + 1]) {
|
|
21
|
+
port = parseDevPort(argv[++i], port);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return port;
|
|
25
|
+
}
|
|
26
|
+
function resolveWebDevPorts(env = process.env) {
|
|
27
|
+
const serverPort = parseDevPort(env.SPECRAILS_DEV_SERVER_PORT, exports.DEFAULT_DEV_SERVER_PORT);
|
|
28
|
+
const clientPort = parseDevPort(env.SPECRAILS_DEV_CLIENT_PORT, exports.DEFAULT_DEV_CLIENT_PORT);
|
|
29
|
+
return {
|
|
30
|
+
serverPort,
|
|
31
|
+
clientPort,
|
|
32
|
+
serverOrigin: `http://localhost:${serverPort}`,
|
|
33
|
+
wsUrl: `ws://localhost:${serverPort}`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createGlobalPluginsRouter = createGlobalPluginsRouter;
|
|
4
|
+
const express_1 = require("express");
|
|
5
|
+
function isProvider(value) {
|
|
6
|
+
return value === 'codex' || value === 'claude';
|
|
7
|
+
}
|
|
8
|
+
function createGlobalPluginsRouter(headroom) {
|
|
9
|
+
const router = (0, express_1.Router)();
|
|
10
|
+
router.get('/', async (_req, res) => {
|
|
11
|
+
res.json({
|
|
12
|
+
plugins: [
|
|
13
|
+
{
|
|
14
|
+
id: 'headroom-ai',
|
|
15
|
+
name: 'Headroom AI',
|
|
16
|
+
scope: 'global',
|
|
17
|
+
status: await headroom.getFreshState(),
|
|
18
|
+
},
|
|
19
|
+
{ id: 'jira', name: 'Jira', scope: 'project' },
|
|
20
|
+
{ id: 'serena', name: 'Serena', scope: 'project' },
|
|
21
|
+
],
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
router.get('/headroom', async (_req, res) => {
|
|
25
|
+
res.json({ state: await headroom.getFreshState() });
|
|
26
|
+
});
|
|
27
|
+
router.get('/headroom/diagnostics', (_req, res) => {
|
|
28
|
+
res.json(headroom.diagnostics());
|
|
29
|
+
});
|
|
30
|
+
router.post('/headroom/install', async (_req, res) => {
|
|
31
|
+
const result = await headroom.install();
|
|
32
|
+
res.status(result.ok ? 200 : 409).json(result);
|
|
33
|
+
});
|
|
34
|
+
router.post('/headroom/activate', async (req, res) => {
|
|
35
|
+
const provider = req.body?.provider;
|
|
36
|
+
if (!isProvider(provider)) {
|
|
37
|
+
res.status(400).json({ error: 'provider must be codex or claude' });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const result = await headroom.activate(provider);
|
|
41
|
+
res.status(result.ok ? 200 : 409).json(result);
|
|
42
|
+
});
|
|
43
|
+
router.post('/headroom/deactivate', async (req, res) => {
|
|
44
|
+
const provider = req.body?.provider;
|
|
45
|
+
if (!isProvider(provider)) {
|
|
46
|
+
res.status(400).json({ error: 'provider must be codex or claude' });
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const result = await headroom.deactivate(provider);
|
|
50
|
+
res.status(result.ok ? 200 : 409).json(result);
|
|
51
|
+
});
|
|
52
|
+
router.post('/headroom/uninstall', async (_req, res) => {
|
|
53
|
+
const result = await headroom.uninstall();
|
|
54
|
+
res.status(result.ok ? 200 : 409).json(result);
|
|
55
|
+
});
|
|
56
|
+
router.post('/headroom/port', async (req, res) => {
|
|
57
|
+
const port = Number(req.body?.port);
|
|
58
|
+
const result = await headroom.setPort(port);
|
|
59
|
+
res.status(result.ok ? 200 : 400).json(result);
|
|
60
|
+
});
|
|
61
|
+
return router;
|
|
62
|
+
}
|