@dylanpiercey/work 0.0.39 → 0.0.40
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 +11 -1
- package/bin/work.mjs +76 -1
- package/dist/index.mjs +1101 -400
- package/dist/public/assets/{_D2YiTEdV2.js → _-KsWGHKz2.js} +2 -2
- package/dist/public/assets/{_D2YiTEdV2.js.map → _-KsWGHKz2.js.map} +1 -1
- package/dist/public/assets/{_D2ch0L3l2.js → _3VenI2OT2.js} +2 -2
- package/dist/public/assets/{_D2ch0L3l2.js.map → _3VenI2OT2.js.map} +1 -1
- package/dist/public/assets/{_CM1Bz2e2.js → _8DPiXP2D.js} +2 -2
- package/dist/public/assets/{_CM1Bz2e2.js.map → _8DPiXP2D.js.map} +1 -1
- package/dist/public/assets/{_CXeLdopD2.js → _8UwDOo_Z2.js} +2 -2
- package/dist/public/assets/{_CXeLdopD2.js.map → _8UwDOo_Z2.js.map} +1 -1
- package/dist/public/assets/{_aF_XxRRK.js → _B0ILW1ln.js} +2 -2
- package/dist/public/assets/{_aF_XxRRK.js.map → _B0ILW1ln.js.map} +1 -1
- package/dist/public/assets/{_bcyfHqN_2.js → _B7cE3DDh2.js} +2 -2
- package/dist/public/assets/{_bcyfHqN_2.js.map → _B7cE3DDh2.js.map} +1 -1
- package/dist/public/assets/{_CR7soDA62.js → _B8CG1lYk2.js} +2 -2
- package/dist/public/assets/{_CR7soDA62.js.map → _B8CG1lYk2.js.map} +1 -1
- package/dist/public/assets/{_frxegHGP.js → _BFoRA3M-.js} +2 -2
- package/dist/public/assets/{_frxegHGP.js.map → _BFoRA3M-.js.map} +1 -1
- package/dist/public/assets/{_BlBppazN.js → _BHNTdpyr.js} +2 -2
- package/dist/public/assets/{_BlBppazN.js.map → _BHNTdpyr.js.map} +1 -1
- package/dist/public/assets/{_DIhu80mU.js → _BJLP6wPD.js} +2 -2
- package/dist/public/assets/{_DIhu80mU.js.map → _BJLP6wPD.js.map} +1 -1
- package/dist/public/assets/{_Cry0Vu092.js → _BKoDBxkc2.js} +2 -2
- package/dist/public/assets/{_Cry0Vu092.js.map → _BKoDBxkc2.js.map} +1 -1
- package/dist/public/assets/{_DzkSj4zS2.js → _BPQMLvu02.js} +2 -2
- package/dist/public/assets/{_DzkSj4zS2.js.map → _BPQMLvu02.js.map} +1 -1
- package/dist/public/assets/{_Dlge38I0.js → _BTgtIJbs.js} +2 -2
- package/dist/public/assets/{_Dlge38I0.js.map → _BTgtIJbs.js.map} +1 -1
- package/dist/public/assets/{_B0tTvCKz.js → _BVhbSv_7.js} +2 -2
- package/dist/public/assets/{_B0tTvCKz.js.map → _BVhbSv_7.js.map} +1 -1
- package/dist/public/assets/{_BpjzFBgX.js → _BXFyaVzV.js} +2 -2
- package/dist/public/assets/{_BpjzFBgX.js.map → _BXFyaVzV.js.map} +1 -1
- package/dist/public/assets/{_DrAyvf042.js → _Ba56VGPa2.js} +2 -2
- package/dist/public/assets/{_DrAyvf042.js.map → _Ba56VGPa2.js.map} +1 -1
- package/dist/public/assets/{_Bq_UbhoI2.js → _BbczFSm62.js} +2 -2
- package/dist/public/assets/{_Bq_UbhoI2.js.map → _BbczFSm62.js.map} +1 -1
- package/dist/public/assets/{_B222bJOA.js → _BdxRwSdd.js} +2 -2
- package/dist/public/assets/{_B222bJOA.js.map → _BdxRwSdd.js.map} +1 -1
- package/dist/public/assets/{_DpZRF37u.js → _BgyAIeMk.js} +2 -2
- package/dist/public/assets/{_DpZRF37u.js.map → _BgyAIeMk.js.map} +1 -1
- package/dist/public/assets/{_Biu1sMqL2.js → _BjYoD_6z2.js} +2 -2
- package/dist/public/assets/{_Biu1sMqL2.js.map → _BjYoD_6z2.js.map} +1 -1
- package/dist/public/assets/{_yNCqh4w6.js → _BlnfI-cd.js} +2 -2
- package/dist/public/assets/{_yNCqh4w6.js.map → _BlnfI-cd.js.map} +1 -1
- package/dist/public/assets/{_BTD-E3MH.js → _Bm15UJ5r.js} +2 -2
- package/dist/public/assets/{_BTD-E3MH.js.map → _Bm15UJ5r.js.map} +1 -1
- package/dist/public/assets/{_Dq_5FFld.js → _BmY-aR2i.js} +2 -2
- package/dist/public/assets/{_Dq_5FFld.js.map → _BmY-aR2i.js.map} +1 -1
- package/dist/public/assets/{_CfjmjCpz2.js → _Bq9rbiCa2.js} +2 -2
- package/dist/public/assets/{_CfjmjCpz2.js.map → _Bq9rbiCa2.js.map} +1 -1
- package/dist/public/assets/{_KoAN5c4U.js → _Br2uo0OK.js} +2 -2
- package/dist/public/assets/{_KoAN5c4U.js.map → _Br2uo0OK.js.map} +1 -1
- package/dist/public/assets/{_DN7QgLB-.js → _Brtx9zLF.js} +2 -2
- package/dist/public/assets/{_DN7QgLB-.js.map → _Brtx9zLF.js.map} +1 -1
- package/dist/public/assets/{_DZOjtuBx.js → _BtnmnAxJ.js} +2 -2
- package/dist/public/assets/{_DZOjtuBx.js.map → _BtnmnAxJ.js.map} +1 -1
- package/dist/public/assets/{_RKCdcM6s.js → _Bv_RWYiQ.js} +2 -2
- package/dist/public/assets/{_RKCdcM6s.js.map → _Bv_RWYiQ.js.map} +1 -1
- package/dist/public/assets/{_C9FF4Nwt2.js → _BvtYDSuT2.js} +2 -2
- package/dist/public/assets/{_C9FF4Nwt2.js.map → _BvtYDSuT2.js.map} +1 -1
- package/dist/public/assets/{_CGlduZ09.js → _C83jn7M7.js} +2 -2
- package/dist/public/assets/{_CGlduZ09.js.map → _C83jn7M7.js.map} +1 -1
- package/dist/public/assets/{_Bn3jsc1x2.js → _CA4_OXC62.js} +2 -2
- package/dist/public/assets/{_Bn3jsc1x2.js.map → _CA4_OXC62.js.map} +1 -1
- package/dist/public/assets/{_CudIJ9N1.js → _CEr-0D0d.js} +2 -2
- package/dist/public/assets/{_CudIJ9N1.js.map → _CEr-0D0d.js.map} +1 -1
- package/dist/public/assets/{_3_h0JIqF2.js → _CGlOgonA2.js} +2 -2
- package/dist/public/assets/{_3_h0JIqF2.js.map → _CGlOgonA2.js.map} +1 -1
- package/dist/public/assets/{_BWmXhThI.js → _CLJ7h8rZ.js} +2 -2
- package/dist/public/assets/{_BWmXhThI.js.map → _CLJ7h8rZ.js.map} +1 -1
- package/dist/public/assets/{_WOCAvL642.js → _CV6LlXY32.js} +2 -2
- package/dist/public/assets/{_WOCAvL642.js.map → _CV6LlXY32.js.map} +1 -1
- package/dist/public/assets/{_B9ZTM6vy.js → _CVFOAkWc.js} +2 -2
- package/dist/public/assets/{_B9ZTM6vy.js.map → _CVFOAkWc.js.map} +1 -1
- package/dist/public/assets/{_BwHPDQ2K2.js → _CVgZFxTy2.js} +2 -2
- package/dist/public/assets/{_BwHPDQ2K2.js.map → _CVgZFxTy2.js.map} +1 -1
- package/dist/public/assets/{__dMnQCKa.js → _CWG8S2bO.js} +2 -2
- package/dist/public/assets/{__dMnQCKa.js.map → _CWG8S2bO.js.map} +1 -1
- package/dist/public/assets/{_8FQvJvvC.js → _CX2FR9en.js} +2 -2
- package/dist/public/assets/{_8FQvJvvC.js.map → _CX2FR9en.js.map} +1 -1
- package/dist/public/assets/{_CN_uVutc.js → _CcyXwmyV.js} +2 -2
- package/dist/public/assets/{_CN_uVutc.js.map → _CcyXwmyV.js.map} +1 -1
- package/dist/public/assets/{_CWq_CViy.js → _CfNBAgk5.js} +2 -2
- package/dist/public/assets/{_CWq_CViy.js.map → _CfNBAgk5.js.map} +1 -1
- package/dist/public/assets/{_0YVFvNq7.js → _CmH32z5I.js} +2 -2
- package/dist/public/assets/{_0YVFvNq7.js.map → _CmH32z5I.js.map} +1 -1
- package/dist/public/assets/{_D51cBuRP.js → _Cn-JhCBl.js} +2 -2
- package/dist/public/assets/{_D51cBuRP.js.map → _Cn-JhCBl.js.map} +1 -1
- package/dist/public/assets/{_CGMrqKQx.js → _Cn880iWo.js} +2 -2
- package/dist/public/assets/{_CGMrqKQx.js.map → _Cn880iWo.js.map} +1 -1
- package/dist/public/assets/{_CFFd0jR-2.js → _CpelmBB72.js} +2 -2
- package/dist/public/assets/{_CFFd0jR-2.js.map → _CpelmBB72.js.map} +1 -1
- package/dist/public/assets/{_zW4ABdBd.js → _CqS9_RIm.js} +2 -2
- package/dist/public/assets/{_zW4ABdBd.js.map → _CqS9_RIm.js.map} +1 -1
- package/dist/public/assets/{_B-8ckAju2.js → _Ct5nAVXE2.js} +2 -2
- package/dist/public/assets/{_B-8ckAju2.js.map → _Ct5nAVXE2.js.map} +1 -1
- package/dist/public/assets/{_D7dsIO-O2.js → _Cu-YDqqS2.js} +2 -2
- package/dist/public/assets/{_D7dsIO-O2.js.map → _Cu-YDqqS2.js.map} +1 -1
- package/dist/public/assets/{_Bl7Ludpl.js → _Cw00Etn-.js} +2 -2
- package/dist/public/assets/{_Bl7Ludpl.js.map → _Cw00Etn-.js.map} +1 -1
- package/dist/public/assets/{_D79L--fl.js → _Cy0mebiK.js} +2 -2
- package/dist/public/assets/{_D79L--fl.js.map → _Cy0mebiK.js.map} +1 -1
- package/dist/public/assets/{_CUhN1PMI.js → _D1KsrNGN.js} +2 -2
- package/dist/public/assets/{_CUhN1PMI.js.map → _D1KsrNGN.js.map} +1 -1
- package/dist/public/assets/{_CsBnKH_a2.js → _D63K5MAL2.js} +2 -2
- package/dist/public/assets/{_CsBnKH_a2.js.map → _D63K5MAL2.js.map} +1 -1
- package/dist/public/assets/{_CYFv9QGU.js → _DDn1qNlx.js} +2 -2
- package/dist/public/assets/{_CYFv9QGU.js.map → _DDn1qNlx.js.map} +1 -1
- package/dist/public/assets/{_B0Zx9TVd.js → _DGWkqOrB.js} +2 -2
- package/dist/public/assets/{_B0Zx9TVd.js.map → _DGWkqOrB.js.map} +1 -1
- package/dist/public/assets/{_BQHdIsH-.js → _DIsTDKVR.js} +2 -2
- package/dist/public/assets/{_BQHdIsH-.js.map → _DIsTDKVR.js.map} +1 -1
- package/dist/public/assets/{_9mIlYM38.js → _DQ-kE1KO.js} +2 -2
- package/dist/public/assets/{_9mIlYM38.js.map → _DQ-kE1KO.js.map} +1 -1
- package/dist/public/assets/{_haaSjWYo.js → _DXPT_5Ww.js} +2 -2
- package/dist/public/assets/{_haaSjWYo.js.map → _DXPT_5Ww.js.map} +1 -1
- package/dist/public/assets/{_Dh3Zdz4W.js → _Dgbb7WCq.js} +2 -2
- package/dist/public/assets/{_Dh3Zdz4W.js.map → _Dgbb7WCq.js.map} +1 -1
- package/dist/public/assets/{_B1sHSj4w2.js → _DiGEIi7y2.js} +2 -2
- package/dist/public/assets/{_B1sHSj4w2.js.map → _DiGEIi7y2.js.map} +1 -1
- package/dist/public/assets/{_D4GRfjHF.js → _DlycnL0G.js} +2 -2
- package/dist/public/assets/{_D4GRfjHF.js.map → _DlycnL0G.js.map} +1 -1
- package/dist/public/assets/{_CVepAYMH.js → _DsnM-qIE.js} +2 -2
- package/dist/public/assets/{_CVepAYMH.js.map → _DsnM-qIE.js.map} +1 -1
- package/dist/public/assets/{_gCS79yat.js → _DvhrN_AC.js} +2 -2
- package/dist/public/assets/{_gCS79yat.js.map → _DvhrN_AC.js.map} +1 -1
- package/dist/public/assets/{_Cj248HDV.js → _Dzmzf0jy.js} +2 -2
- package/dist/public/assets/{_Cj248HDV.js.map → _Dzmzf0jy.js.map} +1 -1
- package/dist/public/assets/{_wqbV3ClO2.js → _FK3N8vMM2.js} +2 -2
- package/dist/public/assets/{_wqbV3ClO2.js.map → _FK3N8vMM2.js.map} +1 -1
- package/dist/public/assets/{_HibLhaHH.js → _Ivuhnz8D.js} +2 -2
- package/dist/public/assets/{_HibLhaHH.js.map → _Ivuhnz8D.js.map} +1 -1
- package/dist/public/assets/{_IEZe9nw42.js → _TKY_rFIy2.js} +2 -2
- package/dist/public/assets/{_IEZe9nw42.js.map → _TKY_rFIy2.js.map} +1 -1
- package/dist/public/assets/{_BWm0ZgI6.js → _UeUsduDg.js} +2 -2
- package/dist/public/assets/{_BWm0ZgI6.js.map → _UeUsduDg.js.map} +1 -1
- package/dist/public/assets/{_BCGHghp3.js → _ZG408fQc.js} +2 -2
- package/dist/public/assets/{_BCGHghp3.js.map → _ZG408fQc.js.map} +1 -1
- package/dist/public/assets/{_CF4aOEw0.js → _dpF9TA5S.js} +2 -2
- package/dist/public/assets/{_CF4aOEw0.js.map → _dpF9TA5S.js.map} +1 -1
- package/dist/public/assets/{_Cd1ynaVf.js → _fIQDai7d.js} +2 -2
- package/dist/public/assets/{_Cd1ynaVf.js.map → _fIQDai7d.js.map} +1 -1
- package/dist/public/assets/{_DpJaOsUS2.js → _irjxI44N2.js} +2 -2
- package/dist/public/assets/{_DpJaOsUS2.js.map → _irjxI44N2.js.map} +1 -1
- package/dist/public/assets/{_CuUIu7A0.js → _jifvQF0M.js} +2 -2
- package/dist/public/assets/{_CuUIu7A0.js.map → _jifvQF0M.js.map} +1 -1
- package/dist/public/assets/{_BaVw_5rb.js → _mH9R9oGB.js} +2 -2
- package/dist/public/assets/{_BaVw_5rb.js.map → _mH9R9oGB.js.map} +1 -1
- package/dist/public/assets/{_CxK19rXP.js → _pUoTA7Pg.js} +2 -2
- package/dist/public/assets/{_CxK19rXP.js.map → _pUoTA7Pg.js.map} +1 -1
- package/dist/public/assets/index--QwhN0hy.css +1 -0
- package/dist/public/assets/index-CdVBL6Kf.js +1615 -0
- package/dist/public/assets/index-CdVBL6Kf.js.map +1 -0
- package/package.json +1 -1
- package/dist/public/assets/index-BJLi-qve.css +0 -1
- package/dist/public/assets/index-YZZGnWtK.js +0 -1615
- package/dist/public/assets/index-YZZGnWtK.js.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -8,6 +8,7 @@ import { Readable } from "node:stream";
|
|
|
8
8
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
9
9
|
import fs from "node:fs";
|
|
10
10
|
import os from "node:os";
|
|
11
|
+
import { DatabaseSync } from "node:sqlite";
|
|
11
12
|
import { spawn } from "node:child_process";
|
|
12
13
|
import fsp from "node:fs/promises";
|
|
13
14
|
import crypto from "node:crypto";
|
|
@@ -4377,30 +4378,30 @@ var _layout_default = _template("a", (input) => {
|
|
|
4377
4378
|
_trailers("</body></html>");
|
|
4378
4379
|
_serialize_if($scope0_reason, 0) && writeScope($scope0_id, {});
|
|
4379
4380
|
}, 1);
|
|
4380
|
-
var page_module_default = { boot: "
|
|
4381
|
+
var page_module_default = { boot: "_a" };
|
|
4381
4382
|
var ui_module_default = {
|
|
4382
|
-
icon: "
|
|
4383
|
-
btn: "
|
|
4384
|
-
primary: "
|
|
4385
|
-
danger: "
|
|
4386
|
-
armed: "
|
|
4387
|
-
chip: "
|
|
4388
|
-
lane: "
|
|
4389
|
-
pr: "
|
|
4390
|
-
draft: "
|
|
4391
|
-
dim: "
|
|
4392
|
-
mono: "
|
|
4393
|
-
spacer: "
|
|
4394
|
-
dot: "
|
|
4395
|
-
working: "
|
|
4396
|
-
waiting: "
|
|
4397
|
-
idle: "
|
|
4398
|
-
off: "
|
|
4399
|
-
splitBtn: "
|
|
4400
|
-
splitPrimary: "_s
|
|
4401
|
-
splitGrow: "
|
|
4402
|
-
spin: "
|
|
4403
|
-
workSpin: "
|
|
4383
|
+
icon: "_b",
|
|
4384
|
+
btn: "_c",
|
|
4385
|
+
primary: "_d",
|
|
4386
|
+
danger: "_e",
|
|
4387
|
+
armed: "_f",
|
|
4388
|
+
chip: "_g",
|
|
4389
|
+
lane: "_h",
|
|
4390
|
+
pr: "_i",
|
|
4391
|
+
draft: "_j",
|
|
4392
|
+
dim: "_k",
|
|
4393
|
+
mono: "_l",
|
|
4394
|
+
spacer: "_m",
|
|
4395
|
+
dot: "_n",
|
|
4396
|
+
working: "_o",
|
|
4397
|
+
waiting: "_p",
|
|
4398
|
+
idle: "_q",
|
|
4399
|
+
off: "_r",
|
|
4400
|
+
splitBtn: "_s",
|
|
4401
|
+
splitPrimary: "_t _s",
|
|
4402
|
+
splitGrow: "_u",
|
|
4403
|
+
spin: "_v",
|
|
4404
|
+
workSpin: "_w"
|
|
4404
4405
|
};
|
|
4405
4406
|
var page_boot_module_default = { root: "_x" };
|
|
4406
4407
|
var bus = new EventTarget();
|
|
@@ -4453,7 +4454,7 @@ var toast_module_default = {
|
|
|
4453
4454
|
toastBody: "_F",
|
|
4454
4455
|
toastContent: "_G",
|
|
4455
4456
|
toastActions: "_H",
|
|
4456
|
-
toastDismiss: "_I
|
|
4457
|
+
toastDismiss: "_I _eA"
|
|
4457
4458
|
};
|
|
4458
4459
|
//#endregion
|
|
4459
4460
|
//#region src/tags/toast.marko
|
|
@@ -4597,27 +4598,27 @@ function sessionPhase(state) {
|
|
|
4597
4598
|
return state?.phase === "working" ? "working" : state?.phase === "waiting" ? "waiting" : state?.alive ? "idle" : "off";
|
|
4598
4599
|
}
|
|
4599
4600
|
var palette_module_default = {
|
|
4600
|
-
paletteBackdrop: "
|
|
4601
|
-
palette: "
|
|
4602
|
-
inline: "
|
|
4603
|
-
rows: "
|
|
4604
|
-
rowWrap: "
|
|
4605
|
-
row: "
|
|
4606
|
-
rowMore: "
|
|
4607
|
-
hi: "
|
|
4608
|
-
archived: "
|
|
4609
|
-
cmdRow: "
|
|
4610
|
-
onboard: "
|
|
4611
|
-
rowName: "
|
|
4612
|
-
rowNameText: "
|
|
4613
|
-
rowStats: "
|
|
4614
|
-
open: "
|
|
4615
|
-
stat: "
|
|
4616
|
-
rowRepos: "
|
|
4617
|
-
paletteFoot: "
|
|
4618
|
-
hint: "
|
|
4619
|
-
archivedLink: "
|
|
4620
|
-
newSessionPop: "
|
|
4601
|
+
paletteBackdrop: "_R",
|
|
4602
|
+
palette: "_S",
|
|
4603
|
+
inline: "_T",
|
|
4604
|
+
rows: "_U",
|
|
4605
|
+
rowWrap: "_V",
|
|
4606
|
+
row: "_W",
|
|
4607
|
+
rowMore: "_X",
|
|
4608
|
+
hi: "_Y",
|
|
4609
|
+
archived: "_Z",
|
|
4610
|
+
cmdRow: "_0",
|
|
4611
|
+
onboard: "_1",
|
|
4612
|
+
rowName: "_2",
|
|
4613
|
+
rowNameText: "_3",
|
|
4614
|
+
rowStats: "_4",
|
|
4615
|
+
open: "_5",
|
|
4616
|
+
stat: "_6",
|
|
4617
|
+
rowRepos: "_7",
|
|
4618
|
+
paletteFoot: "_8",
|
|
4619
|
+
hint: "_9",
|
|
4620
|
+
archivedLink: "__",
|
|
4621
|
+
newSessionPop: "_ba"
|
|
4621
4622
|
};
|
|
4622
4623
|
//#endregion
|
|
4623
4624
|
//#region src/tags/icons/icon-base.marko
|
|
@@ -5017,43 +5018,43 @@ var palette_default = _template("o", (input) => {
|
|
|
5017
5018
|
_resume_branch($scope0_id);
|
|
5018
5019
|
});
|
|
5019
5020
|
var new_workspace_module_default = {
|
|
5020
|
-
content: "
|
|
5021
|
-
actions: "
|
|
5022
|
-
barPrimary: "
|
|
5023
|
-
iconBtn: "
|
|
5024
|
-
spinning: "
|
|
5025
|
-
field: "
|
|
5026
|
-
section: "
|
|
5027
|
-
reposHead: "
|
|
5028
|
-
curRepos: "
|
|
5029
|
-
curRepo: "
|
|
5030
|
-
curFull: "
|
|
5031
|
-
curBase: "
|
|
5032
|
-
curRemove: "
|
|
5033
|
-
emptyNote: "
|
|
5034
|
-
steps: "
|
|
5035
|
-
active: "
|
|
5036
|
-
stepDone: "
|
|
5037
|
-
archived: "
|
|
5038
|
-
archivedCount: "
|
|
5039
|
-
archivedHint: "
|
|
5040
|
-
archivedList: "
|
|
5041
|
-
archivedCard: "
|
|
5042
|
-
archivedMain: "
|
|
5043
|
-
archivedName: "
|
|
5044
|
-
archivedMeta: "
|
|
5045
|
-
restoreBtn: "
|
|
5046
|
-
btn: "
|
|
5021
|
+
content: "_bj _bd",
|
|
5022
|
+
actions: "_bk",
|
|
5023
|
+
barPrimary: "_bl",
|
|
5024
|
+
iconBtn: "_bm _eA",
|
|
5025
|
+
spinning: "_bn _eB",
|
|
5026
|
+
field: "_bo",
|
|
5027
|
+
section: "_bp",
|
|
5028
|
+
reposHead: "_bq",
|
|
5029
|
+
curRepos: "_br",
|
|
5030
|
+
curRepo: "_bs",
|
|
5031
|
+
curFull: "_bt",
|
|
5032
|
+
curBase: "_bu",
|
|
5033
|
+
curRemove: "_bv",
|
|
5034
|
+
emptyNote: "_bw",
|
|
5035
|
+
steps: "_bx",
|
|
5036
|
+
active: "_by",
|
|
5037
|
+
stepDone: "_bz",
|
|
5038
|
+
archived: "_bA",
|
|
5039
|
+
archivedCount: "_bB",
|
|
5040
|
+
archivedHint: "_bC",
|
|
5041
|
+
archivedList: "_bD",
|
|
5042
|
+
archivedCard: "_bE",
|
|
5043
|
+
archivedMain: "_bF",
|
|
5044
|
+
archivedName: "_bG",
|
|
5045
|
+
archivedMeta: "_bH",
|
|
5046
|
+
restoreBtn: "_bI",
|
|
5047
|
+
btn: "_bJ"
|
|
5047
5048
|
};
|
|
5048
5049
|
var page_shell_module_default = {
|
|
5049
|
-
page: "
|
|
5050
|
-
body: "
|
|
5051
|
-
content: "
|
|
5052
|
-
contentWide: "
|
|
5053
|
-
pageHead: "
|
|
5054
|
-
pageHeadText: "
|
|
5055
|
-
pageMeta: "
|
|
5056
|
-
pageHeadAside: "
|
|
5050
|
+
page: "_bb",
|
|
5051
|
+
body: "_bc",
|
|
5052
|
+
content: "_bd",
|
|
5053
|
+
contentWide: "_be",
|
|
5054
|
+
pageHead: "_bf",
|
|
5055
|
+
pageHeadText: "_bg",
|
|
5056
|
+
pageMeta: "_bh",
|
|
5057
|
+
pageHeadAside: "_bi"
|
|
5057
5058
|
};
|
|
5058
5059
|
//#endregion
|
|
5059
5060
|
//#region src/tags/icons/icon-refresh.marko
|
|
@@ -5073,18 +5074,18 @@ var icon_refresh_default = _template("O", (input) => {
|
|
|
5073
5074
|
_serialize_if($scope0_reason, 0) && writeScope($scope0_id, { a: _existing_scope($childScope) });
|
|
5074
5075
|
});
|
|
5075
5076
|
var repo_picker_module_default = {
|
|
5076
|
-
addRepo: "
|
|
5077
|
-
repoResults: "
|
|
5078
|
-
resultWrap: "
|
|
5079
|
-
hi: "
|
|
5080
|
-
resultRow: "
|
|
5081
|
-
resultBranch: "
|
|
5082
|
-
on: "
|
|
5083
|
-
branchPick: "
|
|
5084
|
-
branchList: "
|
|
5085
|
-
resultPlus: "
|
|
5086
|
-
repoName: "
|
|
5087
|
-
emptyNote: "
|
|
5077
|
+
addRepo: "_bK",
|
|
5078
|
+
repoResults: "_bL",
|
|
5079
|
+
resultWrap: "_bM",
|
|
5080
|
+
hi: "_bN",
|
|
5081
|
+
resultRow: "_bO",
|
|
5082
|
+
resultBranch: "_bP",
|
|
5083
|
+
on: "_bQ",
|
|
5084
|
+
branchPick: "_bR",
|
|
5085
|
+
branchList: "_bS",
|
|
5086
|
+
resultPlus: "_bT",
|
|
5087
|
+
repoName: "_bU",
|
|
5088
|
+
emptyNote: "_bV"
|
|
5088
5089
|
};
|
|
5089
5090
|
//#endregion
|
|
5090
5091
|
//#region src/tags/repo-picker.marko
|
|
@@ -5630,23 +5631,23 @@ function vapidKey(base64) {
|
|
|
5630
5631
|
return Uint8Array.from(raw, (c) => c.charCodeAt(0));
|
|
5631
5632
|
}
|
|
5632
5633
|
var side_nav_module_default = {
|
|
5633
|
-
iconBtn: "
|
|
5634
|
-
spinning: "
|
|
5635
|
-
navToggle: "
|
|
5636
|
-
notifyBtn: "
|
|
5637
|
-
sideNav: "
|
|
5638
|
-
pageHead: "
|
|
5639
|
-
pageHeadActions: "
|
|
5640
|
-
sectionLabel: "
|
|
5641
|
-
newSpaceBtn: "
|
|
5642
|
-
page: "
|
|
5643
|
-
sideList: "
|
|
5644
|
-
sideRail: "
|
|
5645
|
-
sideFoot: "
|
|
5646
|
-
footSpacer: "
|
|
5647
|
-
on: "
|
|
5648
|
-
closed: "
|
|
5649
|
-
railPop: "
|
|
5634
|
+
iconBtn: "_dJ _eA",
|
|
5635
|
+
spinning: "_dK _eB",
|
|
5636
|
+
navToggle: "_dL _eA",
|
|
5637
|
+
notifyBtn: "_dM _eA",
|
|
5638
|
+
sideNav: "_dN",
|
|
5639
|
+
pageHead: "_dO",
|
|
5640
|
+
pageHeadActions: "_dP",
|
|
5641
|
+
sectionLabel: "_dQ",
|
|
5642
|
+
newSpaceBtn: "_dR",
|
|
5643
|
+
page: "_dS",
|
|
5644
|
+
sideList: "_dT",
|
|
5645
|
+
sideRail: "_dU",
|
|
5646
|
+
sideFoot: "_dV",
|
|
5647
|
+
footSpacer: "_dW",
|
|
5648
|
+
on: "_dX",
|
|
5649
|
+
closed: "_dY",
|
|
5650
|
+
railPop: "_dZ"
|
|
5650
5651
|
};
|
|
5651
5652
|
_template("C", (input) => {
|
|
5652
5653
|
const $scope0_reason = _scope_reason(), $sg__input_size__OR__input_class = _serialize_guard($scope0_reason, 0);
|
|
@@ -5681,33 +5682,33 @@ var icon_gauge_default = _template("J", (input) => {
|
|
|
5681
5682
|
_serialize_if($scope0_reason, 0) && writeScope($scope0_id, { a: _existing_scope($childScope) });
|
|
5682
5683
|
});
|
|
5683
5684
|
var side_nav_item_module_default = {
|
|
5684
|
-
railBtn: "
|
|
5685
|
-
current: "
|
|
5686
|
-
railDot: "
|
|
5687
|
-
ws: "
|
|
5688
|
-
railPopWs: "
|
|
5689
|
-
wsRow: "
|
|
5690
|
-
wsBtn: "
|
|
5691
|
-
wsActions: "
|
|
5692
|
-
rowIcon: "
|
|
5693
|
-
on: "
|
|
5694
|
-
newSessionPop: "
|
|
5695
|
-
wsText: "
|
|
5696
|
-
wsName: "
|
|
5697
|
-
wsMeta: "
|
|
5698
|
-
wsOpenHint: "
|
|
5699
|
-
statusDot: "
|
|
5700
|
-
pageCard: "
|
|
5701
|
-
sessTitle: "
|
|
5702
|
-
sessActions: "
|
|
5703
|
-
sessRenameDot: "
|
|
5704
|
-
sessRename: "
|
|
5705
|
-
close: "
|
|
5706
|
-
sess: "
|
|
5707
|
-
armed: "
|
|
5708
|
-
sessions: "
|
|
5709
|
-
sessBtn: "
|
|
5710
|
-
sessIcon: "
|
|
5685
|
+
railBtn: "_e2 _eA",
|
|
5686
|
+
current: "_e3",
|
|
5687
|
+
railDot: "_e4",
|
|
5688
|
+
ws: "_e5",
|
|
5689
|
+
railPopWs: "_e6",
|
|
5690
|
+
wsRow: "_e7",
|
|
5691
|
+
wsBtn: "_e8",
|
|
5692
|
+
wsActions: "_e9",
|
|
5693
|
+
rowIcon: "_e_",
|
|
5694
|
+
on: "_fa",
|
|
5695
|
+
newSessionPop: "_fb",
|
|
5696
|
+
wsText: "_fc",
|
|
5697
|
+
wsName: "_fd",
|
|
5698
|
+
wsMeta: "_fe",
|
|
5699
|
+
wsOpenHint: "_ff",
|
|
5700
|
+
statusDot: "_fg",
|
|
5701
|
+
pageCard: "_fh",
|
|
5702
|
+
sessTitle: "_fi",
|
|
5703
|
+
sessActions: "_fj",
|
|
5704
|
+
sessRenameDot: "_fk",
|
|
5705
|
+
sessRename: "_fl",
|
|
5706
|
+
close: "_fm",
|
|
5707
|
+
sess: "_fn",
|
|
5708
|
+
armed: "_fo",
|
|
5709
|
+
sessions: "_fp",
|
|
5710
|
+
sessBtn: "_fq",
|
|
5711
|
+
sessIcon: "_fr"
|
|
5711
5712
|
};
|
|
5712
5713
|
//#endregion
|
|
5713
5714
|
//#region src/tags/icons/icon-edit.marko
|
|
@@ -5727,16 +5728,16 @@ var icon_edit_default = _template("H", (input) => {
|
|
|
5727
5728
|
_serialize_if($scope0_reason, 0) && writeScope($scope0_id, { a: _existing_scope($childScope) });
|
|
5728
5729
|
});
|
|
5729
5730
|
var side_nav_chips_module_default = {
|
|
5730
|
-
sideChips: "
|
|
5731
|
-
prChip: "
|
|
5732
|
-
portChip: "
|
|
5733
|
-
seg: "
|
|
5734
|
-
portOpen: "
|
|
5735
|
-
action: "
|
|
5736
|
-
dismiss: "
|
|
5737
|
-
armed: "
|
|
5738
|
-
merged: "
|
|
5739
|
-
closed: "
|
|
5731
|
+
sideChips: "_fC",
|
|
5732
|
+
prChip: "_fD",
|
|
5733
|
+
portChip: "_fE",
|
|
5734
|
+
seg: "_fF",
|
|
5735
|
+
portOpen: "_fG",
|
|
5736
|
+
action: "_fH",
|
|
5737
|
+
dismiss: "_fI",
|
|
5738
|
+
armed: "_fJ",
|
|
5739
|
+
merged: "_fK",
|
|
5740
|
+
closed: "_fL"
|
|
5740
5741
|
};
|
|
5741
5742
|
//#endregion
|
|
5742
5743
|
//#region src/tags/icons/icon-xmark.marko
|
|
@@ -6913,61 +6914,61 @@ function treeRows(files) {
|
|
|
6913
6914
|
return rows;
|
|
6914
6915
|
}
|
|
6915
6916
|
var diff_view_module_default = {
|
|
6916
|
-
iconBtn: "
|
|
6917
|
-
spinning: "
|
|
6918
|
-
diffView: "
|
|
6919
|
-
treeToggle: "
|
|
6920
|
-
diffTools: "
|
|
6921
|
-
on: "
|
|
6922
|
-
diffCol: "
|
|
6923
|
-
chrome: "
|
|
6924
|
-
backBtn: "
|
|
6925
|
-
headText: "
|
|
6926
|
-
pageTitle: "
|
|
6927
|
-
headWithSend: "
|
|
6928
|
-
toolCtrl: "
|
|
6929
|
-
findBtn: "
|
|
6930
|
-
findSlot: "
|
|
6931
|
-
findSlotClosed: "
|
|
6932
|
-
toolsFind: "
|
|
6933
|
-
fileFindActive: "
|
|
6934
|
-
pathFindActive: "
|
|
6935
|
-
diffMain: "
|
|
6936
|
-
toastMeta: "
|
|
6937
|
-
diffHead: "
|
|
6938
|
-
filterSlot: "
|
|
6939
|
-
diffStats: "
|
|
6940
|
-
statAdd: "
|
|
6941
|
-
statDel: "
|
|
6942
|
-
statEmpty: "
|
|
6943
|
-
statSep: "
|
|
6944
|
-
scope: "
|
|
6945
|
-
scopeOpt: "
|
|
6946
|
-
scopeOn: "
|
|
6947
|
-
scopeChip: "
|
|
6948
|
-
repoSection: "
|
|
6949
|
-
repoSep: "
|
|
6950
|
-
repoSepCollapsed: "
|
|
6951
|
-
repoWorktree: "
|
|
6952
|
-
repoState: "
|
|
6953
|
-
repoTitle: "
|
|
6954
|
-
repoMeta: "
|
|
6955
|
-
compare: "
|
|
6956
|
-
compareBase: "
|
|
6957
|
-
compareHead: "
|
|
6958
|
-
compareVs: "
|
|
6959
|
-
compareTopic: "
|
|
6960
|
-
files: "
|
|
6961
|
-
file: "
|
|
6962
|
-
diffWait: "
|
|
6963
|
-
treeChev: "
|
|
6964
|
-
treeChevOpen: "
|
|
6965
|
-
treeChevBusy: "
|
|
6966
|
-
status: "
|
|
6967
|
-
path: "
|
|
6968
|
-
centerPad: "
|
|
6969
|
-
filesBtn: "
|
|
6970
|
-
diffPad: "
|
|
6917
|
+
iconBtn: "_cR _eA",
|
|
6918
|
+
spinning: "_cS _eB",
|
|
6919
|
+
diffView: "_cT",
|
|
6920
|
+
treeToggle: "_cU _eA",
|
|
6921
|
+
diffTools: "_cV",
|
|
6922
|
+
on: "_cW",
|
|
6923
|
+
diffCol: "_cX",
|
|
6924
|
+
chrome: "_cY",
|
|
6925
|
+
backBtn: "_cZ",
|
|
6926
|
+
headText: "_c0",
|
|
6927
|
+
pageTitle: "_c1",
|
|
6928
|
+
headWithSend: "_c2",
|
|
6929
|
+
toolCtrl: "_c3",
|
|
6930
|
+
findBtn: "_c4",
|
|
6931
|
+
findSlot: "_c5",
|
|
6932
|
+
findSlotClosed: "_c6",
|
|
6933
|
+
toolsFind: "_c7",
|
|
6934
|
+
fileFindActive: "_c8",
|
|
6935
|
+
pathFindActive: "_c9",
|
|
6936
|
+
diffMain: "_c_",
|
|
6937
|
+
toastMeta: "_da",
|
|
6938
|
+
diffHead: "_db",
|
|
6939
|
+
filterSlot: "_dc",
|
|
6940
|
+
diffStats: "_dd",
|
|
6941
|
+
statAdd: "_de",
|
|
6942
|
+
statDel: "_df",
|
|
6943
|
+
statEmpty: "_dg",
|
|
6944
|
+
statSep: "_dh",
|
|
6945
|
+
scope: "_di",
|
|
6946
|
+
scopeOpt: "_dj",
|
|
6947
|
+
scopeOn: "_dk",
|
|
6948
|
+
scopeChip: "_dl",
|
|
6949
|
+
repoSection: "_dm",
|
|
6950
|
+
repoSep: "_dn",
|
|
6951
|
+
repoSepCollapsed: "_do",
|
|
6952
|
+
repoWorktree: "_dp _l",
|
|
6953
|
+
repoState: "_dq",
|
|
6954
|
+
repoTitle: "_dr _k",
|
|
6955
|
+
repoMeta: "_ds",
|
|
6956
|
+
compare: "_dt",
|
|
6957
|
+
compareBase: "_du",
|
|
6958
|
+
compareHead: "_dv",
|
|
6959
|
+
compareVs: "_dw",
|
|
6960
|
+
compareTopic: "_dx",
|
|
6961
|
+
files: "_dy",
|
|
6962
|
+
file: "_dz",
|
|
6963
|
+
diffWait: "_dA",
|
|
6964
|
+
treeChev: "_dB",
|
|
6965
|
+
treeChevOpen: "_dC",
|
|
6966
|
+
treeChevBusy: "_dD",
|
|
6967
|
+
status: "_dE",
|
|
6968
|
+
path: "_dF",
|
|
6969
|
+
centerPad: "_dG",
|
|
6970
|
+
filesBtn: "_dH",
|
|
6971
|
+
diffPad: "_dI"
|
|
6971
6972
|
};
|
|
6972
6973
|
//#endregion
|
|
6973
6974
|
//#region src/tags/icons/icon-back.marko
|
|
@@ -6987,8 +6988,8 @@ var icon_back_default = _template("A", (input) => {
|
|
|
6987
6988
|
_serialize_if($scope0_reason, 0) && writeScope($scope0_id, { a: _existing_scope($childScope) });
|
|
6988
6989
|
});
|
|
6989
6990
|
var file_filter_module_default = {
|
|
6990
|
-
wrap: "
|
|
6991
|
-
fileFilter: "
|
|
6991
|
+
wrap: "_eZ",
|
|
6992
|
+
fileFilter: "_e0"
|
|
6992
6993
|
};
|
|
6993
6994
|
//#endregion
|
|
6994
6995
|
//#region src/tags/file-filter.marko
|
|
@@ -7036,7 +7037,7 @@ var file_filter_default = _template("j", (input) => {
|
|
|
7036
7037
|
});
|
|
7037
7038
|
_resume_branch($scope0_id);
|
|
7038
7039
|
});
|
|
7039
|
-
var diff_send_module_default = { headActions: "
|
|
7040
|
+
var diff_send_module_default = { headActions: "_e1" };
|
|
7040
7041
|
//#endregion
|
|
7041
7042
|
//#region src/tags/diff-send.marko
|
|
7042
7043
|
var diff_send_default = _template("g", (input) => {
|
|
@@ -8528,17 +8529,17 @@ function clip(line, at, len) {
|
|
|
8528
8529
|
return (start > 0 ? "…" : "") + line.slice(start, end) + (end < line.length ? "…" : "");
|
|
8529
8530
|
}
|
|
8530
8531
|
var diff_find_module_default = {
|
|
8531
|
-
findBar: "
|
|
8532
|
-
closed: "
|
|
8533
|
-
findInput: "
|
|
8534
|
-
termOverlay: "
|
|
8535
|
-
count: "
|
|
8536
|
-
findIconBtn: "
|
|
8537
|
-
findWrap: "
|
|
8538
|
-
termOverlayWrap: "
|
|
8539
|
-
termKeybarWrap: "
|
|
8540
|
-
termKeybar: "
|
|
8541
|
-
termClosed: "
|
|
8532
|
+
findBar: "_eD",
|
|
8533
|
+
closed: "_eE",
|
|
8534
|
+
findInput: "_eF",
|
|
8535
|
+
termOverlay: "_eG",
|
|
8536
|
+
count: "_eH",
|
|
8537
|
+
findIconBtn: "_eI _eA",
|
|
8538
|
+
findWrap: "_eJ",
|
|
8539
|
+
termOverlayWrap: "_eK",
|
|
8540
|
+
termKeybarWrap: "_eL",
|
|
8541
|
+
termKeybar: "_eM",
|
|
8542
|
+
termClosed: "_eN"
|
|
8542
8543
|
};
|
|
8543
8544
|
//#endregion
|
|
8544
8545
|
//#region src/tags/diff-find.marko
|
|
@@ -8661,7 +8662,7 @@ var icon_search_default = _template("P", (input) => {
|
|
|
8661
8662
|
});
|
|
8662
8663
|
_serialize_if($scope0_reason, 0) && writeScope($scope0_id, { a: _existing_scope($childScope) });
|
|
8663
8664
|
});
|
|
8664
|
-
var diff_file_module_default = { diffFile: "
|
|
8665
|
+
var diff_file_module_default = { diffFile: "_eO" };
|
|
8665
8666
|
//#endregion
|
|
8666
8667
|
//#region src/tags/diff-file.marko
|
|
8667
8668
|
var diff_file_default = _template("e", (input) => {
|
|
@@ -8686,16 +8687,16 @@ var diff_file_default = _template("e", (input) => {
|
|
|
8686
8687
|
_resume_branch($scope0_id);
|
|
8687
8688
|
});
|
|
8688
8689
|
var diff_tree_module_default = {
|
|
8689
|
-
tree: "
|
|
8690
|
-
closed: "
|
|
8691
|
-
treeRepo: "
|
|
8692
|
-
treeRepoName: "
|
|
8693
|
-
treeDir: "
|
|
8694
|
-
treeFile: "
|
|
8695
|
-
treeFileName: "
|
|
8696
|
-
treeNote: "
|
|
8697
|
-
treeChev: "
|
|
8698
|
-
status: "
|
|
8690
|
+
tree: "_fs",
|
|
8691
|
+
closed: "_ft",
|
|
8692
|
+
treeRepo: "_fu",
|
|
8693
|
+
treeRepoName: "_fv",
|
|
8694
|
+
treeDir: "_fw",
|
|
8695
|
+
treeFile: "_fx",
|
|
8696
|
+
treeFileName: "_fy",
|
|
8697
|
+
treeNote: "_fz",
|
|
8698
|
+
treeChev: "_fA",
|
|
8699
|
+
status: "_fB"
|
|
8699
8700
|
};
|
|
8700
8701
|
//#endregion
|
|
8701
8702
|
//#region src/tags/diff-tree.marko
|
|
@@ -8809,8 +8810,8 @@ var diff_tree_default = _template("h", (input) => {
|
|
|
8809
8810
|
_resume_branch($scope0_id);
|
|
8810
8811
|
});
|
|
8811
8812
|
var diff_file_sheet_module_default = {
|
|
8812
|
-
iconBtn: "_eP
|
|
8813
|
-
spinning: "_eQ
|
|
8813
|
+
iconBtn: "_eP _eA",
|
|
8814
|
+
spinning: "_eQ _eB",
|
|
8814
8815
|
sheetBackdrop: "_eR",
|
|
8815
8816
|
fileSheet: "_eS",
|
|
8816
8817
|
sheetHead: "_eT",
|
|
@@ -9932,37 +9933,37 @@ var diff_view_default = _template("i", (input) => {
|
|
|
9932
9933
|
_resume_branch($scope0_id);
|
|
9933
9934
|
});
|
|
9934
9935
|
var manage_workspace_module_default = {
|
|
9935
|
-
content: "
|
|
9936
|
-
pageMeta: "
|
|
9937
|
-
wsLabel: "
|
|
9938
|
-
metaSep: "
|
|
9939
|
-
pathMeta: "
|
|
9940
|
-
statusPill: "
|
|
9941
|
-
statusOff: "
|
|
9942
|
-
progress: "
|
|
9943
|
-
section: "
|
|
9944
|
-
sectionHead: "
|
|
9945
|
-
sectionCount: "
|
|
9946
|
-
pickerWrap: "
|
|
9947
|
-
cardList: "
|
|
9948
|
-
card: "
|
|
9949
|
-
pending: "
|
|
9950
|
-
cardMain: "
|
|
9951
|
-
cardTitle: "
|
|
9952
|
-
cardMeta: "
|
|
9953
|
-
cardSub: "
|
|
9954
|
-
cardTag: "
|
|
9955
|
-
cardAction: "
|
|
9956
|
-
dangerAction: "
|
|
9957
|
-
armed: "
|
|
9958
|
-
portLink: "
|
|
9959
|
-
emptyNote: "
|
|
9960
|
-
dangerZone: "
|
|
9961
|
-
dangerRow: "
|
|
9962
|
-
dangerBtn: "
|
|
9963
|
-
dangerHint: "
|
|
9964
|
-
iconBtn: "
|
|
9965
|
-
spinning: "
|
|
9936
|
+
content: "_cm _bd",
|
|
9937
|
+
pageMeta: "_cn _bh",
|
|
9938
|
+
wsLabel: "_co",
|
|
9939
|
+
metaSep: "_cp",
|
|
9940
|
+
pathMeta: "_cq",
|
|
9941
|
+
statusPill: "_cr",
|
|
9942
|
+
statusOff: "_cs",
|
|
9943
|
+
progress: "_ct",
|
|
9944
|
+
section: "_cu",
|
|
9945
|
+
sectionHead: "_cv",
|
|
9946
|
+
sectionCount: "_cw",
|
|
9947
|
+
pickerWrap: "_cx",
|
|
9948
|
+
cardList: "_cy",
|
|
9949
|
+
card: "_cz",
|
|
9950
|
+
pending: "_cA",
|
|
9951
|
+
cardMain: "_cB",
|
|
9952
|
+
cardTitle: "_cC",
|
|
9953
|
+
cardMeta: "_cD",
|
|
9954
|
+
cardSub: "_cE",
|
|
9955
|
+
cardTag: "_cF",
|
|
9956
|
+
cardAction: "_cG",
|
|
9957
|
+
dangerAction: "_cH",
|
|
9958
|
+
armed: "_cI",
|
|
9959
|
+
portLink: "_cJ",
|
|
9960
|
+
emptyNote: "_cK",
|
|
9961
|
+
dangerZone: "_cL",
|
|
9962
|
+
dangerRow: "_cM",
|
|
9963
|
+
dangerBtn: "_cN",
|
|
9964
|
+
dangerHint: "_cO",
|
|
9965
|
+
iconBtn: "_cP _eA",
|
|
9966
|
+
spinning: "_cQ _eB"
|
|
9966
9967
|
};
|
|
9967
9968
|
//#endregion
|
|
9968
9969
|
//#region src/tags/manage-workspace.marko
|
|
@@ -10256,32 +10257,33 @@ var manage_workspace_default = _template("k", (input) => {
|
|
|
10256
10257
|
_resume_branch($scope0_id);
|
|
10257
10258
|
});
|
|
10258
10259
|
var usage_stats_module_default = {
|
|
10259
|
-
content: "
|
|
10260
|
-
iconBtn: "
|
|
10261
|
-
spinning: "
|
|
10262
|
-
refreshBtn: "
|
|
10263
|
-
note: "
|
|
10264
|
-
usageList: "
|
|
10265
|
-
usageRow: "
|
|
10266
|
-
usageName: "
|
|
10267
|
-
plan: "
|
|
10268
|
-
usageStale: "
|
|
10269
|
-
stale: "
|
|
10270
|
-
usageMeters: "
|
|
10271
|
-
|
|
10272
|
-
|
|
10273
|
-
|
|
10274
|
-
|
|
10275
|
-
|
|
10276
|
-
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
|
|
10283
|
-
|
|
10284
|
-
|
|
10260
|
+
content: "_bW _bW _be",
|
|
10261
|
+
iconBtn: "_bX _eA",
|
|
10262
|
+
spinning: "_bY _eB",
|
|
10263
|
+
refreshBtn: "_bZ",
|
|
10264
|
+
note: "_b0",
|
|
10265
|
+
usageList: "_b1",
|
|
10266
|
+
usageRow: "_b2",
|
|
10267
|
+
usageName: "_b3",
|
|
10268
|
+
plan: "_b4",
|
|
10269
|
+
usageStale: "_b5",
|
|
10270
|
+
stale: "_b6",
|
|
10271
|
+
usageMeters: "_b7",
|
|
10272
|
+
usageNote: "_b8",
|
|
10273
|
+
meter: "_b9",
|
|
10274
|
+
meterLabel: "_b_",
|
|
10275
|
+
meterTrack: "_ca",
|
|
10276
|
+
meterFill: "_cb",
|
|
10277
|
+
fillOk: "_cc",
|
|
10278
|
+
fillMid: "_cd",
|
|
10279
|
+
fillWarm: "_ce",
|
|
10280
|
+
fillHot: "_cf",
|
|
10281
|
+
meterPct: "_cg",
|
|
10282
|
+
pctOk: "_ch",
|
|
10283
|
+
pctMid: "_ci",
|
|
10284
|
+
pctWarm: "_cj",
|
|
10285
|
+
pctHot: "_ck",
|
|
10286
|
+
meterReset: "_cl"
|
|
10285
10287
|
};
|
|
10286
10288
|
//#endregion
|
|
10287
10289
|
//#region src/tags/usage-stats.marko
|
|
@@ -10352,7 +10354,7 @@ var usage_stats_default = _template("x", (input) => {
|
|
|
10352
10354
|
_if(() => {
|
|
10353
10355
|
if (agent.stale_seconds != null) {
|
|
10354
10356
|
const $scope6_id = _scope_id();
|
|
10355
|
-
_html(`<span${_attr_class(usage_stats_module_default.usageStale)}${_attr("title",
|
|
10357
|
+
_html(`<span${_attr_class(usage_stats_module_default.usageStale)}${_attr("title", `${agent.note || "couldn't reach this provider"} — these are the last cached numbers, ${duration(agent.stale_seconds * 1e3)} old`)}>⚠ <!>${_escape(duration(agent.stale_seconds * 1e3))}${_el_resume($scope6_id, "b")} old</span>${_el_resume($scope6_id, "a")}`);
|
|
10356
10358
|
writeScope($scope6_id, {});
|
|
10357
10359
|
return 0;
|
|
10358
10360
|
}
|
|
@@ -10366,11 +10368,20 @@ var usage_stats_default = _template("x", (input) => {
|
|
|
10366
10368
|
const pctClass = win.used_percent >= 90 ? usage_stats_module_default.pctHot : win.used_percent >= 70 ? usage_stats_module_default.pctWarm : win.used_percent >= 40 ? usage_stats_module_default.pctMid : usage_stats_module_default.pctOk;
|
|
10367
10369
|
_html(`<div${_attr_class(usage_stats_module_default.meter)}${_attr("title", `${win.window}: ${pct}% used${win.resets_at ? ` — resets ${new Date(win.resets_at).toLocaleString()}` : ""}`)}><span${_attr_class(usage_stats_module_default.meterLabel)}>${_escape(win.window)}${_el_resume($scope7_id, "c")}</span><span${_attr_class(usage_stats_module_default.meterTrack)}><span${_attr_class([usage_stats_module_default.meterFill, fillClass])}${_attr_style(`width:${Math.min(100, Math.max(2, win.used_percent))}%`)}></span>${_el_resume($scope7_id, "e")}</span><span${_attr_class([usage_stats_module_default.meterPct, pctClass])}>${_escape(pct)}${_el_resume($scope7_id, "g")}%</span>${_el_resume($scope7_id, "f")}<span${_attr_class(usage_stats_module_default.meterReset)}>${label ? `↻ ${_escape(`${_to_text(label)}`)}` : ""}${_el_resume($scope7_id, "i")}</span></div>${_el_resume($scope7_id, "a")}`);
|
|
10368
10370
|
writeScope($scope7_id, {});
|
|
10369
|
-
}, "window", $scope4_id, "
|
|
10370
|
-
|
|
10371
|
+
}, "window", $scope4_id, "g", 1, 1, 1, 0, 1);
|
|
10372
|
+
_if(() => {
|
|
10373
|
+
if (agent.note) {
|
|
10374
|
+
const $scope8_id = _scope_id();
|
|
10375
|
+
_html(`<p${_attr_class(usage_stats_module_default.usageNote)}>${_escape(agent.note)}${_el_resume($scope8_id, "b")}</p>`);
|
|
10376
|
+
writeScope($scope8_id, {});
|
|
10377
|
+
return 0;
|
|
10378
|
+
}
|
|
10379
|
+
}, $scope4_id, "h", 1, 1, 1, 0, 1);
|
|
10380
|
+
_html(`</div></div>${_el_resume($scope4_id, "a")}`);
|
|
10371
10381
|
writeScope($scope4_id, {
|
|
10372
|
-
|
|
10373
|
-
|
|
10382
|
+
k: agent?.stale_seconds,
|
|
10383
|
+
m: agent?.plan,
|
|
10384
|
+
n: agent?.note
|
|
10374
10385
|
});
|
|
10375
10386
|
}, (a) => `${a.agent}-${a.account || ""}`, $scope2_id, "a", 1, 1, 1, "</div>", 1);
|
|
10376
10387
|
writeScope($scope2_id, {});
|
|
@@ -10389,43 +10400,43 @@ var usage_stats_default = _template("x", (input) => {
|
|
|
10389
10400
|
_resume_branch($scope0_id);
|
|
10390
10401
|
});
|
|
10391
10402
|
var term_module_default = {
|
|
10392
|
-
iconBtn: "
|
|
10393
|
-
termWrap: "
|
|
10394
|
-
term: "
|
|
10395
|
-
xterm: "
|
|
10396
|
-
termDead: "
|
|
10397
|
-
termCopied: "
|
|
10398
|
-
termCopiedFade: "
|
|
10399
|
-
termUploading: "
|
|
10400
|
-
trapBackdrop: "
|
|
10401
|
-
pasteTrap: "
|
|
10402
|
-
kbSlot: "
|
|
10403
|
-
keyBar: "
|
|
10404
|
-
keyBarBtns: "
|
|
10405
|
-
keyBarBtnsHidden: "
|
|
10406
|
-
kspacer: "
|
|
10407
|
-
sessBtn: "
|
|
10408
|
-
sessDot: "
|
|
10409
|
-
sessPop: "
|
|
10410
|
-
sessRow: "
|
|
10411
|
-
current: "
|
|
10412
|
-
sessOpen: "
|
|
10413
|
-
sessTitle: "
|
|
10414
|
-
sessRename: "
|
|
10415
|
-
sessX: "
|
|
10416
|
-
armed: "
|
|
10417
|
-
sessEdit: "
|
|
10418
|
-
sessNew: "
|
|
10419
|
-
lone: "
|
|
10420
|
-
kbarWs: "
|
|
10421
|
-
kbarWsName: "
|
|
10422
|
-
kbtn: "
|
|
10423
|
-
dpadGrid: "
|
|
10424
|
-
repeat: "
|
|
10425
|
-
on: "
|
|
10426
|
-
bigGlyph: "
|
|
10427
|
-
enter: "
|
|
10428
|
-
dpadEsc: "
|
|
10403
|
+
iconBtn: "_d0 _eA",
|
|
10404
|
+
termWrap: "_d1",
|
|
10405
|
+
term: "_d2",
|
|
10406
|
+
xterm: "_d3",
|
|
10407
|
+
termDead: "_d4",
|
|
10408
|
+
termCopied: "_d5",
|
|
10409
|
+
termCopiedFade: "_d6",
|
|
10410
|
+
termUploading: "_d7",
|
|
10411
|
+
trapBackdrop: "_d8",
|
|
10412
|
+
pasteTrap: "_d9",
|
|
10413
|
+
kbSlot: "_d_",
|
|
10414
|
+
keyBar: "_ea",
|
|
10415
|
+
keyBarBtns: "_eb",
|
|
10416
|
+
keyBarBtnsHidden: "_ec",
|
|
10417
|
+
kspacer: "_ed",
|
|
10418
|
+
sessBtn: "_ee",
|
|
10419
|
+
sessDot: "_ef",
|
|
10420
|
+
sessPop: "_eg",
|
|
10421
|
+
sessRow: "_eh",
|
|
10422
|
+
current: "_ei",
|
|
10423
|
+
sessOpen: "_ej",
|
|
10424
|
+
sessTitle: "_ek",
|
|
10425
|
+
sessRename: "_el",
|
|
10426
|
+
sessX: "_em",
|
|
10427
|
+
armed: "_en",
|
|
10428
|
+
sessEdit: "_eo",
|
|
10429
|
+
sessNew: "_ep",
|
|
10430
|
+
lone: "_eq",
|
|
10431
|
+
kbarWs: "_er",
|
|
10432
|
+
kbarWsName: "_es",
|
|
10433
|
+
kbtn: "_et _eA",
|
|
10434
|
+
dpadGrid: "_eu",
|
|
10435
|
+
repeat: "_ev",
|
|
10436
|
+
on: "_ew",
|
|
10437
|
+
bigGlyph: "_ex",
|
|
10438
|
+
enter: "_ey",
|
|
10439
|
+
dpadEsc: "_ez"
|
|
10429
10440
|
};
|
|
10430
10441
|
//#endregion
|
|
10431
10442
|
//#region src/tags/term-find.marko
|
|
@@ -10563,19 +10574,19 @@ var REPEAT_EVERY = 55;
|
|
|
10563
10574
|
var term_default = _template("v", (input) => {
|
|
10564
10575
|
const $scope0_reason = _scope_reason();
|
|
10565
10576
|
_serialize_guard($scope0_reason, 3);
|
|
10566
|
-
_serialize_guard($scope0_reason,
|
|
10567
|
-
_serialize_guard($scope0_reason, 7);
|
|
10577
|
+
_serialize_guard($scope0_reason, 6);
|
|
10568
10578
|
_serialize_guard($scope0_reason, 8);
|
|
10569
|
-
|
|
10579
|
+
_serialize_guard($scope0_reason, 9);
|
|
10580
|
+
const $si__input_sessions = _serialize_if($scope0_reason, 8);
|
|
10570
10581
|
_serialize_guard($scope0_reason, 1);
|
|
10571
10582
|
_serialize_guard($scope0_reason, 10);
|
|
10572
|
-
const $si__input_onRenameSession = _serialize_if($scope0_reason,
|
|
10583
|
+
const $si__input_onRenameSession = _serialize_if($scope0_reason, 9);
|
|
10573
10584
|
_serialize_guard($scope0_reason, 11);
|
|
10574
|
-
const $si__input_agents = _serialize_if($scope0_reason, 11), $si__input_agent = _serialize_if($scope0_reason,
|
|
10585
|
+
const $si__input_agents = _serialize_if($scope0_reason, 11), $si__input_mode = _serialize_if($scope0_reason, 3), $si__input_agent = _serialize_if($scope0_reason, 6);
|
|
10575
10586
|
_serialize_guard($scope0_reason, 2);
|
|
10576
10587
|
_serialize_guard($scope0_reason, 4);
|
|
10577
10588
|
_serialize_guard($scope0_reason, 12);
|
|
10578
|
-
const $si__input_onCloseSession = _serialize_if($scope0_reason, 10), $si__input_sessionId = _serialize_if($scope0_reason,
|
|
10589
|
+
const $si__input_onCloseSession = _serialize_if($scope0_reason, 10), $si__input_sessionId = _serialize_if($scope0_reason, 5), $si__input_sessionState = _serialize_if($scope0_reason, 7), $si__input_workspaceName = _serialize_if($scope0_reason, 12);
|
|
10579
10590
|
const $scope0_id = _scope_id();
|
|
10580
10591
|
_hoist($scope0_id, "v20");
|
|
10581
10592
|
const $findOpen__closures = /* @__PURE__ */ new Set();
|
|
@@ -10587,6 +10598,7 @@ var term_default = _template("v", (input) => {
|
|
|
10587
10598
|
const $input_agent__closures = /* @__PURE__ */ new Set();
|
|
10588
10599
|
const $input_sessionState__closures = /* @__PURE__ */ new Set();
|
|
10589
10600
|
const $input_agents__closures = /* @__PURE__ */ new Set();
|
|
10601
|
+
const $onTermPage__closures = /* @__PURE__ */ new Set();
|
|
10590
10602
|
const $input_workspaceName__closures = /* @__PURE__ */ new Set();
|
|
10591
10603
|
let dead = false;
|
|
10592
10604
|
let kb = false;
|
|
@@ -10655,14 +10667,12 @@ var term_default = _template("v", (input) => {
|
|
|
10655
10667
|
}
|
|
10656
10668
|
openFind();
|
|
10657
10669
|
}, "v7", $scope0_id);
|
|
10658
|
-
const
|
|
10659
|
-
|
|
10660
|
-
|
|
10661
|
-
})();
|
|
10662
|
-
const findLit = !input.mode || input.mode === "term" ? findOpen : input.mode === "diff" && !!input.reviewFindOpen;
|
|
10670
|
+
const onTermPage = input.mode == null || input.mode === "term";
|
|
10671
|
+
const canKeys = onTermPage || input.mode === "diff";
|
|
10672
|
+
const findLit = onTermPage ? findOpen : input.mode === "diff" && !!input.reviewFindOpen;
|
|
10663
10673
|
const toggleSharedFind = _resume(() => {
|
|
10664
|
-
if (!
|
|
10665
|
-
if (
|
|
10674
|
+
if (!canKeys) return;
|
|
10675
|
+
if (onTermPage) {
|
|
10666
10676
|
toggleFind();
|
|
10667
10677
|
return;
|
|
10668
10678
|
}
|
|
@@ -10736,7 +10746,7 @@ var term_default = _template("v", (input) => {
|
|
|
10736
10746
|
trapOpen = true;
|
|
10737
10747
|
}
|
|
10738
10748
|
}, "v14", $scope0_id);
|
|
10739
|
-
_html(`<div${_attr("hidden",
|
|
10749
|
+
_html(`<div${_attr("hidden", !onTermPage)}${_attr_class(term_module_default.termWrap)}><div${_attr_class(term_module_default.term)}></div>${_el_resume($scope0_id, "b")}`);
|
|
10740
10750
|
_if(() => {
|
|
10741
10751
|
if (findOpen) {
|
|
10742
10752
|
const $scope11_id = _scope_id();
|
|
@@ -10789,9 +10799,9 @@ var term_default = _template("v", (input) => {
|
|
|
10789
10799
|
}, $scope0_id, "g", 1, 1, 1, 0, 1);
|
|
10790
10800
|
_html(`</div>${_el_resume($scope0_id, "a")}`);
|
|
10791
10801
|
_if(() => {}, $scope0_id, "h", 1, 1, 1, 0, 1);
|
|
10792
|
-
_script($scope0_id, "v38");
|
|
10793
10802
|
_script($scope0_id, "v39");
|
|
10794
10803
|
_script($scope0_id, "v40");
|
|
10804
|
+
_script($scope0_id, "v41");
|
|
10795
10805
|
writeScope($scope0_id, {
|
|
10796
10806
|
k: input.mode,
|
|
10797
10807
|
l: input.reviewFindOpen,
|
|
@@ -10802,12 +10812,12 @@ var term_default = _template("v", (input) => {
|
|
|
10802
10812
|
q: input.onExitReview,
|
|
10803
10813
|
r: input.onToggleDiff,
|
|
10804
10814
|
s: input.onNewSession,
|
|
10805
|
-
t: input.
|
|
10806
|
-
u: input.
|
|
10807
|
-
v: input.
|
|
10808
|
-
w: input.
|
|
10809
|
-
x: input.
|
|
10810
|
-
y: input.
|
|
10815
|
+
t: input.onOpenTab,
|
|
10816
|
+
u: input.sessionId,
|
|
10817
|
+
v: input.agent,
|
|
10818
|
+
w: input.sessionState,
|
|
10819
|
+
x: input.sessions,
|
|
10820
|
+
y: input.onRenameSession,
|
|
10811
10821
|
z: input.onCloseSession,
|
|
10812
10822
|
a0: input.agents,
|
|
10813
10823
|
a1: input.workspaceName,
|
|
@@ -10817,39 +10827,41 @@ var term_default = _template("v", (input) => {
|
|
|
10817
10827
|
a5: touch,
|
|
10818
10828
|
a8: trapOpen,
|
|
10819
10829
|
a9: findOpen,
|
|
10820
|
-
|
|
10821
|
-
|
|
10822
|
-
|
|
10823
|
-
|
|
10824
|
-
|
|
10825
|
-
|
|
10826
|
-
|
|
10827
|
-
|
|
10828
|
-
|
|
10829
|
-
|
|
10830
|
-
|
|
10831
|
-
|
|
10832
|
-
|
|
10833
|
-
|
|
10834
|
-
ay:
|
|
10835
|
-
|
|
10836
|
-
b1:
|
|
10837
|
-
|
|
10838
|
-
|
|
10839
|
-
b6:
|
|
10840
|
-
b7:
|
|
10841
|
-
|
|
10842
|
-
bb:
|
|
10843
|
-
|
|
10844
|
-
|
|
10845
|
-
|
|
10846
|
-
bk: $
|
|
10847
|
-
|
|
10848
|
-
|
|
10849
|
-
|
|
10850
|
-
|
|
10851
|
-
|
|
10852
|
-
bm: $
|
|
10830
|
+
ab: $openChange,
|
|
10831
|
+
ac: findTick,
|
|
10832
|
+
ae: ioBox.current,
|
|
10833
|
+
ah: searchBox.query,
|
|
10834
|
+
ai: searchBox.overlay,
|
|
10835
|
+
aj: searchBox.refreshTimer,
|
|
10836
|
+
al: findFocusRef,
|
|
10837
|
+
an: scheduleFindRefresh,
|
|
10838
|
+
ao: runFind,
|
|
10839
|
+
ap: clearFind,
|
|
10840
|
+
aq: openFind,
|
|
10841
|
+
as: toggleFind,
|
|
10842
|
+
at: onTermPage,
|
|
10843
|
+
aw: canKeys,
|
|
10844
|
+
ay: findLit,
|
|
10845
|
+
az: toggleSharedFind,
|
|
10846
|
+
b1: copyFlashBox.timer,
|
|
10847
|
+
b2: flashCopied,
|
|
10848
|
+
b4: holdBox.current,
|
|
10849
|
+
b6: startHold,
|
|
10850
|
+
b7: stopHold,
|
|
10851
|
+
b8: uploadAsset,
|
|
10852
|
+
bb: handlePasted,
|
|
10853
|
+
bc: pasteClipboard,
|
|
10854
|
+
bq: $findOpen__closures,
|
|
10855
|
+
bs: $findTick__closures,
|
|
10856
|
+
bk: $si__input_onRenameSession && $input_onRenameSession__closures,
|
|
10857
|
+
bl: $si__input_onCloseSession && $input_onCloseSession__closures,
|
|
10858
|
+
bg: $si__input_sessionId && $input_sessionId__closures,
|
|
10859
|
+
bj: $si__input_sessions && $input_sessions__closures,
|
|
10860
|
+
bh: $si__input_agent && $input_agent__closures,
|
|
10861
|
+
bi: $si__input_sessionState && $input_sessionState__closures,
|
|
10862
|
+
bm: $si__input_agents && $input_agents__closures,
|
|
10863
|
+
bx: $si__input_mode && $onTermPage__closures,
|
|
10864
|
+
bn: $si__input_workspaceName && $input_workspaceName__closures
|
|
10853
10865
|
});
|
|
10854
10866
|
_resume_branch($scope0_id);
|
|
10855
10867
|
});
|
|
@@ -13475,31 +13487,720 @@ function head16(context) {
|
|
|
13475
13487
|
return stripResponseBody(get16(context));
|
|
13476
13488
|
}
|
|
13477
13489
|
//#endregion
|
|
13478
|
-
//#region src/server/usage.ts
|
|
13490
|
+
//#region src/server/usage/shared.ts
|
|
13491
|
+
var HOME = os.homedir();
|
|
13492
|
+
var obj = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
13493
|
+
var arr = (value) => Array.isArray(value) ? value : [];
|
|
13494
|
+
var str = (value) => typeof value === "string" ? value : "";
|
|
13495
|
+
/** Numeric coercion that refuses NaN/Infinity — a provider sending "n/a"
|
|
13496
|
+
* must read as "no number", not as a percentage that renders a bar. */
|
|
13497
|
+
function num(value) {
|
|
13498
|
+
if (value == null || value === "") return null;
|
|
13499
|
+
const n = typeof value === "number" ? value : Number(value);
|
|
13500
|
+
return Number.isFinite(n) ? n : null;
|
|
13501
|
+
}
|
|
13502
|
+
function readJson(file) {
|
|
13503
|
+
try {
|
|
13504
|
+
return obj(JSON.parse(fs.readFileSync(file, "utf8")));
|
|
13505
|
+
} catch {
|
|
13506
|
+
return null;
|
|
13507
|
+
}
|
|
13508
|
+
}
|
|
13509
|
+
/** True if an epoch (seconds or ms) or ISO-8601 expiry is in the past. */
|
|
13510
|
+
function expired(value) {
|
|
13511
|
+
if (value == null) return false;
|
|
13512
|
+
if (typeof value === "string") {
|
|
13513
|
+
const t = Date.parse(value.replace(/\.\d+/, ""));
|
|
13514
|
+
return Number.isFinite(t) && t < Date.now();
|
|
13515
|
+
}
|
|
13516
|
+
const n = num(value);
|
|
13517
|
+
if (n == null) return false;
|
|
13518
|
+
return (n > 1e11 ? n : n * 1e3) < Date.now();
|
|
13519
|
+
}
|
|
13520
|
+
function isoFromEpoch(value) {
|
|
13521
|
+
const n = num(value);
|
|
13522
|
+
if (n == null || n <= 0) return null;
|
|
13523
|
+
const ms = n > 1e11 ? n : n * 1e3;
|
|
13524
|
+
return new Date(ms).toISOString();
|
|
13525
|
+
}
|
|
13526
|
+
/** `p•••@g•••.com` — enough to tell two accounts apart, and the page is
|
|
13527
|
+
* screenshotted into PRs and chat, so the address itself doesn't belong. */
|
|
13528
|
+
function maskEmail(email) {
|
|
13529
|
+
if (!email || !email.includes("@")) return email || "—";
|
|
13530
|
+
const [local, domain] = email.split("@");
|
|
13531
|
+
if (!local || !domain) return email;
|
|
13532
|
+
const tld = domain.split(".").pop() || "";
|
|
13533
|
+
return `${local[0]}•••@${domain[0]}•••.${tld}`;
|
|
13534
|
+
}
|
|
13535
|
+
/** A fetch that failed, carrying a reason fit to show on the row.
|
|
13536
|
+
*
|
|
13537
|
+
* A stale number with no explanation is what makes a usage table untrustworthy
|
|
13538
|
+
* — "why is claude2 from yesterday?" deserves an answer next to the number. */
|
|
13539
|
+
var FetchFailed = class extends Error {
|
|
13540
|
+
reason;
|
|
13541
|
+
constructor(reason) {
|
|
13542
|
+
super(reason);
|
|
13543
|
+
this.reason = reason;
|
|
13544
|
+
}
|
|
13545
|
+
};
|
|
13546
|
+
function httpReason(status) {
|
|
13547
|
+
if (status === 401 || status === 403) return "auth expired";
|
|
13548
|
+
if (status === 429) return "rate limited or auth expired";
|
|
13549
|
+
if (status >= 500) return `provider error (HTTP ${status})`;
|
|
13550
|
+
return `HTTP ${status}`;
|
|
13551
|
+
}
|
|
13552
|
+
var TIMEOUT_MS = 15e3;
|
|
13553
|
+
/** JSON over HTTPS, with every failure mode collapsed into a FetchFailed
|
|
13554
|
+
* whose reason is worth showing to a human. */
|
|
13555
|
+
async function fetchJson(url, init = {}) {
|
|
13556
|
+
let res;
|
|
13557
|
+
try {
|
|
13558
|
+
res = await fetch(url, {
|
|
13559
|
+
...init,
|
|
13560
|
+
signal: AbortSignal.timeout(TIMEOUT_MS)
|
|
13561
|
+
});
|
|
13562
|
+
} catch (err) {
|
|
13563
|
+
const name = err?.name;
|
|
13564
|
+
throw new FetchFailed(name === "TimeoutError" || name === "AbortError" ? "timed out" : "network unreachable");
|
|
13565
|
+
}
|
|
13566
|
+
if (!res.ok) throw new FetchFailed(httpReason(res.status));
|
|
13567
|
+
try {
|
|
13568
|
+
return await res.json();
|
|
13569
|
+
} catch {
|
|
13570
|
+
throw new FetchFailed("unreadable response");
|
|
13571
|
+
}
|
|
13572
|
+
}
|
|
13573
|
+
var cacheDir = path.join(config.dataDir, "usage");
|
|
13574
|
+
function readCache(key) {
|
|
13575
|
+
const blob = readJson(path.join(cacheDir, `${key}.json`));
|
|
13576
|
+
if (!blob) return null;
|
|
13577
|
+
const payload = blob.payload;
|
|
13578
|
+
const at = num(blob.fetched_at);
|
|
13579
|
+
if (!payload || typeof payload !== "object" || at == null) return null;
|
|
13580
|
+
return {
|
|
13581
|
+
payload: obj(payload),
|
|
13582
|
+
ageMs: Math.max(0, Date.now() - at)
|
|
13583
|
+
};
|
|
13584
|
+
}
|
|
13585
|
+
function writeCache(key, payload) {
|
|
13586
|
+
try {
|
|
13587
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
13588
|
+
fs.writeFileSync(path.join(cacheDir, `${key}.json`), JSON.stringify({
|
|
13589
|
+
fetched_at: Date.now(),
|
|
13590
|
+
payload
|
|
13591
|
+
}));
|
|
13592
|
+
} catch {}
|
|
13593
|
+
}
|
|
13594
|
+
/** Live fetch, falling back to the last good payload on disk.
|
|
13595
|
+
*
|
|
13596
|
+
* There is no "cache is fresh enough, skip the fetch" branch: the page's own
|
|
13597
|
+
* 60s stale-while-revalidate (server/usage/index.ts) already decides how often
|
|
13598
|
+
* this runs, and a second TTL underneath it only makes the numbers older than
|
|
13599
|
+
* the page claims. */
|
|
13600
|
+
async function loadPayload(key, live) {
|
|
13601
|
+
let reason;
|
|
13602
|
+
try {
|
|
13603
|
+
const data = await live();
|
|
13604
|
+
if (data) {
|
|
13605
|
+
writeCache(key, data);
|
|
13606
|
+
return {
|
|
13607
|
+
payload: data,
|
|
13608
|
+
source: "live"
|
|
13609
|
+
};
|
|
13610
|
+
}
|
|
13611
|
+
} catch (err) {
|
|
13612
|
+
reason = err instanceof FetchFailed ? err.reason : "fetch failed";
|
|
13613
|
+
}
|
|
13614
|
+
const disk = readCache(key);
|
|
13615
|
+
if (disk) return {
|
|
13616
|
+
payload: disk.payload,
|
|
13617
|
+
source: `stale-cache ${Math.round(disk.ageMs / 1e3)}s`,
|
|
13618
|
+
reason
|
|
13619
|
+
};
|
|
13620
|
+
return {
|
|
13621
|
+
payload: null,
|
|
13622
|
+
source: "missing",
|
|
13623
|
+
reason
|
|
13624
|
+
};
|
|
13625
|
+
}
|
|
13626
|
+
/** How to get a fresh token back, per provider. */
|
|
13627
|
+
var REAUTH = {
|
|
13628
|
+
codex: "codex login",
|
|
13629
|
+
cursor: "cursor-agent login",
|
|
13630
|
+
grok: "grok",
|
|
13631
|
+
copilot: "gh auth login"
|
|
13632
|
+
};
|
|
13633
|
+
/** Never signed in (or the CLI's credentials went missing) — not an outage.
|
|
13634
|
+
* Distinct from a failed request: nothing was ever sent, so blaming the
|
|
13635
|
+
* network would send you debugging the wrong thing. */
|
|
13636
|
+
function noAuthReason(key) {
|
|
13637
|
+
const hint = REAUTH[key];
|
|
13638
|
+
return hint ? `not signed in (run \`${hint}\`)` : "no credentials on disk";
|
|
13639
|
+
}
|
|
13640
|
+
function blankRow(agent, source = "missing") {
|
|
13641
|
+
return {
|
|
13642
|
+
agent,
|
|
13643
|
+
plan: agent,
|
|
13644
|
+
account: "—",
|
|
13645
|
+
five_h: null,
|
|
13646
|
+
five_h_resets: null,
|
|
13647
|
+
seven_d: null,
|
|
13648
|
+
seven_d_resets: null,
|
|
13649
|
+
fable: null,
|
|
13650
|
+
fable_resets: null,
|
|
13651
|
+
source
|
|
13652
|
+
};
|
|
13653
|
+
}
|
|
13654
|
+
/** Say *why* a row is showing last-known numbers, on the row itself.
|
|
13655
|
+
*
|
|
13656
|
+
* `tokenExpired` is the local credential check: true/false where an expiry is
|
|
13657
|
+
* readable off disk, undefined where it isn't. It beats guessing from the
|
|
13658
|
+
* status code — a dead token comes back 429 or 403 as readily as 401 — and
|
|
13659
|
+
* knowing the token is *good* is what lets a 429 be reported as plain
|
|
13660
|
+
* throttling instead of sending you to re-authenticate for nothing. */
|
|
13661
|
+
function markStale(row, key, tokenExpired, reason) {
|
|
13662
|
+
if (!/^(stale|claude\.json|missing)/.test(row.source)) return row;
|
|
13663
|
+
let why = reason ?? (tokenExpired ? "auth expired" : void 0);
|
|
13664
|
+
if (!why) why = "couldn't reach provider";
|
|
13665
|
+
if (why.startsWith("rate limited") && tokenExpired === false) why = "rate limited — retry shortly";
|
|
13666
|
+
else if (/^(auth expired|rate limited)/.test(why)) {
|
|
13667
|
+
const hint = REAUTH[key];
|
|
13668
|
+
why += hint ? ` (run \`${hint}\`)` : " (sign in again)";
|
|
13669
|
+
}
|
|
13670
|
+
return {
|
|
13671
|
+
...row,
|
|
13672
|
+
stale_reason: why
|
|
13673
|
+
};
|
|
13674
|
+
}
|
|
13675
|
+
//#endregion
|
|
13676
|
+
//#region src/server/usage/claude.ts
|
|
13677
|
+
/** Every Claude account this machine can read.
|
|
13678
|
+
*
|
|
13679
|
+
* Numbered dirs (~/.claude-1, -2) keep metadata at <dir>/.claude.json; the
|
|
13680
|
+
* stock single-account install keeps it at ~/.claude.json with only
|
|
13681
|
+
* credentials under ~/.claude/. */
|
|
13682
|
+
function claudeAccounts() {
|
|
13683
|
+
const candidates = [...[1, 2].map((n) => ({
|
|
13684
|
+
suffix: String(n),
|
|
13685
|
+
dir: path.join(HOME, `.claude-${n}`),
|
|
13686
|
+
meta: path.join(HOME, `.claude-${n}`, ".claude.json"),
|
|
13687
|
+
label: `claude${n}`
|
|
13688
|
+
})), {
|
|
13689
|
+
suffix: "",
|
|
13690
|
+
dir: path.join(HOME, ".claude"),
|
|
13691
|
+
meta: path.join(HOME, ".claude.json"),
|
|
13692
|
+
label: "claude"
|
|
13693
|
+
}];
|
|
13694
|
+
const out = [];
|
|
13695
|
+
for (const candidate of candidates) {
|
|
13696
|
+
const meta = readJson(candidate.meta);
|
|
13697
|
+
if (!meta) continue;
|
|
13698
|
+
const oauth = obj(meta.oauthAccount);
|
|
13699
|
+
out.push({
|
|
13700
|
+
...candidate,
|
|
13701
|
+
email: str(oauth.emailAddress).trim(),
|
|
13702
|
+
plan: str(oauth.organizationRateLimitTier || oauth.organizationType)
|
|
13703
|
+
});
|
|
13704
|
+
}
|
|
13705
|
+
return out;
|
|
13706
|
+
}
|
|
13707
|
+
var credentials = (account) => readJson(path.join(account.dir, ".credentials.json"));
|
|
13708
|
+
/** Why an account has no live data — an expired token is the common case
|
|
13709
|
+
* and only that account's own CLI can refresh it. */
|
|
13710
|
+
function credentialNote(account) {
|
|
13711
|
+
const cred = credentials(account);
|
|
13712
|
+
if (!cred) return "no credentials — run: claude";
|
|
13713
|
+
if (expired(obj(cred.claudeAiOauth).expiresAt)) return "token expired — use this Claude account to refresh";
|
|
13714
|
+
return "usage unavailable";
|
|
13715
|
+
}
|
|
13716
|
+
function tokenExpired(account) {
|
|
13717
|
+
const cred = credentials(account);
|
|
13718
|
+
return cred ? expired(obj(cred.claudeAiOauth).expiresAt) : false;
|
|
13719
|
+
}
|
|
13720
|
+
async function fetchUsage$3(account) {
|
|
13721
|
+
const token = str(obj(credentials(account)?.claudeAiOauth).accessToken);
|
|
13722
|
+
if (!token) return null;
|
|
13723
|
+
return obj(await fetchJson("https://api.anthropic.com/api/oauth/usage", { headers: {
|
|
13724
|
+
Authorization: `Bearer ${token}`,
|
|
13725
|
+
"anthropic-beta": "oauth-2025-04-20",
|
|
13726
|
+
"User-Agent": "claude-cli",
|
|
13727
|
+
Accept: "application/json"
|
|
13728
|
+
} }));
|
|
13729
|
+
}
|
|
13730
|
+
/** The CLI's own last-seen utilization, written into .claude.json. Older and
|
|
13731
|
+
* coarser than the API, but it survives an expired token. */
|
|
13732
|
+
function claudeJsonFallback(account) {
|
|
13733
|
+
const cached = readJson(account.meta)?.cachedUsageUtilization;
|
|
13734
|
+
return cached && typeof cached === "object" ? obj(cached) : null;
|
|
13735
|
+
}
|
|
13736
|
+
/** The payload nests windows under `utilization` on some plans and inlines
|
|
13737
|
+
* them on others. */
|
|
13738
|
+
function utilRoot(data) {
|
|
13739
|
+
const util = obj(data.utilization);
|
|
13740
|
+
return "five_hour" in util || "limits" in util ? util : data;
|
|
13741
|
+
}
|
|
13742
|
+
function window$2(data, key) {
|
|
13743
|
+
const win = obj(utilRoot(data)[key]);
|
|
13744
|
+
const used = num(win.utilization);
|
|
13745
|
+
return [used == null ? null : Math.trunc(used), str(win.resets_at) || null];
|
|
13746
|
+
}
|
|
13747
|
+
/** Fable gets its own weekly cap, listed as a model-scoped limit rather than
|
|
13748
|
+
* a top-level window. */
|
|
13749
|
+
function fableWindow(data) {
|
|
13750
|
+
for (const entry of arr(utilRoot(data).limits)) {
|
|
13751
|
+
const limit = obj(entry);
|
|
13752
|
+
if (limit.kind !== "weekly_scoped") continue;
|
|
13753
|
+
const model = obj(obj(limit.scope).model);
|
|
13754
|
+
if (!str(model.display_name || model.id).toLowerCase().includes("fable")) continue;
|
|
13755
|
+
const pct = num(limit.percent);
|
|
13756
|
+
return [pct == null ? null : Math.trunc(pct), str(limit.resets_at) || null];
|
|
13757
|
+
}
|
|
13758
|
+
return [null, null];
|
|
13759
|
+
}
|
|
13760
|
+
function parseRow$4(account, data, source) {
|
|
13761
|
+
const [five, fiveResets] = data ? window$2(data, "five_hour") : [null, null];
|
|
13762
|
+
const [seven, sevenResets] = data ? window$2(data, "seven_day") : [null, null];
|
|
13763
|
+
const [fable, fableResets] = data ? fableWindow(data) : [null, null];
|
|
13764
|
+
const row = {
|
|
13765
|
+
agent: account.label,
|
|
13766
|
+
plan: account.plan || "claude",
|
|
13767
|
+
account: maskEmail(account.email),
|
|
13768
|
+
five_h: five,
|
|
13769
|
+
five_h_resets: fiveResets,
|
|
13770
|
+
seven_d: seven,
|
|
13771
|
+
seven_d_resets: sevenResets,
|
|
13772
|
+
fable,
|
|
13773
|
+
fable_resets: fableResets,
|
|
13774
|
+
source
|
|
13775
|
+
};
|
|
13776
|
+
if (five == null && seven == null && fable == null) row.note = credentialNote(account);
|
|
13777
|
+
return row;
|
|
13778
|
+
}
|
|
13779
|
+
async function claudeRow(account) {
|
|
13780
|
+
const loaded = await loadPayload(`claude${account.suffix}`, () => fetchUsage$3(account));
|
|
13781
|
+
const fallback = loaded.payload ? null : claudeJsonFallback(account);
|
|
13782
|
+
return markStale(parseRow$4(account, loaded.payload ?? fallback, fallback ? "claude.json" : loaded.source), account.label, tokenExpired(account), loaded.reason);
|
|
13783
|
+
}
|
|
13784
|
+
//#endregion
|
|
13785
|
+
//#region src/server/usage/codex.ts
|
|
13786
|
+
var AUTH$2 = path.join(HOME, ".codex", "auth.json");
|
|
13787
|
+
/** Live rate-limit windows from the endpoint the Codex CLI itself uses. */
|
|
13788
|
+
async function fetchUsage$2() {
|
|
13789
|
+
const tokens = obj(readJson(AUTH$2)?.tokens);
|
|
13790
|
+
const token = str(tokens.access_token);
|
|
13791
|
+
if (!token) return null;
|
|
13792
|
+
return obj(await fetchJson("https://chatgpt.com/backend-api/wham/usage", { headers: {
|
|
13793
|
+
Authorization: `Bearer ${token}`,
|
|
13794
|
+
"chatgpt-account-id": str(tokens.account_id),
|
|
13795
|
+
"User-Agent": "codex-cli",
|
|
13796
|
+
Accept: "application/json"
|
|
13797
|
+
} }));
|
|
13798
|
+
}
|
|
13799
|
+
/** (used percent, reset) for whichever window is `seconds` long — the two
|
|
13800
|
+
* windows arrive as primary/secondary rather than named 5h / 7d. */
|
|
13801
|
+
function window$1(rateLimit, seconds) {
|
|
13802
|
+
for (const key of ["primary_window", "secondary_window"]) {
|
|
13803
|
+
const win = obj(rateLimit[key]);
|
|
13804
|
+
if (num(win.limit_window_seconds) !== seconds) continue;
|
|
13805
|
+
const used = num(win.used_percent);
|
|
13806
|
+
return [used == null ? null : Math.trunc(used), isoFromEpoch(win.reset_at)];
|
|
13807
|
+
}
|
|
13808
|
+
return [null, null];
|
|
13809
|
+
}
|
|
13810
|
+
function parseRow$3(payload, source) {
|
|
13811
|
+
const rateLimit = obj(payload.rate_limit);
|
|
13812
|
+
const [five, fiveResets] = window$1(rateLimit, 18e3);
|
|
13813
|
+
const [seven, sevenResets] = window$1(rateLimit, 604800);
|
|
13814
|
+
return {
|
|
13815
|
+
agent: "codex",
|
|
13816
|
+
plan: str(payload.plan_type) || "codex",
|
|
13817
|
+
account: maskEmail(str(payload.email)),
|
|
13818
|
+
five_h: five,
|
|
13819
|
+
five_h_resets: fiveResets,
|
|
13820
|
+
seven_d: seven,
|
|
13821
|
+
seven_d_resets: sevenResets,
|
|
13822
|
+
fable: null,
|
|
13823
|
+
fable_resets: null,
|
|
13824
|
+
source
|
|
13825
|
+
};
|
|
13826
|
+
}
|
|
13827
|
+
async function codexRow() {
|
|
13828
|
+
const { payload, source, reason } = await loadPayload("codex", fetchUsage$2);
|
|
13829
|
+
const missingAuth = fs.existsSync(AUTH$2) ? void 0 : noAuthReason("codex");
|
|
13830
|
+
return markStale(payload ? parseRow$3(payload, source) : {
|
|
13831
|
+
...blankRow("codex", source),
|
|
13832
|
+
note: missingAuth ?? "usage unavailable"
|
|
13833
|
+
}, "codex", void 0, missingAuth ?? reason);
|
|
13834
|
+
}
|
|
13835
|
+
//#endregion
|
|
13836
|
+
//#region src/server/usage/copilot.ts
|
|
13837
|
+
var USER_API = "https://api.github.com/copilot_internal/user";
|
|
13838
|
+
var HOSTS = path.join(process.env.XDG_CONFIG_HOME || path.join(HOME, ".config"), "gh", "hosts.yml");
|
|
13839
|
+
var SESSION_DB = path.join(HOME, ".copilot", "session-store.db");
|
|
13840
|
+
/** github.com's `oauth_token` straight out of gh's own hosts.yml.
|
|
13841
|
+
*
|
|
13842
|
+
* Deliberately not a YAML parse (no dependency): track the current top-level
|
|
13843
|
+
* host key by indentation and take the first token beneath github.com. */
|
|
13844
|
+
function hostsToken() {
|
|
13845
|
+
let text;
|
|
13846
|
+
try {
|
|
13847
|
+
text = fs.readFileSync(HOSTS, "utf8");
|
|
13848
|
+
} catch {
|
|
13849
|
+
return null;
|
|
13850
|
+
}
|
|
13851
|
+
let host = "";
|
|
13852
|
+
for (const line of text.split("\n")) {
|
|
13853
|
+
if (line[0]?.trim() && line.trimEnd().endsWith(":")) {
|
|
13854
|
+
host = line.trim().replace(/:$/, "");
|
|
13855
|
+
continue;
|
|
13856
|
+
}
|
|
13857
|
+
if (host !== "github.com") continue;
|
|
13858
|
+
const match = /^\s+oauth_token:\s*(\S+)/.exec(line);
|
|
13859
|
+
if (match) return match[1] ?? null;
|
|
13860
|
+
}
|
|
13861
|
+
return null;
|
|
13862
|
+
}
|
|
13863
|
+
/** The Copilot CLI keeps its own auth in the OS keyring, so reuse the token
|
|
13864
|
+
* gh manages. Copilot entitlement is account-scoped, so any valid token for
|
|
13865
|
+
* the entitled user reads the quota. */
|
|
13866
|
+
async function token() {
|
|
13867
|
+
for (const key of ["GH_TOKEN", "GITHUB_TOKEN"]) {
|
|
13868
|
+
const value = process.env[key]?.trim();
|
|
13869
|
+
if (value) return value;
|
|
13870
|
+
}
|
|
13871
|
+
const fromHosts = hostsToken();
|
|
13872
|
+
if (fromHosts) return fromHosts;
|
|
13873
|
+
try {
|
|
13874
|
+
return await run("gh", ["auth", "token"]) || null;
|
|
13875
|
+
} catch {
|
|
13876
|
+
return null;
|
|
13877
|
+
}
|
|
13878
|
+
}
|
|
13879
|
+
async function fetchUsage$1(auth) {
|
|
13880
|
+
if (!auth) return null;
|
|
13881
|
+
const data = obj(await fetchJson(USER_API, { headers: {
|
|
13882
|
+
Authorization: `token ${auth}`,
|
|
13883
|
+
"User-Agent": "GitHubCopilotCLI",
|
|
13884
|
+
Accept: "application/json"
|
|
13885
|
+
} }));
|
|
13886
|
+
return data.quota_snapshots == null ? null : data;
|
|
13887
|
+
}
|
|
13888
|
+
/** Billing period start = one month before the quota reset date. */
|
|
13889
|
+
function periodStart(resetIso) {
|
|
13890
|
+
const reset = new Date(resetIso);
|
|
13891
|
+
if (Number.isNaN(reset.getTime())) return null;
|
|
13892
|
+
const year = reset.getUTCMonth() === 0 ? reset.getUTCFullYear() - 1 : reset.getUTCFullYear();
|
|
13893
|
+
const month = reset.getUTCMonth() === 0 ? 12 : reset.getUTCMonth();
|
|
13894
|
+
const day = Math.min(reset.getUTCDate(), 28);
|
|
13895
|
+
return `${String(year).padStart(4, "0")}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
|
13896
|
+
}
|
|
13897
|
+
/** Credits this machine's Copilot CLI has spent in the current period.
|
|
13898
|
+
*
|
|
13899
|
+
* GitHub's own quota snapshot is batched — it can still read `credits_used: 0`
|
|
13900
|
+
* minutes after a session that plainly spent credits — so the CLI's local
|
|
13901
|
+
* ledger is the only number that moves in real time. It sees this machine
|
|
13902
|
+
* only, which is why the caller floors it with upstream rather than trusting
|
|
13903
|
+
* it alone. */
|
|
13904
|
+
function localCredits(start) {
|
|
13905
|
+
if (!start || !fs.existsSync(SESSION_DB)) return null;
|
|
13906
|
+
try {
|
|
13907
|
+
const db = new DatabaseSync(SESSION_DB, { readOnly: true });
|
|
13908
|
+
try {
|
|
13909
|
+
const nano = num(db.prepare("select sum(total_nano_aiu) as nano from assistant_usage_events where created_at >= ?").get(start)?.nano);
|
|
13910
|
+
return nano == null ? 0 : nano / 1e9;
|
|
13911
|
+
} finally {
|
|
13912
|
+
db.close();
|
|
13913
|
+
}
|
|
13914
|
+
} catch {
|
|
13915
|
+
return null;
|
|
13916
|
+
}
|
|
13917
|
+
}
|
|
13918
|
+
function parseRow$2(payload, source) {
|
|
13919
|
+
const premium = obj(obj(payload.quota_snapshots).premium_interactions);
|
|
13920
|
+
const reset = str(payload.quota_reset_date_utc || payload.quota_reset_date) || null;
|
|
13921
|
+
let pct = null;
|
|
13922
|
+
let note;
|
|
13923
|
+
if (!Object.keys(premium).length || !premium.has_quota) note = "no premium quota";
|
|
13924
|
+
else if (premium.unlimited) note = "unlimited premium requests";
|
|
13925
|
+
else {
|
|
13926
|
+
const remaining = num(premium.percent_remaining);
|
|
13927
|
+
if (remaining != null) pct = 100 - remaining;
|
|
13928
|
+
const entitlement = num(premium.entitlement) ?? 0;
|
|
13929
|
+
const used = reset ? localCredits(periodStart(reset)) : null;
|
|
13930
|
+
if (entitlement > 0 && used != null) {
|
|
13931
|
+
const localPct = 100 * used / entitlement;
|
|
13932
|
+
if (pct == null || localPct > pct) {
|
|
13933
|
+
pct = localPct;
|
|
13934
|
+
source = `${source}+local`;
|
|
13935
|
+
}
|
|
13936
|
+
}
|
|
13937
|
+
}
|
|
13938
|
+
if (pct != null) pct = Math.round(pct * 1e3) / 1e3;
|
|
13939
|
+
const row = {
|
|
13940
|
+
agent: "copilot",
|
|
13941
|
+
plan: str(payload.copilot_plan) || "copilot",
|
|
13942
|
+
account: str(payload.login) || "—",
|
|
13943
|
+
five_h: null,
|
|
13944
|
+
five_h_resets: null,
|
|
13945
|
+
seven_d: pct,
|
|
13946
|
+
seven_d_resets: pct == null ? null : reset,
|
|
13947
|
+
fable: null,
|
|
13948
|
+
fable_resets: null,
|
|
13949
|
+
source
|
|
13950
|
+
};
|
|
13951
|
+
if (note) row.note = note;
|
|
13952
|
+
return row;
|
|
13953
|
+
}
|
|
13954
|
+
async function copilotRow() {
|
|
13955
|
+
const auth = await token();
|
|
13956
|
+
const { payload, source, reason } = await loadPayload("copilot", () => fetchUsage$1(auth));
|
|
13957
|
+
const missingAuth = auth ? void 0 : noAuthReason("copilot");
|
|
13958
|
+
return markStale(payload ? parseRow$2(payload, source) : {
|
|
13959
|
+
...blankRow("copilot", source),
|
|
13960
|
+
note: missingAuth ?? "usage unavailable"
|
|
13961
|
+
}, "copilot", void 0, missingAuth ?? reason);
|
|
13962
|
+
}
|
|
13963
|
+
//#endregion
|
|
13964
|
+
//#region src/server/usage/cursor.ts
|
|
13965
|
+
var AUTH$1 = path.join(HOME, ".config", "cursor", "auth.json");
|
|
13966
|
+
var CLI_CONFIG = path.join(HOME, ".cursor", "cli-config.json");
|
|
13967
|
+
var API = "https://api2.cursor.sh";
|
|
13968
|
+
var WWW = "https://cursor.com";
|
|
13969
|
+
function cursorAuth() {
|
|
13970
|
+
const auth = readJson(AUTH$1);
|
|
13971
|
+
if (!auth) return null;
|
|
13972
|
+
const token = str(auth.accessToken || auth.access_token);
|
|
13973
|
+
if (!token) return null;
|
|
13974
|
+
let sub = "";
|
|
13975
|
+
try {
|
|
13976
|
+
sub = str(obj(JSON.parse(Buffer.from(str(token.split(".")[1]), "base64url").toString())).sub);
|
|
13977
|
+
} catch {}
|
|
13978
|
+
return {
|
|
13979
|
+
token,
|
|
13980
|
+
sub,
|
|
13981
|
+
email: str(obj(readJson(CLI_CONFIG)?.authInfo).email).trim()
|
|
13982
|
+
};
|
|
13983
|
+
}
|
|
13984
|
+
var dashboardPost = async (token, method) => obj(await fetchJson(`${API}/aiserver.v1.DashboardService/${method}`, {
|
|
13985
|
+
method: "POST",
|
|
13986
|
+
body: "{}",
|
|
13987
|
+
headers: {
|
|
13988
|
+
Authorization: `Bearer ${token}`,
|
|
13989
|
+
"Content-Type": "application/json",
|
|
13990
|
+
Accept: "application/json",
|
|
13991
|
+
"Connect-Protocol-Version": "1",
|
|
13992
|
+
"User-Agent": "cursor-agent"
|
|
13993
|
+
}
|
|
13994
|
+
}));
|
|
13995
|
+
/** Enterprise/team monthly pool, which the dashboard service leaves empty —
|
|
13996
|
+
* it is only readable with the web session cookie. */
|
|
13997
|
+
async function usageSummary(auth) {
|
|
13998
|
+
if (!auth.sub) return null;
|
|
13999
|
+
const cookie = `WorkosCursorSessionToken=${encodeURIComponent(`${auth.sub}::${auth.token}`)}`;
|
|
14000
|
+
return obj(await fetchJson(`${WWW}/api/usage-summary`, { headers: {
|
|
14001
|
+
Cookie: cookie,
|
|
14002
|
+
Accept: "application/json",
|
|
14003
|
+
"User-Agent": "Mozilla/5.0"
|
|
14004
|
+
} }));
|
|
14005
|
+
}
|
|
14006
|
+
/** Prefer the dashboard's planUsage (Pro/Ultra); fall back to the web
|
|
14007
|
+
* summary for Enterprise/team accounts, where planUsage comes back empty.
|
|
14008
|
+
* Each call is optional on its own, so one failing endpoint must not hide a
|
|
14009
|
+
* number another would have produced — but if nothing lands, the first
|
|
14010
|
+
* failure is rethrown so the row can say why. */
|
|
14011
|
+
async function fetchUsage(auth) {
|
|
14012
|
+
let failure;
|
|
14013
|
+
const soft = async (load) => {
|
|
14014
|
+
try {
|
|
14015
|
+
return await load();
|
|
14016
|
+
} catch (err) {
|
|
14017
|
+
failure ??= err;
|
|
14018
|
+
return null;
|
|
14019
|
+
}
|
|
14020
|
+
};
|
|
14021
|
+
const [period, planInfo] = await Promise.all([soft(() => dashboardPost(auth.token, "GetCurrentPeriodUsage")), soft(() => dashboardPost(auth.token, "GetPlanInfo"))]);
|
|
14022
|
+
const planUsage = obj(obj(period).planUsage);
|
|
14023
|
+
const summary = num(planUsage.limit) ? null : await soft(() => usageSummary(auth));
|
|
14024
|
+
if (!Object.keys(planUsage).length && !summary) {
|
|
14025
|
+
if (failure) throw failure;
|
|
14026
|
+
return null;
|
|
14027
|
+
}
|
|
14028
|
+
return {
|
|
14029
|
+
period: obj(period),
|
|
14030
|
+
plan_info: obj(obj(planInfo).planInfo),
|
|
14031
|
+
summary
|
|
14032
|
+
};
|
|
14033
|
+
}
|
|
14034
|
+
function parseRow$1(payload, auth, source) {
|
|
14035
|
+
const period = obj(payload.period);
|
|
14036
|
+
const planInfo = obj(payload.plan_info);
|
|
14037
|
+
const summary = obj(payload.summary);
|
|
14038
|
+
let pct = num(obj(period.planUsage).totalPercentUsed);
|
|
14039
|
+
let resets = isoFromEpoch(period.billingCycleEnd);
|
|
14040
|
+
if (pct == null) {
|
|
14041
|
+
const overall = obj(obj(summary.individualUsage).overall);
|
|
14042
|
+
const used = num(overall.used);
|
|
14043
|
+
const limit = num(overall.limit);
|
|
14044
|
+
if (used != null && limit) pct = Math.round(100 * used / limit);
|
|
14045
|
+
resets = str(summary.billingCycleEnd) || resets;
|
|
14046
|
+
}
|
|
14047
|
+
return {
|
|
14048
|
+
agent: "cursor",
|
|
14049
|
+
plan: str(planInfo.planName || summary.membershipType) || "cursor",
|
|
14050
|
+
account: auth?.email ? maskEmail(auth.email) : "—",
|
|
14051
|
+
five_h: null,
|
|
14052
|
+
five_h_resets: null,
|
|
14053
|
+
seven_d: pct == null ? null : Math.trunc(pct),
|
|
14054
|
+
seven_d_resets: resets,
|
|
14055
|
+
fable: null,
|
|
14056
|
+
fable_resets: null,
|
|
14057
|
+
source
|
|
14058
|
+
};
|
|
14059
|
+
}
|
|
14060
|
+
async function cursorRow() {
|
|
14061
|
+
const auth = cursorAuth();
|
|
14062
|
+
const { payload, source, reason } = await loadPayload("cursor", () => auth ? fetchUsage(auth) : Promise.resolve(null));
|
|
14063
|
+
const missingAuth = auth ? void 0 : noAuthReason("cursor");
|
|
14064
|
+
return markStale(payload ? parseRow$1(payload, auth, source) : {
|
|
14065
|
+
...blankRow("cursor", source),
|
|
14066
|
+
note: missingAuth ?? "usage unavailable"
|
|
14067
|
+
}, "cursor", void 0, missingAuth ?? reason);
|
|
14068
|
+
}
|
|
14069
|
+
//#endregion
|
|
14070
|
+
//#region src/server/usage/grok.ts
|
|
14071
|
+
var AUTH = path.join(HOME, ".grok", "auth.json");
|
|
14072
|
+
var LOG = path.join(HOME, ".grok", "logs", "unified.jsonl");
|
|
14073
|
+
/** The newest usable entry in ~/.grok/auth.json, which is keyed by scope
|
|
14074
|
+
* rather than being a single credential. */
|
|
14075
|
+
function grokAuth() {
|
|
14076
|
+
const auth = readJson(AUTH);
|
|
14077
|
+
if (!auth) return null;
|
|
14078
|
+
const entry = Object.values(auth).map(obj).filter((entry) => str(entry.key) || str(entry.access_token)).sort((a, b) => str(b.create_time || b.expires_at).localeCompare(str(a.create_time || a.expires_at)))[0];
|
|
14079
|
+
if (!entry) return null;
|
|
14080
|
+
return {
|
|
14081
|
+
token: str(entry.key) || str(entry.access_token),
|
|
14082
|
+
email: str(entry.email),
|
|
14083
|
+
expiresAt: entry.expires_at
|
|
14084
|
+
};
|
|
14085
|
+
}
|
|
14086
|
+
/** Weekly credit pool from the Grok Build CLI's own proxy. */
|
|
14087
|
+
async function fetchBilling(token) {
|
|
14088
|
+
const data = obj(await fetchJson("https://cli-chat-proxy.grok.com/v1/billing?format=credits", { headers: {
|
|
14089
|
+
Authorization: `Bearer ${token}`,
|
|
14090
|
+
Accept: "application/json",
|
|
14091
|
+
"User-Agent": "grok-cli",
|
|
14092
|
+
"x-grok-client-mode": "cli"
|
|
14093
|
+
} }));
|
|
14094
|
+
return data.config ? data : null;
|
|
14095
|
+
}
|
|
14096
|
+
/** Fallback: the last credits config the CLI logged, normalized to the live
|
|
14097
|
+
* API's shape. Reads only the tail — this log grows without bound. */
|
|
14098
|
+
function billingFromLogs() {
|
|
14099
|
+
let chunk;
|
|
14100
|
+
try {
|
|
14101
|
+
const { size } = fs.statSync(LOG);
|
|
14102
|
+
const start = Math.max(0, size - 512e3);
|
|
14103
|
+
const fd = fs.openSync(LOG, "r");
|
|
14104
|
+
try {
|
|
14105
|
+
const buf = Buffer.alloc(size - start);
|
|
14106
|
+
fs.readSync(fd, buf, 0, buf.length, start);
|
|
14107
|
+
chunk = buf.toString("utf8");
|
|
14108
|
+
} finally {
|
|
14109
|
+
fs.closeSync(fd);
|
|
14110
|
+
}
|
|
14111
|
+
} catch {
|
|
14112
|
+
return null;
|
|
14113
|
+
}
|
|
14114
|
+
let latest = null;
|
|
14115
|
+
for (const line of chunk.split("\n")) {
|
|
14116
|
+
if (!line.includes("billing: fetched credits config")) continue;
|
|
14117
|
+
try {
|
|
14118
|
+
const entry = obj(JSON.parse(line));
|
|
14119
|
+
if (entry.msg === "billing: fetched credits config") latest = entry;
|
|
14120
|
+
} catch {}
|
|
14121
|
+
}
|
|
14122
|
+
if (!latest) return null;
|
|
14123
|
+
const ctx = obj(latest.ctx);
|
|
14124
|
+
const cfg = obj(ctx.config);
|
|
14125
|
+
if (!Object.keys(cfg).length) return null;
|
|
14126
|
+
return {
|
|
14127
|
+
config: cfg,
|
|
14128
|
+
subscriptionTier: ctx.subscriptionTier
|
|
14129
|
+
};
|
|
14130
|
+
}
|
|
14131
|
+
function parseRow(payload, auth, source) {
|
|
14132
|
+
const cfg = payload.config ? obj(payload.config) : payload;
|
|
14133
|
+
const pct = num(cfg.creditUsagePercent);
|
|
14134
|
+
let productPct = null;
|
|
14135
|
+
for (const entry of arr(cfg.productUsage)) {
|
|
14136
|
+
const usage = obj(entry);
|
|
14137
|
+
if (!str(usage.product).toLowerCase().includes("grok")) continue;
|
|
14138
|
+
productPct = num(usage.usagePercent);
|
|
14139
|
+
break;
|
|
14140
|
+
}
|
|
14141
|
+
const used = pct ?? productPct;
|
|
14142
|
+
const period = obj(cfg.currentPeriod);
|
|
14143
|
+
return {
|
|
14144
|
+
agent: "grok",
|
|
14145
|
+
plan: str(payload.subscriptionTier || cfg.subscriptionTier) || "Grok Build",
|
|
14146
|
+
account: auth?.email ? maskEmail(auth.email) : "—",
|
|
14147
|
+
five_h: null,
|
|
14148
|
+
five_h_resets: null,
|
|
14149
|
+
seven_d: used == null ? null : Math.trunc(used),
|
|
14150
|
+
seven_d_resets: str(period.end || cfg.billingPeriodEnd) || null,
|
|
14151
|
+
fable: null,
|
|
14152
|
+
fable_resets: null,
|
|
14153
|
+
source
|
|
14154
|
+
};
|
|
14155
|
+
}
|
|
14156
|
+
async function grokRow() {
|
|
14157
|
+
const auth = grokAuth();
|
|
14158
|
+
const loaded = await loadPayload("grok", () => auth?.token ? fetchBilling(auth.token) : Promise.resolve(null));
|
|
14159
|
+
const fromLog = loaded.payload ? null : billingFromLogs();
|
|
14160
|
+
const payload = loaded.payload ?? fromLog;
|
|
14161
|
+
const source = fromLog ? "unified.jsonl" : loaded.source;
|
|
14162
|
+
const missingAuth = auth?.token ? void 0 : noAuthReason("grok");
|
|
14163
|
+
return markStale(payload ? parseRow(payload, auth, source) : {
|
|
14164
|
+
...blankRow("grok", source),
|
|
14165
|
+
note: missingAuth ?? "usage unavailable"
|
|
14166
|
+
}, "grok", expired(auth?.expiresAt), missingAuth ?? loaded.reason);
|
|
14167
|
+
}
|
|
14168
|
+
//#endregion
|
|
14169
|
+
//#region src/server/usage/index.ts
|
|
13479
14170
|
var TTL_MS = 6e4;
|
|
13480
|
-
/** Plan/quota usage across agent
|
|
13481
|
-
|
|
13482
|
-
|
|
13483
|
-
|
|
13484
|
-
*
|
|
13485
|
-
|
|
13486
|
-
|
|
14171
|
+
/** Plan/quota usage across every agent account this machine is signed into.
|
|
14172
|
+
*
|
|
14173
|
+
* Each provider is one blocking HTTPS round trip against the same endpoint its
|
|
14174
|
+
* own CLI uses; they touch disjoint credentials and cache files, so they run
|
|
14175
|
+
* concurrently and the wait is the slowest single provider, not their sum. */
|
|
14176
|
+
async function collect() {
|
|
14177
|
+
const providers = [
|
|
14178
|
+
...claudeAccounts().map((account) => [account.label, () => claudeRow(account)]),
|
|
14179
|
+
["codex", codexRow],
|
|
14180
|
+
["cursor", cursorRow],
|
|
14181
|
+
["grok", grokRow],
|
|
14182
|
+
["copilot", copilotRow]
|
|
14183
|
+
];
|
|
14184
|
+
return Promise.all(providers.map(([key, load]) => load().catch(() => ({
|
|
14185
|
+
...blankRow(key, "error"),
|
|
14186
|
+
note: "fetch failed"
|
|
14187
|
+
}))));
|
|
14188
|
+
}
|
|
14189
|
+
/** Age of a row served from a failed refresh, in seconds — undefined when the
|
|
14190
|
+
* numbers are current. Percentages from a stale row describe a window that has
|
|
14191
|
+
* since moved on, so they can't be shown as live figures. */
|
|
13487
14192
|
function staleSeconds(source) {
|
|
13488
|
-
const match = /^stale-cache\s+(\d+
|
|
14193
|
+
const match = /^stale-cache\s+(\d+)s/.exec(source);
|
|
13489
14194
|
return match ? Number(match[1]) : void 0;
|
|
13490
14195
|
}
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
|
|
13494
|
-
if (!rows.length && !refresh) {
|
|
13495
|
-
out = await run("plan-usage", ["--json"]);
|
|
13496
|
-
rows = JSON.parse(out);
|
|
13497
|
-
}
|
|
13498
|
-
return { agents: rows.map((row) => ({
|
|
14196
|
+
var cached = swr(TTL_MS, (_key, _refresh) => collect());
|
|
14197
|
+
var usage = async (refresh = false) => {
|
|
14198
|
+
return { agents: (await cached("usage", refresh)).map((row) => ({
|
|
13499
14199
|
agent: row.agent,
|
|
13500
14200
|
plan: row.plan,
|
|
13501
14201
|
account: row.account,
|
|
13502
14202
|
stale_seconds: staleSeconds(row.source),
|
|
14203
|
+
note: row.stale_reason || row.note,
|
|
13503
14204
|
windows: [
|
|
13504
14205
|
{
|
|
13505
14206
|
window: "5h",
|
|
@@ -13518,7 +14219,7 @@ async function fetchUsage(_key, refresh) {
|
|
|
13518
14219
|
}
|
|
13519
14220
|
].filter((w) => w.used_percent != null)
|
|
13520
14221
|
})) };
|
|
13521
|
-
}
|
|
14222
|
+
};
|
|
13522
14223
|
//#endregion
|
|
13523
14224
|
//#region __marko-run__api.usage.js
|
|
13524
14225
|
var getHandler$6 = normalizeHandler(Run.GET({ search: (value) => ({ refresh: "refresh" in value }) }, async (ctx) => Response.json(await usage(ctx.search.refresh))), "GET");
|
|
@@ -18650,4 +19351,4 @@ server.listen(port, () => {
|
|
|
18650
19351
|
//#endregion
|
|
18651
19352
|
export {};
|
|
18652
19353
|
|
|
18653
|
-
;var __MARKO_MANIFEST__={"esfPH6H":{"block":[2,"stylesheet#/assets/index
|
|
19354
|
+
;var __MARKO_MANIFEST__={"esfPH6H":{"block":[2,"stylesheet#/assets/index--QwhN0hy.css",6,"<link",0," rel=\"stylesheet\" crossorigin href=\"",1,"assets/index--QwhN0hy.css\"",">"],"defer":[2,"/assets/index-CdVBL6Kf.js",6,"<script",0," async type=\"module\" crossorigin src=\"",1,"assets/index-CdVBL6Kf.js\"","></script>"]}};
|