@organizaone/o1-code 0.4.0 → 0.5.1

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 (300) hide show
  1. package/bundled/qc-helper/docs/configuration/settings.md +1 -0
  2. package/bundled/qc-helper/docs/features/approval-mode.md +4 -0
  3. package/bundled/qc-helper/docs/features/auto-mode.md +3 -0
  4. package/bundled/qc-helper/docs/features/sub-agents.md +7 -8
  5. package/bundled/qc-helper/docs/support/troubleshooting.md +3 -0
  6. package/chunks/{MaxSizedBox-XCALBLMI.js → MaxSizedBox-ZOFIKGJG.js} +41 -41
  7. package/chunks/{StandaloneSessionPicker-4LKUBXYB.js → StandaloneSessionPicker-6S2C7YZK.js} +54 -54
  8. package/chunks/{acp-subagent-executor-DZXFG4X5.js → acp-subagent-executor-HGIGYENO.js} +42 -42
  9. package/chunks/{acpAgent-Q7ZCQ435.js → acpAgent-SXUNXWWP.js} +425 -368
  10. package/chunks/{agent-RMFRDIO3.js → agent-7GI5MAMY.js} +25 -25
  11. package/chunks/{agent-headless-S5VQMQW5.js → agent-headless-7ZSKSLIE.js} +25 -25
  12. package/chunks/{anthropicContentGenerator-FJGXD34B.js → anthropicContentGenerator-FHJ5JNYR.js} +5 -5
  13. package/chunks/{bridge-MPG5WH6G.js → bridge-5YHUATCB.js} +42 -42
  14. package/chunks/{build-F5EUF23Y.js → build-RFEU7TIS.js} +1 -1
  15. package/chunks/{bwrap-execution-EZJNABHL.js → bwrap-execution-QFG5RQSP.js} +5 -5
  16. package/chunks/{chunk-M4RMR6BN.js → chunk-22SKH7LF.js} +3 -3
  17. package/chunks/{chunk-MKUV6LDU.js → chunk-26GB3MTV.js} +2 -2
  18. package/chunks/{chunk-L2YHATCP.js → chunk-2DNMFYMU.js} +3 -3
  19. package/chunks/{chunk-7K3C4CS2.js → chunk-2J53EWTP.js} +6 -6
  20. package/chunks/{chunk-PU3SYVQ7.js → chunk-2OQC7O74.js} +3 -3
  21. package/chunks/{chunk-EPSMNIG6.js → chunk-2QN2TID2.js} +5 -5
  22. package/chunks/{chunk-UUTO4CEV.js → chunk-34ORCXAX.js} +2 -2
  23. package/chunks/{chunk-EXWAECKM.js → chunk-35RKSP4A.js} +2 -2
  24. package/chunks/{chunk-7YG72VGA.js → chunk-3GGCMM7C.js} +2 -2
  25. package/chunks/{chunk-S74WJTCG.js → chunk-3YLEHHA7.js} +12 -3
  26. package/chunks/{chunk-SQQVJC75.js → chunk-3YZPY6YA.js} +1 -1
  27. package/chunks/{chunk-UDQ3FEOE.js → chunk-6DOSH2VF.js} +30 -15
  28. package/chunks/{chunk-ESAUSKWS.js → chunk-6LOAUBTH.js} +10 -10
  29. package/chunks/{chunk-ESDBDHDS.js → chunk-6MEAGROF.js} +1 -1
  30. package/chunks/{chunk-UIZPA6NX.js → chunk-6QYP53HJ.js} +1 -1
  31. package/chunks/{chunk-KXN7Q6SB.js → chunk-6TWJYLJE.js} +1 -1
  32. package/chunks/{chunk-Q56YIKDZ.js → chunk-734USTD3.js} +5 -5
  33. package/chunks/{chunk-TY4PWRCX.js → chunk-7PXVBJL3.js} +1 -1
  34. package/chunks/{chunk-CIMPNO36.js → chunk-7TZRKZWC.js} +1 -1
  35. package/chunks/{chunk-7NLIWXMU.js → chunk-A2K4A5O2.js} +3 -3
  36. package/chunks/{chunk-672SUHHG.js → chunk-ABTF7TPE.js} +1 -1
  37. package/chunks/{chunk-FOVK2DPM.js → chunk-AJS6HD3U.js} +4 -4
  38. package/chunks/{chunk-PUHCGRAC.js → chunk-B2PLLGOC.js} +1 -1
  39. package/chunks/{chunk-WEL3TXQG.js → chunk-B67EYF6M.js} +1 -1
  40. package/chunks/{chunk-PIVKM7A6.js → chunk-C2IESIWR.js} +4 -4
  41. package/chunks/{chunk-X3RSD63L.js → chunk-CHZDN4DI.js} +1 -1
  42. package/chunks/{chunk-S2LBLNBW.js → chunk-CMZHL55Y.js} +2193 -151
  43. package/chunks/{chunk-A53V5RUQ.js → chunk-CVU3EIFH.js} +3 -3
  44. package/chunks/{chunk-HYC64HT7.js → chunk-D42MFAOX.js} +3 -3
  45. package/chunks/{chunk-MW6HQT5X.js → chunk-DLJHG562.js} +2 -2
  46. package/chunks/{chunk-YNJSBU2B.js → chunk-DZPGLX7M.js} +1 -1
  47. package/chunks/{chunk-GJQHQ3DC.js → chunk-E6JZE22X.js} +3 -3
  48. package/chunks/{chunk-YP7V6HRD.js → chunk-EBTQTM56.js} +1 -1
  49. package/chunks/{chunk-LWQQFURM.js → chunk-ELAUQQIT.js} +4 -4
  50. package/chunks/{chunk-WXWA7OOJ.js → chunk-ELVKWFRK.js} +1 -1
  51. package/chunks/{chunk-SAMGM2NV.js → chunk-EMIGZJZT.js} +1 -1
  52. package/chunks/{chunk-DM3OSSGT.js → chunk-F6UT36OB.js} +7 -42
  53. package/chunks/{chunk-T233J2WC.js → chunk-FMDABBCA.js} +3 -3
  54. package/chunks/{chunk-P7UNPKJM.js → chunk-FQO3QDB5.js} +1 -1
  55. package/chunks/{chunk-TKHMBUSK.js → chunk-FZUEC7ES.js} +3 -3
  56. package/chunks/{chunk-L3LXMQJJ.js → chunk-G2I75T4C.js} +1 -1
  57. package/chunks/{chunk-DP5BYVKX.js → chunk-G3W4UY3G.js} +3601 -5403
  58. package/chunks/{chunk-HRWSTIHZ.js → chunk-GAM5VJT7.js} +1 -1
  59. package/chunks/{chunk-5L6KVN6H.js → chunk-GHYY2N2S.js} +1 -1
  60. package/chunks/{chunk-LQR2LD5J.js → chunk-GLT2QUV7.js} +4 -4
  61. package/chunks/{chunk-ONLJONFH.js → chunk-GMR3LAWE.js} +18 -3
  62. package/chunks/{chunk-FXEUBHXO.js → chunk-GN6HVKBI.js} +2 -2
  63. package/chunks/{chunk-532CXTUJ.js → chunk-GW3TK3X2.js} +39 -37
  64. package/chunks/{chunk-V5LAES7R.js → chunk-GWX3EC6J.js} +1 -1
  65. package/chunks/{chunk-E4BNWSC7.js → chunk-H5L5E5NI.js} +1 -1
  66. package/chunks/{chunk-CVGR5FZZ.js → chunk-H65LZ7Q4.js} +1 -1
  67. package/chunks/{chunk-AGF6RZYW.js → chunk-HGW4END7.js} +4 -4
  68. package/chunks/{chunk-PAHN3PPP.js → chunk-IL4VUEEH.js} +1 -1
  69. package/chunks/{chunk-FJHPFQU6.js → chunk-JDPRCTE4.js} +7 -7
  70. package/chunks/{chunk-4NNLMYE3.js → chunk-JOGRE2ZT.js} +1 -1
  71. package/chunks/{chunk-IFURAKKH.js → chunk-JSB66IE5.js} +1 -1
  72. package/chunks/{chunk-IF63JJ4W.js → chunk-K5JXFVNB.js} +5 -5
  73. package/chunks/{chunk-AOXGYW3S.js → chunk-KCHIL32J.js} +5 -5
  74. package/chunks/{chunk-QGDWW62J.js → chunk-KI7AYT4Y.js} +1 -1
  75. package/chunks/{chunk-JHKNFNWE.js → chunk-KJVLRZBK.js} +1 -1
  76. package/chunks/{chunk-WHFNK466.js → chunk-KVQMH7W2.js} +4 -4
  77. package/chunks/{chunk-ROJAAA2B.js → chunk-L6J57N2A.js} +1 -1
  78. package/chunks/{chunk-FD5MGAM2.js → chunk-L7LXG6TN.js} +2 -2
  79. package/chunks/{chunk-L4RFUGED.js → chunk-LERXWKRT.js} +1 -1
  80. package/chunks/{chunk-KFYFHLDM.js → chunk-LHCVJ6NV.js} +1 -1
  81. package/chunks/{chunk-Q2AHXMRI.js → chunk-LHY2PDWX.js} +6 -4
  82. package/chunks/{chunk-IUFQFQ7R.js → chunk-LJU6OPEU.js} +3 -3
  83. package/chunks/{chunk-YIEC5SIW.js → chunk-M2EBVYXC.js} +1 -1
  84. package/chunks/{chunk-DRV3SDND.js → chunk-M5G6OKEY.js} +4 -4
  85. package/chunks/{chunk-5TJZ5DBW.js → chunk-MDQFX2C5.js} +1 -1
  86. package/chunks/{chunk-WQ6N4SRY.js → chunk-MDQYCFNT.js} +16 -16
  87. package/chunks/{chunk-5PZDTHS6.js → chunk-MGVVXFYW.js} +38 -3
  88. package/chunks/{chunk-JQFQB2BI.js → chunk-MIWMCUU5.js} +1 -1
  89. package/chunks/{chunk-XID74DEW.js → chunk-MQ3QD65Z.js} +1 -1
  90. package/chunks/{chunk-KCOLW7TS.js → chunk-MRBPTAOV.js} +4 -4
  91. package/chunks/{chunk-5KDZJN3L.js → chunk-MRJJAG44.js} +10 -10
  92. package/chunks/{chunk-WB4XHWF5.js → chunk-MX7QDQRT.js} +5 -5
  93. package/chunks/{chunk-6ET4INUP.js → chunk-MXIQ6C7B.js} +3 -3
  94. package/chunks/{chunk-VRSR6QUT.js → chunk-NBCYYKYK.js} +3 -3
  95. package/chunks/{chunk-I7XXUDXZ.js → chunk-NGPEFWU4.js} +1 -1
  96. package/chunks/{chunk-YNDEPL5B.js → chunk-ODSVNOLT.js} +4 -4
  97. package/chunks/{chunk-AQVYFR7E.js → chunk-OMJU4YIQ.js} +1 -1
  98. package/chunks/{chunk-TXOO3SJ4.js → chunk-OVOSIR5V.js} +13 -11
  99. package/chunks/{chunk-4372PUEO.js → chunk-PSL5VFNJ.js} +40 -37
  100. package/chunks/{chunk-UNRHVAPY.js → chunk-QDZTSZTF.js} +1 -1
  101. package/chunks/{chunk-XQILGSD3.js → chunk-RIX6ATSB.js} +1 -1
  102. package/chunks/{chunk-T2OY4BYB.js → chunk-RRWM6VZS.js} +1 -1
  103. package/chunks/{chunk-W7IBLOA5.js → chunk-SE33PFPT.js} +7 -7
  104. package/chunks/{chunk-H2V7AUF4.js → chunk-SE3HMQLW.js} +5 -5
  105. package/chunks/{chunk-QFQQICSQ.js → chunk-TCME6IG6.js} +1 -1
  106. package/chunks/{chunk-RWN5ULQM.js → chunk-TDBZBCLU.js} +2 -2
  107. package/chunks/{chunk-IYHIP3OB.js → chunk-TXIBLU7T.js} +8 -8
  108. package/chunks/{chunk-Y4BQMESG.js → chunk-TYAUV2TE.js} +1 -1
  109. package/chunks/{chunk-3QL5SP6K.js → chunk-UZSRQ26K.js} +1 -1
  110. package/chunks/{chunk-J5BDFZYA.js → chunk-V23Q4GBY.js} +1 -1
  111. package/chunks/{chunk-L3YLV3RI.js → chunk-V4XETRAG.js} +24 -9
  112. package/chunks/{chunk-PPR5SHEF.js → chunk-V75J4GJ2.js} +1 -1
  113. package/chunks/{chunk-QLDNOCCI.js → chunk-VJ3EJJ5K.js} +4 -4
  114. package/chunks/{chunk-QJVAY275.js → chunk-W2MWOPYK.js} +13 -10
  115. package/chunks/{chunk-KD2JFDCT.js → chunk-WBW6J5R3.js} +13 -4
  116. package/chunks/{chunk-PYH6MQ2Q.js → chunk-WCFNOALO.js} +1 -1
  117. package/chunks/{chunk-A24OKQOD.js → chunk-WFUXHQZO.js} +6 -2
  118. package/chunks/{chunk-KN233J25.js → chunk-WQNNHDDX.js} +6 -6
  119. package/chunks/{chunk-X6HNUJYB.js → chunk-X655UILS.js} +15 -15
  120. package/chunks/{chunk-RTY3POZ7.js → chunk-XFV6QC4A.js} +2 -2
  121. package/chunks/{chunk-GUMLL5KC.js → chunk-XKOGHPWS.js} +1 -1
  122. package/chunks/{chunk-WBXFLYVH.js → chunk-YQF62HFY.js} +1 -1
  123. package/chunks/{chunk-GWKSWZ3B.js → chunk-Z6HFYF3D.js} +1 -1
  124. package/chunks/{chunk-U6PVPH4S.js → chunk-ZFT5MBI6.js} +1 -1
  125. package/chunks/{chunk-M2WG4ESD.js → chunk-ZQBNP2ZQ.js} +4 -2
  126. package/chunks/{chunk-JPGOF34S.js → chunk-ZZXUYKAG.js} +4 -4
  127. package/chunks/{codex-subagent-executor-E7JQVLPC.js → codex-subagent-executor-NO5C6VPN.js} +42 -42
  128. package/chunks/{contextCommand-7L5H2XXP.js → contextCommand-VWARZSMR.js} +40 -40
  129. package/chunks/{core-runtime-X3V7BURU.js → core-runtime-KL6UEQWI.js} +39 -39
  130. package/chunks/{create-sub-session-VXPEZMFK.js → create-sub-session-CY7EFJX5.js} +40 -40
  131. package/chunks/{daemon-git-worktree-guard-OYFVIIWI.js → daemon-git-worktree-guard-CPIBCRZO.js} +39 -39
  132. package/chunks/{daemon-status-provider-5QIZJJNE.js → daemon-status-provider-BN3RF2FL.js} +47 -47
  133. package/chunks/{daemon-trust-policy-LVRILVI3.js → daemon-trust-policy-4CK5U5IC.js} +44 -44
  134. package/chunks/{daemon-trust-policy-monitor-GI6PLXY4.js → daemon-trust-policy-monitor-CUNFNI4N.js} +44 -44
  135. package/chunks/{deferred-core-runtime-6CBEDR5U.js → deferred-core-runtime-CBJTZJPH.js} +39 -39
  136. package/chunks/{display-image-K4EKCY4Y.js → display-image-U6HZKF3G.js} +1 -1
  137. package/chunks/{edit-C6FPBRWV.js → edit-RM227QNR.js} +27 -27
  138. package/chunks/{enter-worktree-7AEF4YHW.js → enter-worktree-53CUMISV.js} +6 -5
  139. package/chunks/{enterPlanMode-MNSV64QE.js → enterPlanMode-PYAHJFSQ.js} +25 -25
  140. package/chunks/{environment-UHBXJNPE.js → environment-DD54IMFM.js} +45 -43
  141. package/chunks/{errors-N36MS36S.js → errors-HI6DJG4B.js} +41 -41
  142. package/chunks/{execution-sandbox-config-ODVPW3HT.js → execution-sandbox-config-7UDTKDKF.js} +6 -6
  143. package/chunks/{execution-tool-CB46DCPG.js → execution-tool-V3VSCW6K.js} +28 -28
  144. package/chunks/{execution-worker-KGQ3AKWY.js → execution-worker-WBHEON6Q.js} +32 -32
  145. package/chunks/{exit-worktree-7LRFLHHT.js → exit-worktree-CZUYCPZ3.js} +6 -5
  146. package/chunks/{exitPlanMode-XQICYHTC.js → exitPlanMode-HOZQZ5T7.js} +25 -25
  147. package/chunks/{fast-path-YHYEVNSH.js → fast-path-7HGISECB.js} +2 -2
  148. package/chunks/{glob-QZN6HURE.js → glob-3Z2KONQG.js} +25 -25
  149. package/chunks/{goal-tools-DA6LG2SP.js → goal-tools-SZZFOYEQ.js} +25 -25
  150. package/chunks/{grep-TA3S572F.js → grep-ENZEP6KL.js} +2 -2
  151. package/chunks/{handleAutoUpdate-IGXZ2DMP.js → handleAutoUpdate-YW4VDPGO.js} +41 -41
  152. package/chunks/{i18n-IALGY42H.js → i18n-3EQ4CCDM.js} +39 -39
  153. package/chunks/{image-gen-BEM2OTJM.js → image-gen-GJRWPVTR.js} +2 -2
  154. package/chunks/{initializer-ZIHB4XYC.js → initializer-G4SCU6JQ.js} +44 -44
  155. package/chunks/{installationInfo-WG2GZFZT.js → installationInfo-3QFLR7CO.js} +39 -39
  156. package/chunks/{list-RZD6J74J.js → list-S4KQBUXO.js} +46 -46
  157. package/chunks/{llm-46DCEZ2L.js → llm-HBFVSHNO.js} +95 -73
  158. package/chunks/{llm-content-generator-OT4NV35N.js → llm-content-generator-WWIIJ3YF.js} +3 -3
  159. package/chunks/{loadedSettingsAdapter-J2GSJPSR.js → loadedSettingsAdapter-4FCPSPON.js} +44 -44
  160. package/chunks/{local-execution-environment-FX5IZ7Z2.js → local-execution-environment-PUSM6PGS.js} +32 -32
  161. package/chunks/{loggingContentGenerator-RTFUIXIY.js → loggingContentGenerator-OMYQPXBM.js} +27 -27
  162. package/chunks/{managed-npm-update-4FBPYKRR.js → managed-npm-update-MUWFIXMB.js} +56 -50
  163. package/chunks/{mcp-CGZQMURL.js → mcp-IFIMZMMB.js} +44 -44
  164. package/chunks/{model-call-collection-XSB3IOIM.js → model-call-collection-RJ3QGO3O.js} +1 -1
  165. package/chunks/{model-configuration-7XGFDFQQ.js → model-configuration-AQOY5NHG.js} +45 -45
  166. package/chunks/{modelConfigUtils-55SLUTRW.js → modelConfigUtils-3WCZU5US.js} +41 -41
  167. package/chunks/{monitor-6FXANYQK.js → monitor-Z4DAPTBI.js} +40 -36
  168. package/chunks/{nonInteractiveCli-7JRQVPTS.js → nonInteractiveCli-EIFDEYFS.js} +70 -70
  169. package/chunks/{nonInteractiveToolExecutor-EBI7JPSA.js → nonInteractiveToolExecutor-NS2HFUO5.js} +26 -26
  170. package/chunks/{notebook-edit-4NRLVXGD.js → notebook-edit-TXNVV4NZ.js} +26 -26
  171. package/chunks/{omni-SCKLBJ7D.js → omni-EANTWQG5.js} +10 -10
  172. package/chunks/{openaiContentGenerator-5XUSGWXX.js → openaiContentGenerator-JU5KLG5T.js} +12 -12
  173. package/chunks/{openaiResponsesContentGenerator-XKJFDUNK.js → openaiResponsesContentGenerator-BQZ54E6V.js} +3 -3
  174. package/chunks/{processUtils-RZJXB2SU.js → processUtils-PVRINBPF.js} +2 -2
  175. package/chunks/{prompt-terminal-ledger-WDNYXW7Q.js → prompt-terminal-ledger-LDPMNEHI.js} +40 -40
  176. package/chunks/{reactive-degrade-NS277SXZ.js → reactive-degrade-5HVNIKLO.js} +8 -8
  177. package/chunks/{read-file-7A4PDVYW.js → read-file-H4L4HPEH.js} +4 -4
  178. package/chunks/{record-artifact-LO3TFJF4.js → record-artifact-PL2T5AJY.js} +3 -3
  179. package/chunks/{record-source-U2PL3PZS.js → record-source-PHBQTGL4.js} +4 -4
  180. package/chunks/{report-findings-XQQ23B4H.js → report-findings-RFO53756.js} +4 -4
  181. package/chunks/{request-shutdown-HUO3DW4O.js → request-shutdown-OMWHNC3R.js} +3 -3
  182. package/chunks/{resumeHistoryUtils-TQIL6EZ7.js → resumeHistoryUtils-TMGVZMKJ.js} +41 -41
  183. package/chunks/{ripGrep-APKWY2LV.js → ripGrep-YVUC4DXT.js} +7 -7
  184. package/chunks/{run-o1-code-serve-ZPJZEWP7.js → run-o1-code-serve-LAIBSEHT.js} +32 -32
  185. package/chunks/{runtime-shell-policy-7E34X54Z.js → runtime-shell-policy-QXWSET5W.js} +1 -1
  186. package/chunks/{sandboxConfig-FJ6SORCO.js → sandboxConfig-UYUFPT6T.js} +39 -39
  187. package/chunks/{scheduled-tasks-K5FEKEQZ.js → scheduled-tasks-JFRIRKTA.js} +45 -45
  188. package/chunks/{scheduler-LNBDPLM3.js → scheduler-2PWRO4UB.js} +41 -41
  189. package/chunks/{send-message-X55LV3NW.js → send-message-NATKTKQZ.js} +3 -3
  190. package/chunks/{serve-YLTHY7B3.js → serve-5NOYAIKF.js} +44 -44
  191. package/chunks/{server-246IXJV4.js → server-VJ4WGSUY.js} +119 -111
  192. package/chunks/{session-U5PCPVSR.js → session-CGV7TJGH.js} +71 -71
  193. package/chunks/{session-attachments-root-FZBDWCCJ.js → session-attachments-root-COVGVQZC.js} +39 -39
  194. package/chunks/{session-pr-refresh-G4DYR2GA.js → session-pr-refresh-SX33MGB4.js} +44 -44
  195. package/chunks/{settings-5CSMP2XC.js → settings-XRNF45NA.js} +43 -43
  196. package/chunks/{shell-MHNR7ELX.js → shell-RX3LXNJP.js} +25 -25
  197. package/chunks/{skill-BQH2WIPE.js → skill-KCPU5AV6.js} +5 -5
  198. package/chunks/{skill-settings-NBLEU6N3.js → skill-settings-PAEWMBXK.js} +44 -44
  199. package/chunks/{spawnChannel-OWXPYFWT.js → spawnChannel-SNCSRXCH.js} +41 -41
  200. package/chunks/{standalone-update-U6UUKRKU.js → standalone-update-WPASUR47.js} +40 -40
  201. package/chunks/{startInteractiveUI-EJULGCL7.js → startInteractiveUI-ZX3UUKMI.js} +104 -87
  202. package/chunks/{task-create-A2MP37QH.js → task-create-A3FAT34J.js} +4 -4
  203. package/chunks/{task-update-NJG2RTP7.js → task-update-BE27HYCU.js} +4 -4
  204. package/chunks/{team-create-PJK2OS5B.js → team-create-LV77LY5U.js} +25 -25
  205. package/chunks/{team-plan-approval-KSJV7ZQ6.js → team-plan-approval-VBIL6SV3.js} +25 -25
  206. package/chunks/{terminal-image-renderer-3K262PTL.js → terminal-image-renderer-ADP6QUHM.js} +39 -39
  207. package/chunks/{theme-manager-JR5EN3JA.js → theme-manager-EUUSF2Q7.js} +39 -39
  208. package/chunks/{tool-call-VNMKD4BX.js → tool-call-7HZFNB7J.js} +4 -4
  209. package/chunks/{tool-result-media-5G5L5FUD.js → tool-result-media-JVU7TVUQ.js} +10 -10
  210. package/chunks/{tool-search-RMXHOHI6.js → tool-search-PEJVNWOB.js} +7 -7
  211. package/chunks/{total-session-admission-DNSWPKQR.js → total-session-admission-N7ME7DLF.js} +42 -42
  212. package/chunks/{trustedFolders-MXRKCC7V.js → trustedFolders-G3EG6RNC.js} +40 -40
  213. package/chunks/{update-relaunch-YZ752NJD.js → update-relaunch-OAYGBIDB.js} +17 -8
  214. package/chunks/{updateCheck-5B4SBAZT.js → updateCheck-JKYZNZTK.js} +39 -39
  215. package/chunks/{upload-config-CMV4ABF2.js → upload-config-LPONQVLM.js} +6 -6
  216. package/chunks/{useAutoAcceptIndicator-UVPPBAVQ.js → useAutoAcceptIndicator-AZBWWHTT.js} +47 -47
  217. package/chunks/{validateNonInterActiveAuth-Y55S3BD5.js → validateNonInterActiveAuth-5K6TQOCW.js} +68 -68
  218. package/chunks/{version-G4JNJAHP.js → version-7MOVE5JZ.js} +1 -1
  219. package/chunks/{web-fetch-GMZV2QHR.js → web-fetch-ALDHPFKB.js} +5 -5
  220. package/chunks/{web-search-C74YSUHS.js → web-search-4FXUXV76.js} +7 -7
  221. package/chunks/{workflow-QNJRLQVY.js → workflow-W6TQFKWS.js} +26 -26
  222. package/chunks/{workspace-providers-status-NQJJBMZF.js → workspace-providers-status-JRU6E7KT.js} +50 -50
  223. package/chunks/{workspace-registration-store-SFC3KHYO.js → workspace-registration-store-2VLHZRVP.js} +1 -1
  224. package/chunks/{workspace-registry-N5DD5XIM.js → workspace-registry-BYB7WBWO.js} +42 -42
  225. package/chunks/{workspace-runtime-coordinator-BXYGAFZC.js → workspace-runtime-coordinator-EEAZTJ6X.js} +43 -43
  226. package/chunks/{workspace-service-ZVV75GHH.js → workspace-service-7SCTZ2HS.js} +48 -48
  227. package/chunks/{workspace-skills-status-ZTULNHRY.js → workspace-skills-status-HDLEGK3V.js} +47 -47
  228. package/chunks/{workspace-trust-reconciler-FFQBYGN6.js → workspace-trust-reconciler-SONZ46YA.js} +47 -47
  229. package/chunks/{write-file-VLVTXBBH.js → write-file-BIRFPH4F.js} +28 -28
  230. package/chunks/{zoom-image-RCU2ZECA.js → zoom-image-UFU3VEIY.js} +4 -4
  231. package/cli-entry.js +35 -18
  232. package/cli.js +12 -12
  233. package/execution-worker.js +1 -1
  234. package/export-transcript-document.js +1 -1
  235. package/package.json +2 -2
  236. package/release-notes.json +31 -0
  237. package/web-shell/assets/{abnfDiagram-VCTEODGH-C79vZf7q.js → abnfDiagram-VCTEODGH-BvoMbUn4.js} +1 -1
  238. package/web-shell/assets/{arc-By9TNVXj.js → arc-DbQBncMt.js} +1 -1
  239. package/web-shell/assets/{architectureDiagram-5GKGNRK7-dOGgroC-.js → architectureDiagram-5GKGNRK7-C8RG0dgJ.js} +1 -1
  240. package/web-shell/assets/{blockDiagram-NRAW4CY4-B9dT448v.js → blockDiagram-NRAW4CY4-pL2S69WR.js} +1 -1
  241. package/web-shell/assets/{c4Diagram-UCG6FXSJ-BZq7QGRh.js → c4Diagram-UCG6FXSJ-BtqW-kE-.js} +1 -1
  242. package/web-shell/assets/channel-D6P_9m4V.js +1 -0
  243. package/web-shell/assets/{chunk-2Q5K7J3B-Ddaq9Ppd.js → chunk-2Q5K7J3B-DH8xQogC.js} +1 -1
  244. package/web-shell/assets/{chunk-5VM5RSS4-BBjSH5RT.js → chunk-5VM5RSS4-BH3myFbn.js} +1 -1
  245. package/web-shell/assets/{chunk-F27PBJKO-t4UEfBw5.js → chunk-F27PBJKO-iY2yWixd.js} +1 -1
  246. package/web-shell/assets/{chunk-G27WJ6UU-D_VuJGqI.js → chunk-G27WJ6UU-D_j7Xo_Y.js} +1 -1
  247. package/web-shell/assets/{chunk-JWPE2WC7-BqUwq2mP.js → chunk-JWPE2WC7-CxBsiYSx.js} +1 -1
  248. package/web-shell/assets/{chunk-LCL6LL3I-TJVqP4zd.js → chunk-LCL6LL3I-DQbc3B6E.js} +1 -1
  249. package/web-shell/assets/{chunk-POPQ4Y6H-m8_NZQnQ.js → chunk-POPQ4Y6H-BdaRtQLf.js} +1 -1
  250. package/web-shell/assets/{chunk-SVP7TREG-CfC75Ei3.js → chunk-SVP7TREG-D58Lphw-.js} +1 -1
  251. package/web-shell/assets/{chunk-XXDRQBXY-B-Q7EfLc.js → chunk-XXDRQBXY-BSmrr5ej.js} +1 -1
  252. package/web-shell/assets/classDiagram-DTDB5LWJ-BW3KY7XN.js +1 -0
  253. package/web-shell/assets/classDiagram-v2-JRS7N3AN-BW3KY7XN.js +1 -0
  254. package/web-shell/assets/{cose-bilkent-JH36ORCC-D1UWVn_j.js → cose-bilkent-JH36ORCC-DYv3YjD8.js} +1 -1
  255. package/web-shell/assets/{cynefin-OW5HDTMX-BYyvfU2W.js → cynefin-OW5HDTMX-ChRVKOIc.js} +1 -1
  256. package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-h31WLcWO.js → cynefinDiagram-5FMLGOSQ-2dgun5lr.js} +1 -1
  257. package/web-shell/assets/{dagre-3AP2YEHR-CBfIQyq3.js → dagre-3AP2YEHR-IGE15SAI.js} +1 -1
  258. package/web-shell/assets/{diagram-S7CK7UJ4-DvhgeRNT.js → diagram-S7CK7UJ4-BHcZWynB.js} +1 -1
  259. package/web-shell/assets/{diagram-UQ7AKVKN-B45bX9cw.js → diagram-UQ7AKVKN-DalYrZk-.js} +1 -1
  260. package/web-shell/assets/{diagram-VSXAHHWV-w5_5TRwb.js → diagram-VSXAHHWV-CMKHsUs7.js} +1 -1
  261. package/web-shell/assets/{diagram-VX7I27RA-DAiR8vdO.js → diagram-VX7I27RA-DgrQKlmX.js} +1 -1
  262. package/web-shell/assets/{diagram-Z3DM3KII-Da7jZeIH.js → diagram-Z3DM3KII-CVdgT4Q4.js} +1 -1
  263. package/web-shell/assets/{ebnfDiagram-PWID7BFC-B7WF9Qum.js → ebnfDiagram-PWID7BFC-BV7RGD_D.js} +1 -1
  264. package/web-shell/assets/{erDiagram-SSCWMZ5O-Dygfopi-.js → erDiagram-SSCWMZ5O-NbSHPXJb.js} +1 -1
  265. package/web-shell/assets/{flowDiagram-A5DVABFB-BX7okAuU.js → flowDiagram-A5DVABFB-BnKFiusj.js} +1 -1
  266. package/web-shell/assets/{ganttDiagram-EL5Y4UJY-DmUOanpH.js → ganttDiagram-EL5Y4UJY-BVBViIDh.js} +1 -1
  267. package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-DQEg-Tk1.js → gitGraphDiagram-WWUBYQGX-Dpi8eTTY.js} +1 -1
  268. package/web-shell/assets/{index-CvYCzWNp.js → index-D-kPo23X.js} +1 -1
  269. package/web-shell/assets/{index-v3wlXQpe.js → index-DtvQ3DEH.js} +3 -3
  270. package/web-shell/assets/{infoDiagram-RXCK75RN-C1jbM00T.js → infoDiagram-RXCK75RN-BpAv0FDb.js} +1 -1
  271. package/web-shell/assets/{ishikawaDiagram-5VMMS53U-cBjbNTV4.js → ishikawaDiagram-5VMMS53U-B7958rb5.js} +1 -1
  272. package/web-shell/assets/{journeyDiagram-EYS64GPL-BazjwXUM.js → journeyDiagram-EYS64GPL-C3KfVyTV.js} +1 -1
  273. package/web-shell/assets/{kanban-definition-3QL26DDD-CUfveZjf.js → kanban-definition-3QL26DDD-DXrBR6gr.js} +1 -1
  274. package/web-shell/assets/{layout-CtpxXAF_.js → layout-D4sWObAV.js} +1 -1
  275. package/web-shell/assets/{linear-VD2q0Clb.js → linear-Cwd2KGkf.js} +1 -1
  276. package/web-shell/assets/{mermaid.core-B6znjYEM.js → mermaid.core-B2gOqjPo.js} +6 -6
  277. package/web-shell/assets/{mindmap-definition-FBJOCRG2-bOsOTlkR.js → mindmap-definition-FBJOCRG2-Oxi-8t2C.js} +1 -1
  278. package/web-shell/assets/{pegDiagram-XKGWAZYB-iWFBUxYu.js → pegDiagram-XKGWAZYB-XhK_Omz8.js} +1 -1
  279. package/web-shell/assets/{pieDiagram-E7YTZNPT-BXQlXRf2.js → pieDiagram-E7YTZNPT-th4P1FI2.js} +1 -1
  280. package/web-shell/assets/{quadrantDiagram-AXDQQJYC-CL0aHMKX.js → quadrantDiagram-AXDQQJYC-BWHRjMh9.js} +1 -1
  281. package/web-shell/assets/{railroadDiagram-O6MQD6OU-D3kquTPx.js → railroadDiagram-O6MQD6OU-D4h49f-M.js} +1 -1
  282. package/web-shell/assets/{requirementDiagram-EFPCY7ZU-C0xj6gpA.js → requirementDiagram-EFPCY7ZU-DSG8xXCi.js} +1 -1
  283. package/web-shell/assets/{sankeyDiagram-P5KCCOFB-Dllh3B5D.js → sankeyDiagram-P5KCCOFB-Tt-9UBxT.js} +1 -1
  284. package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-CMK9o17d.js → sequenceDiagram-WJ2MYXX4-BOh5x5rY.js} +1 -1
  285. package/web-shell/assets/{sizeCapture-X5ZJPWSS-CJ-FZ3Po.js → sizeCapture-X5ZJPWSS-DP0VY8RY.js} +1 -1
  286. package/web-shell/assets/{stateDiagram-HBIQ2CUA-Dk_gRN1Y.js → stateDiagram-HBIQ2CUA-Bqhxdcnc.js} +1 -1
  287. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-X9Lr9vnN.js +1 -0
  288. package/web-shell/assets/{swimlanes-XN3QIQJK-DCCq_M5v.js → swimlanes-XN3QIQJK-g1wrt3v8.js} +1 -1
  289. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-DCoSHHNU.js +8 -0
  290. package/web-shell/assets/{timeline-definition-24CTP7MA-D-XQqKZ2.js → timeline-definition-24CTP7MA-GGkTR6Uu.js} +1 -1
  291. package/web-shell/assets/{vennDiagram-4TSXK5OY-CGtjiahk.js → vennDiagram-4TSXK5OY-yDSKCBuy.js} +1 -1
  292. package/web-shell/assets/{wardleyDiagram-VM6X3IG4-QC0OvkzN.js → wardleyDiagram-VM6X3IG4-Cmfcjc_f.js} +1 -1
  293. package/web-shell/assets/{xychartDiagram-S5SC5T6Z-C-xkrwRW.js → xychartDiagram-S5SC5T6Z-B9EjOHFX.js} +1 -1
  294. package/web-shell/index.html +1 -1
  295. package/web-shell/sw.js +1 -1
  296. package/web-shell/assets/channel-To-6cDF_.js +0 -1
  297. package/web-shell/assets/classDiagram-DTDB5LWJ-DMRUneay.js +0 -1
  298. package/web-shell/assets/classDiagram-v2-JRS7N3AN-DMRUneay.js +0 -1
  299. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-B4fWCuA5.js +0 -1
  300. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-CTS3qlaP.js +0 -8
