@dylanpiercey/work 0.0.120 → 0.0.122
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -8
- package/bin/work.mjs +380 -41
- package/dist/_B1lVb01g.js +2 -0
- package/dist/{_DEBFGwto.js → _BPX2_wNT.js} +20 -18
- package/dist/{_BZhGz-eY.js → _BdBrOaZF.js} +95 -94
- package/dist/_Bjh5JEm7.js +2 -0
- package/dist/_CfwTkTbL.js +352 -0
- package/dist/{_DE2RUdbF.js → _Cr71Xd0d.js} +8 -3
- package/dist/_DJyHc1w-.js +1739 -0
- package/dist/_Dpa8WFuv.js +2 -0
- package/dist/index.mjs +4136 -4140
- package/dist/public/assets/{_z3QzE4ht2.js → _22Wep3Qj2.js} +1 -1
- package/dist/public/assets/{_DdYfAoJz.js → _4C4ZKftZ.js} +1 -1
- package/dist/public/assets/_4C4ZKftZ.js.br +0 -0
- package/dist/public/assets/{_h6HS-Zb_2.js → _5waGGcsH2.js} +1 -1
- package/dist/public/assets/_5waGGcsH2.js.br +0 -0
- package/dist/public/assets/{_BqNoqWIY.js → _6yLwnUth.js} +1 -1
- package/dist/public/assets/_6yLwnUth.js.br +0 -0
- package/dist/public/assets/{_BuF6uiIm.js → _8ixfpSLV.js} +1 -1
- package/dist/public/assets/_8ixfpSLV.js.br +0 -0
- package/dist/public/assets/{_BEPt7EWk.js → _9NNG2Bg-.js} +1 -1
- package/dist/public/assets/_9NNG2Bg-.js.br +0 -0
- package/dist/public/assets/{_D8lg2J6H.js → _9wp1Weya.js} +1 -1
- package/dist/public/assets/_9wp1Weya.js.br +0 -0
- package/dist/public/assets/{_BoXfCUcF.js → _B80Me7dX.js} +1 -1
- package/dist/public/assets/{_BbE6iGBd.js → _BJVUTWAN.js} +1 -1
- package/dist/public/assets/_BJVUTWAN.js.br +0 -0
- package/dist/public/assets/{_CihMY3_B2.js → _BO5eXuo12.js} +1 -1
- package/dist/public/assets/_BO5eXuo12.js.br +0 -0
- package/dist/public/assets/{_CwZCc-fE2.js → _BO6TG3u42.js} +1 -1
- package/dist/public/assets/_BO6TG3u42.js.br +0 -0
- package/dist/public/assets/{_D4V7vTBe.js → _BO_carFG.js} +1 -1
- package/dist/public/assets/_BO_carFG.js.br +0 -0
- package/dist/public/assets/{_D11ZFURg.js → _BPjnrd1A.js} +1 -1
- package/dist/public/assets/_BPjnrd1A.js.br +0 -0
- package/dist/public/assets/{_DRKLaQtq.js → _BQfrm6Hv.js} +1 -1
- package/dist/public/assets/_BQfrm6Hv.js.br +0 -0
- package/dist/public/assets/{_CwtAB8Ju2.js → _BYOrCsb12.js} +1 -1
- package/dist/public/assets/_BYOrCsb12.js.br +0 -0
- package/dist/public/assets/{_CIio55Q2.js → _BcA9iBrt.js} +1 -1
- package/dist/public/assets/_BcA9iBrt.js.br +0 -0
- package/dist/public/assets/{_Du-i6H8r.js → _BcnKn75V.js} +24 -21
- package/dist/public/assets/_BcnKn75V.js.br +0 -0
- package/dist/public/assets/{_CJ_9Hl5d.js → _BeYy7LJv.js} +1 -1
- package/dist/public/assets/_BeYy7LJv.js.br +0 -0
- package/dist/public/assets/{_DBXfsrRd.js → _BfzwZXGo.js} +1 -1
- package/dist/public/assets/_BfzwZXGo.js.br +0 -0
- package/dist/public/assets/{_BfZMmKaW.js → _Bgq0Djxf.js} +1 -1
- package/dist/public/assets/_Bgq0Djxf.js.br +0 -0
- package/dist/public/assets/{_zJkCtRhb.js → _BgxHsV2q.js} +1 -1
- package/dist/public/assets/_BgxHsV2q.js.br +0 -0
- package/dist/public/assets/{_p1VLQxPw.js → _Bhf_wksG.js} +1 -1
- package/dist/public/assets/_Bhf_wksG.js.br +0 -0
- package/dist/public/assets/{_CrPK-ZOH2.js → _Bkd9T8qO2.js} +1 -1
- package/dist/public/assets/_Bkd9T8qO2.js.br +0 -0
- package/dist/public/assets/{_CYLlpjQc.js → _BllRu2dt.js} +1 -1
- package/dist/public/assets/_BllRu2dt.js.br +0 -0
- package/dist/public/assets/{_DWctbEWg.js → _Buu8_cyc.js} +1 -1
- package/dist/public/assets/_Buu8_cyc.js.br +0 -0
- package/dist/public/assets/{_F8phZWNM2.js → _BvJHLrwP2.js} +1 -1
- package/dist/public/assets/_BvJHLrwP2.js.br +0 -0
- package/dist/public/assets/{_wc-pkVQS.js → _BvTWp2QQ.js} +1 -1
- package/dist/public/assets/_BvTWp2QQ.js.br +0 -0
- package/dist/public/assets/{_CkBv_F0f.js → _BxfzYLyp.js} +1 -1
- package/dist/public/assets/_BxfzYLyp.js.br +0 -0
- package/dist/public/assets/{_BzULaZGs.js → _Bz61WBUI.js} +1 -1
- package/dist/public/assets/_Bz61WBUI.js.br +0 -0
- package/dist/public/assets/{_Cv-4N4xQ.js → _C0Wcm1DA.js} +1 -1
- package/dist/public/assets/_C0Wcm1DA.js.br +0 -0
- package/dist/public/assets/{_BUmLRB7c2.js → _C5fkGs032.js} +1 -1
- package/dist/public/assets/_C5fkGs032.js.br +0 -0
- package/dist/public/assets/{_BEOZghNJ2.js → _CKAWtCKg2.js} +1 -1
- package/dist/public/assets/_CKAWtCKg2.js.br +0 -0
- package/dist/public/assets/{_BFgJoTOo.js → _CLM87vGj.js} +1 -1
- package/dist/public/assets/_CLM87vGj.js.br +0 -0
- package/dist/public/assets/{_B6bSumz1.js → _CM8zmLXB.js} +1 -1
- package/dist/public/assets/_CM8zmLXB.js.br +0 -0
- package/dist/public/assets/{_8hF31A2G.js → _CNBki2Aq.js} +1 -1
- package/dist/public/assets/_CNBki2Aq.js.br +0 -0
- package/dist/public/assets/{_CQ-tqbUq.js → _CNVk64eD.js} +1 -1
- package/dist/public/assets/_CNVk64eD.js.br +0 -0
- package/dist/public/assets/{_BHgE7f-_2.js → _CPCFHsPT2.js} +1 -1
- package/dist/public/assets/_CPCFHsPT2.js.br +0 -0
- package/dist/public/assets/{_BLgtdDQm.js → _CW70CETb.js} +1 -1
- package/dist/public/assets/_CW70CETb.js.br +0 -0
- package/dist/public/assets/{_BCKhXQct2.js → _CWU_IJjz2.js} +1 -1
- package/dist/public/assets/_CWU_IJjz2.js.br +0 -0
- package/dist/public/assets/{_BaiP7ogH.js → _ClA-9QLW.js} +1 -1
- package/dist/public/assets/_ClA-9QLW.js.br +0 -0
- package/dist/public/assets/{_dBVoJwVC.js → _CorgOnjQ.js} +1 -1
- package/dist/public/assets/_CorgOnjQ.js.br +0 -0
- package/dist/public/assets/{_DdnCyOPs.js → _CpByFq0N.js} +1 -1
- package/dist/public/assets/_CpByFq0N.js.br +0 -0
- package/dist/public/assets/{_fR2ilomn.js → _CqEc7KwE.js} +1 -1
- package/dist/public/assets/_CqEc7KwE.js.br +0 -0
- package/dist/public/assets/{_BtmFYBHk.js → _CqgcFjOQ.js} +1 -1
- package/dist/public/assets/_CqgcFjOQ.js.br +0 -0
- package/dist/public/assets/{_CeECfdVo2.js → _CrlXwiFN2.js} +1 -1
- package/dist/public/assets/_CrlXwiFN2.js.br +0 -0
- package/dist/public/assets/{_FEbRnVo7.js → _CtuCeJaB.js} +1 -1
- package/dist/public/assets/_CtuCeJaB.js.br +0 -0
- package/dist/public/assets/{_DfpMH3So2.js → _D1zxC16I2.js} +1 -1
- package/dist/public/assets/_D1zxC16I2.js.br +0 -0
- package/dist/public/assets/{_Cvly93xo2.js → _D2SIC9vH2.js} +1 -1
- package/dist/public/assets/_D2SIC9vH2.js.br +0 -0
- package/dist/public/assets/{_-3OmHyNU.js → _D9QYQO8L.js} +1 -1
- package/dist/public/assets/_D9QYQO8L.js.br +0 -0
- package/dist/public/assets/{_CzMjLSTK.js → _DDNq8klN.js} +1 -1
- package/dist/public/assets/_DDNq8klN.js.br +0 -0
- package/dist/public/assets/{_BIsQjQ872.js → _DL2HExUi2.js} +1 -1
- package/dist/public/assets/_DL2HExUi2.js.br +0 -0
- package/dist/public/assets/{_QuFTKxMO2.js → _DLbcflUX2.js} +1 -1
- package/dist/public/assets/_DLbcflUX2.js.br +0 -0
- package/dist/public/assets/{_N0Ea8Q_R.js → _DMzElmqz.js} +1 -1
- package/dist/public/assets/_DMzElmqz.js.br +0 -0
- package/dist/public/assets/{_cS3NYZ_K2.js → _DOa36sDf2.js} +1 -1
- package/dist/public/assets/_DOa36sDf2.js.br +0 -0
- package/dist/public/assets/{_DDag_nXJ.js → _DWZLw9u5.js} +1 -1
- package/dist/public/assets/_DWZLw9u5.js.br +0 -0
- package/dist/public/assets/{_DiaYv9e1.js → _DY5MuJqh.js} +1 -1
- package/dist/public/assets/_DY5MuJqh.js.br +0 -0
- package/dist/public/assets/{_D2xWjoK-2.js → _DZXcx3AV2.js} +1 -1
- package/dist/public/assets/_DZXcx3AV2.js.br +0 -0
- package/dist/public/assets/{_BPcKgx9L.js → _D_5rjG0o.js} +1 -1
- package/dist/public/assets/_D_5rjG0o.js.br +0 -0
- package/dist/public/assets/{_Ca811EeR.js → _DbEs3COY.js} +1 -1
- package/dist/public/assets/_DbEs3COY.js.br +0 -0
- package/dist/public/assets/{_BrTLGsp82.js → _DegNdi0y2.js} +1 -1
- package/dist/public/assets/_DegNdi0y2.js.br +0 -0
- package/dist/public/assets/{_B_MP9UES.js → _DfLxwQXd.js} +1 -1
- package/dist/public/assets/_DfLxwQXd.js.br +0 -0
- package/dist/public/assets/{_BilqQTfw.js → _DwTIenq9.js} +1 -1
- package/dist/public/assets/_DwTIenq9.js.br +0 -0
- package/dist/public/assets/{_0_ngOEbL.js → _Dwsfrcqr.js} +1 -1
- package/dist/public/assets/_Dwsfrcqr.js.br +0 -0
- package/dist/public/assets/{_uJTU0UZd2.js → _DyZPE8LD2.js} +1 -1
- package/dist/public/assets/_DyZPE8LD2.js.br +0 -0
- package/dist/public/assets/{_D2be5yUI.js → _MEclBKIH.js} +1 -1
- package/dist/public/assets/_MEclBKIH.js.br +0 -0
- package/dist/public/assets/{_DhLWIgCs.js → _Tpid4lIw.js} +1 -1
- package/dist/public/assets/_Tpid4lIw.js.br +0 -0
- package/dist/public/assets/{_cdbANa0O.js → _W9aOkr2v.js} +1 -1
- package/dist/public/assets/_W9aOkr2v.js.br +0 -0
- package/dist/public/assets/{_BDRc66NB2.js → _Y8lHXkX62.js} +1 -1
- package/dist/public/assets/_Y8lHXkX62.js.br +0 -0
- package/dist/public/assets/{_GdcmEEuJ.js → _Z4spekbX.js} +1 -1
- package/dist/public/assets/_Z4spekbX.js.br +0 -0
- package/dist/public/assets/{_CeVHIZWy2.js → _a18bdHwu2.js} +1 -1
- package/dist/public/assets/_a18bdHwu2.js.br +0 -0
- package/dist/public/assets/{_DkYHMy0q2.js → _hO1aV02w2.js} +1 -1
- package/dist/public/assets/{_DZgx_rAt.js → _ih_22Lwc.js} +1 -1
- package/dist/public/assets/_ih_22Lwc.js.br +0 -0
- package/dist/public/assets/{_CG2uZvAG.js → _kQ849tt6.js} +1 -1
- package/dist/public/assets/_kQ849tt6.js.br +0 -0
- package/dist/public/assets/{_Ces5jihM.js → _lo4uGYhv.js} +1 -1
- package/dist/public/assets/_lo4uGYhv.js.br +0 -0
- package/dist/public/assets/{_Brws7C1N.js → _sWtKlZZ5.js} +6 -6
- package/dist/public/assets/_sWtKlZZ5.js.br +0 -0
- package/dist/public/assets/{_BGHYY00K2.js → _xvmiPi6J2.js} +1 -1
- package/dist/public/assets/_xvmiPi6J2.js.br +0 -0
- package/dist/public/assets/app-page-9ukuDxSW.css +1 -0
- package/dist/public/assets/app-page-9ukuDxSW.css.br +0 -0
- package/dist/public/assets/diff-view-BmyKvz_f.css +1 -0
- package/dist/public/assets/diff-view-BmyKvz_f.css.br +0 -0
- package/dist/public/assets/new-PmY_tc2O.js +1 -0
- package/dist/public/assets/settings-PmY_tc2O.js +1 -0
- package/dist/public/assets/w-PmY_tc2O.js +1 -0
- package/dist/public/assets/w._-DL1tdfaH.js +1 -0
- package/dist/public/assets/w._-PmY_tc2O.js +1 -0
- package/lib/review/markdown.mjs +6 -2
- package/lib/setup/catalog.d.mts +3 -1
- package/lib/setup/catalog.mjs +11 -2
- package/lib/setup/doctor.mjs +96 -20
- package/lib/setup/install.d.mts +9 -3
- package/lib/setup/install.mjs +68 -39
- package/lib/share/manifest.d.mts +27 -0
- package/lib/share/manifest.mjs +144 -0
- package/package.json +6 -2
- package/scripts/migrate.mjs +101 -30
- package/dist/_BIDn_RW1.js +0 -2
- package/dist/public/assets/_-3OmHyNU.js.br +0 -0
- package/dist/public/assets/_0_ngOEbL.js.br +0 -0
- package/dist/public/assets/_8hF31A2G.js.br +0 -0
- package/dist/public/assets/_B6bSumz1.js.br +0 -0
- package/dist/public/assets/_BCKhXQct2.js.br +0 -0
- package/dist/public/assets/_BDRc66NB2.js.br +0 -0
- package/dist/public/assets/_BEOZghNJ2.js.br +0 -0
- package/dist/public/assets/_BEPt7EWk.js.br +0 -0
- package/dist/public/assets/_BFgJoTOo.js.br +0 -0
- package/dist/public/assets/_BGHYY00K2.js.br +0 -0
- package/dist/public/assets/_BHgE7f-_2.js.br +0 -0
- package/dist/public/assets/_BIsQjQ872.js.br +0 -0
- package/dist/public/assets/_BLgtdDQm.js.br +0 -0
- package/dist/public/assets/_BPcKgx9L.js.br +0 -0
- package/dist/public/assets/_BUmLRB7c2.js.br +0 -0
- package/dist/public/assets/_B_MP9UES.js.br +0 -0
- package/dist/public/assets/_BaiP7ogH.js.br +0 -0
- package/dist/public/assets/_BbE6iGBd.js.br +0 -0
- package/dist/public/assets/_BfZMmKaW.js.br +0 -0
- package/dist/public/assets/_BilqQTfw.js.br +0 -0
- package/dist/public/assets/_BqNoqWIY.js.br +0 -0
- package/dist/public/assets/_BrTLGsp82.js.br +0 -0
- package/dist/public/assets/_Brws7C1N.js.br +0 -0
- package/dist/public/assets/_BtmFYBHk.js.br +0 -0
- package/dist/public/assets/_BuF6uiIm.js.br +0 -0
- package/dist/public/assets/_BzULaZGs.js.br +0 -0
- package/dist/public/assets/_CG2uZvAG.js.br +0 -0
- package/dist/public/assets/_CIio55Q2.js.br +0 -0
- package/dist/public/assets/_CJ_9Hl5d.js.br +0 -0
- package/dist/public/assets/_CQ-tqbUq.js.br +0 -0
- package/dist/public/assets/_CYLlpjQc.js.br +0 -0
- package/dist/public/assets/_Ca811EeR.js.br +0 -0
- package/dist/public/assets/_CeECfdVo2.js.br +0 -0
- package/dist/public/assets/_CeVHIZWy2.js.br +0 -0
- package/dist/public/assets/_Ces5jihM.js.br +0 -7
- package/dist/public/assets/_CihMY3_B2.js.br +0 -0
- package/dist/public/assets/_CkBv_F0f.js.br +0 -0
- package/dist/public/assets/_CrPK-ZOH2.js.br +0 -0
- package/dist/public/assets/_Cv-4N4xQ.js.br +0 -0
- package/dist/public/assets/_Cvly93xo2.js.br +0 -0
- package/dist/public/assets/_CwZCc-fE2.js.br +0 -0
- package/dist/public/assets/_CwtAB8Ju2.js.br +0 -0
- package/dist/public/assets/_CzMjLSTK.js.br +0 -0
- package/dist/public/assets/_D11ZFURg.js.br +0 -0
- package/dist/public/assets/_D2be5yUI.js.br +0 -0
- package/dist/public/assets/_D2xWjoK-2.js.br +0 -0
- package/dist/public/assets/_D4V7vTBe.js.br +0 -0
- package/dist/public/assets/_D8lg2J6H.js.br +0 -0
- package/dist/public/assets/_DBXfsrRd.js.br +0 -0
- package/dist/public/assets/_DDag_nXJ.js.br +0 -0
- package/dist/public/assets/_DRKLaQtq.js.br +0 -0
- package/dist/public/assets/_DWctbEWg.js.br +0 -3
- package/dist/public/assets/_DZgx_rAt.js.br +0 -0
- package/dist/public/assets/_DdYfAoJz.js.br +0 -0
- package/dist/public/assets/_DdnCyOPs.js.br +0 -0
- package/dist/public/assets/_DfpMH3So2.js.br +0 -0
- package/dist/public/assets/_DhLWIgCs.js.br +0 -0
- package/dist/public/assets/_DiaYv9e1.js.br +0 -0
- package/dist/public/assets/_Du-i6H8r.js.br +0 -0
- package/dist/public/assets/_F8phZWNM2.js.br +0 -0
- package/dist/public/assets/_FEbRnVo7.js.br +0 -0
- package/dist/public/assets/_GdcmEEuJ.js.br +0 -0
- package/dist/public/assets/_N0Ea8Q_R.js.br +0 -0
- package/dist/public/assets/_QuFTKxMO2.js.br +0 -0
- package/dist/public/assets/_cS3NYZ_K2.js.br +0 -0
- package/dist/public/assets/_cdbANa0O.js.br +0 -0
- package/dist/public/assets/_dBVoJwVC.js.br +0 -0
- package/dist/public/assets/_fR2ilomn.js.br +0 -0
- package/dist/public/assets/_h6HS-Zb_2.js.br +0 -0
- package/dist/public/assets/_p1VLQxPw.js.br +0 -0
- package/dist/public/assets/_uJTU0UZd2.js.br +0 -0
- package/dist/public/assets/_wc-pkVQS.js.br +0 -0
- package/dist/public/assets/_zJkCtRhb.js.br +0 -0
- package/dist/public/assets/app-page-DgsAA8Om.css +0 -1
- package/dist/public/assets/app-page-DgsAA8Om.css.br +0 -0
- package/dist/public/assets/diff-view-BqwTpf5k.css +0 -1
- package/dist/public/assets/diff-view-BqwTpf5k.css.br +0 -0
- package/dist/public/assets/new-cBa61wMi.js +0 -1
- package/dist/public/assets/settings-cBa61wMi.js +0 -1
- package/dist/public/assets/w-cBa61wMi.js +0 -1
- package/dist/public/assets/w._-B9llVTHr.js +0 -1
- package/dist/public/assets/w._-cBa61wMi.js +0 -1
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import { U as subscriberCount, V as publish, W as subscriberJoins, dt as all, ft as db, g as sessionStates, l as listSessions } from "./_Cr71Xd0d.js";
|
|
2
|
+
import { A as portsByWorkspace, J as hostToken, K as forgetToken, M as headOid, Q as ownsBranch, R as repoParent, V as DEFAULT_HOST, Y as joinRepo, Z as splitRepo, h as listWorkspaces, o as pushFailureFor, q as graphqlUrl, z as swr } from "./_DJyHc1w-.js";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
//#region src/server/github-api.ts
|
|
5
|
+
/** Run a GraphQL query against one host.
|
|
6
|
+
*
|
|
7
|
+
* Partial failures come back as a populated `errors` alongside usable `data`
|
|
8
|
+
* — one repo deleted, renamed, or outside this token's scope. Callers want
|
|
9
|
+
* the repos that did resolve, so `data` wins whenever it is present; this
|
|
10
|
+
* matches how the `gh` path treated a non-zero exit with usable stdout. */
|
|
11
|
+
async function graphql(query, host = DEFAULT_HOST) {
|
|
12
|
+
const res = await fetch(graphqlUrl(host), {
|
|
13
|
+
method: "POST",
|
|
14
|
+
headers: {
|
|
15
|
+
authorization: `Bearer ${await hostToken(host)}`,
|
|
16
|
+
"content-type": "application/json",
|
|
17
|
+
accept: "application/vnd.github+json",
|
|
18
|
+
"user-agent": "work"
|
|
19
|
+
},
|
|
20
|
+
body: JSON.stringify({ query })
|
|
21
|
+
});
|
|
22
|
+
if (!res.ok && res.status !== 200) {
|
|
23
|
+
if (res.status === 401 || res.status === 403) forgetToken(host);
|
|
24
|
+
throw new Error(`github graphql ${res.status}`);
|
|
25
|
+
}
|
|
26
|
+
const body = await res.json();
|
|
27
|
+
if (!body?.data) throw new Error(body?.errors?.[0]?.message || "graphql response without data");
|
|
28
|
+
return body.data;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/server/prs.ts
|
|
32
|
+
var TTL_MS$1 = 12e4;
|
|
33
|
+
/** PRs whose head is the workspace branch or one of its `-topic` lanes.
|
|
34
|
+
* `exclude` lists other workspaces' branches — slugs are user-chosen, so
|
|
35
|
+
* another workspace's branch can extend this prefix and its PRs must not
|
|
36
|
+
* be attributed here. */
|
|
37
|
+
function prsForBranchPrefix(prs, prefix, exclude = []) {
|
|
38
|
+
return prs.filter((pr) => ownsBranch(pr.headRefName, prefix) && !exclude.some((x) => ownsBranch(pr.headRefName, x)));
|
|
39
|
+
}
|
|
40
|
+
/** `[host/]owner/name#branch` — the host prefix travels with the name. */
|
|
41
|
+
var branchKey = (fullName, branch) => `${fullName}#${branch}`;
|
|
42
|
+
/** One workspace's PRs in one repo — its branch and every `-topic` lane, in
|
|
43
|
+
* every state. Asking for the workspace's own branches is what keeps this
|
|
44
|
+
* proportional to the workspace rather than to the repo: the alternative,
|
|
45
|
+
* a recency window over all of a repo's PRs, fetched roughly twice what it
|
|
46
|
+
* kept here and still aged a quiet workspace out on a busy repo.
|
|
47
|
+
* Key: `fullName#branch`. */
|
|
48
|
+
var branchPrs = swr(TTL_MS$1, async (key, refresh) => {
|
|
49
|
+
const sep = key.indexOf("#");
|
|
50
|
+
const fullName = key.slice(0, sep);
|
|
51
|
+
const { host, name } = splitRepo(fullName);
|
|
52
|
+
const upstream = await repoParent(fullName);
|
|
53
|
+
return (await searchPrs(host, upstream ? [name, splitRepo(upstream).name] : [name], [key.slice(sep + 1)], refresh)).filter((n) => ownsNode(n, fullName, upstream));
|
|
54
|
+
});
|
|
55
|
+
/** A workspace repo's PRs, minus any belonging to a workspace whose branch
|
|
56
|
+
* extends this one's. `since` is an imported workspace's arrival: a
|
|
57
|
+
* restored or joined workspace keeps its branch name, so the branch's whole
|
|
58
|
+
* history on GitHub matches — finished PRs from before it arrived here are
|
|
59
|
+
* its previous life's, not chips to dismiss again. Open PRs always show;
|
|
60
|
+
* hiding live work would be the worse mistake. */
|
|
61
|
+
async function workspacePrs(fullName, branch, foreign, refresh = false, since) {
|
|
62
|
+
return prsForBranchPrefix(await branchPrs(branchKey(fullName, branch), refresh).catch(() => []), branch, foreign).filter((pr) => !since || pr.state === "OPEN" || !pr.updatedAt || pr.updatedAt >= since);
|
|
63
|
+
}
|
|
64
|
+
/** Refresh many repos' PRs with one GraphQL request (vs one `gh pr list`
|
|
65
|
+
* process per repo) — called from the status watcher for active
|
|
66
|
+
* workspaces so open/merge/close flips surface in ~watch-tick time
|
|
67
|
+
* instead of waiting out the per-repo TTL. Throttled internally. */
|
|
68
|
+
var BATCH_MIN_MS = 15e3;
|
|
69
|
+
/** After a detected local push, poll fast for a bit — the PR appears
|
|
70
|
+
* and merges/closes in the minutes right after. */
|
|
71
|
+
var HOT_MIN_MS = 3e3;
|
|
72
|
+
var HOT_WINDOW_MS = 18e4;
|
|
73
|
+
var lastBatch = 0;
|
|
74
|
+
var hotUntil = 0;
|
|
75
|
+
function notePushActivity() {
|
|
76
|
+
hotUntil = Date.now() + HOT_WINDOW_MS;
|
|
77
|
+
}
|
|
78
|
+
/** Inside the post-push window where PR state is actively flipping. */
|
|
79
|
+
function inHotWindow() {
|
|
80
|
+
return Date.now() < hotUntil;
|
|
81
|
+
}
|
|
82
|
+
/** `headRefOid` is the PR's own head commit, which is what the UI compares
|
|
83
|
+
* against. Reaching through `headRef` gets the branch's *current* tip
|
|
84
|
+
* instead — a different commit entirely once a workspace branch is reused,
|
|
85
|
+
* and `headRef { oid }` is not even a field, so GitHub answers 200 with an
|
|
86
|
+
* `errors` array and no `data`. */
|
|
87
|
+
var GQL_PR_FIELDS = "number title url headRefName baseRefName isDraft state headRefOid updatedAt";
|
|
88
|
+
/** Does this search hit belong to `fullName`'s workspace repo? Directly when
|
|
89
|
+
* the PR lives in that repo *with its head branch there too*; via the fork
|
|
90
|
+
* case when it lives in `upstream` with its head on the fork. The head check
|
|
91
|
+
* on both arms keeps one PR from being claimed twice when a workspace holds
|
|
92
|
+
* a fork and its upstream, and keeps a same-named branch pushed by someone
|
|
93
|
+
* else's fork from being claimed at all. A null headRepository (head repo
|
|
94
|
+
* deleted) stays with the PR's own repo. */
|
|
95
|
+
function ownsNode(n, fullName, upstream) {
|
|
96
|
+
const head = n.headRepository?.nameWithOwner;
|
|
97
|
+
return n.repository.nameWithOwner === fullName && (!head || head === fullName) || !!upstream && n.repository.nameWithOwner === upstream && head === fullName;
|
|
98
|
+
}
|
|
99
|
+
/** Dedup key: PR numbers restart per repo, and a fork target's list spans
|
|
100
|
+
* the fork and its upstream. */
|
|
101
|
+
var nodeKey = (p) => `${p.repository.nameWithOwner}#${p.number}`;
|
|
102
|
+
/** Search's `head:` matches a branch *and* its `-topic` lanes, so one term
|
|
103
|
+
* covers a whole workspace, and repeated terms are OR'd within a qualifier
|
|
104
|
+
* while different qualifiers are AND'd — `repo:a repo:b head:x head:y`
|
|
105
|
+
* reads as (a|b) and (x|y). That is what lets every workspace share one
|
|
106
|
+
* request instead of needing an alias per repo and per branch. */
|
|
107
|
+
function searchTerms(repos, branches) {
|
|
108
|
+
return [...repos.map((r) => `repo:${r}`), ...branches.map((b) => `head:${b}`)].join(" ");
|
|
109
|
+
}
|
|
110
|
+
/** Finished PRs are asked for by recency, open ones are not: a merged PR
|
|
111
|
+
* only has to outlive its dismissal, while an open PR must stay visible
|
|
112
|
+
* however long it has sat idle — which is exactly what a recency window
|
|
113
|
+
* over the whole repo got wrong. */
|
|
114
|
+
var CLOSED_FIRST = 60;
|
|
115
|
+
var OPEN_FIRST = 100;
|
|
116
|
+
/** Search pages at 100. Open PRs are the page that can genuinely overflow
|
|
117
|
+
* (every workspace's, in one request), so it is followed — bounded, because
|
|
118
|
+
* an unbounded follow is a way to hang the status tick on a bad query. */
|
|
119
|
+
var MAX_OPEN_PAGES = 4;
|
|
120
|
+
var searchField = (alias, query, first, after) => `${alias}: search(query: ${JSON.stringify(query)}, type: ISSUE, first: ${first}${after ? `, after: ${JSON.stringify(after)}` : ""}) { pageInfo { hasNextPage endCursor } nodes { ... on PullRequest { ${GQL_PR_FIELDS} repository { nameWithOwner } headRepository { nameWithOwner } } } }`;
|
|
121
|
+
/** Every PR on the given branches (and their lanes) across the given repos
|
|
122
|
+
* of one host (`repos` are bare `owner/name`). `refresh` is accepted for the
|
|
123
|
+
* swr signature; freshness here is GitHub's, not ours. Nodes come back with
|
|
124
|
+
* the host folded into `repository.nameWithOwner` so callers compare full
|
|
125
|
+
* names. */
|
|
126
|
+
async function searchPrs(host, repos, branches, _refresh) {
|
|
127
|
+
const terms = searchTerms(repos, branches);
|
|
128
|
+
const out = [];
|
|
129
|
+
let cursor;
|
|
130
|
+
for (let page = 0; page < MAX_OPEN_PAGES; page++) {
|
|
131
|
+
const data = await graphql("query {" + searchField("open", `is:pr is:open ${terms}`, OPEN_FIRST, cursor) + (page === 0 ? " " + searchField("done", `is:pr is:closed sort:updated-desc ${terms}`, CLOSED_FIRST) : "") + "}", host);
|
|
132
|
+
const open = data.open;
|
|
133
|
+
const done = data.done;
|
|
134
|
+
for (const node of [...open?.nodes ?? [], ...done?.nodes ?? []]) if (node?.number) out.push({
|
|
135
|
+
...node,
|
|
136
|
+
repository: { nameWithOwner: joinRepo(host, node.repository.nameWithOwner) },
|
|
137
|
+
headRepository: node.headRepository ? { nameWithOwner: joinRepo(host, node.headRepository.nameWithOwner) } : null
|
|
138
|
+
});
|
|
139
|
+
if (!open?.pageInfo.hasNextPage || !open.pageInfo.endCursor) break;
|
|
140
|
+
cursor = open.pageInfo.endCursor;
|
|
141
|
+
}
|
|
142
|
+
return out;
|
|
143
|
+
}
|
|
144
|
+
async function refreshPrsBatch(targets, force = false) {
|
|
145
|
+
const wanted = [...new Map(targets.filter((t) => t.fullName.includes("/") && t.branch).map((t) => [branchKey(t.fullName, t.branch), t])).values()];
|
|
146
|
+
const minMs = force ? 2e3 : Date.now() < hotUntil ? HOT_MIN_MS : BATCH_MIN_MS;
|
|
147
|
+
if (!wanted.length || Date.now() - lastBatch < minMs) return false;
|
|
148
|
+
const prevBatch = lastBatch;
|
|
149
|
+
lastBatch = Date.now();
|
|
150
|
+
try {
|
|
151
|
+
const upstreams = new Map(await Promise.all(wanted.map(async (t) => [t.fullName, await repoParent(t.fullName)])));
|
|
152
|
+
const byHost = /* @__PURE__ */ new Map();
|
|
153
|
+
for (const t of wanted) {
|
|
154
|
+
const { host, name } = splitRepo(t.fullName);
|
|
155
|
+
const names = (byHost.get(host) || /* @__PURE__ */ new Set()).add(name);
|
|
156
|
+
const upstream = upstreams.get(t.fullName);
|
|
157
|
+
if (upstream) names.add(splitRepo(upstream).name);
|
|
158
|
+
byHost.set(host, names);
|
|
159
|
+
}
|
|
160
|
+
const branches = [...new Set(wanted.map((t) => t.branch))];
|
|
161
|
+
const results = await Promise.all([...byHost].map(([host, names]) => searchPrs(host, [...names], branches).catch((err) => {
|
|
162
|
+
if (byHost.size === 1) throw err;
|
|
163
|
+
return null;
|
|
164
|
+
})));
|
|
165
|
+
const nodes = results.flatMap((r) => r ?? []);
|
|
166
|
+
const failedHosts = new Set([...byHost.keys()].filter((_, i) => results[i] === null));
|
|
167
|
+
for (const target of wanted) {
|
|
168
|
+
if (failedHosts.has(splitRepo(target.fullName).host)) continue;
|
|
169
|
+
const foreign = branches.filter((b) => b !== target.branch);
|
|
170
|
+
const key = branchKey(target.fullName, target.branch);
|
|
171
|
+
const incoming = prsForBranchPrefix(nodes.filter((n) => ownsNode(n, target.fullName, upstreams.get(target.fullName) ?? null)), target.branch, foreign);
|
|
172
|
+
const open = incoming.filter((p) => p.state === "OPEN");
|
|
173
|
+
const openKeys = new Set(open.map(nodeKey));
|
|
174
|
+
const done = /* @__PURE__ */ new Map();
|
|
175
|
+
for (const p of branchPrs.get(key) ?? []) if (p.state !== "OPEN" && !openKeys.has(nodeKey(p))) done.set(nodeKey(p), p);
|
|
176
|
+
for (const p of incoming) if (p.state !== "OPEN" && !openKeys.has(nodeKey(p))) done.set(nodeKey(p), p);
|
|
177
|
+
branchPrs.set(key, [...open, ...done.values()]);
|
|
178
|
+
}
|
|
179
|
+
return true;
|
|
180
|
+
} catch (err) {
|
|
181
|
+
lastBatch = prevBatch;
|
|
182
|
+
throw err;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/** Confirm a finished (merged/closed) PR so it leaves the manage list. */
|
|
186
|
+
function dismissPr(workspaceId, fullName, number) {
|
|
187
|
+
db.prepare("INSERT OR IGNORE INTO dismissed_prs (workspace_id, full_name, number) VALUES (?, ?, ?)").run(workspaceId, fullName, number);
|
|
188
|
+
}
|
|
189
|
+
/** Drop dismissed PRs from a repo's list — unless one reopened. Keyed by
|
|
190
|
+
* each PR's own repo + number: a fork target's list spans the fork and its
|
|
191
|
+
* upstream (same numbers restart per repo), so a workspace-repo-wide key
|
|
192
|
+
* would let dismissing upstream #N hide the fork's own #N too. Rows written
|
|
193
|
+
* before PRs carried their repo are keyed by the workspace repo alone and
|
|
194
|
+
* still match via that fallback. */
|
|
195
|
+
function withoutDismissed(workspaceId, fullName, list) {
|
|
196
|
+
const dismissed = new Set(all("SELECT full_name, number FROM dismissed_prs WHERE workspace_id = ?", workspaceId).map((row) => `${row.full_name}#${row.number}`));
|
|
197
|
+
return list.filter((pr) => pr.state === "OPEN" || !dismissed.has(`${pr.repository?.nameWithOwner ?? fullName}#${pr.number}`));
|
|
198
|
+
}
|
|
199
|
+
//#endregion
|
|
200
|
+
//#region src/server/status.ts
|
|
201
|
+
var TTL_MS = 2e3;
|
|
202
|
+
var snapshot = null;
|
|
203
|
+
var inflight = null;
|
|
204
|
+
var snapshotGen = 0;
|
|
205
|
+
/** Drop the cached snapshot AND detach any in-flight compute — callers
|
|
206
|
+
* after an invalidation get a computation that starts from fresh state. */
|
|
207
|
+
function invalidateSnapshot() {
|
|
208
|
+
snapshot = null;
|
|
209
|
+
snapshotGen++;
|
|
210
|
+
inflight = null;
|
|
211
|
+
}
|
|
212
|
+
function statusForAll() {
|
|
213
|
+
if (snapshot && Date.now() - snapshot.at < TTL_MS) return Promise.resolve(snapshot.value);
|
|
214
|
+
if (!inflight) {
|
|
215
|
+
const gen = snapshotGen;
|
|
216
|
+
const run = computeStatus().then((value) => {
|
|
217
|
+
if (gen === snapshotGen) snapshot = {
|
|
218
|
+
at: Date.now(),
|
|
219
|
+
value
|
|
220
|
+
};
|
|
221
|
+
return value;
|
|
222
|
+
}).finally(() => {
|
|
223
|
+
if (inflight === run) inflight = null;
|
|
224
|
+
});
|
|
225
|
+
inflight = run;
|
|
226
|
+
}
|
|
227
|
+
return inflight;
|
|
228
|
+
}
|
|
229
|
+
/** Push-based freshness: while any events-bus client is connected,
|
|
230
|
+
* recompute the (shared, deduped) snapshot on a slow tick and publish it
|
|
231
|
+
* only when it actually changed — ports appearing, PR open/merge/close flips reach
|
|
232
|
+
* every client in ~15s instead of waiting out a slow poll, and idle
|
|
233
|
+
* systems push nothing at all. */
|
|
234
|
+
var WATCH_MS = 1e4;
|
|
235
|
+
/** Right after a local push, PR+check state flips within seconds — tick
|
|
236
|
+
* fast so the badge lands while it still feels immediate. */
|
|
237
|
+
var WATCH_HOT_MS = 4e3;
|
|
238
|
+
var watching = false;
|
|
239
|
+
/** Last published state per workspace, so a tick can publish the ones that
|
|
240
|
+
* actually moved. Comparing the whole snapshot instead meant one agent's
|
|
241
|
+
* commit — or any session, port or PR flip in a workspace nobody is
|
|
242
|
+
* looking at — pushed every workspace to every client, which each then
|
|
243
|
+
* re-rendered and re-fingerprinted to conclude nothing of theirs had
|
|
244
|
+
* changed. That amplification grows with the number of workspaces. */
|
|
245
|
+
var lastPushed = /* @__PURE__ */ new Map();
|
|
246
|
+
var lastJoins = -1;
|
|
247
|
+
async function watchTick() {
|
|
248
|
+
if (!subscriberCount()) return;
|
|
249
|
+
try {
|
|
250
|
+
if (await refreshPrsBatch(activeRepoTargets()).catch(() => false)) invalidateSnapshot();
|
|
251
|
+
const value = await statusForAll();
|
|
252
|
+
const joins = subscriberJoins();
|
|
253
|
+
const everything = joins !== lastJoins;
|
|
254
|
+
lastJoins = joins;
|
|
255
|
+
const changed = {};
|
|
256
|
+
for (const [id, ws] of Object.entries(value)) {
|
|
257
|
+
const json = JSON.stringify(ws);
|
|
258
|
+
if (everything || lastPushed.get(id) !== json) changed[id] = ws;
|
|
259
|
+
lastPushed.set(id, json);
|
|
260
|
+
}
|
|
261
|
+
for (const id of lastPushed.keys()) if (!(id in value)) lastPushed.delete(id);
|
|
262
|
+
if (Object.keys(changed).length) publish("status.changed", changed);
|
|
263
|
+
} catch {}
|
|
264
|
+
}
|
|
265
|
+
var watchTimer;
|
|
266
|
+
function scheduleTick(ms) {
|
|
267
|
+
clearTimeout(watchTimer);
|
|
268
|
+
watchTimer = setTimeout(tick, ms);
|
|
269
|
+
watchTimer.unref?.();
|
|
270
|
+
}
|
|
271
|
+
async function tick() {
|
|
272
|
+
await watchTick();
|
|
273
|
+
scheduleTick(inHotWindow() ? WATCH_HOT_MS : WATCH_MS);
|
|
274
|
+
}
|
|
275
|
+
/** Recompute and push right now (e.g. a local push was detected) instead
|
|
276
|
+
* of waiting out the watch tick — and drop the loop into its fast cadence
|
|
277
|
+
* (the push opened the hot window, but the pending timeout was scheduled
|
|
278
|
+
* for the slow one). */
|
|
279
|
+
function pokeStatusWatch() {
|
|
280
|
+
invalidateSnapshot();
|
|
281
|
+
watchTick().then(() => {
|
|
282
|
+
if (watching) scheduleTick(inHotWindow() ? WATCH_HOT_MS : WATCH_MS);
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
function startStatusWatch() {
|
|
286
|
+
if (watching) return;
|
|
287
|
+
watching = true;
|
|
288
|
+
scheduleTick(WATCH_MS);
|
|
289
|
+
}
|
|
290
|
+
/** Every active workspace's repos, paired with the branch that workspace
|
|
291
|
+
* works on — the batch refreshes both the recency window and the exact-head
|
|
292
|
+
* lookup for each, in one request. */
|
|
293
|
+
function activeRepoTargets() {
|
|
294
|
+
return listWorkspaces().filter((ws) => ws.status === "active").flatMap((ws) => ws.repos.map((r) => ({
|
|
295
|
+
fullName: r.full_name,
|
|
296
|
+
branch: ws.branch
|
|
297
|
+
})));
|
|
298
|
+
}
|
|
299
|
+
/** Status with PRs refetched first (throttled): a client returning to the
|
|
300
|
+
* foreground wants current PR state — merges/closes happen on GitHub and
|
|
301
|
+
* send no local signal, so without this they wait out the slow poll. */
|
|
302
|
+
async function statusForAllFresh() {
|
|
303
|
+
if (await refreshPrsBatch(activeRepoTargets(), true).catch(() => false)) invalidateSnapshot();
|
|
304
|
+
return statusForAll();
|
|
305
|
+
}
|
|
306
|
+
/** RSS here is the Node + Marko baseline (~80 MB empty, ~115 MB loaded),
|
|
307
|
+
* not a leak and not worth chasing — young-gen flags do not move it. */
|
|
308
|
+
async function computeStatus() {
|
|
309
|
+
const everyWorkspace = listWorkspaces();
|
|
310
|
+
const workspaces = everyWorkspace.filter((ws) => ws.status === "active");
|
|
311
|
+
const paths = new Map(workspaces.map((ws) => [ws.id, ws.path]));
|
|
312
|
+
const [ports, states] = await Promise.all([portsByWorkspace(paths), sessionStates()]);
|
|
313
|
+
const entries = await Promise.all(workspaces.map(async (ws) => {
|
|
314
|
+
const foreign = everyWorkspace.filter((w) => w.id !== ws.id).map((w) => w.branch);
|
|
315
|
+
const statuses = await Promise.all(ws.repos.map((repo) => repoStatus(ws, repo, foreign)));
|
|
316
|
+
return [ws.id, {
|
|
317
|
+
ports: ports.get(ws.id) || [],
|
|
318
|
+
repos: statuses,
|
|
319
|
+
...sessionCounts(ws.id, states)
|
|
320
|
+
}];
|
|
321
|
+
}));
|
|
322
|
+
return Object.fromEntries(entries);
|
|
323
|
+
}
|
|
324
|
+
async function repoStatus(ws, repo, foreign) {
|
|
325
|
+
const dir = path.join(ws.path, repo.worktree);
|
|
326
|
+
const [repoPrs, localHead] = await Promise.all([workspacePrs(repo.full_name, ws.branch, foreign, false, ws.imported_at).then((list) => withoutDismissed(ws.id, repo.full_name, list)), headOid(dir).then((h) => h.oid)]);
|
|
327
|
+
const unpushed = pushFailureFor(repo.full_name, ws.branch, foreign);
|
|
328
|
+
return {
|
|
329
|
+
full_name: repo.full_name,
|
|
330
|
+
worktree: repo.worktree,
|
|
331
|
+
...localHead && { localHead },
|
|
332
|
+
...unpushed && { unpushed },
|
|
333
|
+
prs: repoPrs
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
function sessionCounts(workspaceId, states) {
|
|
337
|
+
const sessions = listSessions(workspaceId).map((s) => ({
|
|
338
|
+
id: s.id,
|
|
339
|
+
agent: s.agent,
|
|
340
|
+
title: s.title,
|
|
341
|
+
state: states[s.id] || { alive: false }
|
|
342
|
+
}));
|
|
343
|
+
const live = sessions.map((s) => s.state).filter((state) => !!state.alive);
|
|
344
|
+
return {
|
|
345
|
+
sessions,
|
|
346
|
+
agents: live.length,
|
|
347
|
+
working: live.filter((state) => state.phase === "working").length,
|
|
348
|
+
waiting: live.filter((state) => state.phase === "waiting").length
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
//#endregion
|
|
352
|
+
export { statusForAllFresh as a, refreshPrsBatch as c, statusForAll as i, workspacePrs as l, pokeStatusWatch as n, dismissPr as o, startStatusWatch as r, notePushActivity as s, activeRepoTargets as t };
|
|
@@ -9,7 +9,8 @@ import { promisify } from "node:util";
|
|
|
9
9
|
import { DatabaseSync } from "node:sqlite";
|
|
10
10
|
import { createHash } from "node:crypto";
|
|
11
11
|
//#region src/server/config.ts
|
|
12
|
-
var
|
|
12
|
+
var rawHome = os.homedir();
|
|
13
|
+
var home$1 = rawHome && rawHome !== "undefined" && rawHome !== "null" ? rawHome : "";
|
|
13
14
|
var config = {
|
|
14
15
|
/** Root directory containing all workspaces. */
|
|
15
16
|
workRoot: process.env.WORK_ROOT || path.join(home$1, "work"),
|
|
@@ -81,6 +82,7 @@ function utf8Locale(env) {
|
|
|
81
82
|
}
|
|
82
83
|
//#endregion
|
|
83
84
|
//#region src/server/db.ts
|
|
85
|
+
if (!path.isAbsolute(config.dataDir)) throw new Error(`data dir must be absolute, got "${config.dataDir}" — check WORK_DATA_DIR and $HOME`);
|
|
84
86
|
var db = new DatabaseSync(path.join(config.dataDir, "work.db"));
|
|
85
87
|
db.exec("PRAGMA busy_timeout = 5000");
|
|
86
88
|
function all(sql, ...params) {
|
|
@@ -165,6 +167,9 @@ function ensureColumn(table, column, decl) {
|
|
|
165
167
|
}
|
|
166
168
|
ensureColumn("review_comments", "head", "TEXT");
|
|
167
169
|
ensureColumn("review_comments", "snippet", "TEXT");
|
|
170
|
+
ensureColumn("workspaces", "materialized", "INTEGER NOT NULL DEFAULT 1");
|
|
171
|
+
ensureColumn("workspaces", "origin_branch", "TEXT");
|
|
172
|
+
ensureColumn("workspaces", "imported_at", "TEXT");
|
|
168
173
|
//#endregion
|
|
169
174
|
//#region lib/setup/agents.json
|
|
170
175
|
var agents_default = [
|
|
@@ -6551,7 +6556,7 @@ function publishChange(sessionId) {
|
|
|
6551
6556
|
const row = get("SELECT workspace_id FROM sessions WHERE id = ?", sessionId);
|
|
6552
6557
|
if (row?.workspace_id) {
|
|
6553
6558
|
const workspaceId = row.workspace_id;
|
|
6554
|
-
import("./
|
|
6559
|
+
import("./_B1lVb01g.js").then((m) => m.notifySessionsChanged(workspaceId));
|
|
6555
6560
|
return;
|
|
6556
6561
|
}
|
|
6557
6562
|
publish("sessions.changed");
|
|
@@ -8213,4 +8218,4 @@ function sleep(ms) {
|
|
|
8213
8218
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
8214
8219
|
}
|
|
8215
8220
|
//#endregion
|
|
8216
|
-
export { setSetting as $, setScrapedPhase as A, saveSubscription as B, agentBadge as C, agentMeta as D, agentLabel as E, manifest as F, agentChoices as G, subscribe as H, normalizeAccent as I, enabledAgents as J, allPrefs as K, setInstance as L, ACCENT_RE as M, getInstance as N, clearAgentPhase as O, iconSvg as P, setPref as Q, deleteSubscription as R, blankRow as S, agentFromCommand as T, subscriberCount as U, publish as V, subscriberJoins as W, preferredAgent as X, getSetting as Y, setDisabledAgents as Z, tmuxName as _,
|
|
8221
|
+
export { setSetting as $, setScrapedPhase as A, saveSubscription as B, agentBadge as C, agentMeta as D, agentLabel as E, manifest as F, agentChoices as G, subscribe as H, normalizeAccent as I, enabledAgents as J, allPrefs as K, setInstance as L, ACCENT_RE as M, getInstance as N, clearAgentPhase as O, iconSvg as P, setPref as Q, deleteSubscription as R, blankRow as S, agentFromCommand as T, subscriberCount as U, publish as V, subscriberJoins as W, preferredAgent as X, getSetting as Y, setDisabledAgents as Z, tmuxName as _, git as _t, ensureTmuxServer as a, which as at, readHookPayload as b, config as bt, killWorkspaceSessions as c, agentById as ct, newSessionArgs as d, all as dt, discoverAgents as et, notifySessionsChanged as f, db as ft, sessionStates as g, gh as gt, sendToSession as h, TMUX_SOCKET as ht, disposeSessions as i, setupPath as it, setSessionViewers as j, setAgentPhase as k, listSessions as l, agentLabel$1 as lt, renameSession as m, workspacePath as mt, clearTmuxStarted as n, ghKnownHosts as nt, getSession as o, DEFAULT_GITHUB_HOST as ot, panePids as p, get as pt, disabledAgents as q, createSession as r, miseVersions as rt, killSession as s, TOOLS as st, cleanEnv as t, doctor as tt, markTmuxStarted as u, toolById as ut, tmuxWasStarted as v, run$1 as vt, agentFamily as w, reportsWorking as x, AGENTS as y, tmux as yt, pushPublicKey as z };
|