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.
Files changed (319) hide show
  1. package/client/dist/assets/{ActivityFeedPage-bDe4VitF.js → ActivityFeedPage-DcMmDAP3.js} +1 -1
  2. package/client/dist/assets/AgentBrowserCapture-CZ3oc1UL.js +1 -0
  3. package/client/dist/assets/AgentIntegrationsModal-DkqooCFn.js +1 -0
  4. package/client/dist/assets/{AgentModeCodePane-Ci39DcOo.js → AgentModeCodePane-CM77ljte.js} +2 -2
  5. package/client/dist/assets/AgentModeJobsPane-DbZzogbi.js +1 -0
  6. package/client/dist/assets/AgentsPage-BZIml7eL.js +86 -0
  7. package/client/dist/assets/{AnalyticsPage-Da21wWWw.js → AnalyticsPage-B4qflNxi.js} +1 -1
  8. package/client/dist/assets/{BarChart-BiLTq3uC.js → BarChart-Ckstq9fl.js} +1 -1
  9. package/client/dist/assets/CodePage-DFZXLbI1.js +2 -0
  10. package/client/dist/assets/{DesktopAnalyticsPage-COkzgMmd.js → DesktopAnalyticsPage-DbgMa8OO.js} +1 -1
  11. package/client/dist/assets/DocsDialog-BQc9Kwev.js +11 -0
  12. package/client/dist/assets/DocsPage-OsV44ECy.js +11 -0
  13. package/client/dist/assets/{ExportDropdown-DDhJH-Jr.js → ExportDropdown-a43XHO3Y.js} +1 -1
  14. package/client/dist/assets/IntegrationsPage-C3E8hZhB.js +1 -0
  15. package/client/dist/assets/InteractiveJobComposer-zj8SrOAl.js +19 -0
  16. package/client/dist/assets/JobDetailModal-Cm6ZeVoh.js +1 -0
  17. package/client/dist/assets/JobDetailPage-DN67LsdX.js +1 -0
  18. package/client/dist/assets/JobsPage-DF9wKGbw.js +1 -0
  19. package/client/dist/assets/{LoopBuilderPage-DsLLrtHa.js → LoopBuilderPage-RJ6GGjli.js} +2 -2
  20. package/client/dist/assets/{LoopPreviewModal-C-fDEgnu.js → LoopPreviewModal-B2wmifF6.js} +1 -1
  21. package/client/dist/assets/LoopsPage-DdlvH-dJ.js +1 -0
  22. package/client/dist/assets/PluginsPage-9DI0a6jI.js +2 -0
  23. package/client/dist/assets/ProjectSettingsDialog-dgy5hqPd.js +1 -0
  24. package/client/dist/assets/{TemplatePreviewModal-DcHFbLA8.js → TemplatePreviewModal-CERf1IYB.js} +1 -1
  25. package/client/dist/assets/agent-BRJCESkc2.js +1 -0
  26. package/client/dist/assets/agent-BuYz6fJd.js +1 -0
  27. package/client/dist/assets/agent-CxnRzL6Z.js +1 -0
  28. package/client/dist/assets/agent-D4JAuEGN2.js +1 -0
  29. package/client/dist/assets/agent-DNQlI8EN.js +1 -0
  30. package/client/dist/assets/agent-DyzUH89R.js +1 -0
  31. package/client/dist/assets/agent-MaTxBlg5.js +1 -0
  32. package/client/dist/assets/agent-ostmMYNz2.js +1 -0
  33. package/client/dist/assets/{brain-BBNUUrUI.js → brain-BPbhM1Jx.js} +1 -1
  34. package/client/dist/assets/dashboard-5C2FOZQX.js +1 -0
  35. package/client/dist/assets/{dashboard-C6w0rICe.js → dashboard-B6iQ-IL_.js} +1 -1
  36. package/client/dist/assets/dashboard-BFfnCtq52.js +1 -0
  37. package/client/dist/assets/dashboard-BIC8KtRf2.js +1 -0
  38. package/client/dist/assets/dashboard-CEgg9NAr.js +1 -0
  39. package/client/dist/assets/dashboard-CiOyDh9L.js +1 -0
  40. package/client/dist/assets/dashboard-D6x5OnNj2.js +1 -0
  41. package/client/dist/assets/dashboard-DBuLfWo9.js +1 -0
  42. package/client/dist/assets/{dist-js-BxjTIvdT.js → dist-js-Byjcju1W.js} +1 -1
  43. package/client/dist/assets/{dist-js-DdP_Gl3p.js → dist-js-Dh-9lbLD.js} +1 -1
  44. package/client/dist/assets/index-89SuhD4Y.js +158 -0
  45. package/client/dist/assets/index-DOGzWJhO.css +2 -0
  46. package/client/dist/assets/integrations-By80EBkf.js +1 -0
  47. package/client/dist/assets/integrations-CAjq5tdW2.js +1 -0
  48. package/client/dist/assets/integrations-CG2dp3Kd.js +1 -0
  49. package/client/dist/assets/integrations-CP_aiV_8.js +1 -0
  50. package/client/dist/assets/integrations-CUNe3t9l2.js +1 -0
  51. package/client/dist/assets/integrations-CWjh5VRk.js +1 -0
  52. package/client/dist/assets/integrations-JOHSCvB3.js +1 -0
  53. package/client/dist/assets/integrations-RJfzXkPx2.js +1 -0
  54. package/client/dist/assets/{lib-BviHZ_gK.js → lib-yKyTNJ1c.js} +1 -1
  55. package/client/dist/assets/nav-B2_ToNqS.js +1 -0
  56. package/client/dist/assets/nav-BAMkVEId.js +1 -0
  57. package/client/dist/assets/nav-BTg8s-cD.js +1 -0
  58. package/client/dist/assets/nav-BY_4EWRv.js +1 -0
  59. package/client/dist/assets/nav-CVXtv0wX2.js +1 -0
  60. package/client/dist/assets/nav-D0Erv9ZJ2.js +1 -0
  61. package/client/dist/assets/nav-DUuw9VIU2.js +1 -0
  62. package/client/dist/assets/nav-S4HM94vW.js +1 -0
  63. package/client/dist/assets/settings-BYCMtxOz.js +1 -0
  64. package/client/dist/assets/{settings-BHdPchJP.js → settings-B_v3zgJf.js} +1 -1
  65. package/client/dist/assets/{settings-BeCczBFS2.js → settings-BemR_e3F.js} +1 -1
  66. package/client/dist/assets/{settings-D54_cgl12.js → settings-Bp24JHlv2.js} +1 -1
  67. package/client/dist/assets/{settings-C_nY14Yz.js → settings-BvIwQ3A1.js} +1 -1
  68. package/client/dist/assets/{settings-BlLi719f.js → settings-Bx2ObkTR2.js} +1 -1
  69. package/client/dist/assets/{settings-CaZ26a0S.js → settings-C_T0-j9d.js} +1 -1
  70. package/client/dist/assets/{settings-cn0tbve62.js → settings-DhaFKpcw2.js} +1 -1
  71. package/client/dist/assets/{upload-CRuuzzvp.js → upload-Qh1NE3xi.js} +1 -1
  72. package/client/dist/assets/{value-CIr5hDMt.js → value-BMPeyInx.js} +1 -1
  73. package/client/dist/index.html +29 -29
  74. package/package.json +1 -1
  75. package/server/dist/agent-chat-router.js +2 -0
  76. package/server/dist/agent-operator-prompt.js +17 -1
  77. package/server/dist/db.js +51 -2
  78. package/server/dist/dev-ports.js +35 -0
  79. package/server/dist/global-plugins-router.js +62 -0
  80. package/server/dist/headroom-manager.js +971 -0
  81. package/server/dist/headroom-routing.js +53 -0
  82. package/server/dist/index.js +9 -6
  83. package/server/dist/mcp/guide.js +3 -0
  84. package/server/dist/mcp/tools/catalog.js +2 -0
  85. package/server/dist/mcp/tools/env.js +72 -0
  86. package/server/dist/mcp/tools/jobs.js +110 -2
  87. package/server/dist/path-resolver.js +84 -18
  88. package/server/dist/project-env.js +30 -0
  89. package/server/dist/project-registry.js +4 -2
  90. package/server/dist/project-router-jobs.js +126 -0
  91. package/server/dist/project-router-settings.js +10 -1
  92. package/server/dist/queue-manager.js +9 -1
  93. package/server/dist/rail-isolated-launch.js +5 -4
  94. package/server/dist/rail-pr-decision.js +27 -17
  95. package/server/dist/rail-pr-store.js +36 -0
  96. package/server/dist/rails-router.js +7 -1
  97. package/server/dist/setup-manager.js +32 -29
  98. package/server/dist/setup-prerequisites.js +3 -1
  99. package/server/dist/transient-children.js +266 -9
  100. package/server/dist/util/cli-prompt.js +3 -0
  101. package/server/dist/workspace-resolution.js +3 -3
  102. package/server/dist/worktree-env-discovery.js +172 -0
  103. package/client/dist/assets/AgentBrowserCapture-DQyeEm2V.js +0 -1
  104. package/client/dist/assets/AgentModeJobsPane-C-g1WNVG.js +0 -1
  105. package/client/dist/assets/AgentsPage-BWgglK7V.js +0 -86
  106. package/client/dist/assets/CodePage-BUcAp7SC.js +0 -2
  107. package/client/dist/assets/DocsDialog-PZHMN18B.js +0 -11
  108. package/client/dist/assets/DocsPage-D3fChfkj.js +0 -11
  109. package/client/dist/assets/IntegrationsPage-F87uxxVH.js +0 -3
  110. package/client/dist/assets/InteractiveJobComposer-DqDCiCa0.js +0 -19
  111. package/client/dist/assets/JobDetailModal-BWJR60fi.js +0 -1
  112. package/client/dist/assets/JobDetailPage-CjWE_jyd.js +0 -1
  113. package/client/dist/assets/JobsPage-LmnXkyCa.js +0 -1
  114. package/client/dist/assets/LoopsPage-DDNO9h9T.js +0 -1
  115. package/client/dist/assets/ProjectSettingsDialog-CX854C8e.js +0 -1
  116. package/client/dist/assets/agent-BI6vr-To.js +0 -1
  117. package/client/dist/assets/agent-BUGXI3Ok2.js +0 -1
  118. package/client/dist/assets/agent-Bph_-xt7.js +0 -1
  119. package/client/dist/assets/agent-Bvy2Csyd.js +0 -1
  120. package/client/dist/assets/agent-Bwkyg2oX2.js +0 -1
  121. package/client/dist/assets/agent-CLCyDaZh.js +0 -1
  122. package/client/dist/assets/agent-Cqs14QMr2.js +0 -1
  123. package/client/dist/assets/agent-DJ0EBUuP.js +0 -1
  124. package/client/dist/assets/dashboard-BjjS1OrL.js +0 -1
  125. package/client/dist/assets/dashboard-Bk6oSk1H2.js +0 -1
  126. package/client/dist/assets/dashboard-BrH-GdOg2.js +0 -1
  127. package/client/dist/assets/dashboard-BurhUI8_.js +0 -1
  128. package/client/dist/assets/dashboard-CAUnfDQL2.js +0 -1
  129. package/client/dist/assets/dashboard-C_ljpeYO.js +0 -1
  130. package/client/dist/assets/dashboard-D6OqDdj6.js +0 -1
  131. package/client/dist/assets/index-C695aPdV.css +0 -2
  132. package/client/dist/assets/index-Dw1N2-ci.js +0 -156
  133. package/client/dist/assets/integrations-4KZnYECp.js +0 -1
  134. package/client/dist/assets/integrations-7W266oqF2.js +0 -1
  135. package/client/dist/assets/integrations-BNuauK3o.js +0 -1
  136. package/client/dist/assets/integrations-CHy8tnpV.js +0 -1
  137. package/client/dist/assets/integrations-Cl_wD5AI.js +0 -1
  138. package/client/dist/assets/integrations-CuWnMR5L.js +0 -1
  139. package/client/dist/assets/integrations-Cy8nZ_dv2.js +0 -1
  140. package/client/dist/assets/integrations-zMqY4VU12.js +0 -1
  141. package/client/dist/assets/nav-40HzpIFb.js +0 -1
  142. package/client/dist/assets/nav-8yPhBn00.js +0 -1
  143. package/client/dist/assets/nav-B6PkGfTk2.js +0 -1
  144. package/client/dist/assets/nav-BHqMLrS72.js +0 -1
  145. package/client/dist/assets/nav-CGy4yx3C.js +0 -1
  146. package/client/dist/assets/nav-CXEDcRdv2.js +0 -1
  147. package/client/dist/assets/nav-CzKzuwH8.js +0 -1
  148. package/client/dist/assets/nav-EI_OhEAo.js +0 -1
  149. package/client/dist/assets/settings-D9bDDe2O.js +0 -1
  150. /package/client/dist/assets/{activity-BZNfOdiS.js → activity-BZZlEG3a.js} +0 -0
  151. /package/client/dist/assets/{activity--iN4Ad2R2.js → activity-BbWiDfn-2.js} +0 -0
  152. /package/client/dist/assets/{activity-CIOLxGvh.js → activity-D3Ic-HTS.js} +0 -0
  153. /package/client/dist/assets/{activity-DtxrAUMo2.js → activity-DFbvNqhE2.js} +0 -0
  154. /package/client/dist/assets/{activity-D8vQJrpW.js → activity-Dbl71S-E.js} +0 -0
  155. /package/client/dist/assets/{activity-BuVo5sPB.js → activity-DtzRy92x.js} +0 -0
  156. /package/client/dist/assets/{activity-6hM_ZSg9.js → activity-DvECTYGt.js} +0 -0
  157. /package/client/dist/assets/{activity-D2r2h3SE2.js → activity-FleOlK0l2.js} +0 -0
  158. /package/client/dist/assets/{addspec-D-JLDsUV.js → addspec-BKrH2Ucz.js} +0 -0
  159. /package/client/dist/assets/{addspec-DfhDbg5c.js → addspec-B_LQMHW3.js} +0 -0
  160. /package/client/dist/assets/{addspec-bsNDdqRm2.js → addspec-Bw_YQwo62.js} +0 -0
  161. /package/client/dist/assets/{addspec-BMtLZLW62.js → addspec-CFxGvmJR2.js} +0 -0
  162. /package/client/dist/assets/{addspec-mgPOt5q02.js → addspec-CR8MB5Fr2.js} +0 -0
  163. /package/client/dist/assets/{addspec-CP0HRuxY.js → addspec-DaA-CbTt.js} +0 -0
  164. /package/client/dist/assets/{addspec-DxW6oPsk.js → addspec-DrXqP8ip.js} +0 -0
  165. /package/client/dist/assets/{addspec-CRuvWn8d.js → addspec-NBbcTbLc.js} +0 -0
  166. /package/client/dist/assets/{agents-BpoUaoW92.js → agents-B9pFSJQI2.js} +0 -0
  167. /package/client/dist/assets/{agents-78bTZGZh.js → agents-BHgn--3j.js} +0 -0
  168. /package/client/dist/assets/{agents-BUdEi3-N.js → agents-B_qGaB0F.js} +0 -0
  169. /package/client/dist/assets/{agents-Cev2oFfX.js → agents-CGDn_3kB.js} +0 -0
  170. /package/client/dist/assets/{agents-bvyRLczL.js → agents-CP8_ezYG.js} +0 -0
  171. /package/client/dist/assets/{agents-BLhWCmDS2.js → agents-CV-_xBvX2.js} +0 -0
  172. /package/client/dist/assets/{agents-CWo-KyAB.js → agents-HFCqQH0Z.js} +0 -0
  173. /package/client/dist/assets/{agents-DDtCJ5M02.js → agents-VsyFhGOS2.js} +0 -0
  174. /package/client/dist/assets/{agentstudio-BMQxc_bz.js → agentstudio-BEp7Sb46.js} +0 -0
  175. /package/client/dist/assets/{agentstudio-Dtq3dGYk.js → agentstudio-BOjG6tgJ.js} +0 -0
  176. /package/client/dist/assets/{agentstudio-C_Jq8Tl4.js → agentstudio-Br3WD7Xs.js} +0 -0
  177. /package/client/dist/assets/{agentstudio-sI27TpBu2.js → agentstudio-CuTt3ZGe2.js} +0 -0
  178. /package/client/dist/assets/{agentstudio-CWgXG5W52.js → agentstudio-D2A5peWV2.js} +0 -0
  179. /package/client/dist/assets/{agentstudio-CZm2rOzt.js → agentstudio-Dxe_94PK.js} +0 -0
  180. /package/client/dist/assets/{agentstudio-COZriimI2.js → agentstudio-RfZavULt2.js} +0 -0
  181. /package/client/dist/assets/{agentstudio-jKMTdT70.js → agentstudio-RsxnZtUA.js} +0 -0
  182. /package/client/dist/assets/{aiedit-igmw-ZoZ2.js → aiedit-26p5A_HY2.js} +0 -0
  183. /package/client/dist/assets/{aiedit-6CHdb_iv2.js → aiedit-CV520D4W2.js} +0 -0
  184. /package/client/dist/assets/{aiedit-pc5JDUq1.js → aiedit-CcugGPbS.js} +0 -0
  185. /package/client/dist/assets/{aiedit-eMN4eQPF.js → aiedit-D0Syl-mC.js} +0 -0
  186. /package/client/dist/assets/{aiedit-hknZlly82.js → aiedit-DnBzjlVz2.js} +0 -0
  187. /package/client/dist/assets/{aiedit-B03pD_Na.js → aiedit-DrIjSojo.js} +0 -0
  188. /package/client/dist/assets/{aiedit-DYtnZU9H.js → aiedit-DrfHQnlz.js} +0 -0
  189. /package/client/dist/assets/{aiedit-BtRqRxML.js → aiedit-a-Z-g5iC.js} +0 -0
  190. /package/client/dist/assets/{analytics-C5dpiS0o.js → analytics-4-eskbtX.js} +0 -0
  191. /package/client/dist/assets/{analytics-CR1TJqUi2.js → analytics-4HvXb0Vn2.js} +0 -0
  192. /package/client/dist/assets/{analytics-rmHuJv0V.js → analytics-Bd9rHGjV.js} +0 -0
  193. /package/client/dist/assets/{analytics-BWMUZ2Pq2.js → analytics-Bpe41fnX2.js} +0 -0
  194. /package/client/dist/assets/{analytics-Bj-SmKHa.js → analytics-CpSTNfui.js} +0 -0
  195. /package/client/dist/assets/{analytics-Ce-sPORu.js → analytics-CxDYcBl9.js} +0 -0
  196. /package/client/dist/assets/{analytics-CCprAqk3.js → analytics-DEe5BMz8.js} +0 -0
  197. /package/client/dist/assets/{analytics-DfNdXR0y2.js → analytics-DcOITHla2.js} +0 -0
  198. /package/client/dist/assets/{attachments-BjyMmrwE.js → attachments-CA2f3qL3.js} +0 -0
  199. /package/client/dist/assets/{attachments-DCZOL1RU.js → attachments-CHDbhKeH.js} +0 -0
  200. /package/client/dist/assets/{attachments-rNn1ekRy2.js → attachments-CKAY5aYG2.js} +0 -0
  201. /package/client/dist/assets/{attachments-BgBNSqQd.js → attachments-CgOQ9K-6.js} +0 -0
  202. /package/client/dist/assets/{attachments-DPCmkFZu2.js → attachments-D2jwJXQ42.js} +0 -0
  203. /package/client/dist/assets/{attachments-C9GTTJsx2.js → attachments-DlEQu56g2.js} +0 -0
  204. /package/client/dist/assets/{attachments-Ci6_42Kh.js → attachments-DvxQbBTC.js} +0 -0
  205. /package/client/dist/assets/{attachments-DL-bPy9E.js → attachments-jVdKzAXn.js} +0 -0
  206. /package/client/dist/assets/{auth-Cvsb7-Ek.js → auth-DpZq5p1e.js} +0 -0
  207. /package/client/dist/assets/{browser-Cvg-QHvd2.js → browser-BQFDxrRq.js} +0 -0
  208. /package/client/dist/assets/{browser-rWKj-RR_2.js → browser-BbJ_q_OT2.js} +0 -0
  209. /package/client/dist/assets/{browser-Cc0iDqUi.js → browser-C4VJ5CW12.js} +0 -0
  210. /package/client/dist/assets/{browser-BPkhILSJ.js → browser-Cl-FwPXs.js} +0 -0
  211. /package/client/dist/assets/{browser-CdS6O1Qb.js → browser-DM8G151q.js} +0 -0
  212. /package/client/dist/assets/{browser-FRv8P02E.js → browser-Do2jf8_N.js} +0 -0
  213. /package/client/dist/assets/{browser-BqLqJVVT.js → browser-JsiohNmW.js} +0 -0
  214. /package/client/dist/assets/{browser-BijVYG0Y2.js → browser-kA31eYhu2.js} +0 -0
  215. /package/client/dist/assets/{chat-VMflhzxn.js → chat-0dg5hOo_.js} +0 -0
  216. /package/client/dist/assets/{chat-DdwZjT8K2.js → chat-BMWD_Rx12.js} +0 -0
  217. /package/client/dist/assets/{chat-Bom6bqK3.js → chat-BalviUAD.js} +0 -0
  218. /package/client/dist/assets/{chat-DsbwJhus.js → chat-CJddjN3D2.js} +0 -0
  219. /package/client/dist/assets/{chat-Dnwg-NpQ.js → chat-D5xEtsf3.js} +0 -0
  220. /package/client/dist/assets/{chat-vylxqR0P2.js → chat-Ds8GvCnv.js} +0 -0
  221. /package/client/dist/assets/{chat-BgL3zv6x2.js → chat-SaG-ng1x2.js} +0 -0
  222. /package/client/dist/assets/{chat-Bh3NdgJs.js → chat-n43nZGvn.js} +0 -0
  223. /package/client/dist/assets/{code-thSEptMx.js → code-B62fClk-.js} +0 -0
  224. /package/client/dist/assets/{code-DzC1rMk12.js → code-Bit_z2Xd2.js} +0 -0
  225. /package/client/dist/assets/{code-BRcDlze52.js → code-BotxM43N2.js} +0 -0
  226. /package/client/dist/assets/{code-UPVvmAKM2.js → code-C9U6M5-e2.js} +0 -0
  227. /package/client/dist/assets/{code-BdMy3Ffq.js → code-CIPmDEd0.js} +0 -0
  228. /package/client/dist/assets/{code-DgeHz9CB.js → code-DUe1Bouz.js} +0 -0
  229. /package/client/dist/assets/{code-CwnBPPyA.js → code-F_KjccGf.js} +0 -0
  230. /package/client/dist/assets/{code-CeQ0FZpC.js → code-HDK4P6Rx.js} +0 -0
  231. /package/client/dist/assets/{commands-DkU0qliq.js → commands-BFQZc9AG.js} +0 -0
  232. /package/client/dist/assets/{commands-u-4eEHCN.js → commands-BMkC5-ki.js} +0 -0
  233. /package/client/dist/assets/{commands-CSDs9q_2.js → commands-BllkJauO.js} +0 -0
  234. /package/client/dist/assets/{commands-xHDDGfcP2.js → commands-CWX9WmDX2.js} +0 -0
  235. /package/client/dist/assets/{commands-C4Y3C-PF2.js → commands-CzFSoIiq2.js} +0 -0
  236. /package/client/dist/assets/{commands-CckaBWdV.js → commands-DCJ-R9E4.js} +0 -0
  237. /package/client/dist/assets/{commands-JWMfGDmr.js → commands-KBbhsnw8.js} +0 -0
  238. /package/client/dist/assets/{commands-RHOchN4n2.js → commands-cKTaLwwV2.js} +0 -0
  239. /package/client/dist/assets/{common-DmqBPwZG.js → common-BfQD173j.js} +0 -0
  240. /package/client/dist/assets/{common-DhWTkocg.js → common-CF8iGXrG.js} +0 -0
  241. /package/client/dist/assets/{common-Bwafujnc2.js → common-Cfmwcrl52.js} +0 -0
  242. /package/client/dist/assets/{common-C-vU-j-I.js → common-D2cimsul.js} +0 -0
  243. /package/client/dist/assets/{common-C5HKSbbz.js → common-DH7fjyL1.js} +0 -0
  244. /package/client/dist/assets/{common-CYaT2yHp.js → common-DXrmj6WD.js} +0 -0
  245. /package/client/dist/assets/{common-BM3LFLCE2.js → common-DZbXlmq72.js} +0 -0
  246. /package/client/dist/assets/{common-DiPTT7V_2.js → common-DtXmzX2o2.js} +0 -0
  247. /package/client/dist/assets/{explore-UvW1jEMa.js → explore-BEpIs343.js} +0 -0
  248. /package/client/dist/assets/{explore-CNBzrEPS.js → explore-BO_OinBD.js} +0 -0
  249. /package/client/dist/assets/{explore-C0k8HrkN.js → explore-Bhy7WWXv.js} +0 -0
  250. /package/client/dist/assets/{explore-B7fblXBb2.js → explore-CAc8Qzu32.js} +0 -0
  251. /package/client/dist/assets/{explore-D_mWBYCS2.js → explore-DCZL9gRN2.js} +0 -0
  252. /package/client/dist/assets/{explore-Dahc1lOx.js → explore-DW_YTkQh.js} +0 -0
  253. /package/client/dist/assets/{explore-BHtEpoNN2.js → explore-ELbrSZyQ2.js} +0 -0
  254. /package/client/dist/assets/{explore-BKVV5JSu.js → explore-_XyU5e7R.js} +0 -0
  255. /package/client/dist/assets/{format-command-CuWuRvka.js → format-command-Db1viey1.js} +0 -0
  256. /package/client/dist/assets/{jira-uNH1gETL2.js → jira-B5wszJ1-2.js} +0 -0
  257. /package/client/dist/assets/{jira-BHAKtc4B.js → jira-C5UjxHE4.js} +0 -0
  258. /package/client/dist/assets/{jira-D5efgwp_.js → jira-CQ7mrZde.js} +0 -0
  259. /package/client/dist/assets/{jira-bDs7Im2C.js → jira-DIRkZk9U.js} +0 -0
  260. /package/client/dist/assets/{jira-CPpgA-5z2.js → jira-DTYu3hJi2.js} +0 -0
  261. /package/client/dist/assets/{jira-B3613-gj.js → jira-DeIjwCK3.js} +0 -0
  262. /package/client/dist/assets/{jira-DS7ownDy.js → jira-DtZpokjJ.js} +0 -0
  263. /package/client/dist/assets/{jira-Be369RIR2.js → jira-ZdKb-50F2.js} +0 -0
  264. /package/client/dist/assets/{jobs-CE8qeIYj.js → jobs-BFIdeDTw.js} +0 -0
  265. /package/client/dist/assets/{jobs-BgQzB0Sx2.js → jobs-BJ-Gcao22.js} +0 -0
  266. /package/client/dist/assets/{jobs-1GV2-4zd2.js → jobs-DAGiPVIS2.js} +0 -0
  267. /package/client/dist/assets/{jobs-26F9gGcE.js → jobs-DAU8C_tZ.js} +0 -0
  268. /package/client/dist/assets/{jobs-BqWui9_f.js → jobs-Da0GaaSc.js} +0 -0
  269. /package/client/dist/assets/{jobs-D5sZzgLs.js → jobs-DrYmsKy5.js} +0 -0
  270. /package/client/dist/assets/{jobs-Wh7dn28q2.js → jobs-P3unxtxo2.js} +0 -0
  271. /package/client/dist/assets/{jobs-DzeuASRf.js → jobs-p360zdf1.js} +0 -0
  272. /package/client/dist/assets/{loops-CvOWsi5r.js → loops-Bi4ywYGn.js} +0 -0
  273. /package/client/dist/assets/{loops-BvqQ-bHR2.js → loops-BjK8lmoZ2.js} +0 -0
  274. /package/client/dist/assets/{loops-Brnx4Fji.js → loops-CO6q75W8.js} +0 -0
  275. /package/client/dist/assets/{loops-K5_HXfJa.js → loops-D3wdUkZV.js} +0 -0
  276. /package/client/dist/assets/{loops-D6D3XHjj.js → loops-DDs4KPu_.js} +0 -0
  277. /package/client/dist/assets/{loops-LIgO_-eM.js → loops-DKzYFcq6.js} +0 -0
  278. /package/client/dist/assets/{loops-DJNhp17p2.js → loops-Du-bNVpc2.js} +0 -0
  279. /package/client/dist/assets/{loops-vhJdbcz92.js → loops-DvGbSfxw2.js} +0 -0
  280. /package/client/dist/assets/{mcp-XJNRfxVp2.js → mcp-BG-OCJca2.js} +0 -0
  281. /package/client/dist/assets/{mcp-DtbxuH3V2.js → mcp-CbJ04oFS2.js} +0 -0
  282. /package/client/dist/assets/{mcp-sRmWE8WJ.js → mcp-CrWdq5db.js} +0 -0
  283. /package/client/dist/assets/{mcp-H-gnQUdN.js → mcp-Dd844F5_.js} +0 -0
  284. /package/client/dist/assets/{mcp-Dcl-XxkR.js → mcp-DfmzoT5t.js} +0 -0
  285. /package/client/dist/assets/{mcp-CjVKXAhD2.js → mcp-DyULurYS2.js} +0 -0
  286. /package/client/dist/assets/{mcp-CIH0pH1K.js → mcp-HwBbQDk0.js} +0 -0
  287. /package/client/dist/assets/{mcp-N1nzp8oL.js → mcp-zSJ2TsJj.js} +0 -0
  288. /package/client/dist/assets/{setup-BuQNKztt2.js → setup-1vN48B-m2.js} +0 -0
  289. /package/client/dist/assets/{setup-BwMovM9z2.js → setup-BmJ0Kx16.js} +0 -0
  290. /package/client/dist/assets/{setup-RiUHzq7E.js → setup-D2CmgAro.js} +0 -0
  291. /package/client/dist/assets/{setup-BXpw07r-.js → setup-DQWsu2TR.js} +0 -0
  292. /package/client/dist/assets/{setup-D84y3wx-.js → setup-JeBwoXoM.js} +0 -0
  293. /package/client/dist/assets/{setup-DU0ULX8q2.js → setup-T_ApeQDV2.js} +0 -0
  294. /package/client/dist/assets/{setup-BiduSX9d.js → setup-mXnzww4f.js} +0 -0
  295. /package/client/dist/assets/{setup-7J8TjG4O.js → setup-q0wRHUp1.js} +0 -0
  296. /package/client/dist/assets/{specs-CWtKcVDC.js → specs-BGRKhM8t.js} +0 -0
  297. /package/client/dist/assets/{specs-CBDvEYKv.js → specs-C6J2zrLM.js} +0 -0
  298. /package/client/dist/assets/{specs-D2clrt2c2.js → specs-CT8exGOy2.js} +0 -0
  299. /package/client/dist/assets/{specs-C9Sd7BhH2.js → specs-Ce5y2iFc2.js} +0 -0
  300. /package/client/dist/assets/{specs-CIPr9reA2.js → specs-DZDoZsDq.js} +0 -0
  301. /package/client/dist/assets/{specs-PozUNhqb.js → specs-DbtIzV8a.js} +0 -0
  302. /package/client/dist/assets/{specs-DTplt2XM.js → specs-GkiL-snY.js} +0 -0
  303. /package/client/dist/assets/{specs-CmEZY57v.js → specs-PGIOzMtc.js} +0 -0
  304. /package/client/dist/assets/{terminal-xGbCZJHg.js → terminal-BNSg2lR7.js} +0 -0
  305. /package/client/dist/assets/{terminal-De2Brd23.js → terminal-BTpE7iki.js} +0 -0
  306. /package/client/dist/assets/{terminal-DFPNRLKp.js → terminal-CFt56A5f.js} +0 -0
  307. /package/client/dist/assets/{terminal-BRm03iFA2.js → terminal-Cvabyzm42.js} +0 -0
  308. /package/client/dist/assets/{terminal-DxQWCqSD2.js → terminal-D0z12_sJ2.js} +0 -0
  309. /package/client/dist/assets/{terminal-Z7KsDM_n.js → terminal-DDk_bTw0.js} +0 -0
  310. /package/client/dist/assets/{terminal-cqfd3EDV.js → terminal-DEyt0prF.js} +0 -0
  311. /package/client/dist/assets/{terminal-WSAvHXoU.js → terminal-a6Uq8B0p.js} +0 -0
  312. /package/client/dist/assets/{tickets-CkfbISuK.js → tickets-BHv3ewvq.js} +0 -0
  313. /package/client/dist/assets/{tickets-C3b8cHhd2.js → tickets-BIxU86j12.js} +0 -0
  314. /package/client/dist/assets/{tickets-SuX_HkK4.js → tickets-C2BhwzwR.js} +0 -0
  315. /package/client/dist/assets/{tickets-DTHo9c3C.js → tickets-D1IeX2EW.js} +0 -0
  316. /package/client/dist/assets/{tickets-BoXom7l8.js → tickets-DZut8Ryt.js} +0 -0
  317. /package/client/dist/assets/{tickets-CWYFvx1W2.js → tickets-LfK6LzKl2.js} +0 -0
  318. /package/client/dist/assets/{tickets-CFXnJsYF.js → tickets-dQfsc7Ph.js} +0 -0
  319. /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 forget. */
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 (!set)
43
- return;
44
- for (const child of set) {
45
- if (child.pid) {
46
- try {
47
- (0, tree_kill_1.default)(child.pid, 'SIGTERM');
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 process.env;
153
+ return baseEnv;
154
154
  const { SPECRAILS_REPO_DIR: _perRun, ...projectEnv } = exec.env;
155
- return { ...process.env, ...projectEnv };
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};