@@ -1,16 +1,22 @@
1
1
  // Force strict mode and setup for ESM
2
2
  "use strict";
3
+ import {
4
+ isUnverifiableIdentityError,
5
+ openNoFollow
6
+ } from "./chunk-DJOP5LOE.js";
3
7
  import {
4
8
  isCommandAvailable
5
- } from "./chunk-J5BDFZYA.js";
9
+ } from "./chunk-V23Q4GBY.js";
6
10
  import {
7
11
  NO_EXEC_CONFIG,
8
- NO_EXEC_CONFIG_SETTINGS
12
+ NO_EXEC_CONFIG_SETTINGS,
13
+ findGitRoot,
14
+ readFirstLineNoFollow
9
15
  } from "./chunk-IO32UWHY.js";
10
16
  import {
11
17
  fileExists,
12
18
  isWithinRoot
13
- } from "./chunk-E4BNWSC7.js";
19
+ } from "./chunk-H5L5E5NI.js";
14
20
  import {
15
21
  atomicWriteFile,
16
22
  atomicWriteJSON
@@ -121,11 +127,1963 @@ __name(isFiniteInteger, "isFiniteInteger");
121
127
  // packages/core/src/services/gitWorktreeService.ts
122
128
  init_esbuild_shims();
123
129
  import nodeFs from "node:fs";
124
- import * as fs2 from "node:fs/promises";
125
- import * as path2 from "node:path";
130
+ import * as fs4 from "node:fs/promises";
131
+ import * as path5 from "node:path";
126
132
  import { randomBytes, randomInt } from "node:crypto";
127
- import { execFile, execSync } from "node:child_process";
133
+ import { execFile as execFile3, execSync } from "node:child_process";
134
+ import { promisify as promisify3 } from "node:util";
135
+
136
+ // packages/core/src/utils/git-branches.ts
137
+ init_esbuild_shims();
138
+ import { execFile as execFile2 } from "node:child_process";
139
+ import * as fs3 from "node:fs";
140
+ import * as path4 from "node:path";
141
+ import { promisify as promisify2 } from "node:util";
142
+
143
+ // packages/core/src/utils/gitDirect.ts
144
+ init_esbuild_shims();
145
+ import * as fs2 from "node:fs";
146
+ import * as fsPromises from "node:fs/promises";
147
+ import * as path3 from "node:path";
148
+
149
+ // packages/core/src/utils/gitDiff.ts
150
+ init_esbuild_shims();
151
+ import { execFile } from "node:child_process";
152
+ import { access, lstat, open, readFile as readFile2, stat } from "node:fs/promises";
153
+ import * as path2 from "node:path";
128
154
  import { promisify } from "node:util";
155
+ var execFileAsync = promisify(execFile);
156
+ var GIT_TIMEOUT_MS = 5e3;
157
+ var MAX_FILES = 50;
158
+ var MAX_DIFF_SIZE_BYTES = 1e6;
159
+ var MAX_LINES_PER_FILE = 400;
160
+ var MAX_FILES_FOR_DETAILS = 500;
161
+ var EMPTY_STATS = {
162
+ filesCount: 0,
163
+ linesAdded: 0,
164
+ linesRemoved: 0
165
+ };
166
+ var UNTRACKED_READ_CAP_BYTES = MAX_DIFF_SIZE_BYTES;
167
+ var UNTRACKED_READ_CHUNK_BYTES = 64 * 1024;
168
+ var BINARY_SNIFF_BYTES = 8 * 1024;
169
+ async function openUntrackedForDiffRead(absPath) {
170
+ try {
171
+ return await openNoFollow(absPath);
172
+ } catch (error) {
173
+ if (!isUnverifiableIdentityError(error)) return void 0;
174
+ }
175
+ try {
176
+ return await open(absPath);
177
+ } catch {
178
+ return void 0;
179
+ }
180
+ }
181
+ __name(openUntrackedForDiffRead, "openUntrackedForDiffRead");
182
+ async function fetchGitDiff(cwd) {
183
+ const gitRoot = findGitRoot(cwd);
184
+ if (!gitRoot) return null;
185
+ if (await isInTransientGitState(gitRoot)) return null;
186
+ const [shortstatOut, untrackedOut] = await Promise.all([
187
+ runGit(
188
+ [
189
+ "--no-optional-locks",
190
+ "diff",
191
+ "--no-ext-diff",
192
+ "--no-textconv",
193
+ "HEAD",
194
+ "--shortstat"
195
+ ],
196
+ gitRoot
197
+ ),
198
+ runGit(
199
+ [
200
+ "--no-optional-locks",
201
+ "ls-files",
202
+ "-z",
203
+ "--others",
204
+ "--exclude-standard"
205
+ ],
206
+ gitRoot
207
+ )
208
+ ]);
209
+ const untrackedCount = countNulDelimited(untrackedOut);
210
+ const quickStats = shortstatOut != null && parseShortstat(shortstatOut) || EMPTY_STATS;
211
+ if (quickStats.filesCount + untrackedCount > MAX_FILES_FOR_DETAILS) {
212
+ return {
213
+ stats: {
214
+ ...quickStats,
215
+ filesCount: quickStats.filesCount + untrackedCount
216
+ },
217
+ perFileStats: /* @__PURE__ */ new Map()
218
+ };
219
+ }
220
+ const [numstatOut, nameStatusOut] = await Promise.all([
221
+ runGit(
222
+ [
223
+ "--no-optional-locks",
224
+ "diff",
225
+ "--no-ext-diff",
226
+ "--no-textconv",
227
+ "HEAD",
228
+ "--numstat",
229
+ "-z"
230
+ ],
231
+ gitRoot
232
+ ),
233
+ runGit(
234
+ [
235
+ "--no-optional-locks",
236
+ "diff",
237
+ "--no-ext-diff",
238
+ "--no-textconv",
239
+ "HEAD",
240
+ "--name-status",
241
+ "-z"
242
+ ],
243
+ gitRoot
244
+ )
245
+ ]);
246
+ if (numstatOut == null) return null;
247
+ const { stats, perFileStats } = parseGitNumstat(numstatOut);
248
+ const deletedPaths = nameStatusOut != null ? parseDeletedFromNameStatus(nameStatusOut) : null;
249
+ if (deletedPaths && deletedPaths.size > 0) {
250
+ for (const [filename, s] of perFileStats) {
251
+ if (deletedPaths.has(filename)) s.isDeleted = true;
252
+ }
253
+ }
254
+ if (untrackedCount > 0) {
255
+ stats.filesCount += untrackedCount;
256
+ const untrackedPaths = splitNulDelimited(untrackedOut);
257
+ const lineStats = await mapWithConcurrency(
258
+ untrackedPaths,
259
+ MAX_FILES,
260
+ (relPath) => countUntrackedLines(path2.join(gitRoot, relPath))
261
+ );
262
+ for (const s of lineStats) stats.linesAdded += s.added;
263
+ const remainingSlots = Math.max(0, MAX_FILES - perFileStats.size);
264
+ const visibleCount = Math.min(remainingSlots, untrackedPaths.length);
265
+ for (let i = 0; i < visibleCount; i++) {
266
+ const relPath = untrackedPaths[i] ?? "";
267
+ const u = lineStats[i] ?? {
268
+ added: 0,
269
+ isBinary: false,
270
+ truncated: false
271
+ };
272
+ perFileStats.set(relPath, {
273
+ added: u.added,
274
+ removed: 0,
275
+ isBinary: u.isBinary,
276
+ isUntracked: true,
277
+ truncated: u.truncated
278
+ });
279
+ }
280
+ }
281
+ return { stats, perFileStats };
282
+ }
283
+ __name(fetchGitDiff, "fetchGitDiff");
284
+ async function fetchGitDiffHunks(cwd) {
285
+ const gitRoot = findGitRoot(cwd);
286
+ if (!gitRoot) return /* @__PURE__ */ new Map();
287
+ if (await isInTransientGitState(gitRoot)) return /* @__PURE__ */ new Map();
288
+ const diffOut = await runGit(
289
+ ["--no-optional-locks", "diff", "--no-ext-diff", "--no-textconv", "HEAD"],
290
+ gitRoot
291
+ );
292
+ if (diffOut == null) return /* @__PURE__ */ new Map();
293
+ return parseGitDiff(diffOut);
294
+ }
295
+ __name(fetchGitDiffHunks, "fetchGitDiffHunks");
296
+ async function fetchGitDiffHunksForFile(cwd, filePath, oldPath) {
297
+ const gitRoot = findGitRoot(cwd);
298
+ if (!gitRoot) return null;
299
+ const relPath = toRepoRelativePath(gitRoot, filePath);
300
+ if (relPath === null) return null;
301
+ if (await isInTransientGitState(gitRoot)) return null;
302
+ const oldRelPath = oldPath != null ? toRepoRelativePath(gitRoot, oldPath) : null;
303
+ const diffArgs = [
304
+ "--no-optional-locks",
305
+ "diff",
306
+ "--no-ext-diff",
307
+ "--no-textconv"
308
+ ];
309
+ if (oldRelPath != null) diffArgs.push("-M");
310
+ diffArgs.push("HEAD", "--");
311
+ if (oldRelPath != null) diffArgs.push(oldRelPath);
312
+ diffArgs.push(relPath);
313
+ const diffOut = await runGit(diffArgs, gitRoot);
314
+ if (diffOut == null) return null;
315
+ const truncatedPaths = /* @__PURE__ */ new Set();
316
+ const parsed = parseGitDiff(diffOut, truncatedPaths);
317
+ if (parsed.size > 0) {
318
+ const [key, hunks] = parsed.entries().next().value;
319
+ return { hunks: hunks ?? [], truncated: truncatedPaths.has(key) };
320
+ }
321
+ const untrackedOut = await runGit(
322
+ [
323
+ "--no-optional-locks",
324
+ "ls-files",
325
+ "--others",
326
+ "--exclude-standard",
327
+ "--",
328
+ relPath
329
+ ],
330
+ gitRoot
331
+ );
332
+ if (untrackedOut && untrackedOut.trim().length > 0) {
333
+ return synthesizeUntrackedHunk(gitRoot, relPath);
334
+ }
335
+ return null;
336
+ }
337
+ __name(fetchGitDiffHunksForFile, "fetchGitDiffHunksForFile");
338
+ function toRepoRelativePath(gitRoot, filePath) {
339
+ if (!path2.isAbsolute(filePath)) {
340
+ if (filePath.length === 0) return null;
341
+ if (filePath.startsWith("/") || filePath.startsWith("\\")) return null;
342
+ if (/^[A-Za-z]:/.test(filePath)) return null;
343
+ if (filePath.split(/[\\/]/).some((segment) => segment === ".."))
344
+ return null;
345
+ return filePath;
346
+ }
347
+ const rel = path2.relative(gitRoot, filePath);
348
+ if (rel === "" || rel === ".." || rel.startsWith(`..${path2.sep}`) || path2.isAbsolute(rel))
349
+ return null;
350
+ return rel;
351
+ }
352
+ __name(toRepoRelativePath, "toRepoRelativePath");
353
+ async function synthesizeUntrackedHunk(gitRoot, filePath) {
354
+ const absPath = path2.join(gitRoot, filePath);
355
+ try {
356
+ const lst = await lstat(absPath);
357
+ if (!lst.isFile()) return null;
358
+ } catch {
359
+ return null;
360
+ }
361
+ const fh = await openUntrackedForDiffRead(absPath);
362
+ if (!fh) return null;
363
+ try {
364
+ const st = await fh.stat();
365
+ if (!st.isFile()) return null;
366
+ const cap = Math.min(st.size, MAX_DIFF_SIZE_BYTES);
367
+ const buf = Buffer.allocUnsafe(cap);
368
+ let offset = 0;
369
+ while (offset < cap) {
370
+ const { bytesRead } = await fh.read(buf, offset, cap - offset, offset);
371
+ if (bytesRead === 0) break;
372
+ offset += bytesRead;
373
+ }
374
+ const sniffEnd = Math.min(offset, BINARY_SNIFF_BYTES);
375
+ for (let i = 0; i < sniffEnd; i++) {
376
+ if (buf[i] === 0) return null;
377
+ }
378
+ const lines = buf.toString("utf8", 0, offset).split("\n");
379
+ if (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
380
+ const capped = lines.slice(0, MAX_LINES_PER_FILE);
381
+ const truncated = st.size > MAX_DIFF_SIZE_BYTES || lines.length > capped.length;
382
+ if (capped.length === 0) return { hunks: [], truncated };
383
+ return {
384
+ hunks: [
385
+ {
386
+ oldStart: 0,
387
+ oldLines: 0,
388
+ newStart: 1,
389
+ newLines: capped.length,
390
+ lines: capped.map((line) => "+" + line)
391
+ }
392
+ ],
393
+ truncated
394
+ };
395
+ } catch {
396
+ return null;
397
+ } finally {
398
+ await fh.close().catch(() => {
399
+ });
400
+ }
401
+ }
402
+ __name(synthesizeUntrackedHunk, "synthesizeUntrackedHunk");
403
+ function forEachNumstatEntry(stdout, visit) {
404
+ const tokens = stdout.split("\0");
405
+ if (tokens.length > 0 && tokens[tokens.length - 1] === "") tokens.pop();
406
+ let pending = null;
407
+ let renameOld = null;
408
+ for (const token of tokens) {
409
+ if (pending) {
410
+ if (renameOld === null) {
411
+ renameOld = token;
412
+ continue;
413
+ }
414
+ visit({ ...pending, path: token, oldPath: renameOld });
415
+ pending = null;
416
+ renameOld = null;
417
+ continue;
418
+ }
419
+ const firstTab = token.indexOf(" ");
420
+ if (firstTab < 0) continue;
421
+ const secondTab = token.indexOf(" ", firstTab + 1);
422
+ if (secondTab < 0) continue;
423
+ const addStr = token.slice(0, firstTab);
424
+ const remStr = token.slice(firstTab + 1, secondTab);
425
+ const path6 = token.slice(secondTab + 1);
426
+ const isBinary = addStr === "-" || remStr === "-";
427
+ const added = isBinary ? 0 : parseInt(addStr, 10) || 0;
428
+ const removed = isBinary ? 0 : parseInt(remStr, 10) || 0;
429
+ if (path6 === "") {
430
+ pending = { added, removed, isBinary };
431
+ continue;
432
+ }
433
+ visit({ path: path6, added, removed, isBinary });
434
+ }
435
+ }
436
+ __name(forEachNumstatEntry, "forEachNumstatEntry");
437
+ function parseGitNumstat(stdout) {
438
+ let added = 0;
439
+ let removed = 0;
440
+ let validFileCount = 0;
441
+ const perFileStats = /* @__PURE__ */ new Map();
442
+ forEachNumstatEntry(stdout, (entry) => {
443
+ commitEntry(
444
+ entry.path,
445
+ entry.added,
446
+ entry.removed,
447
+ entry.isBinary,
448
+ entry.oldPath
449
+ );
450
+ });
451
+ function commitEntry(filePath, fileAdded, fileRemoved, isBinary, oldPath) {
452
+ validFileCount++;
453
+ added += fileAdded;
454
+ removed += fileRemoved;
455
+ if (perFileStats.size < MAX_FILES) {
456
+ perFileStats.set(filePath, {
457
+ added: fileAdded,
458
+ removed: fileRemoved,
459
+ isBinary,
460
+ ...oldPath ? { oldPath } : {}
461
+ });
462
+ }
463
+ }
464
+ __name(commitEntry, "commitEntry");
465
+ return {
466
+ stats: {
467
+ filesCount: validFileCount,
468
+ linesAdded: added,
469
+ linesRemoved: removed
470
+ },
471
+ perFileStats
472
+ };
473
+ }
474
+ __name(parseGitNumstat, "parseGitNumstat");
475
+ function parseGitDiff(stdout, truncatedPaths) {
476
+ const result = /* @__PURE__ */ new Map();
477
+ if (!stdout.trim()) return result;
478
+ const fileDiffs = stdout.split(/^diff --git /m).filter(Boolean);
479
+ for (const fileDiff of fileDiffs) {
480
+ if (result.size >= MAX_FILES) break;
481
+ if (Buffer.byteLength(fileDiff, "utf8") > MAX_DIFF_SIZE_BYTES) continue;
482
+ const lines = fileDiff.split("\n");
483
+ const filePath = extractFilePath(lines);
484
+ if (filePath === null) continue;
485
+ const fileHunks = [];
486
+ let currentHunk = null;
487
+ let lineCount = 0;
488
+ for (let i = 1; i < lines.length; i++) {
489
+ const line = lines[i] ?? "";
490
+ const hunkMatch = line.match(
491
+ /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/
492
+ );
493
+ if (hunkMatch) {
494
+ if (currentHunk) fileHunks.push(currentHunk);
495
+ currentHunk = {
496
+ oldStart: parseInt(hunkMatch[1] ?? "0", 10),
497
+ oldLines: parseInt(hunkMatch[2] ?? "1", 10),
498
+ newStart: parseInt(hunkMatch[3] ?? "0", 10),
499
+ newLines: parseInt(hunkMatch[4] ?? "1", 10),
500
+ lines: []
501
+ };
502
+ continue;
503
+ }
504
+ if (!currentHunk) {
505
+ continue;
506
+ }
507
+ if (line.startsWith("+") || line.startsWith("-") || line.startsWith(" ")) {
508
+ if (lineCount >= MAX_LINES_PER_FILE) {
509
+ truncatedPaths?.add(filePath);
510
+ break;
511
+ }
512
+ currentHunk.lines.push("" + line);
513
+ lineCount++;
514
+ } else if (line.startsWith("\\")) {
515
+ currentHunk.lines.push("" + line);
516
+ }
517
+ }
518
+ if (currentHunk) fileHunks.push(currentHunk);
519
+ if (fileHunks.length > 0) result.set(filePath, fileHunks);
520
+ }
521
+ return result;
522
+ }
523
+ __name(parseGitDiff, "parseGitDiff");
524
+ function unquoteCStylePath(s) {
525
+ if (!s.startsWith('"') || !s.endsWith('"') || s.length < 2) return s;
526
+ const inner = s.slice(1, -1);
527
+ const bytes = [];
528
+ let i = 0;
529
+ while (i < inner.length) {
530
+ const c = inner.charCodeAt(i);
531
+ if (c !== 92) {
532
+ const cp = inner.codePointAt(i);
533
+ if (cp === void 0) {
534
+ i++;
535
+ continue;
536
+ }
537
+ const ch = String.fromCodePoint(cp);
538
+ bytes.push(...Buffer.from(ch, "utf8"));
539
+ i += ch.length;
540
+ continue;
541
+ }
542
+ const next = inner[i + 1];
543
+ if (next === void 0) {
544
+ bytes.push(92);
545
+ i++;
546
+ continue;
547
+ }
548
+ switch (next) {
549
+ case "a":
550
+ bytes.push(7);
551
+ i += 2;
552
+ break;
553
+ case "b":
554
+ bytes.push(8);
555
+ i += 2;
556
+ break;
557
+ case "f":
558
+ bytes.push(12);
559
+ i += 2;
560
+ break;
561
+ case "v":
562
+ bytes.push(11);
563
+ i += 2;
564
+ break;
565
+ case "t":
566
+ bytes.push(9);
567
+ i += 2;
568
+ break;
569
+ case "n":
570
+ bytes.push(10);
571
+ i += 2;
572
+ break;
573
+ case "r":
574
+ bytes.push(13);
575
+ i += 2;
576
+ break;
577
+ case '"':
578
+ bytes.push(34);
579
+ i += 2;
580
+ break;
581
+ case "\\":
582
+ bytes.push(92);
583
+ i += 2;
584
+ break;
585
+ default:
586
+ if (next >= "0" && next <= "7") {
587
+ let octal = "";
588
+ while (octal.length < 3 && i + 1 + octal.length < inner.length && (inner[i + 1 + octal.length] ?? "") >= "0" && (inner[i + 1 + octal.length] ?? "") <= "7") {
589
+ octal += inner[i + 1 + octal.length];
590
+ }
591
+ bytes.push(parseInt(octal, 8) & 255);
592
+ i += 1 + octal.length;
593
+ } else {
594
+ bytes.push(...Buffer.from(next, "utf8"));
595
+ i += 2;
596
+ }
597
+ }
598
+ }
599
+ return Buffer.from(bytes).toString("utf8");
600
+ }
601
+ __name(unquoteCStylePath, "unquoteCStylePath");
602
+ function extractFilePath(lines) {
603
+ let plus = null;
604
+ let minus = null;
605
+ let renameTo = null;
606
+ let copyTo = null;
607
+ for (const line of lines) {
608
+ if (line.startsWith("@@ ")) break;
609
+ if (line.startsWith("+++ ")) plus = line.slice(4);
610
+ else if (line.startsWith("--- ")) minus = line.slice(4);
611
+ else if (line.startsWith("rename to ")) renameTo = line.slice(10);
612
+ else if (line.startsWith("copy to ")) copyTo = line.slice(8);
613
+ }
614
+ const stripTab = /* @__PURE__ */ __name((s) => {
615
+ const t = s.indexOf(" ");
616
+ return t >= 0 ? s.slice(0, t) : s;
617
+ }, "stripTab");
618
+ const normalize = /* @__PURE__ */ __name((s) => unquoteCStylePath(stripTab(s)), "normalize");
619
+ if (renameTo !== null) return normalize(renameTo);
620
+ if (copyTo !== null) return normalize(copyTo);
621
+ if (plus !== null) {
622
+ const p = normalize(plus);
623
+ if (p !== "/dev/null" && p.startsWith("b/")) return p.slice(2);
624
+ if (minus !== null) {
625
+ const m = normalize(minus);
626
+ if (m !== "/dev/null" && m.startsWith("a/")) return m.slice(2);
627
+ }
628
+ return null;
629
+ }
630
+ if (minus !== null) {
631
+ const m = normalize(minus);
632
+ if (m !== "/dev/null" && m.startsWith("a/")) return m.slice(2);
633
+ }
634
+ return null;
635
+ }
636
+ __name(extractFilePath, "extractFilePath");
637
+ function parseShortstat(stdout) {
638
+ const match = stdout.match(
639
+ /^ ?(\d{1,10}) files? changed(?:, (\d{1,10}) insertions?\(\+\))?(?:, (\d{1,10}) deletions?\(-\))?$/m
640
+ );
641
+ if (!match) return null;
642
+ return {
643
+ filesCount: parseInt(match[1] ?? "0", 10),
644
+ linesAdded: parseInt(match[2] ?? "0", 10),
645
+ linesRemoved: parseInt(match[3] ?? "0", 10)
646
+ };
647
+ }
648
+ __name(parseShortstat, "parseShortstat");
649
+ async function getWorkingTreeLineStats(cwd) {
650
+ const stdout = await runGit(
651
+ ["diff-index", "--no-ext-diff", "--no-textconv", "--shortstat", "HEAD"],
652
+ cwd
653
+ );
654
+ if (stdout === null) return null;
655
+ const stats = parseShortstat(stdout);
656
+ return {
657
+ linesAdded: stats?.linesAdded ?? 0,
658
+ linesRemoved: stats?.linesRemoved ?? 0
659
+ };
660
+ }
661
+ __name(getWorkingTreeLineStats, "getWorkingTreeLineStats");
662
+ function parseDeletedFromNameStatus(stdout) {
663
+ const tokens = stdout.split("\0");
664
+ if (tokens.length > 0 && tokens[tokens.length - 1] === "") tokens.pop();
665
+ const deleted = /* @__PURE__ */ new Set();
666
+ let i = 0;
667
+ while (i < tokens.length) {
668
+ const status = tokens[i] ?? "";
669
+ i++;
670
+ if (status === "") continue;
671
+ const head = status[0];
672
+ if (head === "R" || head === "C") {
673
+ i += 2;
674
+ continue;
675
+ }
676
+ const path6 = tokens[i] ?? "";
677
+ i++;
678
+ if (head === "D" && path6 !== "") deleted.add(path6);
679
+ }
680
+ return deleted;
681
+ }
682
+ __name(parseDeletedFromNameStatus, "parseDeletedFromNameStatus");
683
+ function countNulDelimited(stdout) {
684
+ if (!stdout) return 0;
685
+ let count = 0;
686
+ for (let i = 0; i < stdout.length; i++) {
687
+ if (stdout.charCodeAt(i) === 0) count++;
688
+ }
689
+ return count;
690
+ }
691
+ __name(countNulDelimited, "countNulDelimited");
692
+ function splitNulDelimited(stdout) {
693
+ if (!stdout) return [];
694
+ return stdout.split("\0").filter(Boolean);
695
+ }
696
+ __name(splitNulDelimited, "splitNulDelimited");
697
+ async function countUntrackedLines(absPath) {
698
+ let st;
699
+ try {
700
+ st = await lstat(absPath);
701
+ } catch {
702
+ return { added: 0, isBinary: true, truncated: false };
703
+ }
704
+ if (!st.isFile()) {
705
+ return { added: 0, isBinary: true, truncated: false };
706
+ }
707
+ const fh = await openUntrackedForDiffRead(absPath);
708
+ if (!fh) {
709
+ return { added: 0, isBinary: true, truncated: false };
710
+ }
711
+ try {
712
+ const buf = Buffer.allocUnsafe(UNTRACKED_READ_CHUNK_BYTES);
713
+ let totalRead = 0;
714
+ let lines = 0;
715
+ let lastByte = -1;
716
+ let sniffedBytes = 0;
717
+ while (totalRead < UNTRACKED_READ_CAP_BYTES) {
718
+ const remaining = UNTRACKED_READ_CAP_BYTES - totalRead;
719
+ const toRead = Math.min(buf.length, remaining);
720
+ const { bytesRead } = await fh.read(buf, 0, toRead, totalRead);
721
+ if (bytesRead === 0) break;
722
+ if (sniffedBytes < BINARY_SNIFF_BYTES) {
723
+ const sniffEnd = Math.min(bytesRead, BINARY_SNIFF_BYTES - sniffedBytes);
724
+ for (let i = 0; i < sniffEnd; i++) {
725
+ if (buf[i] === 0) {
726
+ return { added: 0, isBinary: true, truncated: false };
727
+ }
728
+ }
729
+ sniffedBytes += sniffEnd;
730
+ }
731
+ for (let i = 0; i < bytesRead; i++) {
732
+ if (buf[i] === 10) lines++;
733
+ }
734
+ lastByte = buf[bytesRead - 1] ?? -1;
735
+ totalRead += bytesRead;
736
+ }
737
+ if (totalRead === 0) {
738
+ return { added: 0, isBinary: false, truncated: false };
739
+ }
740
+ let truncated = false;
741
+ if (totalRead >= UNTRACKED_READ_CAP_BYTES) {
742
+ const { size } = await fh.stat();
743
+ truncated = size > totalRead;
744
+ }
745
+ if (!truncated && lastByte !== 10) lines++;
746
+ return { added: lines, isBinary: false, truncated };
747
+ } catch {
748
+ return { added: 0, isBinary: true, truncated: false };
749
+ } finally {
750
+ await fh.close().catch(() => {
751
+ });
752
+ }
753
+ }
754
+ __name(countUntrackedLines, "countUntrackedLines");
755
+ async function resolveGitDir(cwd) {
756
+ const gitRoot = findGitRoot(cwd);
757
+ if (!gitRoot) return null;
758
+ return resolveGitDirFromRoot(gitRoot);
759
+ }
760
+ __name(resolveGitDir, "resolveGitDir");
761
+ async function resolveGitDirFromRoot(gitRoot) {
762
+ const dotGit = path2.join(gitRoot, ".git");
763
+ try {
764
+ const s = await stat(dotGit);
765
+ if (s.isDirectory()) return dotGit;
766
+ if (!s.isFile()) return null;
767
+ const content = await readFile2(dotGit, "utf8");
768
+ const match = content.match(/^gitdir:\s*(.+?)\s*$/m);
769
+ if (!match || !match[1]) return null;
770
+ const raw = match[1];
771
+ return path2.isAbsolute(raw) ? raw : path2.resolve(gitRoot, raw);
772
+ } catch {
773
+ return null;
774
+ }
775
+ }
776
+ __name(resolveGitDirFromRoot, "resolveGitDirFromRoot");
777
+ async function isInTransientGitState(gitRoot) {
778
+ const gitDir = await resolveGitDirFromRoot(gitRoot);
779
+ if (!gitDir) return false;
780
+ const transientPaths = [
781
+ "MERGE_HEAD",
782
+ "CHERRY_PICK_HEAD",
783
+ "REVERT_HEAD",
784
+ "rebase-merge",
785
+ "rebase-apply"
786
+ ];
787
+ const results = await Promise.all(
788
+ transientPaths.map(
789
+ (name) => access(path2.join(gitDir, name)).then(() => true).catch(() => false)
790
+ )
791
+ );
792
+ return results.some(Boolean);
793
+ }
794
+ __name(isInTransientGitState, "isInTransientGitState");
795
+ async function mapWithConcurrency(items, limit, fn) {
796
+ if (items.length === 0) return [];
797
+ const effective = Math.max(1, limit);
798
+ const results = new Array(items.length);
799
+ for (let i = 0; i < items.length; i += effective) {
800
+ const slice = items.slice(i, i + effective);
801
+ const batch = await Promise.all(slice.map((item) => fn(item)));
802
+ for (let j = 0; j < batch.length; j++) {
803
+ results[i + j] = batch[j];
804
+ }
805
+ }
806
+ return results;
807
+ }
808
+ __name(mapWithConcurrency, "mapWithConcurrency");
809
+ async function runGit(args, cwd) {
810
+ const fullArgs = ["-c", "core.quotepath=false", ...NO_EXEC_CONFIG, ...args];
811
+ try {
812
+ const { stdout } = await execFileAsync("git", fullArgs, {
813
+ cwd,
814
+ timeout: GIT_TIMEOUT_MS,
815
+ maxBuffer: 64 * 1024 * 1024,
816
+ windowsHide: true,
817
+ encoding: "utf8"
818
+ });
819
+ return stdout;
820
+ } catch {
821
+ return null;
822
+ }
823
+ }
824
+ __name(runGit, "runGit");
825
+ async function getGitWorkingTreeStatus(cwd) {
826
+ const gitRoot = findGitRoot(cwd);
827
+ if (!gitRoot) return null;
828
+ const stdout = await runGit(
829
+ ["--no-optional-locks", "status", "--porcelain=v1", "--branch", "-z"],
830
+ gitRoot
831
+ );
832
+ if (stdout == null) return null;
833
+ const tokens = stdout.split("\0");
834
+ if (tokens.length > 0 && tokens[tokens.length - 1] === "") tokens.pop();
835
+ const head = tokens.shift() ?? "";
836
+ const branch = parseStatusBranchLine(head);
837
+ const counts = parseStatusEntries(tokens);
838
+ const [stashCount, operation] = await Promise.all([
839
+ countStashEntries(gitRoot),
840
+ detectGitOperation(gitRoot)
841
+ ]);
842
+ return {
843
+ ...branch,
844
+ ...counts,
845
+ stashCount,
846
+ ...operation ? { operation } : {}
847
+ };
848
+ }
849
+ __name(getGitWorkingTreeStatus, "getGitWorkingTreeStatus");
850
+ var NO_BRANCH = {
851
+ branch: null,
852
+ detached: false,
853
+ hasUpstream: false,
854
+ ahead: 0,
855
+ behind: 0
856
+ };
857
+ function parseStatusBranchLine(line) {
858
+ if (!line.startsWith("## ")) return { ...NO_BRANCH };
859
+ let desc = line.slice(3);
860
+ if (desc.startsWith("HEAD (no branch)")) {
861
+ return { ...NO_BRANCH, detached: true };
862
+ }
863
+ const unborn = desc.match(/^(?:No commits yet|Initial commit) on (.+)$/);
864
+ if (unborn) {
865
+ return { ...NO_BRANCH, branch: unborn[1] ?? null };
866
+ }
867
+ let ahead = 0;
868
+ let behind = 0;
869
+ const bracket = desc.match(/ \[([^\]]*)\]$/);
870
+ if (bracket) {
871
+ const inner = bracket[1] ?? "";
872
+ const aheadMatch = inner.match(/ahead (\d+)/);
873
+ const behindMatch = inner.match(/behind (\d+)/);
874
+ ahead = aheadMatch ? Number(aheadMatch[1]) : 0;
875
+ behind = behindMatch ? Number(behindMatch[1]) : 0;
876
+ desc = desc.slice(0, bracket.index).trimEnd();
877
+ }
878
+ const hasUpstream = desc.includes("...");
879
+ const sepIndex = desc.lastIndexOf("...");
880
+ const branch = sepIndex >= 0 ? desc.slice(0, sepIndex) : desc;
881
+ return {
882
+ branch: branch || null,
883
+ detached: false,
884
+ hasUpstream,
885
+ ahead,
886
+ behind
887
+ };
888
+ }
889
+ __name(parseStatusBranchLine, "parseStatusBranchLine");
890
+ function isUnmergedEntry(x, y) {
891
+ if (x === "U" || y === "U") return true;
892
+ if (x === "D" && y === "D") return true;
893
+ if (x === "A" && y === "A") return true;
894
+ return false;
895
+ }
896
+ __name(isUnmergedEntry, "isUnmergedEntry");
897
+ function parseStatusEntries(tokens) {
898
+ let staged = 0;
899
+ let unstaged = 0;
900
+ let untracked = 0;
901
+ let conflicted = 0;
902
+ for (let i = 0; i < tokens.length; i++) {
903
+ const tok = tokens[i] ?? "";
904
+ if (tok.length < 3 || tok[2] !== " ") continue;
905
+ const x = tok[0];
906
+ const y = tok[1];
907
+ if (x === "?" && y === "?") {
908
+ untracked++;
909
+ continue;
910
+ }
911
+ if (x === "!" && y === "!") continue;
912
+ if (isUnmergedEntry(x, y)) {
913
+ conflicted++;
914
+ continue;
915
+ }
916
+ if (x !== " " && x !== "?") staged++;
917
+ if (y !== " " && y !== "?") unstaged++;
918
+ if (x === "R" || x === "C" || y === "R" || y === "C") i++;
919
+ }
920
+ return { staged, unstaged, untracked, conflicted };
921
+ }
922
+ __name(parseStatusEntries, "parseStatusEntries");
923
+ async function detectGitOperation(gitRoot) {
924
+ const gitDir = await resolveGitDirFromRoot(gitRoot);
925
+ if (!gitDir) return void 0;
926
+ const checks = [
927
+ ["rebase-merge", "rebase"],
928
+ ["rebase-apply", "rebase"],
929
+ ["MERGE_HEAD", "merge"],
930
+ ["CHERRY_PICK_HEAD", "cherry-pick"],
931
+ ["REVERT_HEAD", "revert"],
932
+ ["BISECT_LOG", "bisect"]
933
+ ];
934
+ for (const [name, op] of checks) {
935
+ try {
936
+ await access(path2.join(gitDir, name));
937
+ return op;
938
+ } catch {
939
+ }
940
+ }
941
+ return void 0;
942
+ }
943
+ __name(detectGitOperation, "detectGitOperation");
944
+ async function resolveCommonGitDir(gitDir) {
945
+ const raw = (await readFirstLineNoFollow(path2.join(gitDir, "commondir")))?.trim();
946
+ if (!raw) return gitDir;
947
+ return path2.isAbsolute(raw) ? raw : path2.resolve(gitDir, raw);
948
+ }
949
+ __name(resolveCommonGitDir, "resolveCommonGitDir");
950
+ async function countStashEntries(gitRoot) {
951
+ const gitDir = await resolveGitDirFromRoot(gitRoot);
952
+ if (!gitDir) return 0;
953
+ const commonDir = await resolveCommonGitDir(gitDir);
954
+ const stashLog = path2.join(commonDir, "logs", "refs", "stash");
955
+ try {
956
+ const st = await lstat(stashLog);
957
+ if (!st.isFile()) return 0;
958
+ } catch {
959
+ return 0;
960
+ }
961
+ try {
962
+ const content = await readFile2(stashLog, "utf8");
963
+ return content.split("\n").filter((line) => line.trim().length > 0).length;
964
+ } catch {
965
+ return 0;
966
+ }
967
+ }
968
+ __name(countStashEntries, "countStashEntries");
969
+ var MAX_LOG_LIMIT = 200;
970
+ var DEFAULT_LOG_LIMIT = 50;
971
+ var LOG_FORMAT = "%H%x00%h%x00%an%x00%ae%x00%at%x00%s%x00%D%x00%P%x00%ct";
972
+ var LOG_FIELDS = 9;
973
+ var LOG_DETAIL_FORMAT = "%H%x00%h%x00%an%x00%ae%x00%at%x00%s%x00%D%x00%P%x00%b";
974
+ function parseLogFields(parts) {
975
+ if (parts.length !== LOG_FIELDS) return null;
976
+ return {
977
+ sha: parts[0],
978
+ shortSha: parts[1],
979
+ authorName: parts[2],
980
+ authorEmail: parts[3],
981
+ authorDate: parseInt(parts[4], 10) || 0,
982
+ subject: parts[5],
983
+ refs: parts[6],
984
+ parents: parts[7] ? parts[7].split(" ").filter(Boolean) : [],
985
+ commitDate: parseInt(parts[8], 10) || 0
986
+ };
987
+ }
988
+ __name(parseLogFields, "parseLogFields");
989
+ var LOG_ALL_REVISIONS = ["HEAD", "--branches", "--tags", "--remotes"];
990
+ function isSafeLogRange(range) {
991
+ return !range.startsWith("-") && !range.startsWith("..") && /^[A-Za-z0-9_./~^-]+$/.test(range);
992
+ }
993
+ __name(isSafeLogRange, "isSafeLogRange");
994
+ function parseLogRecords(stdout) {
995
+ const fields = stdout.split("\0");
996
+ if (fields.at(-1) === "") fields.pop();
997
+ const entries = [];
998
+ for (let i = 0; i + LOG_FIELDS <= fields.length; i += LOG_FIELDS) {
999
+ const entry = parseLogFields(fields.slice(i, i + LOG_FIELDS));
1000
+ if (entry) entries.push(entry);
1001
+ }
1002
+ return entries;
1003
+ }
1004
+ __name(parseLogRecords, "parseLogRecords");
1005
+ async function fetchGitLog(cwd, options) {
1006
+ const gitRoot = findGitRoot(cwd);
1007
+ if (!gitRoot) return null;
1008
+ const limit = Math.min(
1009
+ Math.max(options?.limit ?? DEFAULT_LOG_LIMIT, 1),
1010
+ MAX_LOG_LIMIT
1011
+ );
1012
+ const skip = Math.max(options?.skip ?? 0, 0);
1013
+ const revisions = options?.all ? LOG_ALL_REVISIONS : options?.range && isSafeLogRange(options.range) ? [options.range] : [];
1014
+ const search = options?.search?.trim();
1015
+ if (search) {
1016
+ return searchGitLog(gitRoot, revisions, search, limit, skip);
1017
+ }
1018
+ const stdout = await runGit(
1019
+ [
1020
+ "--no-optional-locks",
1021
+ "log",
1022
+ "-z",
1023
+ `--format=${LOG_FORMAT}`,
1024
+ "--date-order",
1025
+ "-n",
1026
+ String(limit + 1),
1027
+ ...skip > 0 ? ["--skip", String(skip)] : [],
1028
+ ...revisions,
1029
+ "--"
1030
+ ],
1031
+ gitRoot
1032
+ );
1033
+ if (stdout === null) {
1034
+ const head = await runGit(["rev-parse", "--verify", "HEAD"], gitRoot);
1035
+ return head === null ? { entries: [], hasMore: false } : null;
1036
+ }
1037
+ const entries = parseLogRecords(stdout);
1038
+ return { entries: entries.slice(0, limit), hasMore: entries.length > limit };
1039
+ }
1040
+ __name(fetchGitLog, "fetchGitLog");
1041
+ async function searchGitLog(gitRoot, revisions, query, limit, skip) {
1042
+ const window = String(skip + limit + 1);
1043
+ const walk = /* @__PURE__ */ __name((filter) => runGit(
1044
+ [
1045
+ "--no-optional-locks",
1046
+ "log",
1047
+ "-z",
1048
+ `--format=${LOG_FORMAT}`,
1049
+ "--date-order",
1050
+ "-i",
1051
+ "--fixed-strings",
1052
+ filter,
1053
+ "-n",
1054
+ window,
1055
+ ...revisions,
1056
+ "--"
1057
+ ],
1058
+ gitRoot
1059
+ ), "walk");
1060
+ const runs = [walk(`--grep=${query}`), walk(`--author=${query}`)];
1061
+ if (/^[0-9a-f]{4,40}$/i.test(query)) {
1062
+ runs.push(
1063
+ runGit(
1064
+ [
1065
+ "rev-parse",
1066
+ "--verify",
1067
+ "--quiet",
1068
+ "--end-of-options",
1069
+ `${query}^{commit}`
1070
+ ],
1071
+ gitRoot
1072
+ ).then(
1073
+ (sha) => sha ? runGit(
1074
+ [
1075
+ "--no-optional-locks",
1076
+ "log",
1077
+ "-z",
1078
+ `--format=${LOG_FORMAT}`,
1079
+ "--no-walk",
1080
+ sha.trim(),
1081
+ "--"
1082
+ ],
1083
+ gitRoot
1084
+ ) : null
1085
+ )
1086
+ );
1087
+ }
1088
+ const bySha = /* @__PURE__ */ new Map();
1089
+ for (const stdout of await Promise.all(runs)) {
1090
+ for (const entry of parseLogRecords(stdout ?? "")) {
1091
+ if (!bySha.has(entry.sha))
1092
+ bySha.set(entry.sha, { entry, rank: bySha.size });
1093
+ }
1094
+ }
1095
+ const entries = [...bySha.values()].sort((a, b) => b.entry.commitDate - a.entry.commitDate || a.rank - b.rank).map((item) => item.entry);
1096
+ return {
1097
+ entries: entries.slice(skip, skip + limit),
1098
+ hasMore: entries.length > skip + limit
1099
+ };
1100
+ }
1101
+ __name(searchGitLog, "searchGitLog");
1102
+ async function fetchGitCommitDetail(cwd, sha) {
1103
+ if (!/^[0-9a-f]{7,40}$/i.test(sha)) return null;
1104
+ const gitRoot = findGitRoot(cwd);
1105
+ if (!gitRoot) return null;
1106
+ const metaRaw = await runGit(
1107
+ [
1108
+ "--no-optional-locks",
1109
+ "log",
1110
+ "-1",
1111
+ "-z",
1112
+ `--format=${LOG_DETAIL_FORMAT}`,
1113
+ sha
1114
+ ],
1115
+ gitRoot
1116
+ );
1117
+ if (metaRaw === null) return null;
1118
+ const parts = metaRaw.split("\0");
1119
+ if (parts.at(-1) === "") parts.pop();
1120
+ if (parts.length !== 9) return null;
1121
+ const parents = parts[7] ? parts[7].split(" ").filter(Boolean) : [];
1122
+ const diffTreeArgs = parents.length > 1 ? [
1123
+ "--no-optional-locks",
1124
+ "diff-tree",
1125
+ "--no-commit-id",
1126
+ "--numstat",
1127
+ // Detect renames so `git mv` counts as one file (by its new path),
1128
+ // matching the main `git diff` path — diff-tree is plumbing and does
1129
+ // NOT honour diff.renames, so without -M a rename splits into a
1130
+ // delete + add pair. The three-token `-z` rename sequence it then
1131
+ // emits is handled by the pending-rename state machine below.
1132
+ "-M",
1133
+ "-r",
1134
+ "-z",
1135
+ `${sha}^1`,
1136
+ sha
1137
+ ] : [
1138
+ "--no-optional-locks",
1139
+ "diff-tree",
1140
+ "--no-commit-id",
1141
+ "--numstat",
1142
+ // Detect renames so `git mv` counts as one file (by its new path),
1143
+ // matching the main `git diff` path — diff-tree is plumbing and does
1144
+ // NOT honour diff.renames, so without -M a rename splits into a
1145
+ // delete + add pair. The three-token `-z` rename sequence it then
1146
+ // emits is handled by the pending-rename state machine below.
1147
+ "-M",
1148
+ "-r",
1149
+ "-z",
1150
+ "--root",
1151
+ sha
1152
+ ];
1153
+ const numstatRaw = await runGit(diffTreeArgs, gitRoot);
1154
+ const files = [];
1155
+ let filesCount = 0;
1156
+ let linesAdded = 0;
1157
+ let linesRemoved = 0;
1158
+ if (numstatRaw) {
1159
+ forEachNumstatEntry(numstatRaw, (entry) => {
1160
+ filesCount++;
1161
+ linesAdded += entry.added;
1162
+ linesRemoved += entry.removed;
1163
+ if (files.length < MAX_FILES) {
1164
+ files.push({
1165
+ path: entry.path,
1166
+ added: entry.added,
1167
+ removed: entry.removed,
1168
+ isBinary: entry.isBinary
1169
+ });
1170
+ }
1171
+ });
1172
+ }
1173
+ return {
1174
+ sha: parts[0],
1175
+ shortSha: parts[1],
1176
+ authorName: parts[2],
1177
+ authorEmail: parts[3],
1178
+ authorDate: parseInt(parts[4], 10) || 0,
1179
+ subject: parts[5],
1180
+ refs: parts[6],
1181
+ parents,
1182
+ body: parts[8].replace(/\n$/, ""),
1183
+ files,
1184
+ filesCount,
1185
+ linesAdded,
1186
+ linesRemoved,
1187
+ hiddenCount: Math.max(filesCount - files.length, 0)
1188
+ };
1189
+ }
1190
+ __name(fetchGitCommitDetail, "fetchGitCommitDetail");
1191
+
1192
+ // packages/core/src/utils/gitDirect.ts
1193
+ var SHORT_SHA_LENGTH = 7;
1194
+ var debug = createDebugLogger("gitDirect");
1195
+ var MAX_REF_COMPONENT_LENGTH = 255;
1196
+ var INVALID_REF_CHARS = /[\x00-\x20\x7f-\x9f\u200b-\u200d\u2028\u2029\u202a-\u202e\u2066-\u2069\ufeff~^:?*[\\]/;
1197
+ function isValidRefName(name) {
1198
+ if (!name || name === "HEAD") return false;
1199
+ if (name.startsWith("/") || name.endsWith("/")) return false;
1200
+ if (name.startsWith(".") || name.endsWith(".")) return false;
1201
+ if (name.endsWith(".lock")) return false;
1202
+ if (name.includes("..") || name.includes("//")) return false;
1203
+ if (name.includes("/.") || name.includes("./") || name.includes(".lock/")) {
1204
+ return false;
1205
+ }
1206
+ if (name.includes("@{")) return false;
1207
+ if (INVALID_REF_CHARS.test(name)) return false;
1208
+ if (name.split("/").some((c) => c.length > MAX_REF_COMPONENT_LENGTH)) {
1209
+ return false;
1210
+ }
1211
+ return true;
1212
+ }
1213
+ __name(isValidRefName, "isValidRefName");
1214
+ function isValidGitSha(value) {
1215
+ return /^[0-9a-f]{40}$/.test(value) || /^[0-9a-f]{64}$/.test(value);
1216
+ }
1217
+ __name(isValidGitSha, "isValidGitSha");
1218
+ var gitDirCache = /* @__PURE__ */ new Map();
1219
+ async function isDir(p) {
1220
+ try {
1221
+ return (await fsPromises.stat(p)).isDirectory();
1222
+ } catch {
1223
+ return false;
1224
+ }
1225
+ }
1226
+ __name(isDir, "isDir");
1227
+ async function hasGitStore(dir) {
1228
+ const [objects, refs] = await Promise.all([
1229
+ isDir(path3.join(dir, "objects")),
1230
+ isDir(path3.join(dir, "refs"))
1231
+ ]);
1232
+ return objects && refs;
1233
+ }
1234
+ __name(hasGitStore, "hasGitStore");
1235
+ async function isRealGitDir(gitDir) {
1236
+ if (await hasGitStore(gitDir)) return true;
1237
+ const rel = await readFirstLineNoFollow(path3.join(gitDir, "commondir"));
1238
+ if (!rel) return false;
1239
+ return hasGitStore(path3.resolve(gitDir, rel.trim()));
1240
+ }
1241
+ __name(isRealGitDir, "isRealGitDir");
1242
+ async function resolveTrustedGitDir(cwd) {
1243
+ const gitDir = await resolveGitDir(cwd);
1244
+ if (!gitDir) return null;
1245
+ return await isRealGitDir(gitDir) ? gitDir : null;
1246
+ }
1247
+ __name(resolveTrustedGitDir, "resolveTrustedGitDir");
1248
+ async function getCachedGitDir(cwd) {
1249
+ const key = path3.resolve(cwd);
1250
+ const cached = gitDirCache.get(key);
1251
+ if (cached !== void 0) return cached;
1252
+ const gitDir = await resolveTrustedGitDir(key);
1253
+ if (gitDir !== null) gitDirCache.set(key, gitDir);
1254
+ return gitDir;
1255
+ }
1256
+ __name(getCachedGitDir, "getCachedGitDir");
1257
+ async function readGitHead(gitDir) {
1258
+ const firstLine = await readFirstLineNoFollow(path3.join(gitDir, "HEAD"));
1259
+ if (firstLine === null) return null;
1260
+ const content = firstLine.trim();
1261
+ if (content.startsWith("ref:")) {
1262
+ const ref = content.slice(4).trim();
1263
+ if (!ref.startsWith("refs/heads/")) return null;
1264
+ const name = ref.slice("refs/heads/".length);
1265
+ if (!isValidRefName(name)) return null;
1266
+ return { type: "branch", name };
1267
+ }
1268
+ if (isValidGitSha(content)) {
1269
+ return { type: "detached", name: content };
1270
+ }
1271
+ return null;
1272
+ }
1273
+ __name(readGitHead, "readGitHead");
1274
+ async function resolveBranchName(cwd) {
1275
+ const gitDir = await getCachedGitDir(cwd);
1276
+ if (!gitDir) return void 0;
1277
+ const head = await readGitHead(gitDir);
1278
+ if (!head) return void 0;
1279
+ return head.type === "branch" ? head.name : head.name.slice(0, SHORT_SHA_LENGTH);
1280
+ }
1281
+ __name(resolveBranchName, "resolveBranchName");
1282
+ var repoBranchWatches = /* @__PURE__ */ new Map();
1283
+ async function watchRepoBranch(cwd, onChange) {
1284
+ const gitDir = await getCachedGitDir(cwd);
1285
+ if (!gitDir) return () => {
1286
+ };
1287
+ let entry = repoBranchWatches.get(gitDir);
1288
+ if (!entry) {
1289
+ const logsHeadPath = path3.join(gitDir, "logs", "HEAD");
1290
+ try {
1291
+ await fsPromises.access(logsHeadPath, fs2.constants?.F_OK ?? 0);
1292
+ if ((await fsPromises.lstat(logsHeadPath)).isSymbolicLink()) {
1293
+ return () => {
1294
+ };
1295
+ }
1296
+ } catch {
1297
+ return () => {
1298
+ };
1299
+ }
1300
+ const existing = repoBranchWatches.get(gitDir);
1301
+ if (existing) {
1302
+ entry = existing;
1303
+ } else {
1304
+ let watcher;
1305
+ try {
1306
+ watcher = fs2.watch(logsHeadPath, (eventType) => {
1307
+ if (eventType === "change" || eventType === "rename") {
1308
+ repoBranchWatches.get(gitDir)?.subscribers.forEach((cb) => {
1309
+ try {
1310
+ cb();
1311
+ } catch {
1312
+ }
1313
+ });
1314
+ }
1315
+ });
1316
+ } catch (err) {
1317
+ debug.warn(`failed to watch reflog for ${gitDir}: ${err}`);
1318
+ return () => {
1319
+ };
1320
+ }
1321
+ watcher.on("error", (err) => {
1322
+ debug.warn(
1323
+ `reflog watcher error for ${gitDir}; branch will no longer auto-update: ${err?.message}`
1324
+ );
1325
+ const current = repoBranchWatches.get(gitDir);
1326
+ if (current?.watcher === watcher) {
1327
+ try {
1328
+ watcher.close();
1329
+ } catch {
1330
+ }
1331
+ repoBranchWatches.delete(gitDir);
1332
+ }
1333
+ });
1334
+ entry = { watcher, subscribers: /* @__PURE__ */ new Set() };
1335
+ repoBranchWatches.set(gitDir, entry);
1336
+ }
1337
+ }
1338
+ entry.subscribers.add(onChange);
1339
+ let disposed = false;
1340
+ return () => {
1341
+ if (disposed) return;
1342
+ disposed = true;
1343
+ const e = repoBranchWatches.get(gitDir);
1344
+ if (!e) return;
1345
+ e.subscribers.delete(onChange);
1346
+ if (e.subscribers.size === 0) {
1347
+ e.watcher.close();
1348
+ repoBranchWatches.delete(gitDir);
1349
+ }
1350
+ };
1351
+ }
1352
+ __name(watchRepoBranch, "watchRepoBranch");
1353
+
1354
+ // packages/core/src/utils/git-branches.ts
1355
+ var debugLogger = createDebugLogger("GIT_BRANCHES");
1356
+ var execFileAsync2 = promisify2(execFile2);
1357
+ var GIT_TIMEOUT_MS2 = 3e4;
1358
+ var MAX_RECENT_BRANCHES = 20;
1359
+ var MAX_REFLOG_ENTRIES = 200;
1360
+ var GIT_ENV_VARS_TO_CLEAR = [
1361
+ "GIT_DIR",
1362
+ "GIT_WORK_TREE",
1363
+ "GIT_COMMON_DIR",
1364
+ "GIT_INDEX_FILE",
1365
+ "GIT_CONFIG_GLOBAL",
1366
+ "GIT_CONFIG_SYSTEM",
1367
+ "GIT_CONFIG_NOSYSTEM",
1368
+ // Repository selectors that an inherited daemon environment could use to
1369
+ // redirect a trusted-workspace git/gh invocation to a different repository
1370
+ // or object database despite the resolved cwd.
1371
+ "GH_REPO",
1372
+ "GIT_CONFIG_COUNT",
1373
+ "GIT_CONFIG_PARAMETERS",
1374
+ "GIT_OBJECT_DIRECTORY",
1375
+ "GIT_ALTERNATE_OBJECT_DIRECTORIES"
1376
+ ];
1377
+ var GIT_ENV_PREFIXES_TO_CLEAR = ["GIT_CONFIG_KEY_", "GIT_CONFIG_VALUE_"];
1378
+ var HELPER_PROTOCOLS = /* @__PURE__ */ new Set(["ext", "fd"]);
1379
+ function gitEnv(base) {
1380
+ const env = { ...base ?? process.env };
1381
+ for (const key of GIT_ENV_VARS_TO_CLEAR) {
1382
+ delete env[key];
1383
+ }
1384
+ for (const key of Object.keys(env)) {
1385
+ if (GIT_ENV_PREFIXES_TO_CLEAR.some((prefix) => key.startsWith(prefix))) {
1386
+ delete env[key];
1387
+ }
1388
+ }
1389
+ const inheritedAllow = env["GIT_ALLOW_PROTOCOL"];
1390
+ if (inheritedAllow !== void 0) {
1391
+ env["GIT_ALLOW_PROTOCOL"] = inheritedAllow.split(":").filter((p) => !HELPER_PROTOCOLS.has(p.trim().toLowerCase())).join(":");
1392
+ }
1393
+ env["LC_ALL"] = "C";
1394
+ env["LANG"] = "C";
1395
+ return env;
1396
+ }
1397
+ __name(gitEnv, "gitEnv");
1398
+ function runGit2(cwd, args, env) {
1399
+ return execFileAsync2("git", args, {
1400
+ cwd,
1401
+ timeout: GIT_TIMEOUT_MS2,
1402
+ maxBuffer: 10 * 1024 * 1024,
1403
+ env: gitEnv(env)
1404
+ }).then(({ stdout }) => stdout);
1405
+ }
1406
+ __name(runGit2, "runGit");
1407
+ var SEPARATOR = "\0";
1408
+ async function fetchGitBranches(cwd, env) {
1409
+ await runGit2(cwd, ["rev-parse", "--git-dir"], env);
1410
+ const [localRaw, remoteRaw, tagsRaw, headRaw, reflogRaw] = await Promise.all([
1411
+ runGit2(
1412
+ cwd,
1413
+ [
1414
+ "for-each-ref",
1415
+ "--format=%(refname:short)%00%(HEAD)%00%(upstream:short)%00%(upstream:track,nobracket)%00%(committerdate:unix)%00%(subject)%00%(symref)%00%(push:short)%00%(push:track,nobracket)",
1416
+ "refs/heads/"
1417
+ ],
1418
+ env
1419
+ ).catch(() => ""),
1420
+ runGit2(
1421
+ cwd,
1422
+ [
1423
+ "for-each-ref",
1424
+ "--format=%(refname:short)%00%(HEAD)%00%(upstream:short)%00%(upstream:track,nobracket)%00%(committerdate:unix)%00%(subject)%00%(symref)%00%(push:short)%00%(push:track,nobracket)",
1425
+ "refs/remotes/"
1426
+ ],
1427
+ env
1428
+ ).catch(() => ""),
1429
+ runGit2(
1430
+ cwd,
1431
+ [
1432
+ "for-each-ref",
1433
+ "--format=%(refname:short)%00%(creatordate:unix)%00%(subject)",
1434
+ "--sort=-creatordate",
1435
+ "refs/tags/"
1436
+ ],
1437
+ env
1438
+ ).catch(() => ""),
1439
+ runGit2(cwd, ["symbolic-ref", "--short", "HEAD"], env).catch(() => ""),
1440
+ runGit2(
1441
+ cwd,
1442
+ ["reflog", "show", "--format=%gs", `-${MAX_REFLOG_ENTRIES}`],
1443
+ env
1444
+ ).catch(() => "")
1445
+ ]);
1446
+ const local = parseBranchLines(localRaw);
1447
+ const remote = parseBranchLines(remoteRaw);
1448
+ const tags = parseTagLines(tagsRaw);
1449
+ const recent = parseRecentBranches(reflogRaw, headRaw.trim());
1450
+ const headTrimmed = headRaw.trim();
1451
+ const detached = !headTrimmed;
1452
+ return {
1453
+ local,
1454
+ remote,
1455
+ tags,
1456
+ recent,
1457
+ head: headTrimmed || await getDetachedHead(cwd, env),
1458
+ detached
1459
+ };
1460
+ }
1461
+ __name(fetchGitBranches, "fetchGitBranches");
1462
+ function parseBranchLines(raw) {
1463
+ if (!raw.trim()) return [];
1464
+ return raw.trim().split("\n").filter(Boolean).filter((line) => {
1465
+ const parts = line.split(SEPARATOR);
1466
+ return !(parts[6] ?? "");
1467
+ }).map((line) => {
1468
+ const parts = line.split(SEPARATOR);
1469
+ const name = parts[0] ?? "";
1470
+ const isHead = parts[1] === "*";
1471
+ const upstream = parts[2] || void 0;
1472
+ const track = parts[3] ?? "";
1473
+ const commitDate = parseInt(parts[4] ?? "0", 10) || 0;
1474
+ const commitSubject = parts[5] ?? "";
1475
+ let ahead = 0;
1476
+ let behind = 0;
1477
+ const aheadMatch = /ahead (\d+)/.exec(track);
1478
+ const behindMatch = /behind (\d+)/.exec(track);
1479
+ if (aheadMatch) ahead = parseInt(aheadMatch[1], 10);
1480
+ if (behindMatch) behind = parseInt(behindMatch[1], 10);
1481
+ const upstreamGone = upstream !== void 0 && /\bgone\b/.test(track);
1482
+ const pushTarget = parts[7] || void 0;
1483
+ const pushTrack = parts[8] ?? "";
1484
+ const pushGone = pushTarget !== void 0 && /\bgone\b/.test(pushTrack);
1485
+ let pushAhead;
1486
+ let pushBehind;
1487
+ if (pushTarget !== void 0 && !pushGone) {
1488
+ const pa = /ahead (\d+)/.exec(pushTrack);
1489
+ const pb = /behind (\d+)/.exec(pushTrack);
1490
+ pushAhead = pa ? parseInt(pa[1], 10) : 0;
1491
+ pushBehind = pb ? parseInt(pb[1], 10) : 0;
1492
+ }
1493
+ return {
1494
+ name,
1495
+ isHead,
1496
+ upstream,
1497
+ ...upstreamGone ? { upstreamGone } : {},
1498
+ ahead,
1499
+ behind,
1500
+ ...pushTarget !== void 0 ? { pushTarget } : {},
1501
+ ...pushAhead !== void 0 ? { pushAhead } : {},
1502
+ ...pushBehind !== void 0 ? { pushBehind } : {},
1503
+ ...pushGone ? { pushGone } : {},
1504
+ commitDate,
1505
+ commitSubject
1506
+ };
1507
+ });
1508
+ }
1509
+ __name(parseBranchLines, "parseBranchLines");
1510
+ function parseTagLines(raw) {
1511
+ if (!raw.trim()) return [];
1512
+ return raw.trim().split("\n").filter(Boolean).map((line) => {
1513
+ const parts = line.split(SEPARATOR);
1514
+ return {
1515
+ name: parts[0] ?? "",
1516
+ date: parseInt(parts[1] ?? "0", 10) || 0,
1517
+ subject: parts[2] ?? ""
1518
+ };
1519
+ });
1520
+ }
1521
+ __name(parseTagLines, "parseTagLines");
1522
+ function parseRecentBranches(reflogRaw, currentHead) {
1523
+ if (!reflogRaw.trim()) return [];
1524
+ const seen = /* @__PURE__ */ new Set();
1525
+ const result = [];
1526
+ for (const line of reflogRaw.trim().split("\n")) {
1527
+ if (!line.startsWith("checkout: moving from ")) continue;
1528
+ const idx = line.indexOf(" to ");
1529
+ if (idx === -1) continue;
1530
+ const branch = line.slice(idx + 4);
1531
+ if (branch && !seen.has(branch) && branch !== currentHead && !/^[0-9a-f]{7,40}$/.test(branch)) {
1532
+ seen.add(branch);
1533
+ result.push(branch);
1534
+ if (result.length >= MAX_RECENT_BRANCHES) break;
1535
+ }
1536
+ }
1537
+ return result;
1538
+ }
1539
+ __name(parseRecentBranches, "parseRecentBranches");
1540
+ async function getDetachedHead(cwd, env) {
1541
+ try {
1542
+ const sha = await runGit2(cwd, ["rev-parse", "--short", "HEAD"], env);
1543
+ return sha.trim();
1544
+ } catch {
1545
+ return "";
1546
+ }
1547
+ }
1548
+ __name(getDetachedHead, "getDetachedHead");
1549
+ function isValidCheckoutRef(value) {
1550
+ const ref = value.trim();
1551
+ if (!ref || ref.startsWith("-")) return false;
1552
+ if (ref === "HEAD") return true;
1553
+ return isValidRefName(ref) || isValidGitSha(ref);
1554
+ }
1555
+ __name(isValidCheckoutRef, "isValidCheckoutRef");
1556
+ async function gitCheckout(cwd, ref, env) {
1557
+ if (!isValidCheckoutRef(ref)) {
1558
+ throw new Error(`invalid checkout ref: ${ref}`);
1559
+ }
1560
+ const isRemoteTracking = await runGit2(
1561
+ cwd,
1562
+ ["show-ref", "--verify", "--quiet", `refs/remotes/${ref}`],
1563
+ env
1564
+ ).then(() => true).catch(() => false);
1565
+ if (isRemoteTracking) {
1566
+ const localName = ref.slice(ref.indexOf("/") + 1);
1567
+ if (!isValidCheckoutRef(localName)) {
1568
+ throw new Error(
1569
+ `invalid local branch name derived from remote ref: ${localName}`
1570
+ );
1571
+ }
1572
+ const hasLocal = await runGit2(
1573
+ cwd,
1574
+ ["show-ref", "--verify", "--quiet", `refs/heads/${localName}`],
1575
+ env
1576
+ ).then(() => true).catch(() => false);
1577
+ if (hasLocal) {
1578
+ await runGit2(cwd, ["checkout", localName, "--"], env);
1579
+ } else {
1580
+ await runGit2(cwd, ["checkout", "--track", ref], env);
1581
+ }
1582
+ const head = (await runGit2(cwd, ["symbolic-ref", "--short", "HEAD"], env)).trim();
1583
+ return { branch: head, detached: false };
1584
+ }
1585
+ await runGit2(cwd, ["checkout", ref, "--"], env);
1586
+ const headRaw = await runGit2(
1587
+ cwd,
1588
+ ["symbolic-ref", "--short", "HEAD"],
1589
+ env
1590
+ ).catch(() => "");
1591
+ const trimmed = headRaw.trim();
1592
+ if (trimmed) {
1593
+ return { branch: trimmed, detached: false };
1594
+ }
1595
+ const sha = await runGit2(cwd, ["rev-parse", "--short", "HEAD"], env);
1596
+ return { branch: sha.trim(), detached: true };
1597
+ }
1598
+ __name(gitCheckout, "gitCheckout");
1599
+ async function gitCreateBranch(cwd, name, startPoint, env) {
1600
+ if (!isValidRefName(name) || name.startsWith("-")) {
1601
+ throw new Error(`invalid branch name: ${name}`);
1602
+ }
1603
+ const args = ["checkout", "-b", name];
1604
+ if (startPoint) {
1605
+ if (!isValidCheckoutRef(startPoint)) {
1606
+ throw new Error(`invalid start point: ${startPoint}`);
1607
+ }
1608
+ args.push(startPoint);
1609
+ }
1610
+ args.push("--");
1611
+ const originalRef = (await runGit2(
1612
+ cwd,
1613
+ ["symbolic-ref", "--quiet", "--short", "HEAD"],
1614
+ env
1615
+ ).catch(() => "")).trim();
1616
+ const originalCommit = originalRef ? "" : (await runGit2(cwd, ["rev-parse", "HEAD"], env).catch(() => "")).trim();
1617
+ const startCommit = (await runGit2(
1618
+ cwd,
1619
+ ["rev-parse", "--verify", `${startPoint || "HEAD"}^{commit}`],
1620
+ env
1621
+ ).catch(() => "")).trim();
1622
+ try {
1623
+ await runGit2(cwd, args, env);
1624
+ } catch (err) {
1625
+ const nowOn = (await runGit2(
1626
+ cwd,
1627
+ ["symbolic-ref", "--quiet", "--short", "HEAD"],
1628
+ env
1629
+ ).catch(() => "")).trim();
1630
+ if (nowOn === name) {
1631
+ if (originalRef) {
1632
+ await runGit2(cwd, ["checkout", originalRef, "--"], env).catch(() => {
1633
+ });
1634
+ } else if (originalCommit) {
1635
+ await runGit2(
1636
+ cwd,
1637
+ ["checkout", "--detach", originalCommit, "--"],
1638
+ env
1639
+ ).catch(() => {
1640
+ });
1641
+ }
1642
+ const newHead = (await runGit2(cwd, ["rev-parse", `refs/heads/${name}`], env).catch(
1643
+ () => ""
1644
+ )).trim();
1645
+ if (newHead && newHead !== startCommit) {
1646
+ debugLogger.warn(
1647
+ `gitCreateBranch: keeping branch "${name}" because it contains commits created after checkout (likely by a failing post-checkout hook)`
1648
+ );
1649
+ } else {
1650
+ await runGit2(cwd, ["branch", "-D", name], env).catch(() => {
1651
+ });
1652
+ }
1653
+ }
1654
+ throw err;
1655
+ }
1656
+ return { branch: name, detached: false };
1657
+ }
1658
+ __name(gitCreateBranch, "gitCreateBranch");
1659
+ async function gitPush(cwd, opts, env) {
1660
+ const args = ["push"];
1661
+ if (opts?.force) args.push("--force-with-lease");
1662
+ if (opts?.setUpstream) {
1663
+ let branch;
1664
+ try {
1665
+ branch = (await runGit2(cwd, ["symbolic-ref", "--short", "HEAD"], env)).trim();
1666
+ } catch {
1667
+ throw new Error(
1668
+ "cannot push with --set-upstream in detached HEAD state; check out a branch first"
1669
+ );
1670
+ }
1671
+ const hasUpstream = await runGit2(
1672
+ cwd,
1673
+ ["rev-parse", "--abbrev-ref", `${branch}@{u}`],
1674
+ env
1675
+ ).catch(() => "");
1676
+ if (hasUpstream.trim()) {
1677
+ const output2 = await runGit2(cwd, args, env);
1678
+ return { success: true, output: output2.trim() };
1679
+ }
1680
+ let remote = (await runGit2(cwd, ["config", `branch.${branch}.pushRemote`], env).catch(
1681
+ () => ""
1682
+ )).trim();
1683
+ if (!remote) {
1684
+ remote = (await runGit2(cwd, ["config", "remote.pushDefault"], env).catch(() => "")).trim();
1685
+ }
1686
+ if (!remote) {
1687
+ remote = (await runGit2(cwd, ["config", `branch.${branch}.remote`], env).catch(
1688
+ () => ""
1689
+ )).trim();
1690
+ }
1691
+ if (!remote) {
1692
+ const remotes = (await runGit2(cwd, ["remote"], env).catch(() => "")).trim();
1693
+ const remoteList = remotes ? remotes.split("\n") : [];
1694
+ remote = remoteList.length === 1 ? remoteList[0] ?? "origin" : "origin";
1695
+ }
1696
+ args.push("--set-upstream", remote, branch);
1697
+ }
1698
+ const output = await runGit2(cwd, args, env);
1699
+ return { success: true, output: output.trim() };
1700
+ }
1701
+ __name(gitPush, "gitPush");
1702
+ var GitPullFailure = class extends Error {
1703
+ static {
1704
+ __name(this, "GitPullFailure");
1705
+ }
1706
+ code;
1707
+ constructor(code, message) {
1708
+ super(message);
1709
+ this.name = "GitPullFailure";
1710
+ this.code = code;
1711
+ }
1712
+ };
1713
+ var AUTO_STASH_MESSAGE = "o1-code: auto-stash before pull";
1714
+ var OPERATION_STATE_PATHS = [
1715
+ ["MERGE_HEAD", "merge"],
1716
+ ["CHERRY_PICK_HEAD", "cherry-pick"],
1717
+ ["REVERT_HEAD", "revert"],
1718
+ ["rebase-merge", "rebase"],
1719
+ ["rebase-apply", "rebase or am"]
1720
+ ];
1721
+ function gitDetail(err) {
1722
+ if (err && typeof err === "object" && ("stdout" in err || "stderr" in err)) {
1723
+ const e = err;
1724
+ const detail = `${e.stdout ?? ""}
1725
+ ${e.stderr ?? ""}`.trim();
1726
+ if (detail) return detail;
1727
+ return "git exited without diagnostic output; a stale lock file (e.g. .git/index.lock) or another git process is the usual cause";
1728
+ }
1729
+ return err instanceof Error ? err.message : String(err);
1730
+ }
1731
+ __name(gitDetail, "gitDetail");
1732
+ function exitCode(err) {
1733
+ const code = err?.code;
1734
+ return typeof code === "number" ? code : void 0;
1735
+ }
1736
+ __name(exitCode, "exitCode");
1737
+ function pullExitCode(err) {
1738
+ const code = exitCode(err);
1739
+ if (code !== void 0) return code;
1740
+ const e = err;
1741
+ if (e && (e.killed === true || typeof e.signal === "string")) return 1;
1742
+ return void 0;
1743
+ }
1744
+ __name(pullExitCode, "pullExitCode");
1745
+ async function gitPaths(cwd, names, env) {
1746
+ const args = ["rev-parse"];
1747
+ for (const name of names) args.push("--git-path", name);
1748
+ return (await runGit2(cwd, args, env)).trim().split("\n").map((line) => path4.resolve(cwd, line));
1749
+ }
1750
+ __name(gitPaths, "gitPaths");
1751
+ async function operationInProgress(cwd, env) {
1752
+ const paths = await gitPaths(
1753
+ cwd,
1754
+ OPERATION_STATE_PATHS.map(([statePath]) => statePath),
1755
+ env
1756
+ );
1757
+ for (let i = 0; i < OPERATION_STATE_PATHS.length; i++) {
1758
+ if (fs3.existsSync(paths[i])) return OPERATION_STATE_PATHS[i][1];
1759
+ }
1760
+ return void 0;
1761
+ }
1762
+ __name(operationInProgress, "operationInProgress");
1763
+ async function refuseOperationInProgress(cwd, env) {
1764
+ const operation = await operationInProgress(cwd, env);
1765
+ if (operation) {
1766
+ throw new GitPullFailure(
1767
+ "operation_in_progress",
1768
+ `cannot update: a ${operation} is in progress; finish or abort it from a terminal first`
1769
+ );
1770
+ }
1771
+ }
1772
+ __name(refuseOperationInProgress, "refuseOperationInProgress");
1773
+ async function upstreamSha(cwd, env, ref = "") {
1774
+ try {
1775
+ return (await runGit2(
1776
+ cwd,
1777
+ ["rev-parse", "--verify", "--quiet", `${ref}@{upstream}`],
1778
+ env
1779
+ )).trim();
1780
+ } catch {
1781
+ return "";
1782
+ }
1783
+ }
1784
+ __name(upstreamSha, "upstreamSha");
1785
+ function readTrimmed(file) {
1786
+ try {
1787
+ return fs3.readFileSync(file, "utf8").trim();
1788
+ } catch {
1789
+ return "";
1790
+ }
1791
+ }
1792
+ __name(readTrimmed, "readTrimmed");
1793
+ async function abortOwnPullState(cwd, pullExitCode2, env) {
1794
+ if (pullExitCode2 !== 1) return;
1795
+ try {
1796
+ const [mergeHead, rebaseMergeDir, rebaseApplyDir] = await gitPaths(
1797
+ cwd,
1798
+ ["MERGE_HEAD", "rebase-merge", "rebase-apply"],
1799
+ env
1800
+ );
1801
+ if (fs3.existsSync(mergeHead)) {
1802
+ const upstream = await upstreamSha(cwd, env);
1803
+ if (upstream && readTrimmed(mergeHead) === upstream) {
1804
+ await runGit2(cwd, ["merge", "--abort"], env);
1805
+ }
1806
+ return;
1807
+ }
1808
+ for (const dir of [rebaseMergeDir, rebaseApplyDir]) {
1809
+ if (!fs3.existsSync(dir)) continue;
1810
+ const headName = readTrimmed(path4.join(dir, "head-name")).replace(
1811
+ /^refs\/heads\//,
1812
+ ""
1813
+ );
1814
+ const upstream = headName ? await upstreamSha(cwd, env, headName) : "";
1815
+ if (upstream && readTrimmed(path4.join(dir, "onto")) === upstream) {
1816
+ await runGit2(cwd, ["rebase", "--abort"], env);
1817
+ }
1818
+ return;
1819
+ }
1820
+ } catch {
1821
+ }
1822
+ }
1823
+ __name(abortOwnPullState, "abortOwnPullState");
1824
+ async function stashEntries(cwd, env) {
1825
+ const raw = await runGit2(cwd, ["stash", "list", "--format=%H%x00%s"], env);
1826
+ return raw.split("\n").filter((line) => line.includes("\0")).map((line) => {
1827
+ const [sha, subject] = line.split("\0");
1828
+ return { sha, subject: subject ?? "" };
1829
+ });
1830
+ }
1831
+ __name(stashEntries, "stashEntries");
1832
+ function parseDroppedStashSha(output) {
1833
+ const match = /\(([0-9a-f]{40,64})\)\s*$/m.exec(output.trim());
1834
+ return match?.[1];
1835
+ }
1836
+ __name(parseDroppedStashSha, "parseDroppedStashSha");
1837
+ async function restoreStash(cwd, sha, env) {
1838
+ let output = "";
1839
+ try {
1840
+ await runGit2(cwd, ["stash", "apply", sha], env);
1841
+ } catch (err) {
1842
+ return { restored: false, output: gitDetail(err) };
1843
+ }
1844
+ let entries;
1845
+ try {
1846
+ entries = await stashEntries(cwd, env);
1847
+ } catch (err) {
1848
+ return {
1849
+ restored: true,
1850
+ output: `restored, but stash entry ${sha} was kept because the stash could not be listed:
1851
+ ${gitDetail(err)}`
1852
+ };
1853
+ }
1854
+ const index = entries.findIndex((entry) => entry.sha === sha);
1855
+ if (index === -1) return { restored: true, output };
1856
+ const slot = `stash@{${index}}`;
1857
+ let dropped;
1858
+ try {
1859
+ dropped = parseDroppedStashSha(
1860
+ await runGit2(cwd, ["stash", "drop", slot], env)
1861
+ );
1862
+ } catch (err) {
1863
+ return {
1864
+ restored: true,
1865
+ output: `restored, but stash entry ${slot} (${sha}) could not be dropped:
1866
+ ${gitDetail(err)}`
1867
+ };
1868
+ }
1869
+ if (dropped !== void 0 && dropped !== sha) {
1870
+ const subject = (await runGit2(cwd, ["log", "-1", "--format=%s", dropped], env).catch(
1871
+ () => ""
1872
+ )).trim();
1873
+ const storeArgs = ["stash", "store", "--quiet"];
1874
+ if (subject) storeArgs.push("-m", subject);
1875
+ storeArgs.push(dropped);
1876
+ const stored = await runGit2(cwd, storeArgs, env).then(() => true).catch(() => false);
1877
+ output = stored ? `restored; stash entry ${sha} was kept because the stash changed while dropping it` : `restored; stash entry ${sha} was kept because the stash changed while dropping it, and the displaced entry ${dropped} could not be stored back \u2014 recover it with: git stash store ${dropped}`;
1878
+ }
1879
+ return { restored: true, output };
1880
+ }
1881
+ __name(restoreStash, "restoreStash");
1882
+ function pullArgs(opts) {
1883
+ const args = ["pull"];
1884
+ if (opts?.rebase) args.push("--rebase");
1885
+ return args;
1886
+ }
1887
+ __name(pullArgs, "pullArgs");
1888
+ async function validatedUpstream(cwd, env) {
1889
+ const sha = await upstreamSha(cwd, env);
1890
+ if (sha) return sha;
1891
+ let branch;
1892
+ try {
1893
+ branch = (await runGit2(cwd, ["symbolic-ref", "--quiet", "--short", "HEAD"], env)).trim();
1894
+ } catch {
1895
+ throw new GitPullFailure(
1896
+ "pull_failed",
1897
+ "cannot update: HEAD is detached; check out a branch from a terminal first"
1898
+ );
1899
+ }
1900
+ const configured = (await runGit2(
1901
+ cwd,
1902
+ ["for-each-ref", "--format=%(upstream)", `refs/heads/${branch}`],
1903
+ env
1904
+ ).catch(() => "")).trim();
1905
+ if (configured) {
1906
+ throw new GitPullFailure(
1907
+ "pull_failed",
1908
+ "cannot update: the upstream branch no longer exists on the remote; nothing was changed"
1909
+ );
1910
+ }
1911
+ await runGit2(cwd, ["rev-parse", "--abbrev-ref", "@{upstream}"], env);
1912
+ throw new GitPullFailure(
1913
+ "pull_failed",
1914
+ "cannot update: the upstream branch could not be resolved; nothing was changed"
1915
+ );
1916
+ }
1917
+ __name(validatedUpstream, "validatedUpstream");
1918
+ async function pushAutoStash(cwd, env) {
1919
+ const before = new Set((await stashEntries(cwd, env)).map((e) => e.sha));
1920
+ await refuseOperationInProgress(cwd, env);
1921
+ try {
1922
+ await runGit2(
1923
+ cwd,
1924
+ ["stash", "push", "--include-untracked", "-m", AUTO_STASH_MESSAGE],
1925
+ env
1926
+ );
1927
+ } catch (err) {
1928
+ throw new GitPullFailure(
1929
+ "pull_failed",
1930
+ `cannot stash the local changes, so the update was not attempted:
1931
+ ${gitDetail(err)}`
1932
+ );
1933
+ }
1934
+ let after;
1935
+ try {
1936
+ after = await stashEntries(cwd, env);
1937
+ } catch (err) {
1938
+ throw new GitPullFailure(
1939
+ "pull_failed",
1940
+ `cannot identify the auto-stash entry, so the update was not attempted; your changes are in the entry labelled "${AUTO_STASH_MESSAGE}" in git stash list:
1941
+ ${gitDetail(err)}`
1942
+ );
1943
+ }
1944
+ const created = after.filter(
1945
+ (e) => !before.has(e.sha) && e.subject.endsWith(AUTO_STASH_MESSAGE)
1946
+ );
1947
+ return created.length > 0 ? created[created.length - 1].sha : void 0;
1948
+ }
1949
+ __name(pushAutoStash, "pushAutoStash");
1950
+ async function stashPull(cwd, opts, env) {
1951
+ await refuseOperationInProgress(cwd, env);
1952
+ await runGit2(cwd, ["fetch", "--prune"], env);
1953
+ await validatedUpstream(cwd, env);
1954
+ const stashed = await pushAutoStash(cwd, env);
1955
+ let output;
1956
+ try {
1957
+ output = (await runGit2(cwd, pullArgs(opts), env)).trim();
1958
+ } catch (err) {
1959
+ const detail = gitDetail(err);
1960
+ await abortOwnPullState(cwd, pullExitCode(err), env);
1961
+ if (stashed === void 0) {
1962
+ throw new GitPullFailure("pull_failed", `update failed:
1963
+ ${detail}`);
1964
+ }
1965
+ const restore2 = await restoreStash(cwd, stashed, env);
1966
+ throw new GitPullFailure(
1967
+ "pull_failed",
1968
+ restore2.restored ? `update failed; your local changes were restored${restore2.output ? ` (${restore2.output})` : ""}:
1969
+ ${detail}` : `update failed and your local changes could not be restored automatically; they are kept in stash entry ${stashed}:
1970
+ ${restore2.output}
1971
+ ${detail}`
1972
+ );
1973
+ }
1974
+ if (stashed === void 0) return { success: true, output };
1975
+ const restore = await restoreStash(cwd, stashed, env);
1976
+ if (restore.restored) {
1977
+ if (restore.output === "") return { success: true, output };
1978
+ return {
1979
+ success: true,
1980
+ stashKept: true,
1981
+ stashSha: stashed,
1982
+ output: `${output}
1983
+ ${restore.output}`.trim()
1984
+ };
1985
+ }
1986
+ return {
1987
+ success: true,
1988
+ stashRestoreConflict: true,
1989
+ stashSha: stashed,
1990
+ output: `${output}
1991
+ restoring your local changes failed; they are kept in stash entry ${stashed}:
1992
+ ${restore.output}`.trim()
1993
+ };
1994
+ }
1995
+ __name(stashPull, "stashPull");
1996
+ async function forcePull(cwd, env) {
1997
+ await refuseOperationInProgress(cwd, env);
1998
+ const toplevel = (await runGit2(cwd, ["rev-parse", "--show-toplevel"], env)).trim();
1999
+ if (await fs3.promises.realpath(cwd) !== await fs3.promises.realpath(toplevel)) {
2000
+ throw new GitPullFailure(
2001
+ "force_unsupported",
2002
+ "cannot discard changes: the workspace is a subdirectory of its repository, so discarding would also reset changes outside the workspace; resolve them from a terminal"
2003
+ );
2004
+ }
2005
+ await runGit2(cwd, ["fetch", "--prune"], env);
2006
+ const validated = await validatedUpstream(cwd, env);
2007
+ try {
2008
+ await runGit2(cwd, ["merge-base", "--is-ancestor", "HEAD", validated], env);
2009
+ } catch (err) {
2010
+ if (exitCode(err) === 1) {
2011
+ throw new GitPullFailure(
2012
+ "diverged",
2013
+ "cannot discard and update: the branch has diverged from its upstream; merge or rebase the local commits from a terminal first"
2014
+ );
2015
+ }
2016
+ throw err;
2017
+ }
2018
+ await refuseOperationInProgress(cwd, env);
2019
+ await runGit2(cwd, ["reset", "--hard"], env);
2020
+ await runGit2(cwd, ["clean", "-fd"], env);
2021
+ let output;
2022
+ try {
2023
+ output = await runGit2(cwd, ["merge", "--ff-only", validated], env);
2024
+ } catch (err) {
2025
+ throw new GitPullFailure(
2026
+ "pull_failed",
2027
+ `discard applied, but the update failed:
2028
+ ${gitDetail(err)}`
2029
+ );
2030
+ }
2031
+ return { success: true, output: output.trim() };
2032
+ }
2033
+ __name(forcePull, "forcePull");
2034
+ async function gitPull(cwd, opts, env) {
2035
+ if (opts?.stash && opts?.force) {
2036
+ throw new Error("stash and force are mutually exclusive");
2037
+ }
2038
+ if (opts?.fetchOnly && (opts?.stash || opts?.force)) {
2039
+ throw new Error("fetchOnly cannot be combined with stash or force");
2040
+ }
2041
+ if (opts?.fetchOnly) {
2042
+ const output2 = await runGit2(cwd, ["fetch", "--all", "--prune"], env);
2043
+ return { success: true, output: output2.trim() };
2044
+ }
2045
+ if (opts?.force) return forcePull(cwd, env);
2046
+ if (opts?.stash) return stashPull(cwd, opts, env);
2047
+ const output = await runGit2(cwd, pullArgs(opts), env);
2048
+ return { success: true, output: output.trim() };
2049
+ }
2050
+ __name(gitPull, "gitPull");
2051
+ async function gitCommit(cwd, message, opts, env) {
2052
+ let savedIndex = null;
2053
+ if (opts?.all) {
2054
+ const tree = (await runGit2(cwd, ["write-tree"], env).catch(() => "")).trim();
2055
+ if (tree) {
2056
+ savedIndex = tree;
2057
+ } else {
2058
+ const unmerged = (await runGit2(cwd, ["ls-files", "--unmerged"], env)).trim();
2059
+ if (unmerged) {
2060
+ throw new Error(
2061
+ "cannot stage all changes: unresolved merge conflicts in the index"
2062
+ );
2063
+ }
2064
+ throw new Error(
2065
+ "cannot stage all changes: failed to snapshot index (write-tree failed)"
2066
+ );
2067
+ }
2068
+ }
2069
+ try {
2070
+ if (opts?.all) {
2071
+ await runGit2(cwd, ["add", "-A"], env);
2072
+ }
2073
+ await runGit2(cwd, ["commit", "-m", message], env);
2074
+ } catch (err) {
2075
+ if (savedIndex) {
2076
+ await runGit2(cwd, ["read-tree", savedIndex], env).catch((rollbackErr) => {
2077
+ console.error("git index rollback failed:", rollbackErr);
2078
+ });
2079
+ }
2080
+ throw err;
2081
+ }
2082
+ const sha = (await runGit2(cwd, ["rev-parse", "--short", "HEAD"], env)).trim();
2083
+ const subject = (await runGit2(cwd, ["log", "-1", "--format=%s"], env)).trim();
2084
+ return { sha, subject };
2085
+ }
2086
+ __name(gitCommit, "gitCommit");
129
2087
 
130
2088
  // packages/core/src/utils/load-simple-git.ts
131
2089
  init_esbuild_shims();
@@ -173,8 +2131,8 @@ async function initRepositoryWithMainBranch(git) {
173
2131
  __name(initRepositoryWithMainBranch, "initRepositoryWithMainBranch");
174
2132
 
175
2133
  // packages/core/src/services/gitWorktreeService.ts
176
- var execFileAsync = promisify(execFile);
177
- var debugLogger = createDebugLogger("GIT_WORKTREE_SERVICE");
2134
+ var execFileAsync3 = promisify3(execFile3);
2135
+ var debugLogger2 = createDebugLogger("GIT_WORKTREE_SERVICE");
178
2136
  var WORKTREE_BRANCH_PREFIX = "worktree-";
179
2137
  function worktreeBranchForSlug(slug) {
180
2138
  return `${WORKTREE_BRANCH_PREFIX}${slug}`;
@@ -182,38 +2140,85 @@ function worktreeBranchForSlug(slug) {
182
2140
  __name(worktreeBranchForSlug, "worktreeBranchForSlug");
183
2141
  var WORKTREE_SESSION_FILE = ".o1-code-session";
184
2142
  var WORKTREE_SESSION_MARKER_MAX_BYTES = 512;
2143
+ var DISPOSABLE_IGNORED_DIRS = /* @__PURE__ */ new Set(["node_modules", "dist", "coverage"]);
2144
+ async function worktreeHasWork(worktreePath) {
2145
+ try {
2146
+ await fs4.access(path5.join(worktreePath, ".git"));
2147
+ const { stdout } = await execFileAsync3(
2148
+ "git",
2149
+ [
2150
+ ...NO_EXEC_CONFIG,
2151
+ "--no-optional-locks",
2152
+ "status",
2153
+ "--porcelain",
2154
+ "-z",
2155
+ "--untracked-files=normal",
2156
+ "--ignored=matching"
2157
+ ],
2158
+ {
2159
+ cwd: worktreePath,
2160
+ env: gitEnv(),
2161
+ encoding: "utf8",
2162
+ maxBuffer: 10 * 1024 * 1024,
2163
+ timeout: 3e4
2164
+ }
2165
+ );
2166
+ for (const record of stdout.split("\0")) {
2167
+ if (record.length === 0) continue;
2168
+ const status = record.slice(0, 2);
2169
+ const entry = record.slice(3);
2170
+ if (status !== "??" && status !== "!!") return true;
2171
+ if (entry === WORKTREE_SESSION_FILE) continue;
2172
+ if (status === "!!" && entry.split("/").some((segment) => DISPOSABLE_IGNORED_DIRS.has(segment))) {
2173
+ continue;
2174
+ }
2175
+ const stats = await fs4.lstat(
2176
+ path5.join(worktreePath, entry.replace(/\/$/, ""))
2177
+ );
2178
+ if (stats.isSymbolicLink()) continue;
2179
+ return true;
2180
+ }
2181
+ return false;
2182
+ } catch (error) {
2183
+ debugLogger2.warn(
2184
+ `worktreeHasWork: cannot inspect ${worktreePath}, keeping it: ${error}`
2185
+ );
2186
+ return true;
2187
+ }
2188
+ }
2189
+ __name(worktreeHasWork, "worktreeHasWork");
185
2190
  var NO_EXEC_DIFF_FLAGS = ["--no-ext-diff", "--no-textconv"];
186
2191
  async function addWorktreeSessionMarkerExclude(worktreePath) {
187
2192
  try {
188
2193
  const { simpleGit } = await loadSimpleGit();
189
2194
  const wtGit = simpleGit(worktreePath);
190
2195
  const commonDir = (await wtGit.revparse(["--git-common-dir"])).trim();
191
- const excludePath = path2.isAbsolute(commonDir) ? path2.join(commonDir, "info", "exclude") : path2.join(worktreePath, commonDir, "info", "exclude");
192
- await fs2.mkdir(path2.dirname(excludePath), { recursive: true });
2196
+ const excludePath = path5.isAbsolute(commonDir) ? path5.join(commonDir, "info", "exclude") : path5.join(worktreePath, commonDir, "info", "exclude");
2197
+ await fs4.mkdir(path5.dirname(excludePath), { recursive: true });
193
2198
  let existing = "";
194
2199
  try {
195
- existing = await fs2.readFile(excludePath, "utf8");
2200
+ existing = await fs4.readFile(excludePath, "utf8");
196
2201
  } catch {
197
2202
  }
198
2203
  const rules = [WORKTREE_SESSION_FILE, `${WORKTREE_SESSION_FILE}.*.tmp`];
199
2204
  let next = existing;
200
2205
  for (const rule of rules) {
201
2206
  if (!next.split(/\r?\n/).includes(rule)) {
202
- const sep = next.length === 0 || next.endsWith("\n") ? "" : "\n";
203
- next = `${next}${sep}${rule}
2207
+ const sep2 = next.length === 0 || next.endsWith("\n") ? "" : "\n";
2208
+ next = `${next}${sep2}${rule}
204
2209
  `;
205
2210
  }
206
2211
  }
207
2212
  if (next !== existing) {
208
- await fs2.writeFile(excludePath, next, "utf8");
2213
+ await fs4.writeFile(excludePath, next, "utf8");
209
2214
  }
210
2215
  } catch {
211
2216
  }
212
2217
  }
213
2218
  __name(addWorktreeSessionMarkerExclude, "addWorktreeSessionMarkerExclude");
214
2219
  async function writeWorktreeSessionMarker(worktreePath, sessionId) {
215
- await fs2.writeFile(
216
- path2.join(worktreePath, WORKTREE_SESSION_FILE),
2220
+ await fs4.writeFile(
2221
+ path5.join(worktreePath, WORKTREE_SESSION_FILE),
217
2222
  sessionId,
218
2223
  "utf8"
219
2224
  );
@@ -236,10 +2241,10 @@ var WorktreeMarkerCommittedError = class extends Error {
236
2241
  };
237
2242
  async function createWorktreeSessionMarkerExclusive(worktreePath, sessionId) {
238
2243
  assertValidWorktreeSessionMarkerOwner(sessionId);
239
- const markerPath = path2.join(worktreePath, WORKTREE_SESSION_FILE);
2244
+ const markerPath = path5.join(worktreePath, WORKTREE_SESSION_FILE);
240
2245
  const stagedPath = `${markerPath}.${randomBytes(6).toString("hex")}.tmp`;
241
2246
  const flags = nodeFs.constants.O_WRONLY | nodeFs.constants.O_CREAT | nodeFs.constants.O_EXCL | (nodeFs.constants.O_NOFOLLOW ?? 0);
242
- const handle = await fs2.open(stagedPath, flags, 384);
2247
+ const handle = await fs4.open(stagedPath, flags, 384);
243
2248
  let stagedDev = 0;
244
2249
  let stagedIno = 0;
245
2250
  try {
@@ -253,20 +2258,20 @@ async function createWorktreeSessionMarkerExclusive(worktreePath, sessionId) {
253
2258
  await handle.sync();
254
2259
  const [after, pathStats] = await Promise.all([
255
2260
  handle.stat(),
256
- fs2.lstat(stagedPath)
2261
+ fs4.lstat(stagedPath)
257
2262
  ]);
258
2263
  if (!after.isFile() || after.nlink !== 1 || after.size > WORKTREE_SESSION_MARKER_MAX_BYTES || after.dev !== before.dev || after.ino !== before.ino || pathStats.dev !== after.dev || pathStats.ino !== after.ino) {
259
2264
  throw new Error("Worktree session marker identity changed");
260
2265
  }
261
- await fs2.link(stagedPath, markerPath);
2266
+ await fs4.link(stagedPath, markerPath);
262
2267
  } catch (error) {
263
2268
  await handle.close().catch(() => {
264
2269
  });
265
2270
  if (stagedIno !== 0) {
266
2271
  try {
267
- const current = await fs2.lstat(stagedPath);
2272
+ const current = await fs4.lstat(stagedPath);
268
2273
  if (current.dev === stagedDev && current.ino === stagedIno) {
269
- await fs2.unlink(stagedPath);
2274
+ await fs4.unlink(stagedPath);
270
2275
  }
271
2276
  } catch {
272
2277
  }
@@ -274,7 +2279,7 @@ async function createWorktreeSessionMarkerExclusive(worktreePath, sessionId) {
274
2279
  throw error;
275
2280
  }
276
2281
  try {
277
- await fs2.unlink(stagedPath);
2282
+ await fs4.unlink(stagedPath);
278
2283
  await handle.close();
279
2284
  } catch (error) {
280
2285
  await handle.close().catch(() => {
@@ -291,12 +2296,12 @@ function assertValidWorktreeSessionMarkerOwner(sessionId) {
291
2296
  }
292
2297
  __name(assertValidWorktreeSessionMarkerOwner, "assertValidWorktreeSessionMarkerOwner");
293
2298
  async function readWorktreeSessionMarkerStrict(worktreePath) {
294
- const markerPath = path2.join(worktreePath, WORKTREE_SESSION_FILE);
2299
+ const markerPath = path5.join(worktreePath, WORKTREE_SESSION_FILE);
295
2300
  let handle;
296
2301
  let observedMarker = false;
297
2302
  try {
298
2303
  const flags = nodeFs.constants.O_RDONLY | (nodeFs.constants.O_NOFOLLOW ?? 0) | (nodeFs.constants.O_NONBLOCK ?? 0);
299
- const before = await fs2.lstat(markerPath);
2304
+ const before = await fs4.lstat(markerPath);
300
2305
  observedMarker = true;
301
2306
  if (before.isSymbolicLink() || !before.isFile() || before.nlink !== 1) {
302
2307
  return { state: "invalid", reason: "unsafe marker file type" };
@@ -304,7 +2309,7 @@ async function readWorktreeSessionMarkerStrict(worktreePath) {
304
2309
  if (before.ino === 0 || before.size > WORKTREE_SESSION_MARKER_MAX_BYTES) {
305
2310
  return { state: "invalid", reason: "unsafe marker size or identity" };
306
2311
  }
307
- handle = await fs2.open(markerPath, flags);
2312
+ handle = await fs4.open(markerPath, flags);
308
2313
  const opened = await handle.stat();
309
2314
  if (!opened.isFile() || opened.nlink !== 1 || opened.dev !== before.dev || opened.ino !== before.ino) {
310
2315
  return {
@@ -329,7 +2334,7 @@ async function readWorktreeSessionMarkerStrict(worktreePath) {
329
2334
  }
330
2335
  const raw = markerBuffer.subarray(0, bytesRead).toString("utf8");
331
2336
  const after = await handle.stat();
332
- const pathStats = await fs2.lstat(markerPath);
2337
+ const pathStats = await fs4.lstat(markerPath);
333
2338
  if (!after.isFile() || after.nlink !== 1 || after.size !== bytesRead || after.size > WORKTREE_SESSION_MARKER_MAX_BYTES || after.dev !== opened.dev || after.ino !== opened.ino || !pathStats.isFile() || pathStats.nlink !== 1 || pathStats.dev !== after.dev || pathStats.ino !== after.ino) {
334
2339
  return {
335
2340
  state: "invalid",
@@ -362,7 +2367,7 @@ async function readWorktreeSessionMarkerStrict(worktreePath) {
362
2367
  }
363
2368
  __name(readWorktreeSessionMarkerStrict, "readWorktreeSessionMarkerStrict");
364
2369
  function readWorktreeSessionMarkerStrictSync(worktreePath) {
365
- const markerPath = path2.join(worktreePath, WORKTREE_SESSION_FILE);
2370
+ const markerPath = path5.join(worktreePath, WORKTREE_SESSION_FILE);
366
2371
  let fd;
367
2372
  let observedMarker = false;
368
2373
  try {
@@ -463,7 +2468,7 @@ async function transferWorktreeSessionMarkerOwner(worktreePath, expectedOwner, n
463
2468
  if (euid !== void 0 && opening.uid !== null && opening.uid !== euid) {
464
2469
  throw new Error("Worktree marker is owned by a different uid");
465
2470
  }
466
- const markerPath = path2.join(worktreePath, WORKTREE_SESSION_FILE);
2471
+ const markerPath = path5.join(worktreePath, WORKTREE_SESSION_FILE);
467
2472
  await atomicWriteFile(markerPath, newOwner, {
468
2473
  mode: 384,
469
2474
  noFollow: true,
@@ -478,14 +2483,14 @@ async function transferWorktreeSessionMarkerOwner(worktreePath, expectedOwner, n
478
2483
  }
479
2484
  __name(transferWorktreeSessionMarkerOwner, "transferWorktreeSessionMarkerOwner");
480
2485
  async function readWorktreeSessionMarker(worktreePath) {
481
- const markerPath = path2.join(worktreePath, WORKTREE_SESSION_FILE);
2486
+ const markerPath = path5.join(worktreePath, WORKTREE_SESSION_FILE);
482
2487
  try {
483
- const raw = await fs2.readFile(markerPath, "utf8");
2488
+ const raw = await fs4.readFile(markerPath, "utf8");
484
2489
  const trimmed = raw.trim();
485
2490
  return trimmed.length > 0 ? trimmed : null;
486
2491
  } catch (error) {
487
2492
  if (error.code !== "ENOENT") {
488
- debugLogger.warn(
2493
+ debugLogger2.warn(
489
2494
  `readWorktreeSessionMarker: cannot read ${markerPath}: ${error}`
490
2495
  );
491
2496
  }
@@ -517,7 +2522,7 @@ var GitWorktreeService = class _GitWorktreeService {
517
2522
  gitPromise;
518
2523
  customBaseDir;
519
2524
  constructor(sourceRepoPath, customBaseDir) {
520
- this.sourceRepoPath = path2.resolve(sourceRepoPath);
2525
+ this.sourceRepoPath = path5.resolve(sourceRepoPath);
521
2526
  this.customBaseDir = customBaseDir;
522
2527
  }
523
2528
  getGit() {
@@ -532,23 +2537,23 @@ var GitWorktreeService = class _GitWorktreeService {
532
2537
  */
533
2538
  static getBaseDir(customDir) {
534
2539
  if (customDir) {
535
- return path2.resolve(customDir);
2540
+ return path5.resolve(customDir);
536
2541
  }
537
- return path2.join(Storage.getGlobalO1CodeDir(), WORKTREES_DIR);
2542
+ return path5.join(Storage.getGlobalO1CodeDir(), WORKTREES_DIR);
538
2543
  }
539
2544
  /**
540
2545
  * Gets the directory for a specific session.
541
2546
  * @param customBaseDir - Optional custom base directory override
542
2547
  */
543
2548
  static getSessionDir(sessionId, customBaseDir) {
544
- return path2.join(_GitWorktreeService.getBaseDir(customBaseDir), sessionId);
2549
+ return path5.join(_GitWorktreeService.getBaseDir(customBaseDir), sessionId);
545
2550
  }
546
2551
  /**
547
2552
  * Gets the worktrees directory for a specific session.
548
2553
  * @param customBaseDir - Optional custom base directory override
549
2554
  */
550
2555
  static getWorktreesDir(sessionId, customBaseDir) {
551
- return path2.join(
2556
+ return path5.join(
552
2557
  _GitWorktreeService.getSessionDir(sessionId, customBaseDir),
553
2558
  WORKTREES_DIR
554
2559
  );
@@ -589,7 +2594,7 @@ var GitWorktreeService = class _GitWorktreeService {
589
2594
  const top = out.replace(/\n$/, "");
590
2595
  return top.length > 0 ? top : null;
591
2596
  } catch (error) {
592
- debugLogger.warn(
2597
+ debugLogger2.warn(
593
2598
  `getRepoTopLevel failed at ${this.sourceRepoPath}: ${error}`
594
2599
  );
595
2600
  return null;
@@ -634,7 +2639,7 @@ var GitWorktreeService = class _GitWorktreeService {
634
2639
  if (mainPath.length === 0) return null;
635
2640
  const realpathOr = /* @__PURE__ */ __name(async (p) => {
636
2641
  try {
637
- return await fs2.realpath(p);
2642
+ return await fs4.realpath(p);
638
2643
  } catch {
639
2644
  return p;
640
2645
  }
@@ -645,14 +2650,14 @@ var GitWorktreeService = class _GitWorktreeService {
645
2650
  simpleGit(mainPath).raw(["rev-parse", "--git-common-dir"])
646
2651
  ]);
647
2652
  const ourCommonDir = await realpathOr(
648
- path2.resolve(this.sourceRepoPath, ourRaw.trim())
2653
+ path5.resolve(this.sourceRepoPath, ourRaw.trim())
649
2654
  );
650
2655
  const anchorCommonDir = await realpathOr(
651
- path2.resolve(mainPath, anchorRaw.trim())
2656
+ path5.resolve(mainPath, anchorRaw.trim())
652
2657
  );
653
2658
  return ourCommonDir === anchorCommonDir ? mainPath : null;
654
2659
  } catch (error) {
655
- debugLogger.warn(
2660
+ debugLogger2.warn(
656
2661
  `getMainWorktreePath failed at ${this.sourceRepoPath}: ${error}`
657
2662
  );
658
2663
  return null;
@@ -749,9 +2754,9 @@ var GitWorktreeService = class _GitWorktreeService {
749
2754
  sessionId,
750
2755
  this.customBaseDir
751
2756
  );
752
- await fs2.mkdir(worktreesDir, { recursive: true });
2757
+ await fs4.mkdir(worktreesDir, { recursive: true });
753
2758
  const sanitizedName = this.sanitizeName(name);
754
- const worktreePath = path2.join(worktreesDir, sanitizedName);
2759
+ const worktreePath = path5.join(worktreesDir, sanitizedName);
755
2760
  const exists = await this.pathExists(worktreePath);
756
2761
  if (exists) {
757
2762
  return {
@@ -831,8 +2836,8 @@ var GitWorktreeService = class _GitWorktreeService {
831
2836
  config.sessionId,
832
2837
  this.customBaseDir
833
2838
  );
834
- await fs2.mkdir(sessionDir, { recursive: true });
835
- const configPath = path2.join(sessionDir, "config.json");
2839
+ await fs4.mkdir(sessionDir, { recursive: true });
2840
+ const configPath = path5.join(sessionDir, "config.json");
836
2841
  const configFile = {
837
2842
  sessionId: config.sessionId,
838
2843
  sourceRepoPath: config.sourceRepoPath,
@@ -841,7 +2846,7 @@ var GitWorktreeService = class _GitWorktreeService {
841
2846
  createdAt: Date.now(),
842
2847
  ...config.metadata
843
2848
  };
844
- await fs2.writeFile(configPath, JSON.stringify(configFile, null, 2));
2849
+ await fs4.writeFile(configPath, JSON.stringify(configFile, null, 2));
845
2850
  let dirtyStateSnapshot = "";
846
2851
  try {
847
2852
  dirtyStateSnapshot = (await (await this.getGit()).stash(["create"])).trim();
@@ -894,10 +2899,10 @@ var GitWorktreeService = class _GitWorktreeService {
894
2899
  }
895
2900
  for (const relPath of untrackedFiles) {
896
2901
  try {
897
- const src = path2.join(this.sourceRepoPath, relPath);
898
- const dst = path2.join(worktree.path, relPath);
899
- await fs2.mkdir(path2.dirname(dst), { recursive: true });
900
- await fs2.copyFile(src, dst);
2902
+ const src = path5.join(this.sourceRepoPath, relPath);
2903
+ const dst = path5.join(worktree.path, relPath);
2904
+ await fs4.mkdir(path5.dirname(dst), { recursive: true });
2905
+ await fs4.copyFile(src, dst);
901
2906
  } catch {
902
2907
  }
903
2908
  }
@@ -922,11 +2927,11 @@ var GitWorktreeService = class _GitWorktreeService {
922
2927
  this.customBaseDir
923
2928
  );
924
2929
  try {
925
- const entries = await fs2.readdir(worktreesDir, { withFileTypes: true });
2930
+ const entries = await fs4.readdir(worktreesDir, { withFileTypes: true });
926
2931
  const worktrees = [];
927
2932
  for (const entry of entries) {
928
2933
  if (entry.isDirectory()) {
929
- const worktreePath = path2.join(worktreesDir, entry.name);
2934
+ const worktreePath = path5.join(worktreesDir, entry.name);
930
2935
  let branchName = "";
931
2936
  try {
932
2937
  branchName = execSync("git rev-parse --abbrev-ref HEAD", {
@@ -938,7 +2943,7 @@ var GitWorktreeService = class _GitWorktreeService {
938
2943
  }
939
2944
  let createdAt = Date.now();
940
2945
  try {
941
- const stats = await fs2.stat(worktreePath);
2946
+ const stats = await fs4.stat(worktreePath);
942
2947
  createdAt = stats.birthtimeMs;
943
2948
  } catch {
944
2949
  }
@@ -978,7 +2983,7 @@ var GitWorktreeService = class _GitWorktreeService {
978
2983
  return { success: true };
979
2984
  } catch (error) {
980
2985
  try {
981
- await fs2.rm(worktreePath, { recursive: true, force: true });
2986
+ await fs4.rm(worktreePath, { recursive: true, force: true });
982
2987
  await git.raw(["worktree", "prune"]);
983
2988
  return { success: true };
984
2989
  } catch (_rmError) {
@@ -1019,7 +3024,7 @@ var GitWorktreeService = class _GitWorktreeService {
1019
3024
  this.customBaseDir
1020
3025
  );
1021
3026
  try {
1022
- await fs2.rm(sessionDir, { recursive: true, force: true });
3027
+ await fs4.rm(sessionDir, { recursive: true, force: true });
1023
3028
  } catch (error) {
1024
3029
  result.errors.push(
1025
3030
  `Failed to remove session directory: ${error instanceof Error ? error.message : "Unknown error"}`
@@ -1084,17 +3089,17 @@ var GitWorktreeService = class _GitWorktreeService {
1084
3089
  if (!patch.trim()) {
1085
3090
  return { success: true };
1086
3091
  }
1087
- const patchFile = path2.join(
3092
+ const patchFile = path5.join(
1088
3093
  this.getBaseDirForInstance(),
1089
3094
  `.worktree-apply-${Date.now()}-${Math.random().toString(16).slice(2)}.patch`
1090
3095
  );
1091
- await fs2.mkdir(path2.dirname(patchFile), { recursive: true });
1092
- await fs2.writeFile(patchFile, patch, "utf-8");
3096
+ await fs4.mkdir(path5.dirname(patchFile), { recursive: true });
3097
+ await fs4.writeFile(patchFile, patch, "utf-8");
1093
3098
  try {
1094
3099
  const applyArgs = hasBaseline ? ["apply", "--whitespace=nowarn", patchFile] : ["apply", "--3way", "--whitespace=nowarn", patchFile];
1095
3100
  await targetGit.raw(applyArgs);
1096
3101
  } finally {
1097
- await fs2.rm(patchFile, { force: true });
3102
+ await fs4.rm(patchFile, { force: true });
1098
3103
  }
1099
3104
  return { success: true };
1100
3105
  } catch (error) {
@@ -1111,17 +3116,17 @@ var GitWorktreeService = class _GitWorktreeService {
1111
3116
  const baseDir = _GitWorktreeService.getBaseDir(customBaseDir);
1112
3117
  const sessions = [];
1113
3118
  try {
1114
- const entries = await fs2.readdir(baseDir, { withFileTypes: true });
3119
+ const entries = await fs4.readdir(baseDir, { withFileTypes: true });
1115
3120
  for (const entry of entries) {
1116
3121
  if (entry.isDirectory()) {
1117
- const configPath = path2.join(baseDir, entry.name, "config.json");
3122
+ const configPath = path5.join(baseDir, entry.name, "config.json");
1118
3123
  try {
1119
- const configContent = await fs2.readFile(configPath, "utf-8");
3124
+ const configContent = await fs4.readFile(configPath, "utf-8");
1120
3125
  const config = JSON.parse(configContent);
1121
- const worktreesDir = path2.join(baseDir, entry.name, WORKTREES_DIR);
3126
+ const worktreesDir = path5.join(baseDir, entry.name, WORKTREES_DIR);
1122
3127
  let worktreeCount = 0;
1123
3128
  try {
1124
- const worktreeEntries = await fs2.readdir(worktreesDir);
3129
+ const worktreeEntries = await fs4.readdir(worktreesDir);
1125
3130
  worktreeCount = worktreeEntries.length;
1126
3131
  } catch {
1127
3132
  }
@@ -1175,7 +3180,7 @@ var GitWorktreeService = class _GitWorktreeService {
1175
3180
  }
1176
3181
  async pathExists(p) {
1177
3182
  try {
1178
- await fs2.access(p);
3183
+ await fs4.access(p);
1179
3184
  return true;
1180
3185
  } catch {
1181
3186
  return false;
@@ -1192,13 +3197,13 @@ var GitWorktreeService = class _GitWorktreeService {
1192
3197
  * repo: `<projectRoot>/.o1-code/worktrees`.
1193
3198
  */
1194
3199
  getUserWorktreesDir() {
1195
- return path2.join(this.sourceRepoPath, ".o1-code", WORKTREES_DIR);
3200
+ return path5.join(this.sourceRepoPath, ".o1-code", WORKTREES_DIR);
1196
3201
  }
1197
3202
  /**
1198
3203
  * Returns the absolute worktree path for a given slug.
1199
3204
  */
1200
3205
  getUserWorktreePath(slug) {
1201
- return path2.join(this.getUserWorktreesDir(), slug);
3206
+ return path5.join(this.getUserWorktreesDir(), slug);
1202
3207
  }
1203
3208
  /**
1204
3209
  * Generates an auto-slug `{adj}-{noun}-{6hex}` for an unnamed worktree.
@@ -1295,9 +3300,9 @@ var GitWorktreeService = class _GitWorktreeService {
1295
3300
  async getRegisteredWorktreeBranch(worktreePath) {
1296
3301
  let resolvedWorktreePath;
1297
3302
  try {
1298
- const stat2 = await fs2.stat(worktreePath);
1299
- if (!stat2.isDirectory()) return null;
1300
- resolvedWorktreePath = await fs2.realpath(worktreePath);
3303
+ const stat4 = await fs4.stat(worktreePath);
3304
+ if (!stat4.isDirectory()) return null;
3305
+ resolvedWorktreePath = await fs4.realpath(worktreePath);
1301
3306
  } catch {
1302
3307
  return null;
1303
3308
  }
@@ -1320,27 +3325,27 @@ var GitWorktreeService = class _GitWorktreeService {
1320
3325
  "--show-toplevel"
1321
3326
  ])
1322
3327
  ]);
1323
- ourCommonDir = path2.resolve(this.sourceRepoPath, ourRaw.trim());
3328
+ ourCommonDir = path5.resolve(this.sourceRepoPath, ourRaw.trim());
1324
3329
  const lines = probeRaw.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
1325
3330
  if (lines.length < 4) return null;
1326
3331
  headCommit = lines[0];
1327
3332
  branch = lines[1];
1328
- probeCommonDir = path2.resolve(worktreePath, lines[2]);
1329
- probeToplevel = path2.resolve(lines[3]);
3333
+ probeCommonDir = path5.resolve(worktreePath, lines[2]);
3334
+ probeToplevel = path5.resolve(lines[3]);
1330
3335
  } catch (error) {
1331
- debugLogger.debug(
3336
+ debugLogger2.debug(
1332
3337
  `getRegisteredWorktreeBranch: probe at ${worktreePath} failed: ${error}`
1333
3338
  );
1334
3339
  return null;
1335
3340
  }
1336
3341
  if (probeCommonDir !== ourCommonDir) {
1337
- debugLogger.debug(
3342
+ debugLogger2.debug(
1338
3343
  `getRegisteredWorktreeBranch: ${worktreePath} belongs to a different repo (common-dir=${probeCommonDir}, expected ${ourCommonDir})`
1339
3344
  );
1340
3345
  return null;
1341
3346
  }
1342
3347
  if (probeToplevel !== resolvedWorktreePath) {
1343
- debugLogger.debug(
3348
+ debugLogger2.debug(
1344
3349
  `getRegisteredWorktreeBranch: ${worktreePath} is not a registered worktree (toplevel=${probeToplevel}, expected ${resolvedWorktreePath})`
1345
3350
  );
1346
3351
  return null;
@@ -1385,34 +3390,34 @@ var GitWorktreeService = class _GitWorktreeService {
1385
3390
  async isRegisteredLinkedWorktree(worktreePath) {
1386
3391
  const realpathOr = /* @__PURE__ */ __name(async (p) => {
1387
3392
  try {
1388
- return await fs2.realpath(p);
3393
+ return await fs4.realpath(p);
1389
3394
  } catch {
1390
- return path2.resolve(p);
3395
+ return path5.resolve(p);
1391
3396
  }
1392
3397
  }, "realpathOr");
1393
3398
  try {
1394
- const target = await fs2.realpath(worktreePath);
1395
- const ourCommonDir = path2.resolve(
3399
+ const target = await fs4.realpath(worktreePath);
3400
+ const ourCommonDir = path5.resolve(
1396
3401
  this.sourceRepoPath,
1397
3402
  (await (await this.getGit()).raw(["rev-parse", "--git-common-dir"])).trim()
1398
3403
  );
1399
- const worktreesDir = path2.join(ourCommonDir, "worktrees");
3404
+ const worktreesDir = path5.join(ourCommonDir, "worktrees");
1400
3405
  let entryNames;
1401
3406
  try {
1402
- entryNames = await fs2.readdir(worktreesDir);
3407
+ entryNames = await fs4.readdir(worktreesDir);
1403
3408
  } catch {
1404
3409
  return false;
1405
3410
  }
1406
3411
  let entryGitDir = null;
1407
3412
  for (const name of entryNames) {
1408
- const entry = path2.join(worktreesDir, name);
3413
+ const entry = path5.join(worktreesDir, name);
1409
3414
  let pointer;
1410
3415
  try {
1411
- pointer = (await fs2.readFile(path2.join(entry, "gitdir"), "utf8")).trim();
3416
+ pointer = (await fs4.readFile(path5.join(entry, "gitdir"), "utf8")).trim();
1412
3417
  } catch {
1413
3418
  continue;
1414
3419
  }
1415
- if (await realpathOr(path2.dirname(pointer)) === target) {
3420
+ if (await realpathOr(path5.dirname(pointer)) === target) {
1416
3421
  entryGitDir = entry;
1417
3422
  break;
1418
3423
  }
@@ -1420,10 +3425,10 @@ var GitWorktreeService = class _GitWorktreeService {
1420
3425
  if (!entryGitDir) return false;
1421
3426
  const { simpleGit } = await loadSimpleGit();
1422
3427
  const rawGitDir = (await simpleGit(target).raw(["rev-parse", "--git-dir"])).trim();
1423
- const probeGitDir = await realpathOr(path2.resolve(target, rawGitDir));
3428
+ const probeGitDir = await realpathOr(path5.resolve(target, rawGitDir));
1424
3429
  return probeGitDir === await realpathOr(entryGitDir);
1425
3430
  } catch (error) {
1426
- debugLogger.debug(
3431
+ debugLogger2.debug(
1427
3432
  `isRegisteredLinkedWorktree: probe at ${worktreePath} failed: ${error}`
1428
3433
  );
1429
3434
  return false;
@@ -1468,7 +3473,7 @@ var GitWorktreeService = class _GitWorktreeService {
1468
3473
  }
1469
3474
  const refspec = `pull/${prNumberStr}/head`;
1470
3475
  try {
1471
- await execFileAsync(
3476
+ await execFileAsync3(
1472
3477
  "git",
1473
3478
  ["fetch", "--end-of-options", "origin", refspec],
1474
3479
  {
@@ -1502,7 +3507,7 @@ var GitWorktreeService = class _GitWorktreeService {
1502
3507
  }
1503
3508
  const firstLine = stderr.split("\n").find((l) => l.trim().length > 0);
1504
3509
  const detail = firstLine ? ` (${firstLine.trim()})` : "";
1505
- debugLogger.warn(
3510
+ debugLogger2.warn(
1506
3511
  `fetchPullRequestRef: git fetch pull/${prNumber}/head failed: ${error}`
1507
3512
  );
1508
3513
  return {
@@ -1565,18 +3570,18 @@ var GitWorktreeService = class _GitWorktreeService {
1565
3570
  options?.prBacked === true ? { allowPrBackedShape: true } : void 0
1566
3571
  );
1567
3572
  if (validationError) {
1568
- debugLogger.warn(
3573
+ debugLogger2.warn(
1569
3574
  `createUserWorktree: invalid slug ${slug}: ${validationError}`
1570
3575
  );
1571
3576
  return { success: false, error: validationError };
1572
3577
  }
1573
3578
  try {
1574
3579
  const worktreesDir = this.getUserWorktreesDir();
1575
- await fs2.mkdir(worktreesDir, { recursive: true });
1576
- const worktreePath = path2.join(worktreesDir, slug);
3580
+ await fs4.mkdir(worktreesDir, { recursive: true });
3581
+ const worktreePath = path5.join(worktreesDir, slug);
1577
3582
  if (await fileExists(worktreePath)) {
1578
3583
  const error = `Worktree already exists at ${worktreePath}`;
1579
- debugLogger.warn(`createUserWorktree: ${error}`);
3584
+ debugLogger2.warn(`createUserWorktree: ${error}`);
1580
3585
  return { success: false, error };
1581
3586
  }
1582
3587
  await this.ensureWorktreesGitignored();
@@ -1585,12 +3590,12 @@ var GitWorktreeService = class _GitWorktreeService {
1585
3590
  const branchExists = await this.localBranchExists(branchName);
1586
3591
  if (branchExists) {
1587
3592
  const error = `Cannot create worktree "${slug}": branch ${branchName} already exists. Choose a different name, or delete the branch first (e.g. \`git branch -d ${branchName}\`).`;
1588
- debugLogger.warn(`createUserWorktree: ${error}`);
3593
+ debugLogger2.warn(`createUserWorktree: ${error}`);
1589
3594
  return { success: false, error };
1590
3595
  }
1591
3596
  await (await this.getGit()).raw(["worktree", "add", "-b", branchName, worktreePath, base]);
1592
3597
  await this.configureHooksPath(worktreePath).catch((error) => {
1593
- debugLogger.warn(
3598
+ debugLogger2.warn(
1594
3599
  `createUserWorktree: failed to configure core.hooksPath for ${slug}: ${error}`
1595
3600
  );
1596
3601
  });
@@ -1600,7 +3605,7 @@ var GitWorktreeService = class _GitWorktreeService {
1600
3605
  worktreePath,
1601
3606
  symlinkPaths
1602
3607
  ).catch((error) => {
1603
- debugLogger.warn(
3608
+ debugLogger2.warn(
1604
3609
  `createUserWorktree: symlinkConfiguredDirectories failed for ${slug}: ${error}`
1605
3610
  );
1606
3611
  });
@@ -1616,7 +3621,7 @@ var GitWorktreeService = class _GitWorktreeService {
1616
3621
  return { success: true, worktree };
1617
3622
  } catch (error) {
1618
3623
  const message = `Failed to create worktree "${slug}": ${error instanceof Error ? error.message : "Unknown error"}`;
1619
- debugLogger.warn(`createUserWorktree: ${message}`);
3624
+ debugLogger2.warn(`createUserWorktree: ${message}`);
1620
3625
  return { success: false, error: message };
1621
3626
  }
1622
3627
  }
@@ -1635,14 +3640,14 @@ var GitWorktreeService = class _GitWorktreeService {
1635
3640
  * creation so the extra ~14ms isn't worth the file-parsing complexity).
1636
3641
  */
1637
3642
  async configureHooksPath(worktreePath) {
1638
- const huskyPath = path2.join(this.sourceRepoPath, ".husky");
3643
+ const huskyPath = path5.join(this.sourceRepoPath, ".husky");
1639
3644
  let hooksPath = null;
1640
3645
  try {
1641
- await fs2.stat(huskyPath);
3646
+ await fs4.stat(huskyPath);
1642
3647
  hooksPath = huskyPath;
1643
3648
  } catch (error) {
1644
3649
  if (!(isNodeError(error) && error.code === "ENOENT")) {
1645
- debugLogger.warn(
3650
+ debugLogger2.warn(
1646
3651
  `configureHooksPath: cannot stat ${huskyPath}: ${error}`
1647
3652
  );
1648
3653
  }
@@ -1650,13 +3655,13 @@ var GitWorktreeService = class _GitWorktreeService {
1650
3655
  if (!hooksPath) {
1651
3656
  try {
1652
3657
  const commonDir = (await (await this.getGit()).raw(["rev-parse", "--git-common-dir"])).trim();
1653
- const resolvedCommonDir = path2.isAbsolute(commonDir) ? commonDir : path2.resolve(this.sourceRepoPath, commonDir);
1654
- const candidate = path2.join(resolvedCommonDir, "hooks");
1655
- await fs2.stat(candidate);
3658
+ const resolvedCommonDir = path5.isAbsolute(commonDir) ? commonDir : path5.resolve(this.sourceRepoPath, commonDir);
3659
+ const candidate = path5.join(resolvedCommonDir, "hooks");
3660
+ await fs4.stat(candidate);
1656
3661
  hooksPath = candidate;
1657
3662
  } catch (error) {
1658
3663
  if (!(isNodeError(error) && error.code === "ENOENT")) {
1659
- debugLogger.warn(
3664
+ debugLogger2.warn(
1660
3665
  `configureHooksPath: cannot resolve git common hooks dir: ${error}`
1661
3666
  );
1662
3667
  }
@@ -1675,7 +3680,7 @@ var GitWorktreeService = class _GitWorktreeService {
1675
3680
  if (existing === "") {
1676
3681
  await worktreeGit.raw(["config", "core.hooksPath", hooksPath]);
1677
3682
  } else if (existing !== hooksPath) {
1678
- debugLogger.debug(
3683
+ debugLogger2.debug(
1679
3684
  `configureHooksPath: preserving existing core.hooksPath=${existing} (o1-code would have set it to ${hooksPath})`
1680
3685
  );
1681
3686
  }
@@ -1707,70 +3712,70 @@ var GitWorktreeService = class _GitWorktreeService {
1707
3712
  async symlinkConfiguredDirectories(worktreePath, configured) {
1708
3713
  let repoRootAbs;
1709
3714
  try {
1710
- repoRootAbs = await fs2.realpath(this.sourceRepoPath);
3715
+ repoRootAbs = await fs4.realpath(this.sourceRepoPath);
1711
3716
  } catch {
1712
- debugLogger.warn(
3717
+ debugLogger2.warn(
1713
3718
  `symlinkConfiguredDirectories: cannot realpath sourceRepoPath "${this.sourceRepoPath}", skipping all entries`
1714
3719
  );
1715
3720
  return;
1716
3721
  }
1717
- const gitDirAbs = path2.join(repoRootAbs, ".git");
1718
- const o1codeDirAbs = path2.join(repoRootAbs, ".o1-code");
1719
- const realWorktreePath = await fs2.realpath(worktreePath).catch(() => worktreePath);
3722
+ const gitDirAbs = path5.join(repoRootAbs, ".git");
3723
+ const o1codeDirAbs = path5.join(repoRootAbs, ".o1-code");
3724
+ const realWorktreePath = await fs4.realpath(worktreePath).catch(() => worktreePath);
1720
3725
  for (const raw of configured) {
1721
3726
  if (typeof raw !== "string" || raw.length === 0) {
1722
- debugLogger.warn(
3727
+ debugLogger2.warn(
1723
3728
  `symlinkConfiguredDirectories: skipping non-string / empty entry: ${JSON.stringify(raw)}`
1724
3729
  );
1725
3730
  continue;
1726
3731
  }
1727
- if (path2.isAbsolute(raw)) {
1728
- debugLogger.warn(
3732
+ if (path5.isAbsolute(raw)) {
3733
+ debugLogger2.warn(
1729
3734
  `symlinkConfiguredDirectories: refusing absolute path "${raw}"`
1730
3735
  );
1731
3736
  continue;
1732
3737
  }
1733
3738
  if (raw.split(/[\\/]/).includes("..")) {
1734
- debugLogger.warn(
3739
+ debugLogger2.warn(
1735
3740
  `symlinkConfiguredDirectories: refusing path "${raw}" \u2014 contains '..' segment`
1736
3741
  );
1737
3742
  continue;
1738
3743
  }
1739
- const sourceAbs = path2.resolve(repoRootAbs, raw);
3744
+ const sourceAbs = path5.resolve(repoRootAbs, raw);
1740
3745
  if (sourceAbs === repoRootAbs) {
1741
- debugLogger.warn(
3746
+ debugLogger2.warn(
1742
3747
  `symlinkConfiguredDirectories: refusing empty / repo-root path "${raw}"`
1743
3748
  );
1744
3749
  continue;
1745
3750
  }
1746
3751
  if (!isWithinRoot(sourceAbs, repoRootAbs)) {
1747
- debugLogger.warn(
3752
+ debugLogger2.warn(
1748
3753
  `symlinkConfiguredDirectories: refusing path "${raw}" \u2014 resolves outside repo root (${sourceAbs} vs ${repoRootAbs})`
1749
3754
  );
1750
3755
  continue;
1751
3756
  }
1752
3757
  if (isWithinRoot(sourceAbs, gitDirAbs)) {
1753
- debugLogger.warn(
3758
+ debugLogger2.warn(
1754
3759
  `symlinkConfiguredDirectories: refusing git-internal path "${raw}"`
1755
3760
  );
1756
3761
  continue;
1757
3762
  }
1758
3763
  if (isWithinRoot(sourceAbs, o1codeDirAbs)) {
1759
- debugLogger.warn(
3764
+ debugLogger2.warn(
1760
3765
  `symlinkConfiguredDirectories: refusing path "${raw}" \u2014 the .o1-code tree is CLI-managed; symlinking any of it could create a worktrees-inside-worktrees loop or alias CLI metadata.`
1761
3766
  );
1762
3767
  continue;
1763
3768
  }
1764
3769
  let sourceStat = null;
1765
3770
  try {
1766
- sourceStat = await fs2.stat(sourceAbs);
3771
+ sourceStat = await fs4.stat(sourceAbs);
1767
3772
  } catch (error) {
1768
3773
  if (isNodeError(error) && error.code === "ENOENT") {
1769
- debugLogger.debug(
3774
+ debugLogger2.debug(
1770
3775
  `symlinkConfiguredDirectories: source missing, skipping: ${sourceAbs}`
1771
3776
  );
1772
3777
  } else {
1773
- debugLogger.warn(
3778
+ debugLogger2.warn(
1774
3779
  `symlinkConfiguredDirectories: cannot stat ${sourceAbs}: ${error}`
1775
3780
  );
1776
3781
  }
@@ -1778,68 +3783,68 @@ var GitWorktreeService = class _GitWorktreeService {
1778
3783
  }
1779
3784
  let realSource;
1780
3785
  try {
1781
- realSource = await fs2.realpath(sourceAbs);
3786
+ realSource = await fs4.realpath(sourceAbs);
1782
3787
  } catch (error) {
1783
- debugLogger.warn(
3788
+ debugLogger2.warn(
1784
3789
  `symlinkConfiguredDirectories: cannot realpath source "${sourceAbs}": ${error}`
1785
3790
  );
1786
3791
  continue;
1787
3792
  }
1788
3793
  if (!isWithinRoot(realSource, repoRootAbs)) {
1789
- debugLogger.warn(
3794
+ debugLogger2.warn(
1790
3795
  `symlinkConfiguredDirectories: refusing path "${raw}" \u2014 real source ${realSource} escapes repo root ${repoRootAbs}`
1791
3796
  );
1792
3797
  continue;
1793
3798
  }
1794
3799
  if (isWithinRoot(realSource, gitDirAbs)) {
1795
- debugLogger.warn(
3800
+ debugLogger2.warn(
1796
3801
  `symlinkConfiguredDirectories: refusing path "${raw}" \u2014 real source ${realSource} resolves inside .git`
1797
3802
  );
1798
3803
  continue;
1799
3804
  }
1800
3805
  if (isWithinRoot(realSource, o1codeDirAbs)) {
1801
- debugLogger.warn(
3806
+ debugLogger2.warn(
1802
3807
  `symlinkConfiguredDirectories: refusing path "${raw}" \u2014 real source ${realSource} resolves inside .o1-code`
1803
3808
  );
1804
3809
  continue;
1805
3810
  }
1806
- const destAbs = path2.join(worktreePath, raw);
3811
+ const destAbs = path5.join(worktreePath, raw);
1807
3812
  try {
1808
- await fs2.mkdir(path2.dirname(destAbs), { recursive: true });
3813
+ await fs4.mkdir(path5.dirname(destAbs), { recursive: true });
1809
3814
  } catch (error) {
1810
- debugLogger.warn(
3815
+ debugLogger2.warn(
1811
3816
  `symlinkConfiguredDirectories: cannot mkdir parent of ${destAbs}: ${error}`
1812
3817
  );
1813
3818
  continue;
1814
3819
  }
1815
3820
  let realDestParent;
1816
3821
  try {
1817
- realDestParent = await fs2.realpath(path2.dirname(destAbs));
3822
+ realDestParent = await fs4.realpath(path5.dirname(destAbs));
1818
3823
  } catch (error) {
1819
- debugLogger.warn(
1820
- `symlinkConfiguredDirectories: cannot realpath dest parent for "${raw}" (${path2.dirname(destAbs)}): ${error}`
3824
+ debugLogger2.warn(
3825
+ `symlinkConfiguredDirectories: cannot realpath dest parent for "${raw}" (${path5.dirname(destAbs)}): ${error}`
1821
3826
  );
1822
3827
  continue;
1823
3828
  }
1824
3829
  if (!isWithinRoot(realDestParent, realWorktreePath)) {
1825
- debugLogger.warn(
3830
+ debugLogger2.warn(
1826
3831
  `symlinkConfiguredDirectories: refusing path "${raw}" \u2014 dest parent ${realDestParent} escapes worktree root ${realWorktreePath} (committed-symlink chain)`
1827
3832
  );
1828
3833
  continue;
1829
3834
  }
1830
3835
  try {
1831
3836
  const symlinkType = sourceStat.isDirectory() ? process.platform === "win32" ? "junction" : "dir" : "file";
1832
- await fs2.symlink(realSource, destAbs, symlinkType);
1833
- debugLogger.debug(
3837
+ await fs4.symlink(realSource, destAbs, symlinkType);
3838
+ debugLogger2.debug(
1834
3839
  `symlinkConfiguredDirectories: linked ${destAbs} \u2192 ${realSource} (${symlinkType})`
1835
3840
  );
1836
3841
  } catch (error) {
1837
3842
  if (isNodeError(error) && error.code === "EEXIST") {
1838
- debugLogger.debug(
3843
+ debugLogger2.debug(
1839
3844
  `symlinkConfiguredDirectories: destination exists, skipping: ${destAbs}`
1840
3845
  );
1841
3846
  } else {
1842
- debugLogger.warn(
3847
+ debugLogger2.warn(
1843
3848
  `symlinkConfiguredDirectories: failed to link ${destAbs} \u2192 ${realSource}: ${error}`
1844
3849
  );
1845
3850
  }
@@ -1870,7 +3875,7 @@ var GitWorktreeService = class _GitWorktreeService {
1870
3875
  ]);
1871
3876
  return out.trim().length > 0;
1872
3877
  } catch (error) {
1873
- debugLogger.warn(`localBranchExists failed for ${branchName}: ${error}`);
3878
+ debugLogger2.warn(`localBranchExists failed for ${branchName}: ${error}`);
1874
3879
  return false;
1875
3880
  }
1876
3881
  }
@@ -1882,11 +3887,11 @@ var GitWorktreeService = class _GitWorktreeService {
1882
3887
  */
1883
3888
  async ensureWorktreesGitignored() {
1884
3889
  try {
1885
- const o1codeDir = path2.join(this.sourceRepoPath, ".o1-code");
1886
- await fs2.mkdir(o1codeDir, { recursive: true });
1887
- const gitignorePath = path2.join(o1codeDir, ".gitignore");
3890
+ const o1codeDir = path5.join(this.sourceRepoPath, ".o1-code");
3891
+ await fs4.mkdir(o1codeDir, { recursive: true });
3892
+ const gitignorePath = path5.join(o1codeDir, ".gitignore");
1888
3893
  try {
1889
- await fs2.writeFile(
3894
+ await fs4.writeFile(
1890
3895
  gitignorePath,
1891
3896
  `# Auto-generated by o1-code.
1892
3897
  ${WORKTREES_DIR}/
@@ -1900,7 +3905,7 @@ ${WORKTREES_DIR}/
1900
3905
  throw error;
1901
3906
  }
1902
3907
  } catch (error) {
1903
- debugLogger.warn(
3908
+ debugLogger2.warn(
1904
3909
  `ensureWorktreesGitignored failed (non-fatal): ${error}`
1905
3910
  );
1906
3911
  }
@@ -1930,7 +3935,7 @@ ${WORKTREES_DIR}/
1930
3935
  await git.branch(["-d", branchName]);
1931
3936
  return { success: true };
1932
3937
  } catch (error) {
1933
- debugLogger.warn(
3938
+ debugLogger2.warn(
1934
3939
  `removeUserWorktree: safe branch delete failed for ${branchName}: ${error}`
1935
3940
  );
1936
3941
  }
@@ -1939,7 +3944,7 @@ ${WORKTREES_DIR}/
1939
3944
  await git.branch(["-D", branchName]);
1940
3945
  return { success: true };
1941
3946
  } catch (error) {
1942
- debugLogger.warn(
3947
+ debugLogger2.warn(
1943
3948
  `removeUserWorktree: force branch delete failed for ${branchName}: ${error}`
1944
3949
  );
1945
3950
  }
@@ -1973,7 +3978,7 @@ ${WORKTREES_DIR}/
1973
3978
  ])).split("\n").map((s) => s.trim()).filter((s) => s.length > 0 && s !== `refs/heads/${branchName}`);
1974
3979
  return refs.length === 0;
1975
3980
  } catch (error) {
1976
- debugLogger.warn(
3981
+ debugLogger2.warn(
1977
3982
  `hasUnmergedWorktreeCommits failed for slug ${slug}: ${error}`
1978
3983
  );
1979
3984
  return true;
@@ -1989,7 +3994,7 @@ ${WORKTREES_DIR}/
1989
3994
  */
1990
3995
  async hasWorktreeChanges(worktreePath) {
1991
3996
  try {
1992
- const { stdout } = await execFileAsync(
3997
+ const { stdout } = await execFileAsync3(
1993
3998
  "git",
1994
3999
  [
1995
4000
  ...NO_EXEC_CONFIG,
@@ -2015,7 +4020,7 @@ ${WORKTREES_DIR}/
2015
4020
  */
2016
4021
  async countWorktreeChanges(worktreePath) {
2017
4022
  try {
2018
- const { stdout } = await execFileAsync(
4023
+ const { stdout } = await execFileAsync3(
2019
4024
  "git",
2020
4025
  [
2021
4026
  ...NO_EXEC_CONFIG,
@@ -2048,12 +4053,44 @@ ${WORKTREES_DIR}/
2048
4053
  };
2049
4054
 
2050
4055
  export {
4056
+ MAX_FILES,
4057
+ MAX_DIFF_SIZE_BYTES,
4058
+ MAX_LINES_PER_FILE,
4059
+ MAX_FILES_FOR_DETAILS,
4060
+ fetchGitDiff,
4061
+ fetchGitDiffHunks,
4062
+ fetchGitDiffHunksForFile,
4063
+ parseGitNumstat,
4064
+ parseGitDiff,
4065
+ unquoteCStylePath,
4066
+ getWorkingTreeLineStats,
4067
+ parseDeletedFromNameStatus,
4068
+ getGitWorkingTreeStatus,
4069
+ parseStatusBranchLine,
4070
+ parseStatusEntries,
4071
+ MAX_LOG_LIMIT,
4072
+ DEFAULT_LOG_LIMIT,
4073
+ fetchGitLog,
4074
+ fetchGitCommitDetail,
2051
4075
  writeRuntimeStatus,
2052
4076
  readRuntimeStatus,
2053
4077
  clearRuntimeStatus,
4078
+ isValidRefName,
4079
+ resolveBranchName,
4080
+ watchRepoBranch,
4081
+ gitEnv,
4082
+ runGit2 as runGit,
4083
+ fetchGitBranches,
4084
+ isValidCheckoutRef,
4085
+ gitCheckout,
4086
+ gitCreateBranch,
4087
+ gitPush,
4088
+ GitPullFailure,
4089
+ gitPull,
4090
+ gitCommit,
2054
4091
  loadSimpleGit,
2055
4092
  worktreeBranchForSlug,
2056
- WORKTREE_SESSION_FILE,
4093
+ worktreeHasWork,
2057
4094
  writeWorktreeSessionMarker,
2058
4095
  WorktreeMarkerCommittedError,
2059
4096
  createWorktreeSessionMarkerExclusive,
@@ -2100,6 +4137,11 @@ export {
2100
4137
  * The schema is small and stable; external consumers should treat
2101
4138
  * unknown fields as forward-compatible additions.
2102
4139
  */
4140
+ /**
4141
+ * @license
4142
+ * Copyright 2025 Google LLC
4143
+ * SPDX-License-Identifier: Apache-2.0
4144
+ */
2103
4145
  /**
2104
4146
  * @license
2105
4147
  * Copyright 2026 Qwen Team