@band-app/server 0.58.0 → 0.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/_shell.html +0 -0
- package/dist/client/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/client/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/client/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/client/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/client/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/client/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/client/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/client/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/client/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/client/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/client/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/client/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/client/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/client/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/client/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/client/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/client/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/client/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/client/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/client/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/client/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/client/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/client/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/client/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/client/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/client/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/client/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/client/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/client/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/client/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/client/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/client/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/client/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/client/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/client/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/client/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/client/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/client/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/client/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/client/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/client/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/client/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/client/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/client/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/client/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/client/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/client/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/client/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/client/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/client/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/client/assets/{TerminalPanel-DZpYM-2e.js → TerminalPanel-B15ghqjC.js} +1 -1
- package/dist/client/assets/{_basePickBy-6zU_l56i.js → _basePickBy-DnTEmDSj.js} +1 -1
- package/dist/client/assets/{_baseUniq-BmNIWTzJ.js → _baseUniq-vhCiyIYf.js} +1 -1
- package/dist/client/assets/{arc-C2guaHsn.js → arc-CZ4Bw9uS.js} +1 -1
- package/dist/client/assets/{architectureDiagram-VXUJARFQ-CC-6zRwy.js → architectureDiagram-VXUJARFQ-CvqgWcYx.js} +1 -1
- package/dist/client/assets/{blockDiagram-VD42YOAC-SUU89nqx.js → blockDiagram-VD42YOAC-D8REfakL.js} +1 -1
- package/dist/client/assets/{c4Diagram-YG6GDRKO-Brqvl68E.js → c4Diagram-YG6GDRKO-BIgJnhrx.js} +1 -1
- package/dist/client/assets/channel-DaBOqDcm.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-aSJIRJbo.js → chunk-4BX2VUAB-BO8PrQP3.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-Be_ygmcl.js → chunk-55IACEB6-DO5fHd1T.js} +1 -1
- package/dist/client/assets/{chunk-B4BG7PRW-DO9kuFIX.js → chunk-B4BG7PRW-CAtAtkCf.js} +1 -1
- package/dist/client/assets/{chunk-DI55MBZ5-Cs6PrThE.js → chunk-DI55MBZ5-DRnZO_Tx.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-NBjR-LSj.js → chunk-FMBD7UC4-DzqqzV_F.js} +1 -1
- package/dist/client/assets/{chunk-QN33PNHL-CthBcGPW.js → chunk-QN33PNHL-DETRpC4Q.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-DFzP7rYv.js → chunk-QZHKN3VN-D6X6jOAA.js} +1 -1
- package/dist/client/assets/{chunk-TZMSLE5B-BtqUkL_w.js → chunk-TZMSLE5B-C8IfJ5NA.js} +1 -1
- package/dist/client/assets/classDiagram-2ON5EDUG-CovRsOYg.js +1 -0
- package/dist/client/assets/classDiagram-v2-WZHVMYZB-CovRsOYg.js +1 -0
- package/dist/client/assets/clone-CEAieby9.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-DhyKm2TQ.js → cose-bilkent-S5V4N54A-DMKRB7Bs.js} +1 -1
- package/dist/client/assets/{dagre-6UL2VRFP-NY1AKNho.js → dagre-6UL2VRFP-C_cXM9p2.js} +1 -1
- package/dist/client/assets/{diagram-PSM6KHXK-CCYOdCnq.js → diagram-PSM6KHXK-D_A2BJh_.js} +1 -1
- package/dist/client/assets/{diagram-QEK2KX5R-EcSNtDiG.js → diagram-QEK2KX5R-BnKjlyrI.js} +1 -1
- package/dist/client/assets/{diagram-S2PKOQOG-Cvp7SMU7.js → diagram-S2PKOQOG-R4tiwc1I.js} +1 -1
- package/dist/client/assets/{erDiagram-Q2GNP2WA-BF1T1k5o.js → erDiagram-Q2GNP2WA-CNV08IQO.js} +1 -1
- package/dist/client/assets/{flowDiagram-NV44I4VS-PZ3CeJSZ.js → flowDiagram-NV44I4VS-BAXwfe4s.js} +1 -1
- package/dist/client/assets/{ganttDiagram-JELNMOA3-BHzq_mda.js → ganttDiagram-JELNMOA3-Bk3PXBP9.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-CEkwii1J.js → gitGraphDiagram-V2S2FVAM-C8tujQgm.js} +1 -1
- package/dist/client/assets/{graph-CKhBarkm.js → graph-BIBqorc8.js} +1 -1
- package/dist/client/assets/{highlighted-body-B3W2YXNL-Cyw8VbMw.js → highlighted-body-B3W2YXNL-NymhDWI2.js} +1 -1
- package/dist/client/assets/{index-gv92vNY4.js → index-BKBEQAUS.js} +1 -1
- package/dist/client/assets/{index-78ZDd0_e.js → index-BYs8YaN9.js} +1 -1
- package/dist/client/assets/{index-DsKR-Mzt.js → index-BYzUhLmm.js} +1 -1
- package/dist/client/assets/{index-Bunws-S6.js → index-BvS6Fo_E.js} +1 -1
- package/dist/client/assets/{index-CXP92XgX.js → index-C6Buf5vO.js} +1 -1
- package/dist/client/assets/{index-s6CshXgO.js → index-Cqclrque.js} +1 -1
- package/dist/client/assets/{index-D5VI3PBL.js → index-D9qmTeqK.js} +1 -1
- package/dist/client/assets/{index-Co0BifvH.js → index-DJlBcjuS.js} +1 -1
- package/dist/client/assets/{index-vgGRpYpH.js → index-DSUNlkvo.js} +1 -1
- package/dist/client/assets/{index-BcU6fwij.js → index-Dc6DOl2V.js} +1 -1
- package/dist/client/assets/{index-ufFGOVtC.js → index-Dg2MZcDG.js} +1 -1
- package/dist/client/assets/{index-9FdHLIm3.js → index-PQDlzdDe.js} +1 -1
- package/dist/client/assets/{index-CQzYQxW2.js → index-secZqOa5.js} +1 -1
- package/dist/client/assets/{infoDiagram-HS3SLOUP-AFDG1cfu.js → infoDiagram-HS3SLOUP-GzU-nr0a.js} +1 -1
- package/dist/client/assets/{journeyDiagram-XKPGCS4Q-OD_QroD7.js → journeyDiagram-XKPGCS4Q-Dv_GZIcq.js} +1 -1
- package/dist/client/assets/{kanban-definition-3W4ZIXB7-DAnN30hM.js → kanban-definition-3W4ZIXB7-BuCDku9Z.js} +1 -1
- package/dist/client/assets/{layout-B5dwS7ni.js → layout-C1BWvm3U.js} +1 -1
- package/dist/client/assets/{main-BbrdKUoC.js → main-CW1tJAHn.js} +314 -310
- package/dist/client/assets/main-CYIZgqYb.css +1 -0
- package/dist/client/assets/{mindmap-definition-VGOIOE7T-AKV3Q3Hd.js → mindmap-definition-VGOIOE7T-D-ySOJ80.js} +1 -1
- package/dist/client/assets/{pieDiagram-ADFJNKIX-i4GRsEWp.js → pieDiagram-ADFJNKIX-BCPXro4s.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-AYHSOK5B-DNSnhdH3.js → quadrantDiagram-AYHSOK5B-6iX-Hvg-.js} +1 -1
- package/dist/client/assets/{requirementDiagram-UZGBJVZJ-iUlIxrQo.js → requirementDiagram-UZGBJVZJ-CZu5itKP.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-TZEHDZUN-BSJNlHPV.js → sankeyDiagram-TZEHDZUN-C7dzQDVd.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-WL72ISMW-CjyKPEZX.js → sequenceDiagram-WL72ISMW-Q9GYKo64.js} +1 -1
- package/dist/client/assets/{stateDiagram-FKZM4ZOC-DpwtZO7l.js → stateDiagram-FKZM4ZOC-DcAjq5pM.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-4FDKWEC3-D0LqsI9r.js +1 -0
- package/dist/client/assets/{timeline-definition-IT6M3QCI-C36BxQGp.js → timeline-definition-IT6M3QCI-CkyryJCh.js} +1 -1
- package/dist/client/assets/{treemap-GDKQZRPO-B4ZwYsLv.js → treemap-GDKQZRPO-BW9t3c2Z.js} +1 -1
- package/dist/client/assets/{worktree._worktreeId-BuDv4Wcj.js → worktree._worktreeId-BvQb_KmW.js} +1 -1
- package/dist/client/assets/{worktree._worktreeId-7gZfrkWN.js → worktree._worktreeId-CWpDyVL-.js} +1 -1
- package/dist/client/assets/{xychartDiagram-PRI3JC2R-B5IPrNpQ.js → xychartDiagram-PRI3JC2R-DxUmnBlk.js} +1 -1
- package/dist/openapi.json +759 -260
- package/dist/start-server.mjs +1216 -548
- package/package.json +11 -11
- package/dist/client/assets/channel-Cw0fhbpQ.js +0 -1
- package/dist/client/assets/classDiagram-2ON5EDUG-B6EGY8M-.js +0 -1
- package/dist/client/assets/classDiagram-v2-WZHVMYZB-B6EGY8M-.js +0 -1
- package/dist/client/assets/clone-BfwFgnQO.js +0 -1
- package/dist/client/assets/main-CsceWi1l.css +0 -1
- package/dist/client/assets/stateDiagram-v2-4FDKWEC3-Cq_p4YyT.js +0 -1
package/dist/start-server.mjs
CHANGED
|
@@ -2136,7 +2136,7 @@ var require_thread_stream = __commonJS({
|
|
|
2136
2136
|
var { version: version3 } = require_package();
|
|
2137
2137
|
var { EventEmitter: EventEmitter4 } = __require("events");
|
|
2138
2138
|
var { Worker: Worker2 } = __require("worker_threads");
|
|
2139
|
-
var { join:
|
|
2139
|
+
var { join: join63 } = __require("path");
|
|
2140
2140
|
var { pathToFileURL } = __require("url");
|
|
2141
2141
|
var { wait } = require_wait();
|
|
2142
2142
|
var {
|
|
@@ -2172,7 +2172,7 @@ var require_thread_stream = __commonJS({
|
|
|
2172
2172
|
function createWorker(stream, opts) {
|
|
2173
2173
|
const { filename, workerData } = opts;
|
|
2174
2174
|
const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
|
|
2175
|
-
const toExecute = bundlerOverrides["thread-stream-worker"] ||
|
|
2175
|
+
const toExecute = bundlerOverrides["thread-stream-worker"] || join63(__dirname, "lib", "worker.js");
|
|
2176
2176
|
const worker2 = new Worker2(toExecute, {
|
|
2177
2177
|
...opts.workerOpts,
|
|
2178
2178
|
trackUnmanagedFds: false,
|
|
@@ -2558,7 +2558,7 @@ var require_transport = __commonJS({
|
|
|
2558
2558
|
"use strict";
|
|
2559
2559
|
var { createRequire: createRequire3 } = __require("module");
|
|
2560
2560
|
var getCallers = require_caller();
|
|
2561
|
-
var { join:
|
|
2561
|
+
var { join: join63, isAbsolute: isAbsolute7, sep: sep13 } = __require("node:path");
|
|
2562
2562
|
var sleep3 = require_atomic_sleep();
|
|
2563
2563
|
var onExit = require_on_exit_leak_free();
|
|
2564
2564
|
var ThreadStream = require_thread_stream();
|
|
@@ -2621,7 +2621,7 @@ var require_transport = __commonJS({
|
|
|
2621
2621
|
throw new Error("only one of target or targets can be specified");
|
|
2622
2622
|
}
|
|
2623
2623
|
if (targets) {
|
|
2624
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
2624
|
+
target = bundlerOverrides["pino-worker"] || join63(__dirname, "worker.js");
|
|
2625
2625
|
options.targets = targets.filter((dest) => dest.target).map((dest) => {
|
|
2626
2626
|
return {
|
|
2627
2627
|
...dest,
|
|
@@ -2639,7 +2639,7 @@ var require_transport = __commonJS({
|
|
|
2639
2639
|
});
|
|
2640
2640
|
});
|
|
2641
2641
|
} else if (pipeline4) {
|
|
2642
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
2642
|
+
target = bundlerOverrides["pino-worker"] || join63(__dirname, "worker.js");
|
|
2643
2643
|
options.pipelines = [pipeline4.map((dest) => {
|
|
2644
2644
|
return {
|
|
2645
2645
|
...dest,
|
|
@@ -2661,7 +2661,7 @@ var require_transport = __commonJS({
|
|
|
2661
2661
|
return origin;
|
|
2662
2662
|
}
|
|
2663
2663
|
if (origin === "pino/file") {
|
|
2664
|
-
return
|
|
2664
|
+
return join63(__dirname, "..", "file.js");
|
|
2665
2665
|
}
|
|
2666
2666
|
let fixTarget2;
|
|
2667
2667
|
for (const filePath of callers) {
|
|
@@ -3650,7 +3650,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
3650
3650
|
return circularValue;
|
|
3651
3651
|
}
|
|
3652
3652
|
let res = "";
|
|
3653
|
-
let
|
|
3653
|
+
let join63 = ",";
|
|
3654
3654
|
const originalIndentation = indentation;
|
|
3655
3655
|
if (Array.isArray(value)) {
|
|
3656
3656
|
if (value.length === 0) {
|
|
@@ -3664,7 +3664,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
3664
3664
|
indentation += spacer;
|
|
3665
3665
|
res += `
|
|
3666
3666
|
${indentation}`;
|
|
3667
|
-
|
|
3667
|
+
join63 = `,
|
|
3668
3668
|
${indentation}`;
|
|
3669
3669
|
}
|
|
3670
3670
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -3672,13 +3672,13 @@ ${indentation}`;
|
|
|
3672
3672
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
3673
3673
|
const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
3674
3674
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
3675
|
-
res +=
|
|
3675
|
+
res += join63;
|
|
3676
3676
|
}
|
|
3677
3677
|
const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
3678
3678
|
res += tmp !== void 0 ? tmp : "null";
|
|
3679
3679
|
if (value.length - 1 > maximumBreadth) {
|
|
3680
3680
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
3681
|
-
res += `${
|
|
3681
|
+
res += `${join63}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
3682
3682
|
}
|
|
3683
3683
|
if (spacer !== "") {
|
|
3684
3684
|
res += `
|
|
@@ -3699,7 +3699,7 @@ ${originalIndentation}`;
|
|
|
3699
3699
|
let separator = "";
|
|
3700
3700
|
if (spacer !== "") {
|
|
3701
3701
|
indentation += spacer;
|
|
3702
|
-
|
|
3702
|
+
join63 = `,
|
|
3703
3703
|
${indentation}`;
|
|
3704
3704
|
whitespace = " ";
|
|
3705
3705
|
}
|
|
@@ -3713,13 +3713,13 @@ ${indentation}`;
|
|
|
3713
3713
|
const tmp = stringifyFnReplacer(key3, value, stack, replacer, spacer, indentation);
|
|
3714
3714
|
if (tmp !== void 0) {
|
|
3715
3715
|
res += `${separator}${strEscape(key3)}:${whitespace}${tmp}`;
|
|
3716
|
-
separator =
|
|
3716
|
+
separator = join63;
|
|
3717
3717
|
}
|
|
3718
3718
|
}
|
|
3719
3719
|
if (keyLength > maximumBreadth) {
|
|
3720
3720
|
const removedKeys = keyLength - maximumBreadth;
|
|
3721
3721
|
res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
|
|
3722
|
-
separator =
|
|
3722
|
+
separator = join63;
|
|
3723
3723
|
}
|
|
3724
3724
|
if (spacer !== "" && separator.length > 1) {
|
|
3725
3725
|
res = `
|
|
@@ -3760,7 +3760,7 @@ ${originalIndentation}`;
|
|
|
3760
3760
|
}
|
|
3761
3761
|
const originalIndentation = indentation;
|
|
3762
3762
|
let res = "";
|
|
3763
|
-
let
|
|
3763
|
+
let join63 = ",";
|
|
3764
3764
|
if (Array.isArray(value)) {
|
|
3765
3765
|
if (value.length === 0) {
|
|
3766
3766
|
return "[]";
|
|
@@ -3773,7 +3773,7 @@ ${originalIndentation}`;
|
|
|
3773
3773
|
indentation += spacer;
|
|
3774
3774
|
res += `
|
|
3775
3775
|
${indentation}`;
|
|
3776
|
-
|
|
3776
|
+
join63 = `,
|
|
3777
3777
|
${indentation}`;
|
|
3778
3778
|
}
|
|
3779
3779
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -3781,13 +3781,13 @@ ${indentation}`;
|
|
|
3781
3781
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
3782
3782
|
const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
3783
3783
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
3784
|
-
res +=
|
|
3784
|
+
res += join63;
|
|
3785
3785
|
}
|
|
3786
3786
|
const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
3787
3787
|
res += tmp !== void 0 ? tmp : "null";
|
|
3788
3788
|
if (value.length - 1 > maximumBreadth) {
|
|
3789
3789
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
3790
|
-
res += `${
|
|
3790
|
+
res += `${join63}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
3791
3791
|
}
|
|
3792
3792
|
if (spacer !== "") {
|
|
3793
3793
|
res += `
|
|
@@ -3800,7 +3800,7 @@ ${originalIndentation}`;
|
|
|
3800
3800
|
let whitespace = "";
|
|
3801
3801
|
if (spacer !== "") {
|
|
3802
3802
|
indentation += spacer;
|
|
3803
|
-
|
|
3803
|
+
join63 = `,
|
|
3804
3804
|
${indentation}`;
|
|
3805
3805
|
whitespace = " ";
|
|
3806
3806
|
}
|
|
@@ -3809,7 +3809,7 @@ ${indentation}`;
|
|
|
3809
3809
|
const tmp = stringifyArrayReplacer(key3, value[key3], stack, replacer, spacer, indentation);
|
|
3810
3810
|
if (tmp !== void 0) {
|
|
3811
3811
|
res += `${separator}${strEscape(key3)}:${whitespace}${tmp}`;
|
|
3812
|
-
separator =
|
|
3812
|
+
separator = join63;
|
|
3813
3813
|
}
|
|
3814
3814
|
}
|
|
3815
3815
|
if (spacer !== "" && separator.length > 1) {
|
|
@@ -3867,20 +3867,20 @@ ${originalIndentation}`;
|
|
|
3867
3867
|
indentation += spacer;
|
|
3868
3868
|
let res2 = `
|
|
3869
3869
|
${indentation}`;
|
|
3870
|
-
const
|
|
3870
|
+
const join64 = `,
|
|
3871
3871
|
${indentation}`;
|
|
3872
3872
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
3873
3873
|
let i = 0;
|
|
3874
3874
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
3875
3875
|
const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
3876
3876
|
res2 += tmp2 !== void 0 ? tmp2 : "null";
|
|
3877
|
-
res2 +=
|
|
3877
|
+
res2 += join64;
|
|
3878
3878
|
}
|
|
3879
3879
|
const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
3880
3880
|
res2 += tmp !== void 0 ? tmp : "null";
|
|
3881
3881
|
if (value.length - 1 > maximumBreadth) {
|
|
3882
3882
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
3883
|
-
res2 += `${
|
|
3883
|
+
res2 += `${join64}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
3884
3884
|
}
|
|
3885
3885
|
res2 += `
|
|
3886
3886
|
${originalIndentation}`;
|
|
@@ -3896,16 +3896,16 @@ ${originalIndentation}`;
|
|
|
3896
3896
|
return '"[Object]"';
|
|
3897
3897
|
}
|
|
3898
3898
|
indentation += spacer;
|
|
3899
|
-
const
|
|
3899
|
+
const join63 = `,
|
|
3900
3900
|
${indentation}`;
|
|
3901
3901
|
let res = "";
|
|
3902
3902
|
let separator = "";
|
|
3903
3903
|
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
|
|
3904
3904
|
if (isTypedArrayWithEntries(value)) {
|
|
3905
|
-
res += stringifyTypedArray(value,
|
|
3905
|
+
res += stringifyTypedArray(value, join63, maximumBreadth);
|
|
3906
3906
|
keys = keys.slice(value.length);
|
|
3907
3907
|
maximumPropertiesToStringify -= value.length;
|
|
3908
|
-
separator =
|
|
3908
|
+
separator = join63;
|
|
3909
3909
|
}
|
|
3910
3910
|
if (deterministic) {
|
|
3911
3911
|
keys = sort(keys, comparator2);
|
|
@@ -3916,13 +3916,13 @@ ${indentation}`;
|
|
|
3916
3916
|
const tmp = stringifyIndent(key3, value[key3], stack, spacer, indentation);
|
|
3917
3917
|
if (tmp !== void 0) {
|
|
3918
3918
|
res += `${separator}${strEscape(key3)}: ${tmp}`;
|
|
3919
|
-
separator =
|
|
3919
|
+
separator = join63;
|
|
3920
3920
|
}
|
|
3921
3921
|
}
|
|
3922
3922
|
if (keyLength > maximumBreadth) {
|
|
3923
3923
|
const removedKeys = keyLength - maximumBreadth;
|
|
3924
3924
|
res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
|
|
3925
|
-
separator =
|
|
3925
|
+
separator = join63;
|
|
3926
3926
|
}
|
|
3927
3927
|
if (separator !== "") {
|
|
3928
3928
|
res = `
|
|
@@ -4289,7 +4289,7 @@ var require_pino = __commonJS({
|
|
|
4289
4289
|
} = symbols;
|
|
4290
4290
|
var { epochTime, nullTime } = time6;
|
|
4291
4291
|
var { pid } = process;
|
|
4292
|
-
var
|
|
4292
|
+
var hostname7 = os.hostname();
|
|
4293
4293
|
var defaultErrorSerializer = stdSerializers.err;
|
|
4294
4294
|
var defaultOptions2 = {
|
|
4295
4295
|
level: "info",
|
|
@@ -4299,7 +4299,7 @@ var require_pino = __commonJS({
|
|
|
4299
4299
|
errorKey: "err",
|
|
4300
4300
|
nestedKey: null,
|
|
4301
4301
|
enabled: true,
|
|
4302
|
-
base: { pid, hostname:
|
|
4302
|
+
base: { pid, hostname: hostname7 },
|
|
4303
4303
|
serializers: Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
4304
4304
|
err: defaultErrorSerializer
|
|
4305
4305
|
}),
|
|
@@ -4604,9 +4604,9 @@ function checkEndpointOwner(socketPath) {
|
|
|
4604
4604
|
}
|
|
4605
4605
|
return "ok";
|
|
4606
4606
|
}
|
|
4607
|
-
function entryIdentity(path2,
|
|
4607
|
+
function entryIdentity(path2, stat9) {
|
|
4608
4608
|
try {
|
|
4609
|
-
const stats =
|
|
4609
|
+
const stats = stat9(path2, { bigint: true });
|
|
4610
4610
|
return { dev: stats.dev, ino: stats.ino };
|
|
4611
4611
|
} catch {
|
|
4612
4612
|
return null;
|
|
@@ -15184,7 +15184,7 @@ var require_stream = __commonJS({
|
|
|
15184
15184
|
};
|
|
15185
15185
|
duplex._final = function(callback) {
|
|
15186
15186
|
if (ws.readyState === ws.CONNECTING) {
|
|
15187
|
-
ws.once("open", function
|
|
15187
|
+
ws.once("open", function open3() {
|
|
15188
15188
|
duplex._final(callback);
|
|
15189
15189
|
});
|
|
15190
15190
|
return;
|
|
@@ -15205,7 +15205,7 @@ var require_stream = __commonJS({
|
|
|
15205
15205
|
};
|
|
15206
15206
|
duplex._write = function(chunk, encoding, callback) {
|
|
15207
15207
|
if (ws.readyState === ws.CONNECTING) {
|
|
15208
|
-
ws.once("open", function
|
|
15208
|
+
ws.once("open", function open3() {
|
|
15209
15209
|
duplex._write(chunk, encoding, callback);
|
|
15210
15210
|
});
|
|
15211
15211
|
return;
|
|
@@ -16489,6 +16489,13 @@ var init_pty2 = __esm({
|
|
|
16489
16489
|
}
|
|
16490
16490
|
});
|
|
16491
16491
|
|
|
16492
|
+
// ../../packages/host-api/src/resources.ts
|
|
16493
|
+
var init_resources = __esm({
|
|
16494
|
+
"../../packages/host-api/src/resources.ts"() {
|
|
16495
|
+
"use strict";
|
|
16496
|
+
}
|
|
16497
|
+
});
|
|
16498
|
+
|
|
16492
16499
|
// ../../packages/host-api/src/index.ts
|
|
16493
16500
|
var init_src3 = __esm({
|
|
16494
16501
|
"../../packages/host-api/src/index.ts"() {
|
|
@@ -16498,6 +16505,7 @@ var init_src3 = __esm({
|
|
|
16498
16505
|
init_git_run();
|
|
16499
16506
|
init_host();
|
|
16500
16507
|
init_pty2();
|
|
16508
|
+
init_resources();
|
|
16501
16509
|
}
|
|
16502
16510
|
});
|
|
16503
16511
|
|
|
@@ -16835,6 +16843,8 @@ var init_rpc = __esm({
|
|
|
16835
16843
|
"fs.copy": 5 * 6e4,
|
|
16836
16844
|
"fs.rm": 2 * 6e4,
|
|
16837
16845
|
"fs.du": 2 * 6e4,
|
|
16846
|
+
// Measures every worktree of a worker, three `du` at a time.
|
|
16847
|
+
"resources.storage": 10 * 6e4,
|
|
16838
16848
|
"fs.glob": 6e4,
|
|
16839
16849
|
"search.listFiles": 6e4,
|
|
16840
16850
|
"scripts.runHidden": 10 * 6e4,
|
|
@@ -17061,6 +17071,10 @@ var init_remote_host = __esm({
|
|
|
17061
17071
|
return duplexOf(this.rpc.channel(reply.chan));
|
|
17062
17072
|
}
|
|
17063
17073
|
};
|
|
17074
|
+
resources = {
|
|
17075
|
+
snapshot: () => this.rpc.call("resources.snapshot", {}),
|
|
17076
|
+
storage: (request) => this.rpc.call("resources.storage", request)
|
|
17077
|
+
};
|
|
17064
17078
|
speech = {
|
|
17065
17079
|
transcribe: async (req) => {
|
|
17066
17080
|
const { audio, ...rest } = req;
|
|
@@ -17128,7 +17142,7 @@ var init_remote_host = __esm({
|
|
|
17128
17142
|
// The worker keeps the browser. `browser.connect` opens one channel of length-prefixed CDP
|
|
17129
17143
|
// messages, and resetting it drops the connection but not the browser.
|
|
17130
17144
|
browser = {
|
|
17131
|
-
open: (spec) => this.rpc.call("browser.open", spec, { timeoutMs:
|
|
17145
|
+
open: (spec) => this.rpc.call("browser.open", spec, { timeoutMs: 15e4 }),
|
|
17132
17146
|
connect: async (worktreeId4) => {
|
|
17133
17147
|
const reply = await this.rpc.request("browser.connect", { worktreeId: worktreeId4 });
|
|
17134
17148
|
const ch = this.rpc.channel(reply.chan);
|
|
@@ -20859,9 +20873,9 @@ function parseURLObject(trimmed, def) {
|
|
|
20859
20873
|
function stripTabAndNewline(value) {
|
|
20860
20874
|
return value.replace(asciiTabOrNewline, "");
|
|
20861
20875
|
}
|
|
20862
|
-
function urlHostnameOk(url3,
|
|
20863
|
-
|
|
20864
|
-
return
|
|
20876
|
+
function urlHostnameOk(url3, hostname7) {
|
|
20877
|
+
hostname7.lastIndex = 0;
|
|
20878
|
+
return hostname7.test(url3.hostname);
|
|
20865
20879
|
}
|
|
20866
20880
|
function urlProtocolOk(url3, protocol) {
|
|
20867
20881
|
protocol.lastIndex = 0;
|
|
@@ -38570,7 +38584,7 @@ function visit(schema, fnOrHandlers) {
|
|
|
38570
38584
|
return h ? h(node2, rewritten) : node2;
|
|
38571
38585
|
};
|
|
38572
38586
|
const cache2 = /* @__PURE__ */ new Map();
|
|
38573
|
-
function
|
|
38587
|
+
function run4(s2) {
|
|
38574
38588
|
const cached4 = cache2.get(s2);
|
|
38575
38589
|
if (cached4 === RESOLVING) {
|
|
38576
38590
|
return new $ZodLazy({
|
|
@@ -38596,21 +38610,21 @@ function visit(schema, fnOrHandlers) {
|
|
|
38596
38610
|
let changed = false;
|
|
38597
38611
|
const newShape = {};
|
|
38598
38612
|
for (const k2 of keys) {
|
|
38599
|
-
const mapped =
|
|
38613
|
+
const mapped = run4(oldShape[k2]);
|
|
38600
38614
|
if (mapped !== oldShape[k2])
|
|
38601
38615
|
changed = true;
|
|
38602
38616
|
newShape[k2] = mapped;
|
|
38603
38617
|
}
|
|
38604
38618
|
let newCatchall = def.catchall;
|
|
38605
38619
|
if (def.catchall) {
|
|
38606
|
-
newCatchall =
|
|
38620
|
+
newCatchall = run4(def.catchall);
|
|
38607
38621
|
if (newCatchall !== def.catchall)
|
|
38608
38622
|
changed = true;
|
|
38609
38623
|
}
|
|
38610
38624
|
return changed ? clone(s2, { ...def, shape: newShape, catchall: newCatchall }) : s2;
|
|
38611
38625
|
}
|
|
38612
38626
|
case "array": {
|
|
38613
|
-
const mapped =
|
|
38627
|
+
const mapped = run4(def.element);
|
|
38614
38628
|
return mapped === def.element ? s2 : clone(s2, { ...def, element: mapped });
|
|
38615
38629
|
}
|
|
38616
38630
|
case "tuple": {
|
|
@@ -38618,14 +38632,14 @@ function visit(schema, fnOrHandlers) {
|
|
|
38618
38632
|
let changed = false;
|
|
38619
38633
|
const newItems = [];
|
|
38620
38634
|
for (const item of oldItems) {
|
|
38621
|
-
const mapped =
|
|
38635
|
+
const mapped = run4(item);
|
|
38622
38636
|
if (mapped !== item)
|
|
38623
38637
|
changed = true;
|
|
38624
38638
|
newItems.push(mapped);
|
|
38625
38639
|
}
|
|
38626
38640
|
let newRest = def.rest;
|
|
38627
38641
|
if (def.rest) {
|
|
38628
|
-
newRest =
|
|
38642
|
+
newRest = run4(def.rest);
|
|
38629
38643
|
if (newRest !== def.rest)
|
|
38630
38644
|
changed = true;
|
|
38631
38645
|
}
|
|
@@ -38633,12 +38647,12 @@ function visit(schema, fnOrHandlers) {
|
|
|
38633
38647
|
}
|
|
38634
38648
|
case "record":
|
|
38635
38649
|
case "map": {
|
|
38636
|
-
const newKey =
|
|
38637
|
-
const newVal =
|
|
38650
|
+
const newKey = run4(def.keyType);
|
|
38651
|
+
const newVal = run4(def.valueType);
|
|
38638
38652
|
return newKey === def.keyType && newVal === def.valueType ? s2 : clone(s2, { ...def, keyType: newKey, valueType: newVal });
|
|
38639
38653
|
}
|
|
38640
38654
|
case "set": {
|
|
38641
|
-
const newVal =
|
|
38655
|
+
const newVal = run4(def.valueType);
|
|
38642
38656
|
return newVal === def.valueType ? s2 : clone(s2, { ...def, valueType: newVal });
|
|
38643
38657
|
}
|
|
38644
38658
|
case "union": {
|
|
@@ -38646,7 +38660,7 @@ function visit(schema, fnOrHandlers) {
|
|
|
38646
38660
|
let changed = false;
|
|
38647
38661
|
const newOptions = [];
|
|
38648
38662
|
for (const opt of oldOptions) {
|
|
38649
|
-
const mapped =
|
|
38663
|
+
const mapped = run4(opt);
|
|
38650
38664
|
if (mapped !== opt)
|
|
38651
38665
|
changed = true;
|
|
38652
38666
|
newOptions.push(mapped);
|
|
@@ -38654,8 +38668,8 @@ function visit(schema, fnOrHandlers) {
|
|
|
38654
38668
|
return changed ? clone(s2, { ...def, options: newOptions }) : s2;
|
|
38655
38669
|
}
|
|
38656
38670
|
case "intersection": {
|
|
38657
|
-
const newLeft =
|
|
38658
|
-
const newRight =
|
|
38671
|
+
const newLeft = run4(def.left);
|
|
38672
|
+
const newRight = run4(def.right);
|
|
38659
38673
|
return newLeft === def.left && newRight === def.right ? s2 : clone(s2, { ...def, left: newLeft, right: newRight });
|
|
38660
38674
|
}
|
|
38661
38675
|
case "optional":
|
|
@@ -38667,23 +38681,23 @@ function visit(schema, fnOrHandlers) {
|
|
|
38667
38681
|
case "nonoptional":
|
|
38668
38682
|
case "promise":
|
|
38669
38683
|
case "success": {
|
|
38670
|
-
const newInner =
|
|
38684
|
+
const newInner = run4(def.innerType);
|
|
38671
38685
|
return newInner === def.innerType ? s2 : clone(s2, { ...def, innerType: newInner });
|
|
38672
38686
|
}
|
|
38673
38687
|
case "pipe": {
|
|
38674
|
-
const newIn =
|
|
38675
|
-
const newOut =
|
|
38688
|
+
const newIn = run4(def.in);
|
|
38689
|
+
const newOut = run4(def.out);
|
|
38676
38690
|
return newIn === def.in && newOut === def.out ? s2 : clone(s2, { ...def, in: newIn, out: newOut });
|
|
38677
38691
|
}
|
|
38678
38692
|
case "function": {
|
|
38679
|
-
const newInput =
|
|
38680
|
-
const newOutput =
|
|
38693
|
+
const newInput = run4(def.input);
|
|
38694
|
+
const newOutput = run4(def.output);
|
|
38681
38695
|
return newInput === def.input && newOutput === def.output ? s2 : clone(s2, { ...def, input: newInput, output: newOutput });
|
|
38682
38696
|
}
|
|
38683
38697
|
case "lazy": {
|
|
38684
38698
|
const original = def.getter;
|
|
38685
38699
|
const { _cachedInner, ...rest } = def;
|
|
38686
|
-
return clone(s2, { ...rest, getter: () =>
|
|
38700
|
+
return clone(s2, { ...rest, getter: () => run4(original()) });
|
|
38687
38701
|
}
|
|
38688
38702
|
// A leaf by choice: `parts` are regex fragments, not data positions.
|
|
38689
38703
|
case "template_literal":
|
|
@@ -38714,7 +38728,7 @@ function visit(schema, fnOrHandlers) {
|
|
|
38714
38728
|
}
|
|
38715
38729
|
}
|
|
38716
38730
|
}
|
|
38717
|
-
return
|
|
38731
|
+
return run4(schema);
|
|
38718
38732
|
}
|
|
38719
38733
|
var RESOLVING;
|
|
38720
38734
|
var init_visit = __esm({
|
|
@@ -43517,27 +43531,27 @@ function textChunk(row) {
|
|
|
43517
43531
|
}
|
|
43518
43532
|
function rowsToEvents(rows) {
|
|
43519
43533
|
const out = [];
|
|
43520
|
-
let
|
|
43534
|
+
let run4 = null;
|
|
43521
43535
|
const flush = () => {
|
|
43522
|
-
if (!
|
|
43536
|
+
if (!run4) return;
|
|
43523
43537
|
out.push({
|
|
43524
43538
|
type: "update",
|
|
43525
|
-
update: { ...
|
|
43526
|
-
eventId:
|
|
43527
|
-
createdAt:
|
|
43539
|
+
update: { ...run4.update, content: { type: "text", text: run4.text } },
|
|
43540
|
+
eventId: run4.lastId,
|
|
43541
|
+
createdAt: run4.createdAt
|
|
43528
43542
|
});
|
|
43529
|
-
|
|
43543
|
+
run4 = null;
|
|
43530
43544
|
};
|
|
43531
43545
|
for (const row of rows) {
|
|
43532
43546
|
const chunk = textChunk(row);
|
|
43533
|
-
if (chunk &&
|
|
43534
|
-
if (chunk.content.type === "text")
|
|
43535
|
-
|
|
43547
|
+
if (chunk && run4 && run4.update.sessionUpdate === chunk.sessionUpdate && (run4.update.messageId ?? null) === (chunk.messageId ?? null)) {
|
|
43548
|
+
if (chunk.content.type === "text") run4.text += chunk.content.text;
|
|
43549
|
+
run4.lastId = row.id;
|
|
43536
43550
|
continue;
|
|
43537
43551
|
}
|
|
43538
43552
|
flush();
|
|
43539
43553
|
if (chunk) {
|
|
43540
|
-
|
|
43554
|
+
run4 = {
|
|
43541
43555
|
update: chunk,
|
|
43542
43556
|
text: chunk.content.type === "text" ? chunk.content.text : "",
|
|
43543
43557
|
lastId: row.id,
|
|
@@ -43831,10 +43845,10 @@ var init_table = __esm({
|
|
|
43831
43845
|
[IsDrizzleTable] = true;
|
|
43832
43846
|
/** @internal */
|
|
43833
43847
|
[ExtraConfigBuilder] = void 0;
|
|
43834
|
-
constructor(name5, schema,
|
|
43848
|
+
constructor(name5, schema, baseName2) {
|
|
43835
43849
|
this[TableName] = this[OriginalName] = name5;
|
|
43836
43850
|
this[TableSchema] = schema;
|
|
43837
|
-
this[BaseName] =
|
|
43851
|
+
this[BaseName] = baseName2;
|
|
43838
43852
|
}
|
|
43839
43853
|
};
|
|
43840
43854
|
}
|
|
@@ -44191,7 +44205,7 @@ var init_sql = __esm({
|
|
|
44191
44205
|
return new SQL([new StringChunk(str3)]);
|
|
44192
44206
|
}
|
|
44193
44207
|
_sql.raw = raw;
|
|
44194
|
-
function
|
|
44208
|
+
function join63(chunks, separator) {
|
|
44195
44209
|
const result = [];
|
|
44196
44210
|
for (const [i, chunk] of chunks.entries()) {
|
|
44197
44211
|
if (i > 0 && separator !== void 0) result.push(separator);
|
|
@@ -44199,7 +44213,7 @@ var init_sql = __esm({
|
|
|
44199
44213
|
}
|
|
44200
44214
|
return new SQL(result);
|
|
44201
44215
|
}
|
|
44202
|
-
_sql.join =
|
|
44216
|
+
_sql.join = join63;
|
|
44203
44217
|
function identifier(value) {
|
|
44204
44218
|
return new Name(value);
|
|
44205
44219
|
}
|
|
@@ -45146,9 +45160,9 @@ var init_all = __esm({
|
|
|
45146
45160
|
});
|
|
45147
45161
|
|
|
45148
45162
|
// ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.1_@opentelemetry+api@1.9.0_@types+better-sqlite3@7.6.13_better-sql_2010f6373f8103f640f869e889df39c3/node_modules/drizzle-orm/sqlite-core/table.js
|
|
45149
|
-
function sqliteTableBase(name5, columns, extraConfig, schema, casing,
|
|
45163
|
+
function sqliteTableBase(name5, columns, extraConfig, schema, casing, baseName2 = name5) {
|
|
45150
45164
|
const casingFn = getCasingFn(casing);
|
|
45151
|
-
const rawTable = new SQLiteTable(name5, schema,
|
|
45165
|
+
const rawTable = new SQLiteTable(name5, schema, baseName2);
|
|
45152
45166
|
const parsedColumns = typeof columns === "function" ? columns(getSQLiteColumnBuilders()) : columns;
|
|
45153
45167
|
const builtColumns = Object.fromEntries(Object.entries(parsedColumns).map(([name6, colBuilderBase]) => {
|
|
45154
45168
|
const colBuilder = colBuilderBase;
|
|
@@ -45743,10 +45757,10 @@ var init_table3 = __esm({
|
|
|
45743
45757
|
[IsDrizzleTable2] = true;
|
|
45744
45758
|
/** @internal */
|
|
45745
45759
|
[ExtraConfigBuilder2] = void 0;
|
|
45746
|
-
constructor(name5, schema,
|
|
45760
|
+
constructor(name5, schema, baseName2) {
|
|
45747
45761
|
this[TableName2] = this[OriginalName2] = name5;
|
|
45748
45762
|
this[TableSchema2] = schema;
|
|
45749
|
-
this[BaseName2] =
|
|
45763
|
+
this[BaseName2] = baseName2;
|
|
45750
45764
|
}
|
|
45751
45765
|
};
|
|
45752
45766
|
}
|
|
@@ -46127,7 +46141,7 @@ var init_sql2 = __esm({
|
|
|
46127
46141
|
return new SQL3([new StringChunk2(str3)]);
|
|
46128
46142
|
}
|
|
46129
46143
|
_sql.raw = raw;
|
|
46130
|
-
function
|
|
46144
|
+
function join63(chunks, separator) {
|
|
46131
46145
|
const result = [];
|
|
46132
46146
|
for (const [i, chunk] of chunks.entries()) {
|
|
46133
46147
|
if (i > 0 && separator !== void 0) result.push(separator);
|
|
@@ -46135,7 +46149,7 @@ var init_sql2 = __esm({
|
|
|
46135
46149
|
}
|
|
46136
46150
|
return new SQL3(result);
|
|
46137
46151
|
}
|
|
46138
|
-
_sql.join =
|
|
46152
|
+
_sql.join = join63;
|
|
46139
46153
|
function identifier(value) {
|
|
46140
46154
|
return new Name2(value);
|
|
46141
46155
|
}
|
|
@@ -49667,9 +49681,9 @@ var init_casing2 = __esm({
|
|
|
49667
49681
|
});
|
|
49668
49682
|
|
|
49669
49683
|
// ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.1_@opentelemetry+api@1.9.0_@types+better-sqlite3@7.6.13_better-sql_95478898f63cc8c3fbbd0c5f8c1e464f/node_modules/drizzle-orm/pg-core/table.js
|
|
49670
|
-
function pgTableWithSchema(name5, columns, extraConfig, schema, casing,
|
|
49684
|
+
function pgTableWithSchema(name5, columns, extraConfig, schema, casing, baseName2 = name5) {
|
|
49671
49685
|
const casingFn = getCasingFn2(casing);
|
|
49672
|
-
const rawTable = new PgTable(name5, schema,
|
|
49686
|
+
const rawTable = new PgTable(name5, schema, baseName2);
|
|
49673
49687
|
const parsedColumns = typeof columns === "function" ? columns(getPgColumnBuilders()) : columns;
|
|
49674
49688
|
const builtColumns = Object.fromEntries(Object.entries(parsedColumns).map(([name6, colBuilderBase]) => {
|
|
49675
49689
|
const colBuilder = colBuilderBase;
|
|
@@ -51046,9 +51060,9 @@ var init_all3 = __esm({
|
|
|
51046
51060
|
});
|
|
51047
51061
|
|
|
51048
51062
|
// ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.1_@opentelemetry+api@1.9.0_@types+better-sqlite3@7.6.13_better-sql_95478898f63cc8c3fbbd0c5f8c1e464f/node_modules/drizzle-orm/sqlite-core/table.js
|
|
51049
|
-
function sqliteTableBase2(name5, columns, extraConfig, schema, casing,
|
|
51063
|
+
function sqliteTableBase2(name5, columns, extraConfig, schema, casing, baseName2 = name5) {
|
|
51050
51064
|
const casingFn = getCasingFn2(casing);
|
|
51051
|
-
const rawTable = new SQLiteTable2(name5, schema,
|
|
51065
|
+
const rawTable = new SQLiteTable2(name5, schema, baseName2);
|
|
51052
51066
|
const parsedColumns = typeof columns === "function" ? columns(getSQLiteColumnBuilders2()) : columns;
|
|
51053
51067
|
const builtColumns = Object.fromEntries(Object.entries(parsedColumns).map(([name6, colBuilderBase]) => {
|
|
51054
51068
|
const colBuilder = colBuilderBase;
|
|
@@ -51328,7 +51342,7 @@ var init_select3 = __esm({
|
|
|
51328
51342
|
const baseTableName = this.tableName;
|
|
51329
51343
|
const tableName = getTableLikeName(table);
|
|
51330
51344
|
for (const item of extractUsedTable(table)) this.usedTables.add(item);
|
|
51331
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
51345
|
+
if (typeof tableName === "string" && this.config.joins?.some((join63) => join63.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
51332
51346
|
if (!this.isPartialSelect) {
|
|
51333
51347
|
if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
|
|
51334
51348
|
if (typeof tableName === "string" && !is2(table, SQL3)) {
|
|
@@ -52593,7 +52607,7 @@ var init_dialect = __esm({
|
|
|
52593
52607
|
if (!joins2) return;
|
|
52594
52608
|
const withEntries = Object.entries(joins2).filter(([_2, v2]) => v2);
|
|
52595
52609
|
if (!withEntries.length) return;
|
|
52596
|
-
return sql2.join(withEntries.map(([k2,
|
|
52610
|
+
return sql2.join(withEntries.map(([k2, join63]) => {
|
|
52597
52611
|
const relation = tableConfig.relations[k2];
|
|
52598
52612
|
const isSingle2 = is2(relation, One);
|
|
52599
52613
|
const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
|
|
@@ -52604,7 +52618,7 @@ var init_dialect = __esm({
|
|
|
52604
52618
|
table: targetTable,
|
|
52605
52619
|
mode: isSingle2 ? "first" : "many",
|
|
52606
52620
|
schema,
|
|
52607
|
-
queryConfig:
|
|
52621
|
+
queryConfig: join63,
|
|
52608
52622
|
tableConfig: schema[relation.targetTableName],
|
|
52609
52623
|
relationWhere: filter,
|
|
52610
52624
|
isNested: true,
|
|
@@ -52618,7 +52632,7 @@ var init_dialect = __esm({
|
|
|
52618
52632
|
key: k2,
|
|
52619
52633
|
selection: innerQuery.selection,
|
|
52620
52634
|
isArray: !isSingle2,
|
|
52621
|
-
isOptional: (relation.optional ?? false) ||
|
|
52635
|
+
isOptional: (relation.optional ?? false) || join63 !== true && !!join63.where
|
|
52622
52636
|
});
|
|
52623
52637
|
const jsonColumns = sql2.join(innerQuery.selection.map((s2) => {
|
|
52624
52638
|
return sql2`${sql2.raw(this.escapeString(s2.key))}, ${s2.selection ? sql2`${jsonb2}(${sql2.identifier(s2.key)})` : sql2.identifier(s2.key)}`;
|
|
@@ -53137,7 +53151,7 @@ var init_update = __esm({
|
|
|
53137
53151
|
createJoin(joinType) {
|
|
53138
53152
|
return ((table, on) => {
|
|
53139
53153
|
const tableName = getTableLikeName(table);
|
|
53140
|
-
if (typeof tableName === "string" && this.config.joins.some((
|
|
53154
|
+
if (typeof tableName === "string" && this.config.joins.some((join63) => join63.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
53141
53155
|
if (typeof on === "function") {
|
|
53142
53156
|
const from = this.config.from ? is2(table, SQLiteTable2) ? table[Table2.Symbol.Columns] : is2(table, Subquery2) ? table._.selectedFields : is2(table, SQLiteViewBase) ? table[ViewBaseConfig2].selectedFields : void 0 : void 0;
|
|
53143
53157
|
on = on(new Proxy(this.config.table[Table2.Symbol.Columns], new SelectionProxyHandler({
|
|
@@ -56294,7 +56308,7 @@ var init_held_agent = __esm({
|
|
|
56294
56308
|
});
|
|
56295
56309
|
if (!record4) return null;
|
|
56296
56310
|
handle = new _HeldAgentProcess(holder, record4, offsets);
|
|
56297
|
-
for (const
|
|
56311
|
+
for (const run4 of pending2) run4();
|
|
56298
56312
|
return handle;
|
|
56299
56313
|
}
|
|
56300
56314
|
get pid() {
|
|
@@ -56885,7 +56899,7 @@ var init_skills_install = __esm({
|
|
|
56885
56899
|
// ../../packages/host-local/src/browser/chromium.ts
|
|
56886
56900
|
import { spawn as spawn2 } from "node:child_process";
|
|
56887
56901
|
import { closeSync as closeSync4, existsSync as existsSync10, openSync as openSync4, readdirSync as readdirSync7 } from "node:fs";
|
|
56888
|
-
import { mkdir as mkdir2, readFile as readFile2, rm } from "node:fs/promises";
|
|
56902
|
+
import { mkdir as mkdir2, readFile as readFile2, rm, stat as stat3 } from "node:fs/promises";
|
|
56889
56903
|
import { homedir as homedir11 } from "node:os";
|
|
56890
56904
|
import { join as join22 } from "node:path";
|
|
56891
56905
|
function playwrightCandidates() {
|
|
@@ -56935,9 +56949,19 @@ function findChromium() {
|
|
|
56935
56949
|
];
|
|
56936
56950
|
return candidates.find((c) => existsSync10(c));
|
|
56937
56951
|
}
|
|
56952
|
+
async function fileSize(path2) {
|
|
56953
|
+
try {
|
|
56954
|
+
return (await stat3(path2)).size;
|
|
56955
|
+
} catch {
|
|
56956
|
+
return 0;
|
|
56957
|
+
}
|
|
56958
|
+
}
|
|
56938
56959
|
async function readDevToolsPort(profileDir, proc, logPath, timeoutMs) {
|
|
56939
56960
|
const file3 = join22(profileDir, "DevToolsActivePort");
|
|
56940
|
-
const
|
|
56961
|
+
const startedAt = Date.now();
|
|
56962
|
+
const hardDeadline = startedAt + timeoutMs * PROGRESS_CAP_FACTOR;
|
|
56963
|
+
let deadline = startedAt + timeoutMs;
|
|
56964
|
+
let lastProgress = "";
|
|
56941
56965
|
while (Date.now() < deadline) {
|
|
56942
56966
|
if (proc.exitCode !== null || proc.signalCode !== null) {
|
|
56943
56967
|
throw new Error("Chromium exited before it opened a DevTools port");
|
|
@@ -56950,6 +56974,16 @@ async function readDevToolsPort(profileDir, proc, logPath, timeoutMs) {
|
|
|
56950
56974
|
if (port && path2) return { port: Number(port), path: path2.trim() };
|
|
56951
56975
|
} catch {
|
|
56952
56976
|
}
|
|
56977
|
+
let entries = 0;
|
|
56978
|
+
try {
|
|
56979
|
+
entries = readdirSync7(profileDir).length;
|
|
56980
|
+
} catch {
|
|
56981
|
+
}
|
|
56982
|
+
const progress = `${entries}:${await fileSize(logPath)}`;
|
|
56983
|
+
if (progress !== lastProgress) {
|
|
56984
|
+
lastProgress = progress;
|
|
56985
|
+
deadline = Math.min(Date.now() + timeoutMs, hardDeadline);
|
|
56986
|
+
}
|
|
56953
56987
|
await sleep(50);
|
|
56954
56988
|
}
|
|
56955
56989
|
throw new StartTimeoutError("Chromium did not open a DevTools port in time");
|
|
@@ -57016,13 +57050,14 @@ function wrapSocket(ws) {
|
|
|
57016
57050
|
}
|
|
57017
57051
|
};
|
|
57018
57052
|
}
|
|
57019
|
-
var FIRST_ATTEMPT_TIMEOUT_MS, RETRY_TIMEOUT_FRACTION, START_ATTEMPTS, SINGLETON_FILES, PROCESS_GROUP_GONE_TIMEOUT_MS, CLOSE_GRACE_MS, sleep, StartTimeoutError, MAX_QUEUED_BYTES, ChromiumManager;
|
|
57053
|
+
var FIRST_ATTEMPT_TIMEOUT_MS, RETRY_TIMEOUT_FRACTION, START_ATTEMPTS, PROGRESS_CAP_FACTOR, SINGLETON_FILES, PROCESS_GROUP_GONE_TIMEOUT_MS, CLOSE_GRACE_MS, sleep, StartTimeoutError, MAX_QUEUED_BYTES, ChromiumManager;
|
|
57020
57054
|
var init_chromium = __esm({
|
|
57021
57055
|
"../../packages/host-local/src/browser/chromium.ts"() {
|
|
57022
57056
|
"use strict";
|
|
57023
57057
|
FIRST_ATTEMPT_TIMEOUT_MS = 2e4;
|
|
57024
57058
|
RETRY_TIMEOUT_FRACTION = 0.6;
|
|
57025
57059
|
START_ATTEMPTS = 3;
|
|
57060
|
+
PROGRESS_CAP_FACTOR = 3;
|
|
57026
57061
|
SINGLETON_FILES = ["SingletonLock", "SingletonCookie", "SingletonSocket"];
|
|
57027
57062
|
PROCESS_GROUP_GONE_TIMEOUT_MS = 5e3;
|
|
57028
57063
|
CLOSE_GRACE_MS = 4e3;
|
|
@@ -57356,7 +57391,7 @@ parentPort.on("message", ({ id, command, args, options }) => {
|
|
|
57356
57391
|
|
|
57357
57392
|
// ../../packages/host-local/src/git/git-client.ts
|
|
57358
57393
|
import { execFile as execFile6 } from "node:child_process";
|
|
57359
|
-
import { readFile as readFile3, stat as
|
|
57394
|
+
import { readFile as readFile3, stat as stat4 } from "node:fs/promises";
|
|
57360
57395
|
import { join as join24 } from "node:path";
|
|
57361
57396
|
function parseGitRemoteUrl(url3) {
|
|
57362
57397
|
const sshMatch = url3.match(/^[\w.-]+@([^:]+):([^/]+)\/(.+?)(?:\.git)?$/);
|
|
@@ -57387,7 +57422,7 @@ async function resolveDetachedBranch(worktreePath) {
|
|
|
57387
57422
|
const dotGit = join24(worktreePath, ".git");
|
|
57388
57423
|
let gitdir;
|
|
57389
57424
|
try {
|
|
57390
|
-
const st = await
|
|
57425
|
+
const st = await stat4(dotGit);
|
|
57391
57426
|
if (st.isDirectory()) {
|
|
57392
57427
|
gitdir = dotGit;
|
|
57393
57428
|
} else {
|
|
@@ -57489,9 +57524,9 @@ async function listWorktrees(repoPath) {
|
|
|
57489
57524
|
if (currentPath) await pushCurrent();
|
|
57490
57525
|
return worktrees2;
|
|
57491
57526
|
}
|
|
57492
|
-
async function getRepoInfo(worktreePath,
|
|
57527
|
+
async function getRepoInfo(worktreePath, run4 = execGit) {
|
|
57493
57528
|
try {
|
|
57494
|
-
const remoteUrl = (await
|
|
57529
|
+
const remoteUrl = (await run4(["remote", "get-url", "origin"], worktreePath)).trim();
|
|
57495
57530
|
const parsed = parseGitRemoteUrl(remoteUrl);
|
|
57496
57531
|
if (!parsed) {
|
|
57497
57532
|
log12.debug('getRepoInfo: failed to parse remote URL "%s" for %s', remoteUrl, worktreePath);
|
|
@@ -62407,7 +62442,7 @@ var init_capabilities2 = __esm({
|
|
|
62407
62442
|
|
|
62408
62443
|
// ../../packages/host-local/src/process/du.ts
|
|
62409
62444
|
import { execFile as execFile8 } from "node:child_process";
|
|
62410
|
-
import { readdir as readdir3, stat as
|
|
62445
|
+
import { readdir as readdir3, stat as stat5 } from "node:fs/promises";
|
|
62411
62446
|
import { join as join27 } from "node:path";
|
|
62412
62447
|
async function duBytesNodeWalk(path2) {
|
|
62413
62448
|
const deadline = Date.now() + DU_TIMEOUT_MS;
|
|
@@ -62430,7 +62465,7 @@ async function duBytesNodeWalk(path2) {
|
|
|
62430
62465
|
if (Date.now() > deadline) break;
|
|
62431
62466
|
const sizes = await Promise.all(
|
|
62432
62467
|
filePaths.slice(i, i + STAT_CHUNK).map(
|
|
62433
|
-
(p2) =>
|
|
62468
|
+
(p2) => stat5(p2).then(
|
|
62434
62469
|
(s2) => s2.size,
|
|
62435
62470
|
() => 0
|
|
62436
62471
|
// vanished between readdir and stat — count as 0
|
|
@@ -62679,7 +62714,7 @@ var init_remote_url = __esm({
|
|
|
62679
62714
|
import { execFile as execFile11 } from "node:child_process";
|
|
62680
62715
|
import { createHash as createHash5, randomBytes as randomBytes4 } from "node:crypto";
|
|
62681
62716
|
import { existsSync as existsSync11 } from "node:fs";
|
|
62682
|
-
import { mkdir as mkdir3, readdir as readdir5, readFile as readFile5, realpath as realpath2, rename as rename2, stat as
|
|
62717
|
+
import { mkdir as mkdir3, readdir as readdir5, readFile as readFile5, realpath as realpath2, rename as rename2, stat as stat6, writeFile as writeFile2 } from "node:fs/promises";
|
|
62683
62718
|
import { homedir as homedir13 } from "node:os";
|
|
62684
62719
|
import { dirname as dirname9, join as join29, sep as sep3 } from "node:path";
|
|
62685
62720
|
function defaultReposDir() {
|
|
@@ -62714,7 +62749,7 @@ function clone2(url3, dest) {
|
|
|
62714
62749
|
}
|
|
62715
62750
|
async function isDirectory(path2) {
|
|
62716
62751
|
try {
|
|
62717
|
-
return (await
|
|
62752
|
+
return (await stat6(path2)).isDirectory();
|
|
62718
62753
|
} catch {
|
|
62719
62754
|
return false;
|
|
62720
62755
|
}
|
|
@@ -62825,11 +62860,11 @@ var init_host_repos = __esm({
|
|
|
62825
62860
|
}
|
|
62826
62861
|
const running = this.ensuring.get(id.key);
|
|
62827
62862
|
if (running) return running;
|
|
62828
|
-
const
|
|
62863
|
+
const run4 = this.doEnsure(id.key, id.url, id.owner, id.name).finally(
|
|
62829
62864
|
() => this.ensuring.delete(id.key)
|
|
62830
62865
|
);
|
|
62831
|
-
this.ensuring.set(id.key,
|
|
62832
|
-
return
|
|
62866
|
+
this.ensuring.set(id.key, run4);
|
|
62867
|
+
return run4;
|
|
62833
62868
|
}
|
|
62834
62869
|
async doEnsure(key2, url3, owner, name5) {
|
|
62835
62870
|
const mappings = await this.load();
|
|
@@ -62859,8 +62894,462 @@ var init_host_repos = __esm({
|
|
|
62859
62894
|
}
|
|
62860
62895
|
});
|
|
62861
62896
|
|
|
62897
|
+
// ../../packages/host-local/src/resources/classify.ts
|
|
62898
|
+
function baseName(command2) {
|
|
62899
|
+
const first = command2.trim().split(/\s+/)[0] ?? "";
|
|
62900
|
+
const name5 = first.split("/").pop() ?? first;
|
|
62901
|
+
return name5.replace(/^-/, "");
|
|
62902
|
+
}
|
|
62903
|
+
function hasRunDir(command2, runDir) {
|
|
62904
|
+
const tokens2 = command2.split(/\s+/);
|
|
62905
|
+
const at = tokens2.indexOf("--run-dir");
|
|
62906
|
+
return at >= 0 && tokens2[at + 1] === runDir;
|
|
62907
|
+
}
|
|
62908
|
+
function classify(rows, opts) {
|
|
62909
|
+
const children = /* @__PURE__ */ new Map();
|
|
62910
|
+
const byPid = /* @__PURE__ */ new Map();
|
|
62911
|
+
for (const row of rows) {
|
|
62912
|
+
byPid.set(row.pid, row);
|
|
62913
|
+
const list = children.get(row.ppid) ?? [];
|
|
62914
|
+
list.push(row.pid);
|
|
62915
|
+
children.set(row.ppid, list);
|
|
62916
|
+
}
|
|
62917
|
+
const roots = [];
|
|
62918
|
+
const seen = /* @__PURE__ */ new Set();
|
|
62919
|
+
const add = (pid, kind, name5, subtree) => {
|
|
62920
|
+
if (seen.has(pid)) return;
|
|
62921
|
+
seen.add(pid);
|
|
62922
|
+
roots.push({ pid, kind, name: name5, subtree });
|
|
62923
|
+
};
|
|
62924
|
+
if (byPid.has(opts.selfPid))
|
|
62925
|
+
add(opts.selfPid, opts.selfKind, opts.selfKind === "hub" ? "Hub server" : "band-worker", false);
|
|
62926
|
+
for (const row of rows) {
|
|
62927
|
+
if (/terminal-daemon/.test(row.command) && hasRunDir(row.command, opts.runDir)) {
|
|
62928
|
+
add(row.pid, "terminal-daemon", "terminal daemon", false);
|
|
62929
|
+
for (const child of children.get(row.pid) ?? []) {
|
|
62930
|
+
const c = byPid.get(child);
|
|
62931
|
+
if (c) add(child, "terminal", baseName(c.command), true);
|
|
62932
|
+
}
|
|
62933
|
+
} else if (/agent-daemon/.test(row.command) && hasRunDir(row.command, `${opts.runDir}/agents`)) {
|
|
62934
|
+
add(row.pid, "agent-daemon", "agent daemon", false);
|
|
62935
|
+
for (const child of children.get(row.pid) ?? []) {
|
|
62936
|
+
const c = byPid.get(child);
|
|
62937
|
+
if (c) add(child, "agent", agentName(c.command), true);
|
|
62938
|
+
}
|
|
62939
|
+
}
|
|
62940
|
+
}
|
|
62941
|
+
for (const child of children.get(opts.selfPid) ?? []) {
|
|
62942
|
+
const c = byPid.get(child);
|
|
62943
|
+
if (!c || seen.has(child)) continue;
|
|
62944
|
+
const name5 = baseName(c.command);
|
|
62945
|
+
if (SHELLS.has(name5)) add(child, "terminal", name5, true);
|
|
62946
|
+
else if (LSP_NAMES.test(c.command)) add(child, "lsp", lspName(c.command), true);
|
|
62947
|
+
else if (BROWSER.test(c.command)) add(child, "browser", "Chromium", true);
|
|
62948
|
+
else if (SIMULATOR.test(c.command)) add(child, "simulator", "Simulator", true);
|
|
62949
|
+
else if (AGENT_NAMES.test(c.command)) add(child, "agent", agentName(c.command), true);
|
|
62950
|
+
else if (/mcp/i.test(c.command)) add(child, "mcp", name5, true);
|
|
62951
|
+
else if (name5 !== "ps" && name5 !== "lsof" && name5 !== "du" && name5 !== "df")
|
|
62952
|
+
add(child, "other", name5, true);
|
|
62953
|
+
}
|
|
62954
|
+
const subtreeRoots = new Set(roots.filter((r) => r.subtree).map((r) => r.pid));
|
|
62955
|
+
for (const row of rows) {
|
|
62956
|
+
if (seen.has(row.pid)) continue;
|
|
62957
|
+
if (hasAncestorIn(row.pid, subtreeRoots, byPid)) continue;
|
|
62958
|
+
if (LSP_NAMES.test(row.command) && isUnder(row.pid, opts.selfPid, byPid)) {
|
|
62959
|
+
add(row.pid, "lsp", lspName(row.command), true);
|
|
62960
|
+
} else if (BROWSER.test(row.command) && isUnder(row.pid, opts.selfPid, byPid)) {
|
|
62961
|
+
add(row.pid, "browser", "Chromium", true);
|
|
62962
|
+
}
|
|
62963
|
+
}
|
|
62964
|
+
return { roots, children };
|
|
62965
|
+
}
|
|
62966
|
+
function hasAncestorIn(pid, set2, byPid) {
|
|
62967
|
+
let cur = byPid.get(pid)?.ppid;
|
|
62968
|
+
for (let i = 0; cur !== void 0 && i < 64; i++) {
|
|
62969
|
+
if (set2.has(cur)) return true;
|
|
62970
|
+
cur = byPid.get(cur)?.ppid;
|
|
62971
|
+
}
|
|
62972
|
+
return false;
|
|
62973
|
+
}
|
|
62974
|
+
function isUnder(pid, ancestor, byPid) {
|
|
62975
|
+
let cur = byPid.get(pid)?.ppid;
|
|
62976
|
+
for (let i = 0; cur !== void 0 && i < 64; i++) {
|
|
62977
|
+
if (cur === ancestor) return true;
|
|
62978
|
+
cur = byPid.get(cur)?.ppid;
|
|
62979
|
+
}
|
|
62980
|
+
return false;
|
|
62981
|
+
}
|
|
62982
|
+
function lspName(command2) {
|
|
62983
|
+
return LSP_NAMES.exec(command2)?.[1] ?? "language server";
|
|
62984
|
+
}
|
|
62985
|
+
function agentName(command2) {
|
|
62986
|
+
if (/claude/i.test(command2)) return "Claude Code";
|
|
62987
|
+
if (/codex/i.test(command2)) return "Codex";
|
|
62988
|
+
if (/gemini/i.test(command2)) return "Gemini";
|
|
62989
|
+
if (/opencode/i.test(command2)) return "OpenCode";
|
|
62990
|
+
if (/cursor/i.test(command2)) return "Cursor";
|
|
62991
|
+
return baseName(command2);
|
|
62992
|
+
}
|
|
62993
|
+
function subtreeOf(root, children) {
|
|
62994
|
+
const out = [];
|
|
62995
|
+
const stack = [root];
|
|
62996
|
+
while (stack.length > 0 && out.length < 5e3) {
|
|
62997
|
+
const pid = stack.pop();
|
|
62998
|
+
out.push(pid);
|
|
62999
|
+
for (const c of children.get(pid) ?? []) stack.push(c);
|
|
63000
|
+
}
|
|
63001
|
+
return out;
|
|
63002
|
+
}
|
|
63003
|
+
function sumRoots(classified, first, second, windowMs) {
|
|
63004
|
+
const out = [];
|
|
63005
|
+
for (const root of classified.roots) {
|
|
63006
|
+
const pids = root.subtree ? subtreeOf(root.pid, classified.children) : [root.pid];
|
|
63007
|
+
let rss = 0;
|
|
63008
|
+
let cpuMs = 0;
|
|
63009
|
+
let count3 = 0;
|
|
63010
|
+
for (const pid of pids) {
|
|
63011
|
+
const b2 = second.get(pid);
|
|
63012
|
+
if (!b2) continue;
|
|
63013
|
+
count3++;
|
|
63014
|
+
rss += b2.rssBytes;
|
|
63015
|
+
const a = first.get(pid);
|
|
63016
|
+
cpuMs += Math.max(0, a ? b2.cpuMs - a.cpuMs : b2.cpuMs);
|
|
63017
|
+
}
|
|
63018
|
+
const self = second.get(root.pid);
|
|
63019
|
+
if (!self) continue;
|
|
63020
|
+
out.push({
|
|
63021
|
+
pid: root.pid,
|
|
63022
|
+
kind: root.kind,
|
|
63023
|
+
name: root.name,
|
|
63024
|
+
command: self.command.slice(0, 200),
|
|
63025
|
+
rssBytes: rss,
|
|
63026
|
+
cpuPercent: windowMs > 0 ? Math.round(cpuMs / windowMs * 1e3) / 10 : 0,
|
|
63027
|
+
processCount: count3
|
|
63028
|
+
});
|
|
63029
|
+
}
|
|
63030
|
+
return out;
|
|
63031
|
+
}
|
|
63032
|
+
var SHELLS, LSP_NAMES, AGENT_NAMES, BROWSER, SIMULATOR;
|
|
63033
|
+
var init_classify = __esm({
|
|
63034
|
+
"../../packages/host-local/src/resources/classify.ts"() {
|
|
63035
|
+
"use strict";
|
|
63036
|
+
SHELLS = /* @__PURE__ */ new Set(["sh", "bash", "zsh", "fish", "dash", "ksh", "tcsh", "csh", "nu", "pwsh"]);
|
|
63037
|
+
LSP_NAMES = /(typescript-language-server|tsserver|rust-analyzer|gopls|pyright|basedpyright|jdtls|clangd|lua-language-server|vscode-[a-z]+-language-server|yaml-language-server)/;
|
|
63038
|
+
AGENT_NAMES = /(claude-agent-acp|claude-code-acp|codex-acp|gemini|opencode|cursor-agent|-acp\b)/;
|
|
63039
|
+
BROWSER = /(chrom(e|ium)|headless_shell).*--remote-debugging-port/i;
|
|
63040
|
+
SIMULATOR = /(serve-sim|simctl|Simulator\.app|CoreSimulator)/;
|
|
63041
|
+
}
|
|
63042
|
+
});
|
|
63043
|
+
|
|
63044
|
+
// ../../packages/host-local/src/resources/process-table.ts
|
|
63045
|
+
import { execFile as execFile12 } from "node:child_process";
|
|
63046
|
+
import { readdir as readdir6, readFile as readFile6 } from "node:fs/promises";
|
|
63047
|
+
function run3(bin, args) {
|
|
63048
|
+
return new Promise((resolve16) => {
|
|
63049
|
+
execFile12(
|
|
63050
|
+
bin,
|
|
63051
|
+
args,
|
|
63052
|
+
{ timeout: PS_TIMEOUT_MS, maxBuffer: PS_MAX_BUFFER },
|
|
63053
|
+
(_err, out) => resolve16(out ?? "")
|
|
63054
|
+
);
|
|
63055
|
+
});
|
|
63056
|
+
}
|
|
63057
|
+
function parsePsTime(text4) {
|
|
63058
|
+
const m2 = /^(?:(\d+)-)?(?:(\d+):)?(\d+):(\d+(?:\.\d+)?)$/.exec(text4.trim());
|
|
63059
|
+
if (!m2) return 0;
|
|
63060
|
+
const days = Number(m2[1] ?? 0);
|
|
63061
|
+
const hours = Number(m2[2] ?? 0);
|
|
63062
|
+
const minutes = Number(m2[3]);
|
|
63063
|
+
const seconds = Number(m2[4]);
|
|
63064
|
+
return Math.round((((days * 24 + hours) * 60 + minutes) * 60 + seconds) * 1e3);
|
|
63065
|
+
}
|
|
63066
|
+
function parsePs(output2) {
|
|
63067
|
+
const rows = [];
|
|
63068
|
+
for (const line2 of output2.split("\n")) {
|
|
63069
|
+
const m2 = /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(.*)$/.exec(line2);
|
|
63070
|
+
if (!m2) continue;
|
|
63071
|
+
rows.push({
|
|
63072
|
+
pid: Number(m2[1]),
|
|
63073
|
+
ppid: Number(m2[2]),
|
|
63074
|
+
rssBytes: Number(m2[3]) * 1024,
|
|
63075
|
+
cpuMs: parsePsTime(m2[4]),
|
|
63076
|
+
command: m2[5].trim()
|
|
63077
|
+
});
|
|
63078
|
+
}
|
|
63079
|
+
return rows;
|
|
63080
|
+
}
|
|
63081
|
+
function parseProcStat(stat9) {
|
|
63082
|
+
const close = stat9.lastIndexOf(")");
|
|
63083
|
+
if (close < 0) return null;
|
|
63084
|
+
const fields = stat9.slice(close + 2).trim().split(/\s+/);
|
|
63085
|
+
const ppid = Number(fields[1]);
|
|
63086
|
+
const utime = Number(fields[11]);
|
|
63087
|
+
const stime = Number(fields[12]);
|
|
63088
|
+
const rss = Number(fields[21]);
|
|
63089
|
+
if (![ppid, utime, stime, rss].every(Number.isFinite)) return null;
|
|
63090
|
+
return { ppid, cpuMs: (utime + stime) * 1e3 / CLK_TCK, rssPages: rss };
|
|
63091
|
+
}
|
|
63092
|
+
async function readLinux() {
|
|
63093
|
+
let names;
|
|
63094
|
+
try {
|
|
63095
|
+
names = await readdir6("/proc");
|
|
63096
|
+
} catch {
|
|
63097
|
+
return [];
|
|
63098
|
+
}
|
|
63099
|
+
const rows = await Promise.all(
|
|
63100
|
+
names.filter((n) => /^\d+$/.test(n)).map(async (n) => {
|
|
63101
|
+
try {
|
|
63102
|
+
const [stat9, cmd] = await Promise.all([
|
|
63103
|
+
readFile6(`/proc/${n}/stat`, "utf8"),
|
|
63104
|
+
readFile6(`/proc/${n}/cmdline`, "utf8").catch(() => "")
|
|
63105
|
+
]);
|
|
63106
|
+
const parsed = parseProcStat(stat9);
|
|
63107
|
+
if (!parsed) return null;
|
|
63108
|
+
const comm = /\((.*)\)/s.exec(stat9)?.[1] ?? "";
|
|
63109
|
+
return {
|
|
63110
|
+
pid: Number(n),
|
|
63111
|
+
ppid: parsed.ppid,
|
|
63112
|
+
rssBytes: parsed.rssPages * PAGE_SIZE,
|
|
63113
|
+
cpuMs: parsed.cpuMs,
|
|
63114
|
+
command: cmd.replace(/\0/g, " ").trim() || comm
|
|
63115
|
+
};
|
|
63116
|
+
} catch {
|
|
63117
|
+
return null;
|
|
63118
|
+
}
|
|
63119
|
+
})
|
|
63120
|
+
);
|
|
63121
|
+
return rows.filter((r) => r !== null);
|
|
63122
|
+
}
|
|
63123
|
+
async function readProcessTable() {
|
|
63124
|
+
if (process.platform === "linux") {
|
|
63125
|
+
const rows = await readLinux();
|
|
63126
|
+
if (rows.length > 0) return rows;
|
|
63127
|
+
}
|
|
63128
|
+
if (process.platform === "win32") return [];
|
|
63129
|
+
return parsePs(await run3("ps", ["-axww", "-o", "pid=,ppid=,rss=,time=,command="]));
|
|
63130
|
+
}
|
|
63131
|
+
async function readProcessEnv(pid, names) {
|
|
63132
|
+
const out = {};
|
|
63133
|
+
let text4 = "";
|
|
63134
|
+
if (process.platform === "linux") {
|
|
63135
|
+
text4 = (await readFile6(`/proc/${pid}/environ`, "utf8").catch(() => "")).replace(/\0/g, " ");
|
|
63136
|
+
} else if (process.platform === "darwin") {
|
|
63137
|
+
text4 = await run3("ps", ["-E", "-ww", "-o", "command=", "-p", String(pid)]);
|
|
63138
|
+
}
|
|
63139
|
+
for (const name5 of names) {
|
|
63140
|
+
const m2 = new RegExp(`(?:^|\\s)${name5}=(\\S+)`).exec(text4);
|
|
63141
|
+
if (m2) out[name5] = m2[1];
|
|
63142
|
+
}
|
|
63143
|
+
return out;
|
|
63144
|
+
}
|
|
63145
|
+
async function readProcessCwds(pids) {
|
|
63146
|
+
const out = /* @__PURE__ */ new Map();
|
|
63147
|
+
if (pids.length === 0) return out;
|
|
63148
|
+
if (process.platform === "linux") {
|
|
63149
|
+
const { readlink } = await import("node:fs/promises");
|
|
63150
|
+
await Promise.all(
|
|
63151
|
+
pids.map(async (pid) => {
|
|
63152
|
+
try {
|
|
63153
|
+
out.set(pid, await readlink(`/proc/${pid}/cwd`));
|
|
63154
|
+
} catch {
|
|
63155
|
+
}
|
|
63156
|
+
})
|
|
63157
|
+
);
|
|
63158
|
+
return out;
|
|
63159
|
+
}
|
|
63160
|
+
if (process.platform === "darwin") {
|
|
63161
|
+
const text4 = await run3("lsof", ["-a", "-d", "cwd", "-Fpn", "-p", pids.join(",")]);
|
|
63162
|
+
let current3 = 0;
|
|
63163
|
+
for (const line2 of text4.split("\n")) {
|
|
63164
|
+
if (line2.startsWith("p")) current3 = Number(line2.slice(1));
|
|
63165
|
+
else if (line2.startsWith("n") && current3) out.set(current3, line2.slice(1));
|
|
63166
|
+
}
|
|
63167
|
+
}
|
|
63168
|
+
return out;
|
|
63169
|
+
}
|
|
63170
|
+
var PS_TIMEOUT_MS, PS_MAX_BUFFER, CLK_TCK, PAGE_SIZE;
|
|
63171
|
+
var init_process_table = __esm({
|
|
63172
|
+
"../../packages/host-local/src/resources/process-table.ts"() {
|
|
63173
|
+
"use strict";
|
|
63174
|
+
PS_TIMEOUT_MS = 5e3;
|
|
63175
|
+
PS_MAX_BUFFER = 64 * 1024 * 1024;
|
|
63176
|
+
CLK_TCK = 100;
|
|
63177
|
+
PAGE_SIZE = 4096;
|
|
63178
|
+
}
|
|
63179
|
+
});
|
|
63180
|
+
|
|
63181
|
+
// ../../packages/host-local/src/resources/resources.ts
|
|
63182
|
+
import { execFile as execFile13 } from "node:child_process";
|
|
63183
|
+
import { readdir as readdir7, readFile as readFile7 } from "node:fs/promises";
|
|
63184
|
+
import { cpus, freemem, hostname as hostname4, loadavg, totalmem } from "node:os";
|
|
63185
|
+
import { join as join30 } from "node:path";
|
|
63186
|
+
function execOut(bin, args) {
|
|
63187
|
+
return new Promise((resolve16) => {
|
|
63188
|
+
execFile13(bin, args, { timeout: 5e3 }, (_e, out) => resolve16(out ?? ""));
|
|
63189
|
+
});
|
|
63190
|
+
}
|
|
63191
|
+
async function memoryUsedBytes(total) {
|
|
63192
|
+
if (process.platform === "linux") {
|
|
63193
|
+
const meminfo = await readFile7("/proc/meminfo", "utf8").catch(() => "");
|
|
63194
|
+
const m2 = /MemAvailable:\s+(\d+) kB/.exec(meminfo);
|
|
63195
|
+
if (m2) return Math.max(0, total - Number(m2[1]) * 1024);
|
|
63196
|
+
}
|
|
63197
|
+
if (process.platform === "darwin") {
|
|
63198
|
+
const out = await execOut("vm_stat", []);
|
|
63199
|
+
const page = Number(/page size of (\d+) bytes/.exec(out)?.[1] ?? 16384);
|
|
63200
|
+
const pages = (label2) => Number(new RegExp(`${label2}:\\s+(\\d+)`).exec(out)?.[1] ?? 0);
|
|
63201
|
+
const reclaimable = pages("Pages free") + pages("Pages inactive") + pages("Pages speculative");
|
|
63202
|
+
if (reclaimable > 0) return Math.max(0, total - reclaimable * page);
|
|
63203
|
+
}
|
|
63204
|
+
return Math.max(0, total - freemem());
|
|
63205
|
+
}
|
|
63206
|
+
function cpuTimes() {
|
|
63207
|
+
let busy = 0;
|
|
63208
|
+
let total = 0;
|
|
63209
|
+
for (const c of cpus()) {
|
|
63210
|
+
const t2 = c.times;
|
|
63211
|
+
total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
|
|
63212
|
+
busy += t2.user + t2.nice + t2.sys + t2.irq;
|
|
63213
|
+
}
|
|
63214
|
+
return { busy, total };
|
|
63215
|
+
}
|
|
63216
|
+
async function diskOf(path2) {
|
|
63217
|
+
const out = await execOut("df", ["-k", path2]);
|
|
63218
|
+
const line2 = out.trim().split("\n").pop();
|
|
63219
|
+
const f2 = line2?.trim().split(/\s+/);
|
|
63220
|
+
if (!f2 || f2.length < 4) return null;
|
|
63221
|
+
const total = Number(f2[1]);
|
|
63222
|
+
const free = Number(f2[3]);
|
|
63223
|
+
if (!Number.isFinite(total) || !Number.isFinite(free)) return null;
|
|
63224
|
+
return { path: path2, totalBytes: total * 1024, freeBytes: free * 1024 };
|
|
63225
|
+
}
|
|
63226
|
+
async function limited(items, limit, fn) {
|
|
63227
|
+
const results = new Array(items.length);
|
|
63228
|
+
let next = 0;
|
|
63229
|
+
await Promise.all(
|
|
63230
|
+
Array.from({ length: Math.min(limit, items.length) }, async () => {
|
|
63231
|
+
while (next < items.length) {
|
|
63232
|
+
const i = next++;
|
|
63233
|
+
results[i] = await fn(items[i]);
|
|
63234
|
+
}
|
|
63235
|
+
})
|
|
63236
|
+
);
|
|
63237
|
+
return results;
|
|
63238
|
+
}
|
|
63239
|
+
var SAMPLE_WINDOW_MS, CACHE_MS, DU_CONCURRENCY, ENV_NAMES, LocalResources;
|
|
63240
|
+
var init_resources2 = __esm({
|
|
63241
|
+
"../../packages/host-local/src/resources/resources.ts"() {
|
|
63242
|
+
"use strict";
|
|
63243
|
+
init_du();
|
|
63244
|
+
init_classify();
|
|
63245
|
+
init_process_table();
|
|
63246
|
+
SAMPLE_WINDOW_MS = 500;
|
|
63247
|
+
CACHE_MS = 3e3;
|
|
63248
|
+
DU_CONCURRENCY = 3;
|
|
63249
|
+
ENV_NAMES = ["BAND_WORKTREE_ID", "BAND_CHAT_ID", "BAND_TERMINAL_ID"];
|
|
63250
|
+
LocalResources = class {
|
|
63251
|
+
constructor(options) {
|
|
63252
|
+
this.options = options;
|
|
63253
|
+
}
|
|
63254
|
+
cached = null;
|
|
63255
|
+
snapshot() {
|
|
63256
|
+
const now = Date.now();
|
|
63257
|
+
if (this.cached && now - this.cached.at < CACHE_MS) return this.cached.value;
|
|
63258
|
+
const value = this.sample();
|
|
63259
|
+
this.cached = { at: now, value };
|
|
63260
|
+
value.catch(() => {
|
|
63261
|
+
if (this.cached?.value === value) this.cached = null;
|
|
63262
|
+
});
|
|
63263
|
+
return value;
|
|
63264
|
+
}
|
|
63265
|
+
async sample() {
|
|
63266
|
+
const stateDir = this.options.stateDir();
|
|
63267
|
+
const cpu1 = cpuTimes();
|
|
63268
|
+
const started = Date.now();
|
|
63269
|
+
const firstRows = await readProcessTable();
|
|
63270
|
+
await new Promise((r) => setTimeout(r, SAMPLE_WINDOW_MS));
|
|
63271
|
+
const secondRows = await readProcessTable();
|
|
63272
|
+
const windowMs = Date.now() - started;
|
|
63273
|
+
const cpu2 = cpuTimes();
|
|
63274
|
+
const first = new Map(firstRows.map((r) => [r.pid, r]));
|
|
63275
|
+
const second = new Map(secondRows.map((r) => [r.pid, r]));
|
|
63276
|
+
const classified = classify(secondRows, {
|
|
63277
|
+
selfPid: process.pid,
|
|
63278
|
+
selfKind: this.options.selfKind,
|
|
63279
|
+
runDir: join30(stateDir, "run")
|
|
63280
|
+
});
|
|
63281
|
+
const processes = sumRoots(classified, first, second, windowMs);
|
|
63282
|
+
await this.attachIds(processes);
|
|
63283
|
+
const total = totalmem();
|
|
63284
|
+
const totalDelta = cpu2.total - cpu1.total;
|
|
63285
|
+
return {
|
|
63286
|
+
hostname: hostname4(),
|
|
63287
|
+
os: process.platform,
|
|
63288
|
+
cores: cpus().length,
|
|
63289
|
+
memTotalBytes: total,
|
|
63290
|
+
memUsedBytes: await memoryUsedBytes(total),
|
|
63291
|
+
machineCpuPercent: totalDelta > 0 ? Math.round((cpu2.busy - cpu1.busy) / totalDelta * 1e3) / 10 : null,
|
|
63292
|
+
loadAverage: loadavg()[0],
|
|
63293
|
+
windowMs,
|
|
63294
|
+
takenAt: Date.now(),
|
|
63295
|
+
processes
|
|
63296
|
+
};
|
|
63297
|
+
}
|
|
63298
|
+
/** Reads the ids a terminal or agent was started with, and its folder. */
|
|
63299
|
+
async attachIds(processes) {
|
|
63300
|
+
const wanted = processes.filter(
|
|
63301
|
+
(p2) => p2.kind === "terminal" || p2.kind === "agent" || p2.kind === "lsp" || p2.kind === "browser"
|
|
63302
|
+
);
|
|
63303
|
+
const cwds = await readProcessCwds(wanted.map((p2) => p2.pid));
|
|
63304
|
+
await limited(wanted, 6, async (p2) => {
|
|
63305
|
+
const cwd = cwds.get(p2.pid);
|
|
63306
|
+
if (cwd) p2.cwd = cwd;
|
|
63307
|
+
if (p2.kind !== "terminal" && p2.kind !== "agent") return;
|
|
63308
|
+
const env = await readProcessEnv(p2.pid, ENV_NAMES);
|
|
63309
|
+
if (env.BAND_WORKTREE_ID) p2.worktreeId = env.BAND_WORKTREE_ID;
|
|
63310
|
+
if (env.BAND_CHAT_ID) p2.chatId = env.BAND_CHAT_ID;
|
|
63311
|
+
if (env.BAND_TERMINAL_ID) p2.terminalId = env.BAND_TERMINAL_ID;
|
|
63312
|
+
});
|
|
63313
|
+
}
|
|
63314
|
+
/** Calls with the same worktrees share one run, so a repeated refresh does not stack `du` passes. */
|
|
63315
|
+
storageRuns = /* @__PURE__ */ new Map();
|
|
63316
|
+
storage(request) {
|
|
63317
|
+
const key2 = JSON.stringify(request.worktrees);
|
|
63318
|
+
const running = this.storageRuns.get(key2);
|
|
63319
|
+
if (running) return running;
|
|
63320
|
+
const run4 = this.measureStorage(request);
|
|
63321
|
+
this.storageRuns.set(key2, run4);
|
|
63322
|
+
const done = () => this.storageRuns.delete(key2);
|
|
63323
|
+
run4.then(done, done);
|
|
63324
|
+
return run4;
|
|
63325
|
+
}
|
|
63326
|
+
async measureStorage(request) {
|
|
63327
|
+
const stateDir = this.options.stateDir();
|
|
63328
|
+
const worktrees2 = await limited(request.worktrees, DU_CONCURRENCY, async (wt) => {
|
|
63329
|
+
try {
|
|
63330
|
+
return { id: wt.id, sizeBytes: await duBytes(wt.path) };
|
|
63331
|
+
} catch (err) {
|
|
63332
|
+
return {
|
|
63333
|
+
id: wt.id,
|
|
63334
|
+
sizeBytes: 0,
|
|
63335
|
+
error: err instanceof Error ? err.message : String(err)
|
|
63336
|
+
};
|
|
63337
|
+
}
|
|
63338
|
+
});
|
|
63339
|
+
const names = await readdir7(stateDir).catch(() => []);
|
|
63340
|
+
const state2 = await limited(names, DU_CONCURRENCY, async (name5) => ({
|
|
63341
|
+
name: name5,
|
|
63342
|
+
sizeBytes: await duBytes(join30(stateDir, name5)).catch(() => 0)
|
|
63343
|
+
}));
|
|
63344
|
+
state2.sort((a, b2) => b2.sizeBytes - a.sizeBytes);
|
|
63345
|
+
return { worktrees: worktrees2, state: state2, disk: await diskOf(stateDir) };
|
|
63346
|
+
}
|
|
63347
|
+
};
|
|
63348
|
+
}
|
|
63349
|
+
});
|
|
63350
|
+
|
|
62862
63351
|
// ../../packages/host-local/src/search/ripgrep-client.ts
|
|
62863
|
-
import { execFile as
|
|
63352
|
+
import { execFile as execFile14, spawn as spawn4 } from "node:child_process";
|
|
62864
63353
|
import { rgPath } from "@vscode/ripgrep";
|
|
62865
63354
|
function streamMatches(options) {
|
|
62866
63355
|
return {
|
|
@@ -62981,7 +63470,7 @@ function listFiles(cwd) {
|
|
|
62981
63470
|
"!**/.DS_Store"
|
|
62982
63471
|
];
|
|
62983
63472
|
return new Promise((resolve16, reject) => {
|
|
62984
|
-
|
|
63473
|
+
execFile14(
|
|
62985
63474
|
rgPath,
|
|
62986
63475
|
args,
|
|
62987
63476
|
{ cwd, maxBuffer: LIST_FILES_MAX_BUFFER, encoding: "utf-8" },
|
|
@@ -63005,10 +63494,10 @@ var init_ripgrep_client = __esm({
|
|
|
63005
63494
|
});
|
|
63006
63495
|
|
|
63007
63496
|
// ../../packages/host-local/src/setup/repo-config.ts
|
|
63008
|
-
import { join as
|
|
63497
|
+
import { join as join31 } from "node:path";
|
|
63009
63498
|
async function loadRepoConfig(host, worktreePath, repoPath) {
|
|
63010
63499
|
for (const base of [worktreePath, repoPath]) {
|
|
63011
|
-
const text4 = await readConfig(host,
|
|
63500
|
+
const text4 = await readConfig(host, join31(base, ".band", "config.json"));
|
|
63012
63501
|
if (text4 === null) continue;
|
|
63013
63502
|
try {
|
|
63014
63503
|
return JSON.parse(text4);
|
|
@@ -63019,10 +63508,10 @@ async function loadRepoConfig(host, worktreePath, repoPath) {
|
|
|
63019
63508
|
}
|
|
63020
63509
|
async function loadEnvironment(host, worktreePath, repoPath) {
|
|
63021
63510
|
for (const base of [worktreePath, repoPath]) {
|
|
63022
|
-
const file3 =
|
|
63511
|
+
const file3 = join31(base, ENVIRONMENT_FILE);
|
|
63023
63512
|
const text4 = await readConfig(host, file3);
|
|
63024
63513
|
if (text4 === null) continue;
|
|
63025
|
-
const exists4 = (relative2) => host.fs.stat(
|
|
63514
|
+
const exists4 = (relative2) => host.fs.stat(join31(base, relative2)).then(
|
|
63026
63515
|
() => true,
|
|
63027
63516
|
() => false
|
|
63028
63517
|
);
|
|
@@ -63053,7 +63542,7 @@ async function readConfig(host, configPath) {
|
|
|
63053
63542
|
}
|
|
63054
63543
|
}
|
|
63055
63544
|
async function getCopyFiles(host, repoPath) {
|
|
63056
|
-
const configPath =
|
|
63545
|
+
const configPath = join31(repoPath, ".band", "config.json");
|
|
63057
63546
|
const text4 = await readConfig(host, configPath);
|
|
63058
63547
|
if (text4 === null) return null;
|
|
63059
63548
|
let raw;
|
|
@@ -63088,14 +63577,14 @@ var init_repo_config = __esm({
|
|
|
63088
63577
|
});
|
|
63089
63578
|
|
|
63090
63579
|
// ../../packages/host-local/src/setup/script-run.ts
|
|
63091
|
-
import { join as
|
|
63580
|
+
import { join as join32 } from "node:path";
|
|
63092
63581
|
function quote(value) {
|
|
63093
63582
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
63094
63583
|
}
|
|
63095
63584
|
async function prepareScriptRun(host, script, label2) {
|
|
63096
63585
|
const dir = await host.fs.mkdtemp("band-script-");
|
|
63097
|
-
const scriptFile =
|
|
63098
|
-
const exitFile =
|
|
63586
|
+
const scriptFile = join32(dir, `${label2}.sh`);
|
|
63587
|
+
const exitFile = join32(dir, "exit-code");
|
|
63099
63588
|
const partialFile = `${exitFile}.partial`;
|
|
63100
63589
|
const onExit = [
|
|
63101
63590
|
"rc=$?",
|
|
@@ -63164,7 +63653,7 @@ var init_script_run = __esm({
|
|
|
63164
63653
|
});
|
|
63165
63654
|
|
|
63166
63655
|
// ../../packages/host-local/src/setup/worktree-files.ts
|
|
63167
|
-
import { dirname as dirname10, isAbsolute, join as
|
|
63656
|
+
import { dirname as dirname10, isAbsolute, join as join33, relative, resolve as resolve6, sep as sep4 } from "node:path";
|
|
63168
63657
|
async function copyWorktreeFiles(host, repoPath, worktreePath) {
|
|
63169
63658
|
const byAbs = /* @__PURE__ */ new Map();
|
|
63170
63659
|
const missingFromConfig = [];
|
|
@@ -63192,7 +63681,7 @@ async function copyWorktreeFiles(host, repoPath, worktreePath) {
|
|
|
63192
63681
|
}
|
|
63193
63682
|
for (const [absSource, source] of byAbs) {
|
|
63194
63683
|
const rel = relative(repoPath, absSource);
|
|
63195
|
-
const dest =
|
|
63684
|
+
const dest = join33(worktreePath, rel);
|
|
63196
63685
|
if (rel.startsWith("..") || isAbsolute(rel)) {
|
|
63197
63686
|
log16.warn({ source, entry: absSource }, "refusing to copy file outside repo root \u2014 skipping");
|
|
63198
63687
|
continue;
|
|
@@ -63281,7 +63770,7 @@ async function resolveFromConfig(host, repoPath, missing) {
|
|
|
63281
63770
|
return out;
|
|
63282
63771
|
}
|
|
63283
63772
|
async function resolveFromWorktreeInclude(host, repoPath) {
|
|
63284
|
-
const includePath =
|
|
63773
|
+
const includePath = join33(repoPath, ".worktreeinclude");
|
|
63285
63774
|
let includeContent;
|
|
63286
63775
|
try {
|
|
63287
63776
|
includeContent = new TextDecoder().decode(await host.fs.readFile(includePath));
|
|
@@ -63399,11 +63888,11 @@ var init_common4 = __esm({
|
|
|
63399
63888
|
});
|
|
63400
63889
|
|
|
63401
63890
|
// ../../packages/host-local/src/usage/claude-usage.ts
|
|
63402
|
-
import { execFile as
|
|
63891
|
+
import { execFile as execFile15 } from "node:child_process";
|
|
63403
63892
|
import { createHash as createHash6 } from "node:crypto";
|
|
63404
|
-
import { readFile as
|
|
63893
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
63405
63894
|
import { homedir as homedir14, userInfo } from "node:os";
|
|
63406
|
-
import { join as
|
|
63895
|
+
import { join as join34 } from "node:path";
|
|
63407
63896
|
function windowOf(label2, raw) {
|
|
63408
63897
|
if (!raw || typeof raw !== "object") return null;
|
|
63409
63898
|
const percent = percentOf(raw.utilization ?? raw.used_percentage);
|
|
@@ -63423,7 +63912,7 @@ function mapClaudeUsage(data) {
|
|
|
63423
63912
|
);
|
|
63424
63913
|
}
|
|
63425
63914
|
function claudeConfigDir3() {
|
|
63426
|
-
return process.env.CLAUDE_CONFIG_DIR ||
|
|
63915
|
+
return process.env.CLAUDE_CONFIG_DIR || join34(homedir14(), ".claude");
|
|
63427
63916
|
}
|
|
63428
63917
|
function parseCredentials(raw) {
|
|
63429
63918
|
try {
|
|
@@ -63438,7 +63927,7 @@ function parseCredentials(raw) {
|
|
|
63438
63927
|
}
|
|
63439
63928
|
function keychainPassword(service) {
|
|
63440
63929
|
return new Promise((resolve16) => {
|
|
63441
|
-
|
|
63930
|
+
execFile15(
|
|
63442
63931
|
"security",
|
|
63443
63932
|
["find-generic-password", "-s", service, "-a", userInfo().username, "-w"],
|
|
63444
63933
|
{ timeout: KEYCHAIN_TIMEOUT_MS },
|
|
@@ -63449,7 +63938,7 @@ function keychainPassword(service) {
|
|
|
63449
63938
|
async function readLogin() {
|
|
63450
63939
|
const dir = claudeConfigDir3();
|
|
63451
63940
|
try {
|
|
63452
|
-
const fromFile = parseCredentials(await
|
|
63941
|
+
const fromFile = parseCredentials(await readFile8(join34(dir, ".credentials.json"), "utf8"));
|
|
63453
63942
|
if (fromFile) return fromFile;
|
|
63454
63943
|
} catch {
|
|
63455
63944
|
}
|
|
@@ -63459,9 +63948,9 @@ async function readLogin() {
|
|
|
63459
63948
|
return raw ? parseCredentials(raw) : null;
|
|
63460
63949
|
}
|
|
63461
63950
|
async function readIdentity() {
|
|
63462
|
-
const file3 = process.env.CLAUDE_CONFIG_DIR ?
|
|
63951
|
+
const file3 = process.env.CLAUDE_CONFIG_DIR ? join34(process.env.CLAUDE_CONFIG_DIR, ".claude.json") : join34(homedir14(), ".claude.json");
|
|
63463
63952
|
try {
|
|
63464
|
-
const account = JSON.parse(await
|
|
63953
|
+
const account = JSON.parse(await readFile8(file3, "utf8")).oauthAccount;
|
|
63465
63954
|
const email4 = account?.emailAddress;
|
|
63466
63955
|
if (typeof email4 === "string" && email4) return email4;
|
|
63467
63956
|
const id = account?.accountUuid;
|
|
@@ -63502,9 +63991,9 @@ var init_claude_usage = __esm({
|
|
|
63502
63991
|
});
|
|
63503
63992
|
|
|
63504
63993
|
// ../../packages/host-local/src/usage/codex-usage.ts
|
|
63505
|
-
import { readFile as
|
|
63994
|
+
import { readFile as readFile9 } from "node:fs/promises";
|
|
63506
63995
|
import { homedir as homedir15 } from "node:os";
|
|
63507
|
-
import { join as
|
|
63996
|
+
import { join as join35 } from "node:path";
|
|
63508
63997
|
function labelFor(raw, fallback) {
|
|
63509
63998
|
const seconds = raw.limit_window_seconds;
|
|
63510
63999
|
if (typeof seconds === "number" && Number.isFinite(seconds) && seconds > 0) {
|
|
@@ -63538,9 +64027,9 @@ function emailOfIdToken(idToken) {
|
|
|
63538
64027
|
}
|
|
63539
64028
|
}
|
|
63540
64029
|
async function readLogin2() {
|
|
63541
|
-
const home = process.env.CODEX_HOME ||
|
|
64030
|
+
const home = process.env.CODEX_HOME || join35(homedir15(), ".codex");
|
|
63542
64031
|
try {
|
|
63543
|
-
const auth2 = JSON.parse(await
|
|
64032
|
+
const auth2 = JSON.parse(await readFile9(join35(home, "auth.json"), "utf8"));
|
|
63544
64033
|
const token = auth2.tokens?.access_token;
|
|
63545
64034
|
if (typeof token !== "string" || token === "") return null;
|
|
63546
64035
|
const accountId = auth2.tokens?.account_id;
|
|
@@ -63645,7 +64134,7 @@ var init_account_usage = __esm({
|
|
|
63645
64134
|
});
|
|
63646
64135
|
|
|
63647
64136
|
// ../../packages/host-local/src/local-host.ts
|
|
63648
|
-
import { execFile as
|
|
64137
|
+
import { execFile as execFile16, spawn as spawn5 } from "node:child_process";
|
|
63649
64138
|
import { createReadStream as createReadStream3, watch as fsWatch } from "node:fs";
|
|
63650
64139
|
import {
|
|
63651
64140
|
cp,
|
|
@@ -63653,16 +64142,16 @@ import {
|
|
|
63653
64142
|
lstat,
|
|
63654
64143
|
mkdir as mkdir4,
|
|
63655
64144
|
mkdtemp,
|
|
63656
|
-
readdir as
|
|
63657
|
-
readFile as
|
|
64145
|
+
readdir as readdir8,
|
|
64146
|
+
readFile as readFile10,
|
|
63658
64147
|
realpath as realpath3,
|
|
63659
64148
|
rename as rename3,
|
|
63660
64149
|
rm as rm2,
|
|
63661
|
-
stat as
|
|
64150
|
+
stat as stat7,
|
|
63662
64151
|
writeFile as writeFile3
|
|
63663
64152
|
} from "node:fs/promises";
|
|
63664
|
-
import { homedir as homedir16, hostname as
|
|
63665
|
-
import { join as
|
|
64153
|
+
import { homedir as homedir16, hostname as hostname5, tmpdir as tmpdir2 } from "node:os";
|
|
64154
|
+
import { join as join36 } from "node:path";
|
|
63666
64155
|
async function createWorktree(spec) {
|
|
63667
64156
|
const refs = await execGit(
|
|
63668
64157
|
["for-each-ref", "--format=%(refname)", "refs/heads", "refs/remotes/origin"],
|
|
@@ -63815,6 +64304,7 @@ var init_local_host = __esm({
|
|
|
63815
64304
|
init_power();
|
|
63816
64305
|
init_tools();
|
|
63817
64306
|
init_host_repos();
|
|
64307
|
+
init_resources2();
|
|
63818
64308
|
init_ripgrep_client();
|
|
63819
64309
|
init_repo_config();
|
|
63820
64310
|
init_script_run();
|
|
@@ -63829,11 +64319,15 @@ var init_local_host = __esm({
|
|
|
63829
64319
|
LocalHost = class {
|
|
63830
64320
|
constructor(options) {
|
|
63831
64321
|
this.options = options;
|
|
63832
|
-
const bandHome2 = () => process.env.BAND_HOME ??
|
|
64322
|
+
const bandHome2 = () => process.env.BAND_HOME ?? join36(homedir16(), ".band");
|
|
63833
64323
|
this.repos = new LocalRepos({
|
|
63834
|
-
mappingsFile: options.repos?.mappingsFile ?? (() =>
|
|
64324
|
+
mappingsFile: options.repos?.mappingsFile ?? (() => join36(bandHome2(), "repo-mappings.json")),
|
|
63835
64325
|
reposDir: options.repos?.reposDir ?? defaultReposDir
|
|
63836
64326
|
});
|
|
64327
|
+
this.resources = new LocalResources({
|
|
64328
|
+
selfKind: options.resources?.selfKind ?? "worker",
|
|
64329
|
+
stateDir: options.resources?.stateDir ?? bandHome2
|
|
64330
|
+
});
|
|
63837
64331
|
void this.toolVersions();
|
|
63838
64332
|
}
|
|
63839
64333
|
id = LOCAL_HOST_ID;
|
|
@@ -63870,7 +64364,7 @@ var init_local_host = __esm({
|
|
|
63870
64364
|
openStdio: (spec) => openMcpStdio(spec)
|
|
63871
64365
|
};
|
|
63872
64366
|
chromium = new ChromiumManager(
|
|
63873
|
-
() =>
|
|
64367
|
+
() => join36(process.env.BAND_HOME ?? join36(homedir16(), ".band"), "browser-profiles")
|
|
63874
64368
|
);
|
|
63875
64369
|
browser = {
|
|
63876
64370
|
open: (spec) => this.chromium.open(spec),
|
|
@@ -63879,6 +64373,7 @@ var init_local_host = __esm({
|
|
|
63879
64373
|
};
|
|
63880
64374
|
desktop = { open: () => openDesktop() };
|
|
63881
64375
|
speech = { transcribe: (req) => transcribeLocally(req) };
|
|
64376
|
+
resources;
|
|
63882
64377
|
scripts = {
|
|
63883
64378
|
command: (worktree) => scriptCommand(this, worktree),
|
|
63884
64379
|
runHidden: (script, cwd, timeoutMs) => runScriptHidden(script, cwd, timeoutMs),
|
|
@@ -64018,7 +64513,7 @@ var init_local_host = __esm({
|
|
|
64018
64513
|
id: this.id,
|
|
64019
64514
|
os: process.platform,
|
|
64020
64515
|
arch: process.arch,
|
|
64021
|
-
hostname:
|
|
64516
|
+
hostname: hostname5(),
|
|
64022
64517
|
home: homedir16(),
|
|
64023
64518
|
labels: [],
|
|
64024
64519
|
roots: [],
|
|
@@ -64043,7 +64538,7 @@ var init_local_host = __esm({
|
|
|
64043
64538
|
return new Promise((resolve16, reject) => {
|
|
64044
64539
|
const env = { ...process.env, ...options.env };
|
|
64045
64540
|
env.PATH = prependBinDirs(env.PATH);
|
|
64046
|
-
|
|
64541
|
+
execFile16(
|
|
64047
64542
|
bin,
|
|
64048
64543
|
args,
|
|
64049
64544
|
{ cwd: options.cwd, env, maxBuffer: EXEC_MAX_BUFFER, timeout: options.timeoutMs },
|
|
@@ -64060,11 +64555,11 @@ var init_local_host = __esm({
|
|
|
64060
64555
|
};
|
|
64061
64556
|
localFs = {
|
|
64062
64557
|
async stat(path2, options) {
|
|
64063
|
-
const stats = options?.followSymlinks ? await
|
|
64558
|
+
const stats = options?.followSymlinks ? await stat7(path2) : await lstat(path2);
|
|
64064
64559
|
return { kind: kindOf(stats), size: stats.size, mtimeMs: stats.mtimeMs };
|
|
64065
64560
|
},
|
|
64066
64561
|
async readFile(path2) {
|
|
64067
|
-
return new Uint8Array(await
|
|
64562
|
+
return new Uint8Array(await readFile10(path2));
|
|
64068
64563
|
},
|
|
64069
64564
|
realpath: (path2) => realpath3(path2),
|
|
64070
64565
|
async *readStream(path2, range) {
|
|
@@ -64082,9 +64577,9 @@ var init_local_host = __esm({
|
|
|
64082
64577
|
for await (const match of fsGlob(pattern, { cwd })) matches2.push(match);
|
|
64083
64578
|
return matches2;
|
|
64084
64579
|
},
|
|
64085
|
-
mkdtemp: (prefix) => mkdtemp(
|
|
64580
|
+
mkdtemp: (prefix) => mkdtemp(join36(tmpdir2(), prefix)),
|
|
64086
64581
|
async list(path2) {
|
|
64087
|
-
const entries = await
|
|
64582
|
+
const entries = await readdir8(path2, { withFileTypes: true });
|
|
64088
64583
|
return entries.map((entry) => ({ name: entry.name, kind: kindOf(entry) }));
|
|
64089
64584
|
},
|
|
64090
64585
|
async mkdir(path2, options) {
|
|
@@ -64124,10 +64619,10 @@ var init_drizzle_orm2 = __esm({
|
|
|
64124
64619
|
|
|
64125
64620
|
// src/server/infra/db/queries/repos.ts
|
|
64126
64621
|
import { existsSync as existsSync12 } from "node:fs";
|
|
64127
|
-
import { join as
|
|
64622
|
+
import { join as join37 } from "node:path";
|
|
64128
64623
|
function reconcileKindForRepo(repo) {
|
|
64129
64624
|
if (!repo.path || !existsSync12(repo.path)) return false;
|
|
64130
|
-
const detectedKind = existsSync12(
|
|
64625
|
+
const detectedKind = existsSync12(join37(repo.path, ".git")) ? "git" : "plain";
|
|
64131
64626
|
if (detectedKind === repo.kind) return false;
|
|
64132
64627
|
repo.kind = detectedKind;
|
|
64133
64628
|
if (detectedKind === "plain") {
|
|
@@ -64889,7 +65384,7 @@ var init_isolation = __esm({
|
|
|
64889
65384
|
|
|
64890
65385
|
// src/server/services/_utils/runner-config.ts
|
|
64891
65386
|
import { existsSync as existsSync13 } from "node:fs";
|
|
64892
|
-
import { dirname as dirname11, isAbsolute as isAbsolute2, join as
|
|
65387
|
+
import { dirname as dirname11, isAbsolute as isAbsolute2, join as join38, resolve as resolve7 } from "node:path";
|
|
64893
65388
|
function parseRunners(raw) {
|
|
64894
65389
|
if (raw === void 0 || raw === null) return { runners: [], errors: [] };
|
|
64895
65390
|
if (!Array.isArray(raw)) return { runners: [], errors: ["runners must be a list"] };
|
|
@@ -64914,8 +65409,8 @@ function bundledRunnersDir() {
|
|
|
64914
65409
|
if (fromEnv) return resolve7(fromEnv);
|
|
64915
65410
|
let dir = import.meta.dirname;
|
|
64916
65411
|
for (let i = 0; i < 10; i++) {
|
|
64917
|
-
const candidate =
|
|
64918
|
-
if (existsSync13(
|
|
65412
|
+
const candidate = join38(dir, "runners");
|
|
65413
|
+
if (existsSync13(join38(candidate, "local", "spawn.sh"))) return candidate;
|
|
64919
65414
|
const parent = dirname11(dir);
|
|
64920
65415
|
if (parent === dir) break;
|
|
64921
65416
|
dir = parent;
|
|
@@ -64926,7 +65421,7 @@ function resolveHookPath(spec, script) {
|
|
|
64926
65421
|
if (spec.startsWith(BUNDLED_PREFIX)) {
|
|
64927
65422
|
const name5 = spec.slice(BUNDLED_PREFIX.length);
|
|
64928
65423
|
if (!/^[a-z][a-z0-9-]*$/.test(name5)) throw new Error(`invalid bundled hook "${spec}"`);
|
|
64929
|
-
return
|
|
65424
|
+
return join38(bundledRunnersDir(), name5, `${script}.sh`);
|
|
64930
65425
|
}
|
|
64931
65426
|
return isAbsolute2(spec) ? spec : resolve7(bandHome(), spec);
|
|
64932
65427
|
}
|
|
@@ -65025,7 +65520,7 @@ var init_runner_config = __esm({
|
|
|
65025
65520
|
});
|
|
65026
65521
|
|
|
65027
65522
|
// src/server/services/settings-service.ts
|
|
65028
|
-
import { join as
|
|
65523
|
+
import { join as join39 } from "node:path";
|
|
65029
65524
|
function agentModeFromVia(via) {
|
|
65030
65525
|
if (via === "chat") return "gui";
|
|
65031
65526
|
if (via === "terminal") return "tui";
|
|
@@ -65243,7 +65738,7 @@ var init_settings_service = __esm({
|
|
|
65243
65738
|
*/
|
|
65244
65739
|
worktreesDir() {
|
|
65245
65740
|
const raw = this.rawWorktreesDir();
|
|
65246
|
-
return raw ??
|
|
65741
|
+
return raw ?? join39(bandHome(), "worktrees");
|
|
65247
65742
|
}
|
|
65248
65743
|
/**
|
|
65249
65744
|
* Return the raw `worktreesDir` value from settings without applying the
|
|
@@ -65669,6 +66164,7 @@ var init_registry = __esm({
|
|
|
65669
66164
|
terminalBackend = null;
|
|
65670
66165
|
hostRegistry = new HostRegistry(
|
|
65671
66166
|
new LocalHost({
|
|
66167
|
+
resources: { selfKind: "hub" },
|
|
65672
66168
|
// `gh` is the GitHub plugin's tool: with that plugin disabled the host never runs it. The
|
|
65673
66169
|
// import is dynamic because the services import this registry.
|
|
65674
66170
|
ghEnabled: async () => {
|
|
@@ -65913,11 +66409,11 @@ var init_credential_events = __esm({
|
|
|
65913
66409
|
// src/server/services/_utils/shared-dir.ts
|
|
65914
66410
|
import { readdirSync as readdirSync8 } from "node:fs";
|
|
65915
66411
|
import { mkdir as mkdir5 } from "node:fs/promises";
|
|
65916
|
-
import { join as
|
|
66412
|
+
import { join as join40 } from "node:path";
|
|
65917
66413
|
async function openSharedDir(worktreeId4, chatId) {
|
|
65918
66414
|
const host = hostRegistry.hostFor(worktreeId4);
|
|
65919
66415
|
if (host.id === hostRegistry.local.id) {
|
|
65920
|
-
const path3 =
|
|
66416
|
+
const path3 = join40(bandHome(), "shared", worktreeId4, chatId);
|
|
65921
66417
|
await mkdir5(path3, { recursive: true });
|
|
65922
66418
|
return {
|
|
65923
66419
|
path: path3,
|
|
@@ -65932,7 +66428,7 @@ async function openSharedDir(worktreeId4, chatId) {
|
|
|
65932
66428
|
}
|
|
65933
66429
|
const dirs = (await host.info()).dirs;
|
|
65934
66430
|
if (!dirs) throw new Error(`Worker ${host.id} has no directory for shared files`);
|
|
65935
|
-
const path2 =
|
|
66431
|
+
const path2 = join40(dirs.shared, worktreeId4, chatId);
|
|
65936
66432
|
await host.fs.mkdir(path2, { recursive: true });
|
|
65937
66433
|
return {
|
|
65938
66434
|
path: path2,
|
|
@@ -65948,7 +66444,7 @@ async function openSharedDir(worktreeId4, chatId) {
|
|
|
65948
66444
|
async function agentExtraDirs(worktreeId4) {
|
|
65949
66445
|
const host = hostRegistry.hostFor(worktreeId4);
|
|
65950
66446
|
if (host.id === hostRegistry.local.id) {
|
|
65951
|
-
return [
|
|
66447
|
+
return [join40(bandHome(), "uploads"), join40(bandHome(), "shared")];
|
|
65952
66448
|
}
|
|
65953
66449
|
const dirs = (await host.info()).dirs;
|
|
65954
66450
|
return dirs ? [dirs.uploads, dirs.shared] : [];
|
|
@@ -66462,9 +66958,9 @@ var init_oauth_client = __esm({
|
|
|
66462
66958
|
// src/server/services/_utils/vault-crypto.ts
|
|
66463
66959
|
import { createCipheriv, createDecipheriv, randomBytes as randomBytes6 } from "node:crypto";
|
|
66464
66960
|
import { chmodSync as chmodSync2, existsSync as existsSync14, readFileSync as readFileSync9, renameSync as renameSync7, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
66465
|
-
import { join as
|
|
66961
|
+
import { join as join41 } from "node:path";
|
|
66466
66962
|
function vaultKeyFile() {
|
|
66467
|
-
return
|
|
66963
|
+
return join41(bandHome(), "vault.key");
|
|
66468
66964
|
}
|
|
66469
66965
|
function keySource() {
|
|
66470
66966
|
return process.env.BAND_VAULT_KEY?.trim() ? "env" : "file";
|
|
@@ -66538,9 +67034,9 @@ var init_vault_crypto = __esm({
|
|
|
66538
67034
|
// src/server/infra/subscriptions/webhook-secret.ts
|
|
66539
67035
|
import { randomBytes as randomBytes7 } from "node:crypto";
|
|
66540
67036
|
import { chmodSync as chmodSync3, existsSync as existsSync15, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "node:fs";
|
|
66541
|
-
import { dirname as dirname12, join as
|
|
67037
|
+
import { dirname as dirname12, join as join42 } from "node:path";
|
|
66542
67038
|
function secretPath() {
|
|
66543
|
-
return
|
|
67039
|
+
return join42(bandHome(), "github-webhook-secret");
|
|
66544
67040
|
}
|
|
66545
67041
|
function readWebhookSecret() {
|
|
66546
67042
|
const fromEnv = process.env.BAND_GITHUB_WEBHOOK_SECRET;
|
|
@@ -66611,10 +67107,10 @@ async function hubGhEnv() {
|
|
|
66611
67107
|
async function hubGhHasNoCredential() {
|
|
66612
67108
|
return !await machineHasLogin() && vaultService.findGitHubToken() === void 0;
|
|
66613
67109
|
}
|
|
66614
|
-
async function withHubGhCredential(
|
|
67110
|
+
async function withHubGhCredential(run4) {
|
|
66615
67111
|
const env = await hubGhEnv();
|
|
66616
67112
|
try {
|
|
66617
|
-
return await
|
|
67113
|
+
return await run4(env);
|
|
66618
67114
|
} catch (err) {
|
|
66619
67115
|
const message = err instanceof Error ? err.message : String(err);
|
|
66620
67116
|
if (env.GH_TOKEN === void 0 && UNAUTHENTICATED.test(message) && await hubGhHasNoCredential()) {
|
|
@@ -66990,14 +67486,14 @@ function pickPullRequest(allNodes, repoOwner2, isDefaultBranch) {
|
|
|
66990
67486
|
);
|
|
66991
67487
|
const node2 = nodes2.find((n) => n.state === "OPEN") ?? (isDefaultBranch ? void 0 : nodes2.find((n) => n.state === "MERGED") ?? nodes2.find((n) => n.state === "CLOSED"));
|
|
66992
67488
|
if (!node2) return null;
|
|
66993
|
-
const
|
|
66994
|
-
const mergeQueue =
|
|
66995
|
-
const autoMerge =
|
|
67489
|
+
const open3 = node2.state === "OPEN";
|
|
67490
|
+
const mergeQueue = open3 ? parseMergeQueue(node2) : null;
|
|
67491
|
+
const autoMerge = open3 ? parseAutoMerge(node2) : null;
|
|
66996
67492
|
return {
|
|
66997
67493
|
number: node2.number,
|
|
66998
67494
|
title: node2.title,
|
|
66999
67495
|
url: node2.url,
|
|
67000
|
-
state:
|
|
67496
|
+
state: open3 ? "open" : node2.state === "MERGED" ? "merged" : "closed",
|
|
67001
67497
|
isDraft: node2.isDraft,
|
|
67002
67498
|
...mergeQueue && { mergeQueue },
|
|
67003
67499
|
...autoMerge && { autoMerge }
|
|
@@ -67055,20 +67551,20 @@ function parseBranchStatusResponse(data, branches) {
|
|
|
67055
67551
|
}
|
|
67056
67552
|
let aggregatedState = "success";
|
|
67057
67553
|
let aggregatedUrl = null;
|
|
67058
|
-
for (const
|
|
67554
|
+
for (const run4 of latestByWorkflow.values()) {
|
|
67059
67555
|
let runState;
|
|
67060
|
-
if (
|
|
67061
|
-
runState =
|
|
67062
|
-
} else if (
|
|
67556
|
+
if (run4.status === "IN_PROGRESS" || run4.status === "QUEUED") {
|
|
67557
|
+
runState = run4.status === "QUEUED" ? "pending" : "running";
|
|
67558
|
+
} else if (run4.conclusion === "FAILURE") {
|
|
67063
67559
|
runState = "failure";
|
|
67064
|
-
} else if (
|
|
67560
|
+
} else if (run4.conclusion === "CANCELLED") {
|
|
67065
67561
|
runState = "cancelled";
|
|
67066
67562
|
} else {
|
|
67067
67563
|
runState = "success";
|
|
67068
67564
|
}
|
|
67069
67565
|
if (statePriority(runState) >= statePriority(aggregatedState)) {
|
|
67070
67566
|
aggregatedState = runState;
|
|
67071
|
-
aggregatedUrl =
|
|
67567
|
+
aggregatedUrl = run4.url;
|
|
67072
67568
|
}
|
|
67073
67569
|
}
|
|
67074
67570
|
results[branch] = { state: aggregatedState, url: reviewUrl ?? aggregatedUrl, review };
|
|
@@ -67203,11 +67699,11 @@ function parseBranchChecks(data) {
|
|
|
67203
67699
|
if (!suite.workflowRun) continue;
|
|
67204
67700
|
const workflowName = suite.workflowRun.workflow.name;
|
|
67205
67701
|
for (const node2 of suite.checkRuns.nodes) {
|
|
67206
|
-
const
|
|
67207
|
-
const key2 = `${workflowName}\0${
|
|
67702
|
+
const run4 = fromCheckRun(node2, workflowName);
|
|
67703
|
+
const key2 = `${workflowName}\0${run4.name}`;
|
|
67208
67704
|
const existing = latest.get(key2);
|
|
67209
|
-
if (!existing || (
|
|
67210
|
-
latest.set(key2,
|
|
67705
|
+
if (!existing || (run4.startedAt ?? "") > (existing.startedAt ?? "")) {
|
|
67706
|
+
latest.set(key2, run4);
|
|
67211
67707
|
}
|
|
67212
67708
|
}
|
|
67213
67709
|
}
|
|
@@ -67558,15 +68054,15 @@ function parseCheckRuns(output2) {
|
|
|
67558
68054
|
const runs = parsed?.check_runs;
|
|
67559
68055
|
if (!Array.isArray(runs)) throw new Error("Unexpected check-runs response");
|
|
67560
68056
|
return runs.flatMap((r) => {
|
|
67561
|
-
const
|
|
67562
|
-
if (!
|
|
68057
|
+
const run4 = obj(r);
|
|
68058
|
+
if (!run4) return [];
|
|
67563
68059
|
return [
|
|
67564
68060
|
{
|
|
67565
|
-
name: str2(
|
|
67566
|
-
status: str2(
|
|
67567
|
-
conclusion: typeof
|
|
67568
|
-
url: str2(
|
|
67569
|
-
headSha: str2(
|
|
68061
|
+
name: str2(run4.name) || "unnamed check",
|
|
68062
|
+
status: str2(run4.status),
|
|
68063
|
+
conclusion: typeof run4.conclusion === "string" ? run4.conclusion : null,
|
|
68064
|
+
url: str2(run4.html_url) || void 0,
|
|
68065
|
+
headSha: str2(run4.head_sha) || void 0
|
|
67570
68066
|
}
|
|
67571
68067
|
];
|
|
67572
68068
|
});
|
|
@@ -67810,10 +68306,10 @@ function parseGithubDelivery(eventType, delivery, payload, now = Date.now()) {
|
|
|
67810
68306
|
case "check_suite":
|
|
67811
68307
|
case "workflow_run": {
|
|
67812
68308
|
if (action !== "completed") return { type: "ignored" };
|
|
67813
|
-
const
|
|
67814
|
-
const suite = obj(
|
|
67815
|
-
const branch = str2(
|
|
67816
|
-
const sha = str2(
|
|
68309
|
+
const run4 = obj(body[eventType]);
|
|
68310
|
+
const suite = obj(run4?.check_suite);
|
|
68311
|
+
const branch = str2(run4?.head_branch) || str2(suite?.head_branch);
|
|
68312
|
+
const sha = str2(run4?.head_sha) || str2(suite?.head_sha);
|
|
67817
68313
|
if (!branch || !/^[0-9a-f]{7,64}$/i.test(sha)) return { type: "ignored" };
|
|
67818
68314
|
return { type: "check", trigger: { repo, branch, sha } };
|
|
67819
68315
|
}
|
|
@@ -67851,9 +68347,9 @@ function reviewTargetOf(eventType, payload) {
|
|
|
67851
68347
|
return match ? target("", match[1]) : { repo };
|
|
67852
68348
|
}
|
|
67853
68349
|
default: {
|
|
67854
|
-
const
|
|
67855
|
-
const suite = obj(
|
|
67856
|
-
const branch = str2(
|
|
68350
|
+
const run4 = obj(body[eventType]);
|
|
68351
|
+
const suite = obj(run4?.check_suite);
|
|
68352
|
+
const branch = str2(run4?.head_branch) || str2(suite?.head_branch);
|
|
67857
68353
|
return branch ? target(branch, void 0) : { repo };
|
|
67858
68354
|
}
|
|
67859
68355
|
}
|
|
@@ -68096,14 +68592,14 @@ var init_server3 = __esm({
|
|
|
68096
68592
|
const handoff2 = /* @__PURE__ */ new Map();
|
|
68097
68593
|
const keyOf2 = (repo, branch) => `${repoArg(repo)}#${branch}`;
|
|
68098
68594
|
const noMergeQueue = /* @__PURE__ */ new Set();
|
|
68099
|
-
async function withMergeQueueFallback(repo,
|
|
68100
|
-
if (noMergeQueue.has(repo.host)) return
|
|
68595
|
+
async function withMergeQueueFallback(repo, run4) {
|
|
68596
|
+
if (noMergeQueue.has(repo.host)) return run4(false);
|
|
68101
68597
|
try {
|
|
68102
|
-
return await
|
|
68598
|
+
return await run4(true);
|
|
68103
68599
|
} catch (error63) {
|
|
68104
68600
|
if (!isUnknownMergeQueueField(error63)) throw error63;
|
|
68105
68601
|
noMergeQueue.add(repo.host);
|
|
68106
|
-
return
|
|
68602
|
+
return run4(false);
|
|
68107
68603
|
}
|
|
68108
68604
|
}
|
|
68109
68605
|
function query(repo, branch, ctx) {
|
|
@@ -69060,12 +69556,12 @@ var init_worktree_checkpoints = __esm({
|
|
|
69060
69556
|
|
|
69061
69557
|
// src/server/services/_utils/checkpoint-store.ts
|
|
69062
69558
|
import { rmSync as rmSync4 } from "node:fs";
|
|
69063
|
-
import { join as
|
|
69559
|
+
import { join as join43 } from "node:path";
|
|
69064
69560
|
function worktreeCheckpointDir(worktreeId4) {
|
|
69065
|
-
return
|
|
69561
|
+
return join43(bandHome(), "checkpoints", worktreeId4);
|
|
69066
69562
|
}
|
|
69067
69563
|
function checkpointDir(worktreeId4, checkpointId2) {
|
|
69068
|
-
return
|
|
69564
|
+
return join43(worktreeCheckpointDir(worktreeId4), checkpointId2);
|
|
69069
69565
|
}
|
|
69070
69566
|
function forgetCheckpoints(worktreeId4) {
|
|
69071
69567
|
queries.deleteForWorktree(worktreeId4);
|
|
@@ -72280,7 +72776,7 @@ var init_chat_ownership_service = __esm({
|
|
|
72280
72776
|
this.deliverAgain.add(hostId2);
|
|
72281
72777
|
return;
|
|
72282
72778
|
}
|
|
72283
|
-
const
|
|
72779
|
+
const run4 = (async () => {
|
|
72284
72780
|
do {
|
|
72285
72781
|
this.deliverAgain.delete(hostId2);
|
|
72286
72782
|
for (; ; ) {
|
|
@@ -72302,8 +72798,8 @@ var init_chat_ownership_service = __esm({
|
|
|
72302
72798
|
}
|
|
72303
72799
|
} while (this.deliverAgain.has(hostId2));
|
|
72304
72800
|
})();
|
|
72305
|
-
this.delivering.set(hostId2,
|
|
72306
|
-
void
|
|
72801
|
+
this.delivering.set(hostId2, run4);
|
|
72802
|
+
void run4.catch((err) => log24.warn({ hostId: hostId2, err }, "chat outbox delivery failed")).finally(() => {
|
|
72307
72803
|
this.delivering.delete(hostId2);
|
|
72308
72804
|
if (this.deliverAgain.delete(hostId2) && !this.retryTimers.has(hostId2)) {
|
|
72309
72805
|
this.deliver(hostId2);
|
|
@@ -75175,8 +75671,8 @@ var init_placement_service = __esm({
|
|
|
75175
75671
|
*/
|
|
75176
75672
|
async placeWorktree(input3, placement) {
|
|
75177
75673
|
const worktreeId4 = toWorktreeId(input3.repo, input3.branch, void 0);
|
|
75178
|
-
const
|
|
75179
|
-
if (
|
|
75674
|
+
const open3 = this.queries.findOpenForWorktree(worktreeId4);
|
|
75675
|
+
if (open3) return { kind: "request", requestId: open3.id };
|
|
75180
75676
|
const holders = this.holdersOfRemotelessRepo(input3.repo);
|
|
75181
75677
|
const agent = input3.codingAgentId ? loadSettings().codingAgents?.find((a) => a.id === input3.codingAgentId)?.type ?? input3.codingAgentId : void 0;
|
|
75182
75678
|
const allowed2 = allowedHostsOf(input3.repo);
|
|
@@ -75244,8 +75740,8 @@ var init_placement_service = __esm({
|
|
|
75244
75740
|
requestWake(wake, repo, branch) {
|
|
75245
75741
|
const first = wake.worktreeIds[0];
|
|
75246
75742
|
if (!first) throw new Error("A wake request names no worktree");
|
|
75247
|
-
const
|
|
75248
|
-
if (
|
|
75743
|
+
const open3 = this.queries.findOpenForWorktree(first);
|
|
75744
|
+
if (open3) return open3;
|
|
75249
75745
|
const earlier = this.queries.latestForHost(wake.hostId);
|
|
75250
75746
|
const now = this.now();
|
|
75251
75747
|
const row = {
|
|
@@ -76331,7 +76827,7 @@ var init_git_credential_service = __esm({
|
|
|
76331
76827
|
import { spawn as spawn6 } from "node:child_process";
|
|
76332
76828
|
import { randomBytes as randomBytes10 } from "node:crypto";
|
|
76333
76829
|
import { appendFileSync, mkdirSync as mkdirSync8, readFileSync as readFileSync11, rmSync as rmSync5, statSync as statSync14 } from "node:fs";
|
|
76334
|
-
import { dirname as dirname13, join as
|
|
76830
|
+
import { dirname as dirname13, join as join44 } from "node:path";
|
|
76335
76831
|
function snapshotSweepMs() {
|
|
76336
76832
|
const raw = Number(process.env.BAND_SNAPSHOT_SWEEP_MS);
|
|
76337
76833
|
return Number.isFinite(raw) && raw > 0 ? raw : SNAPSHOT_SWEEP_MS;
|
|
@@ -76528,7 +77024,7 @@ var init_runner_service = __esm({
|
|
|
76528
77024
|
}
|
|
76529
77025
|
}
|
|
76530
77026
|
logFile(requestId2) {
|
|
76531
|
-
return
|
|
77027
|
+
return join44(bandHome(), "runners", "logs", `${requestId2}.log`);
|
|
76532
77028
|
}
|
|
76533
77029
|
/** Every valid runner in settings. */
|
|
76534
77030
|
configs() {
|
|
@@ -76544,12 +77040,12 @@ var init_runner_service = __esm({
|
|
|
76544
77040
|
}
|
|
76545
77041
|
/** Whether the worker id belongs to an attempt in flight. */
|
|
76546
77042
|
isAttempting(workerId) {
|
|
76547
|
-
for (const
|
|
77043
|
+
for (const run4 of this.running.values()) if (run4.workerId === workerId) return true;
|
|
76548
77044
|
return false;
|
|
76549
77045
|
}
|
|
76550
77046
|
runningCount(runnerId2) {
|
|
76551
77047
|
let n = 0;
|
|
76552
|
-
for (const
|
|
77048
|
+
for (const run4 of this.running.values()) if (run4.runnerId === runnerId2) n++;
|
|
76553
77049
|
return n;
|
|
76554
77050
|
}
|
|
76555
77051
|
// ---- leasing -------------------------------------------------------------
|
|
@@ -76585,7 +77081,7 @@ var init_runner_service = __esm({
|
|
|
76585
77081
|
}
|
|
76586
77082
|
}
|
|
76587
77083
|
begin(runner, row) {
|
|
76588
|
-
const
|
|
77084
|
+
const run4 = {
|
|
76589
77085
|
requestId: row.id,
|
|
76590
77086
|
runnerId: runner.id,
|
|
76591
77087
|
worktreeId: row.worktreeId,
|
|
@@ -76596,27 +77092,27 @@ var init_runner_service = __esm({
|
|
|
76596
77092
|
endedAt: null,
|
|
76597
77093
|
error: null
|
|
76598
77094
|
};
|
|
76599
|
-
this.running.set(row.id,
|
|
76600
|
-
const done = this.run(runner, row,
|
|
77095
|
+
this.running.set(row.id, run4);
|
|
77096
|
+
const done = this.run(runner, row, run4).catch(
|
|
76601
77097
|
(err) => log32.error(`run of ${row.id} crashed: ${err instanceof Error ? err.stack : err}`)
|
|
76602
77098
|
).finally(() => {
|
|
76603
77099
|
this.running.delete(row.id);
|
|
76604
|
-
|
|
76605
|
-
this.history.push(
|
|
77100
|
+
run4.endedAt = Date.now();
|
|
77101
|
+
this.history.push(run4);
|
|
76606
77102
|
if (this.history.length > HISTORY_LIMIT) this.history.shift();
|
|
76607
77103
|
this.settled.delete(done);
|
|
76608
77104
|
});
|
|
76609
77105
|
this.settled.add(done);
|
|
76610
77106
|
}
|
|
76611
77107
|
// ---- one request ---------------------------------------------------------
|
|
76612
|
-
async run(runner, row,
|
|
77108
|
+
async run(runner, row, run4) {
|
|
76613
77109
|
const runLog = new RunLog(this.logFile(row.id));
|
|
76614
77110
|
runLog.write("hub", `runner ${runner.id} took request ${row.id} for ${row.worktreeId}`);
|
|
76615
77111
|
const environment = parseRequestEnvironment(row);
|
|
76616
77112
|
if (!environment.ok) {
|
|
76617
77113
|
runLog.write("hub", environment.error);
|
|
76618
|
-
|
|
76619
|
-
|
|
77114
|
+
run4.status = "failed";
|
|
77115
|
+
run4.error = environment.error;
|
|
76620
77116
|
try {
|
|
76621
77117
|
placementService.fail(row.id, environment.error);
|
|
76622
77118
|
} catch (err) {
|
|
@@ -76626,19 +77122,19 @@ var init_runner_service = __esm({
|
|
|
76626
77122
|
}
|
|
76627
77123
|
let lastError = "";
|
|
76628
77124
|
for (let attempt = 1; attempt <= ATTEMPTS; attempt++) {
|
|
76629
|
-
|
|
77125
|
+
run4.attempt = attempt;
|
|
76630
77126
|
runLog.write("hub", `attempt ${attempt} of ${ATTEMPTS}`);
|
|
76631
77127
|
const attemptState = { hostId: null, token: null };
|
|
76632
77128
|
try {
|
|
76633
|
-
const hostId2 = await this.attempt(runner, row,
|
|
76634
|
-
|
|
76635
|
-
|
|
77129
|
+
const hostId2 = await this.attempt(runner, row, run4, runLog, attemptState);
|
|
77130
|
+
run4.workerId = hostId2;
|
|
77131
|
+
run4.status = "ready";
|
|
76636
77132
|
runLog.write("hub", `worker ${hostId2} said hello; request fulfilled`);
|
|
76637
77133
|
return;
|
|
76638
77134
|
} catch (err) {
|
|
76639
77135
|
if (err instanceof Aborted) {
|
|
76640
|
-
|
|
76641
|
-
|
|
77136
|
+
run4.status = "aborted";
|
|
77137
|
+
run4.error = err.message;
|
|
76642
77138
|
runLog.write("hub", `stopped: ${err.message}`);
|
|
76643
77139
|
await this.cleanup(runner, row, attemptState, runLog);
|
|
76644
77140
|
return;
|
|
@@ -76649,8 +77145,8 @@ var init_runner_service = __esm({
|
|
|
76649
77145
|
}
|
|
76650
77146
|
}
|
|
76651
77147
|
const reason = this.failureReason(runner, lastError, runLog);
|
|
76652
|
-
|
|
76653
|
-
|
|
77148
|
+
run4.status = "failed";
|
|
77149
|
+
run4.error = lastError;
|
|
76654
77150
|
try {
|
|
76655
77151
|
placementService.fail(row.id, reason);
|
|
76656
77152
|
} catch (err) {
|
|
@@ -76723,13 +77219,13 @@ ${tail}` : head;
|
|
|
76723
77219
|
* runner holds a snapshot for tries `restore` first, and starts a fresh worker with `spawn` when
|
|
76724
77220
|
* that fails, so the git and session state the sleep stored is what brings the worktree back.
|
|
76725
77221
|
*/
|
|
76726
|
-
async attempt(runner, row,
|
|
77222
|
+
async attempt(runner, row, run4, runLog, state2) {
|
|
76727
77223
|
const wake = wakeOf(row);
|
|
76728
77224
|
const snapshot = wake ? this.restorableSnapshot(runner, wake.hostId) : void 0;
|
|
76729
77225
|
if (snapshot) {
|
|
76730
77226
|
this.restoring.add(snapshot.id);
|
|
76731
77227
|
try {
|
|
76732
|
-
return await this.launch(runner, row,
|
|
77228
|
+
return await this.launch(runner, row, run4, runLog, state2, "restore", snapshot);
|
|
76733
77229
|
} catch (err) {
|
|
76734
77230
|
if (err instanceof Aborted) throw err;
|
|
76735
77231
|
runLog.write(
|
|
@@ -76742,7 +77238,7 @@ ${tail}` : head;
|
|
|
76742
77238
|
this.restoring.delete(snapshot.id);
|
|
76743
77239
|
}
|
|
76744
77240
|
}
|
|
76745
|
-
return this.launch(runner, row,
|
|
77241
|
+
return this.launch(runner, row, run4, runLog, state2, "spawn");
|
|
76746
77242
|
}
|
|
76747
77243
|
/** The snapshot a wake can restore from: this runner's, still alive, and the runner has a `restore` hook. */
|
|
76748
77244
|
restorableSnapshot(runner, hostId2) {
|
|
@@ -76752,7 +77248,7 @@ ${tail}` : head;
|
|
|
76752
77248
|
return void 0;
|
|
76753
77249
|
return latest;
|
|
76754
77250
|
}
|
|
76755
|
-
async launch(runner, row,
|
|
77251
|
+
async launch(runner, row, run4, runLog, state2, kind, snapshot) {
|
|
76756
77252
|
const deadline = Date.now() + runner.timeoutSec * 1e3;
|
|
76757
77253
|
const labelList = Object.entries(row.labels).map(([k2, v2]) => `${k2}=${v2}`);
|
|
76758
77254
|
const wanted = requestedIsolation(row.environment);
|
|
@@ -76770,7 +77266,7 @@ ${tail}` : head;
|
|
|
76770
77266
|
state2.reused = wake !== null;
|
|
76771
77267
|
state2.token = issued.token;
|
|
76772
77268
|
runLog.addSecret(issued.token);
|
|
76773
|
-
|
|
77269
|
+
run4.workerId = issued.hostId;
|
|
76774
77270
|
runLog.write("hub", `issued worker ${issued.hostId}`);
|
|
76775
77271
|
const machineId = this.recordMachine(runner, row, issued.hostId);
|
|
76776
77272
|
state2.machineId = machineId;
|
|
@@ -76905,11 +77401,11 @@ ${tail}` : head;
|
|
|
76905
77401
|
destroyMachine(machineId, reason) {
|
|
76906
77402
|
const inflight = this.destroying.get(machineId);
|
|
76907
77403
|
if (inflight) return inflight;
|
|
76908
|
-
const
|
|
77404
|
+
const run4 = this.doDestroyMachine(machineId, reason).finally(
|
|
76909
77405
|
() => this.destroying.delete(machineId)
|
|
76910
77406
|
);
|
|
76911
|
-
this.destroying.set(machineId,
|
|
76912
|
-
return
|
|
77407
|
+
this.destroying.set(machineId, run4);
|
|
77408
|
+
return run4;
|
|
76913
77409
|
}
|
|
76914
77410
|
async doDestroyMachine(machineId, reason) {
|
|
76915
77411
|
const machine = this.machines.get(machineId);
|
|
@@ -76918,7 +77414,7 @@ ${tail}` : head;
|
|
|
76918
77414
|
const runner = this.findRunner(machine.runnerId);
|
|
76919
77415
|
const request = machine.requestId ? placementService.get(machine.requestId) : void 0;
|
|
76920
77416
|
const runLog = new RunLog(
|
|
76921
|
-
machine.requestId ? this.logFile(machine.requestId) :
|
|
77417
|
+
machine.requestId ? this.logFile(machine.requestId) : join44(bandHome(), "runners", "logs", `${machine.id}.log`)
|
|
76922
77418
|
);
|
|
76923
77419
|
runLog.write(
|
|
76924
77420
|
"hub",
|
|
@@ -76966,7 +77462,7 @@ ${tail}` : head;
|
|
|
76966
77462
|
/** Runs `destroy` for a machine the hub has no record of, named only by the handle `status` printed. */
|
|
76967
77463
|
async destroyHandle(runner, handle, reason) {
|
|
76968
77464
|
if (!runner.destroy) return false;
|
|
76969
|
-
const file3 =
|
|
77465
|
+
const file3 = join44(bandHome(), "runners", "logs", "reaper.log");
|
|
76970
77466
|
try {
|
|
76971
77467
|
if (statSync14(file3).size > LOG_FILE_LIMIT) rmSync5(file3, { force: true });
|
|
76972
77468
|
} catch {
|
|
@@ -77188,7 +77684,7 @@ ${tail}` : head;
|
|
|
77188
77684
|
// The repo's current environment image (plan step 3.2), empty before its first ready build.
|
|
77189
77685
|
BAND_REPO_IMAGE: row ? this.repoImage(row.repo) : "",
|
|
77190
77686
|
BAND_RUNNER_ID: runner.id,
|
|
77191
|
-
BAND_RUNNER_DIR:
|
|
77687
|
+
BAND_RUNNER_DIR: join44(bandHome(), "runners", runner.id),
|
|
77192
77688
|
BAND_NODE: process.execPath
|
|
77193
77689
|
});
|
|
77194
77690
|
if (runner.desktop) env.BAND_DESKTOP = "1";
|
|
@@ -77217,7 +77713,7 @@ ${tail}` : head;
|
|
|
77217
77713
|
*/
|
|
77218
77714
|
runHook(opts) {
|
|
77219
77715
|
const { runner, name: name5, path: path2, env, timeoutMs, runLog, watch, onStdout, onStderr } = opts;
|
|
77220
|
-
const cwd =
|
|
77716
|
+
const cwd = join44(bandHome(), "runners", runner.id);
|
|
77221
77717
|
mkdirSync8(cwd, { recursive: true, mode: 448 });
|
|
77222
77718
|
return new Promise((resolve16, reject) => {
|
|
77223
77719
|
let child;
|
|
@@ -77277,14 +77773,14 @@ ${tail}` : head;
|
|
|
77277
77773
|
|
|
77278
77774
|
// src/server/services/ephemeral-lifecycle-service.ts
|
|
77279
77775
|
import { rmSync as rmSync6 } from "node:fs";
|
|
77280
|
-
import { mkdir as mkdir6, readFile as
|
|
77281
|
-
import { join as
|
|
77776
|
+
import { mkdir as mkdir6, readFile as readFile11, writeFile as writeFile4 } from "node:fs/promises";
|
|
77777
|
+
import { join as join45, posix as posix5 } from "node:path";
|
|
77282
77778
|
function idleTimeoutMs() {
|
|
77283
77779
|
const raw = Number(process.env.BAND_EPHEMERAL_IDLE_TIMEOUT_MS);
|
|
77284
77780
|
return Number.isFinite(raw) && raw > 0 ? raw : void 0;
|
|
77285
77781
|
}
|
|
77286
77782
|
function sleepDir(worktreeId4) {
|
|
77287
|
-
return
|
|
77783
|
+
return join45(bandHome(), "sleep", worktreeId4);
|
|
77288
77784
|
}
|
|
77289
77785
|
var log33, LOCAL_HOST_ID6, WAKE_POLL_MS, WAKE_GRACE_MS, EXIT_GRACE_MS2, SleepError, errorText2, EphemeralLifecycleService, ephemeralLifecycleService;
|
|
77290
77786
|
var init_ephemeral_lifecycle_service = __esm({
|
|
@@ -77606,7 +78102,7 @@ var init_ephemeral_lifecycle_service = __esm({
|
|
|
77606
78102
|
const dir = sleepDir(worktreeId4);
|
|
77607
78103
|
try {
|
|
77608
78104
|
await mkdir6(dir, { recursive: true, mode: 448 });
|
|
77609
|
-
await writeFile4(
|
|
78105
|
+
await writeFile4(join45(dir, "snapshot.bundle"), await host.fs.readFile(bundle), {
|
|
77610
78106
|
mode: 384
|
|
77611
78107
|
});
|
|
77612
78108
|
} catch (err) {
|
|
@@ -77630,7 +78126,7 @@ var init_ephemeral_lifecycle_service = __esm({
|
|
|
77630
78126
|
try {
|
|
77631
78127
|
const dir = sleepDir(worktreeId4);
|
|
77632
78128
|
await mkdir6(dir, { recursive: true, mode: 448 });
|
|
77633
|
-
await writeFile4(
|
|
78129
|
+
await writeFile4(join45(dir, "sessions.json"), JSON.stringify({ files }), { mode: 384 });
|
|
77634
78130
|
} catch (err) {
|
|
77635
78131
|
log33.warn(`could not keep the agent sessions of ${worktreeId4}: ${errorText2(err)}`);
|
|
77636
78132
|
return [];
|
|
@@ -77756,7 +78252,7 @@ var init_ephemeral_lifecycle_service = __esm({
|
|
|
77756
78252
|
const bundle = posix5.join(wipDir, `${row.worktreeId}.bundle`);
|
|
77757
78253
|
await host.fs.writeFile(
|
|
77758
78254
|
bundle,
|
|
77759
|
-
await
|
|
78255
|
+
await readFile11(join45(sleepDir(row.worktreeId), "snapshot.bundle"))
|
|
77760
78256
|
);
|
|
77761
78257
|
try {
|
|
77762
78258
|
await git2(["fetch", "--force", bundle, `${local}:${local}`]);
|
|
@@ -77813,7 +78309,7 @@ var init_ephemeral_lifecycle_service = __esm({
|
|
|
77813
78309
|
if (row.sessionIds.length === 0) return;
|
|
77814
78310
|
let files;
|
|
77815
78311
|
try {
|
|
77816
|
-
files = JSON.parse(await
|
|
78312
|
+
files = JSON.parse(await readFile11(join45(sleepDir(row.worktreeId), "sessions.json"), "utf8")).files;
|
|
77817
78313
|
} catch (err) {
|
|
77818
78314
|
log33.warn(`${row.worktreeId}: no saved agent sessions: ${errorText2(err)}`);
|
|
77819
78315
|
return;
|
|
@@ -78553,7 +79049,7 @@ var init_watcher_service = __esm({
|
|
|
78553
79049
|
this.poller.start();
|
|
78554
79050
|
const statuses = loadCurrentStatuses();
|
|
78555
79051
|
const runningScripts = worktreeScriptService.getRunning();
|
|
78556
|
-
const runningSetups = [...new Set(runningScripts.map((
|
|
79052
|
+
const runningSetups = [...new Set(runningScripts.map((run4) => run4.worktreeId))];
|
|
78557
79053
|
listener({ kind: "snapshot", statuses, runningSetups });
|
|
78558
79054
|
for (const event of this.loadCurrentBranchStatuses()) {
|
|
78559
79055
|
listener(event);
|
|
@@ -78645,13 +79141,13 @@ var init_agent_session_registry_service = __esm({
|
|
|
78645
79141
|
* agent sessions gets its row here, the first time its id is known.
|
|
78646
79142
|
*/
|
|
78647
79143
|
recordChatProviderSession(chat, providerSessionId) {
|
|
78648
|
-
const
|
|
78649
|
-
if (
|
|
78650
|
-
if (
|
|
78651
|
-
if (providerSessionId) this.update(
|
|
79144
|
+
const open3 = this.queries.findOpenByChat(chat.id);
|
|
79145
|
+
if (open3 && open3.providerSessionId === providerSessionId) return;
|
|
79146
|
+
if (open3 && open3.providerSessionId === null) {
|
|
79147
|
+
if (providerSessionId) this.update(open3.id, { providerSessionId, state: "running" });
|
|
78652
79148
|
return;
|
|
78653
79149
|
}
|
|
78654
|
-
if (
|
|
79150
|
+
if (open3) this.end(open3.id);
|
|
78655
79151
|
if (!providerSessionId) return;
|
|
78656
79152
|
this.create({
|
|
78657
79153
|
worktreeId: chat.worktreeId,
|
|
@@ -78662,12 +79158,12 @@ var init_agent_session_registry_service = __esm({
|
|
|
78662
79158
|
});
|
|
78663
79159
|
}
|
|
78664
79160
|
endForChat(chatId) {
|
|
78665
|
-
const
|
|
78666
|
-
if (
|
|
79161
|
+
const open3 = this.queries.findOpenByChat(chatId);
|
|
79162
|
+
if (open3) this.end(open3.id);
|
|
78667
79163
|
}
|
|
78668
79164
|
endForTerminal(terminalId) {
|
|
78669
|
-
const
|
|
78670
|
-
if (
|
|
79165
|
+
const open3 = this.queries.findOpenByTerminal(terminalId);
|
|
79166
|
+
if (open3) this.end(open3.id);
|
|
78671
79167
|
}
|
|
78672
79168
|
end(id) {
|
|
78673
79169
|
const ended = this.queries.update(id, { state: "ended", updatedAt: Date.now() });
|
|
@@ -80675,7 +81171,7 @@ var init_worker_lease_service = __esm({
|
|
|
80675
81171
|
entry.again = true;
|
|
80676
81172
|
return entry.running;
|
|
80677
81173
|
}
|
|
80678
|
-
const
|
|
81174
|
+
const run4 = (async () => {
|
|
80679
81175
|
do {
|
|
80680
81176
|
entry.again = false;
|
|
80681
81177
|
await this.renewOnce(hostId2, entry);
|
|
@@ -80684,8 +81180,8 @@ var init_worker_lease_service = __esm({
|
|
|
80684
81180
|
entry.running = null;
|
|
80685
81181
|
entry.again = false;
|
|
80686
81182
|
});
|
|
80687
|
-
entry.running =
|
|
80688
|
-
return
|
|
81183
|
+
entry.running = run4;
|
|
81184
|
+
return run4;
|
|
80689
81185
|
}
|
|
80690
81186
|
async renewOnce(hostId2, entry) {
|
|
80691
81187
|
const params = { ttlMs: leaseMs(), blockedPaths: this.blockedPaths(hostId2) };
|
|
@@ -80922,7 +81418,7 @@ __export(worktree_service_exports, {
|
|
|
80922
81418
|
});
|
|
80923
81419
|
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
80924
81420
|
import { unlinkSync as unlinkSync5 } from "node:fs";
|
|
80925
|
-
import { join as
|
|
81421
|
+
import { join as join46, posix as posix6 } from "node:path";
|
|
80926
81422
|
function findWorktreeRow(worktrees2, name5, hostId2) {
|
|
80927
81423
|
const named = worktrees2.filter((wt) => wt.name === name5);
|
|
80928
81424
|
if (hostId2 !== void 0) return named.find((wt) => (wt.hostId ?? "local") === hostId2);
|
|
@@ -81383,8 +81879,8 @@ var init_worktree_service = __esm({
|
|
|
81383
81879
|
try {
|
|
81384
81880
|
repoPath = await this.checkoutOn(repo, host, input3.hostRepoPath);
|
|
81385
81881
|
const wtDir = remote ? await this.remoteWorktreesDir(host) : worktreesDir();
|
|
81386
|
-
worktreePath = remote ? posix6.join(wtDir, input3.repo, input3.branch) :
|
|
81387
|
-
await host.fs.mkdir(remote ? posix6.join(wtDir, input3.repo) :
|
|
81882
|
+
worktreePath = remote ? posix6.join(wtDir, input3.repo, input3.branch) : join46(wtDir, input3.repo, input3.branch);
|
|
81883
|
+
await host.fs.mkdir(remote ? posix6.join(wtDir, input3.repo) : join46(wtDir, input3.repo), {
|
|
81388
81884
|
recursive: true
|
|
81389
81885
|
});
|
|
81390
81886
|
try {
|
|
@@ -81666,7 +82162,7 @@ var init_worktree_service = __esm({
|
|
|
81666
82162
|
if (gone.supersededBy)
|
|
81667
82163
|
void workerLeaseService.pushBlockedPaths(gone.hostId ?? hostRegistry.local.id);
|
|
81668
82164
|
try {
|
|
81669
|
-
unlinkSync5(
|
|
82165
|
+
unlinkSync5(join46(bandHome(), "workspace-prompts", `${worktreeId4}.json`));
|
|
81670
82166
|
} catch {
|
|
81671
82167
|
}
|
|
81672
82168
|
deleteWorktreeStatus(worktreeId4);
|
|
@@ -82273,7 +82769,7 @@ var init_worktree_service = __esm({
|
|
|
82273
82769
|
if (!/^[a-zA-Z0-9._-]+$/.test(input3.scriptType) || input3.scriptType.includes("..")) {
|
|
82274
82770
|
throw new Error(`Invalid script type "${input3.scriptType}"`);
|
|
82275
82771
|
}
|
|
82276
|
-
const scriptPath =
|
|
82772
|
+
const scriptPath = join46(input3.path, ".band", input3.scriptType);
|
|
82277
82773
|
const host = hostRegistry.local;
|
|
82278
82774
|
try {
|
|
82279
82775
|
await host.fs.stat(scriptPath);
|
|
@@ -82851,11 +83347,11 @@ var init_subscription_source_service = __esm({
|
|
|
82851
83347
|
if (running) {
|
|
82852
83348
|
await running;
|
|
82853
83349
|
}
|
|
82854
|
-
const
|
|
82855
|
-
if (checking.get(check3.flight) ===
|
|
83350
|
+
const run4 = this.fetchAndIngest(provider, check3.trigger).finally(() => {
|
|
83351
|
+
if (checking.get(check3.flight) === run4) checking.delete(check3.flight);
|
|
82856
83352
|
});
|
|
82857
|
-
checking.set(check3.flight,
|
|
82858
|
-
await
|
|
83353
|
+
checking.set(check3.flight, run4);
|
|
83354
|
+
await run4;
|
|
82859
83355
|
}
|
|
82860
83356
|
async fetchAndIngest(provider, trigger) {
|
|
82861
83357
|
const event = await provider.aggregateChecks(trigger, subscriptionContext());
|
|
@@ -82882,11 +83378,11 @@ var init_subscription_source_service = __esm({
|
|
|
82882
83378
|
const repo = sub.config.repo;
|
|
82883
83379
|
if (sub.source !== GITHUB || !repo) return;
|
|
82884
83380
|
const previous = registering.get(repo) ?? Promise.resolve();
|
|
82885
|
-
const
|
|
82886
|
-
if (registering.get(repo) ===
|
|
83381
|
+
const run4 = previous.then(() => this.register(sub.id, repo, sub.source)).finally(() => {
|
|
83382
|
+
if (registering.get(repo) === run4) registering.delete(repo);
|
|
82887
83383
|
});
|
|
82888
|
-
registering.set(repo,
|
|
82889
|
-
await
|
|
83384
|
+
registering.set(repo, run4);
|
|
83385
|
+
await run4;
|
|
82890
83386
|
}
|
|
82891
83387
|
async register(subscriptionId, repo, source) {
|
|
82892
83388
|
const set2 = (status, error63) => {
|
|
@@ -85469,6 +85965,15 @@ var init_agent_session_service = __esm({
|
|
|
85469
85965
|
observeBackgroundTasks(observer) {
|
|
85470
85966
|
backgroundObserver = observer;
|
|
85471
85967
|
}
|
|
85968
|
+
/** The agent process of each chat that has one: the chat, its worktree and the pid on the worker. */
|
|
85969
|
+
agentPids() {
|
|
85970
|
+
const out = [];
|
|
85971
|
+
for (const rt of runtimes.values()) {
|
|
85972
|
+
const pid = rt.process?.pid;
|
|
85973
|
+
if (pid !== void 0) out.push({ chatId: rt.chatId, worktreeId: rt.worktreeId, pid });
|
|
85974
|
+
}
|
|
85975
|
+
return out;
|
|
85976
|
+
}
|
|
85472
85977
|
/** When the chat's agent last sent anything (ms since epoch), or null. */
|
|
85473
85978
|
lastActivityAt(chatId) {
|
|
85474
85979
|
return runtimes.get(chatId)?.lastActivityAt ?? null;
|
|
@@ -92859,7 +93364,7 @@ import {
|
|
|
92859
93364
|
statSync as statSync17
|
|
92860
93365
|
} from "node:fs";
|
|
92861
93366
|
import { createServer as createServer3 } from "node:http";
|
|
92862
|
-
import { basename as basename7, join as
|
|
93367
|
+
import { basename as basename7, join as join62, resolve as resolve15, sep as sep12 } from "node:path";
|
|
92863
93368
|
import { pipeline as pipeline3, Readable as Readable2 } from "node:stream";
|
|
92864
93369
|
import { parseArgs } from "node:util";
|
|
92865
93370
|
|
|
@@ -96282,7 +96787,7 @@ var sessionIdSchema = external_exports2.string().regex(SESSION_ID_PATTERN2, "inv
|
|
|
96282
96787
|
init_registry();
|
|
96283
96788
|
init_state();
|
|
96284
96789
|
import { mkdir as mkdir7, writeFile as writeFile5 } from "node:fs/promises";
|
|
96285
|
-
import { join as
|
|
96790
|
+
import { join as join47, resolve as resolve8, sep as sep5 } from "node:path";
|
|
96286
96791
|
function decodeParts(fileParts) {
|
|
96287
96792
|
const baseTimestamp = Date.now();
|
|
96288
96793
|
const decoded = [];
|
|
@@ -96302,11 +96807,11 @@ function decodeParts(fileParts) {
|
|
|
96302
96807
|
return decoded;
|
|
96303
96808
|
}
|
|
96304
96809
|
async function saveUploadedFilesDetailed(fileParts) {
|
|
96305
|
-
const uploadDir =
|
|
96810
|
+
const uploadDir = join47(bandHome(), "uploads");
|
|
96306
96811
|
await mkdir7(uploadDir, { recursive: true });
|
|
96307
96812
|
const saved = [];
|
|
96308
96813
|
for (const part of decodeParts(fileParts)) {
|
|
96309
|
-
const filePath =
|
|
96814
|
+
const filePath = join47(uploadDir, part.storedName);
|
|
96310
96815
|
await writeFile5(filePath, part.buffer);
|
|
96311
96816
|
saved.push({
|
|
96312
96817
|
path: filePath,
|
|
@@ -96321,7 +96826,7 @@ async function saveUploadedFilesDetailed(fileParts) {
|
|
|
96321
96826
|
async function remoteUploadDir(host, worktreeId4) {
|
|
96322
96827
|
const dirs = (await host.info()).dirs;
|
|
96323
96828
|
if (!dirs) throw new Error(`Worker ${host.id} has no directory for uploads`);
|
|
96324
|
-
return
|
|
96829
|
+
return join47(dirs.uploads, worktreeId4);
|
|
96325
96830
|
}
|
|
96326
96831
|
async function saveWorktreeUploads(worktreeId4, fileParts) {
|
|
96327
96832
|
const host = hostRegistry.hostFor(worktreeId4);
|
|
@@ -96330,7 +96835,7 @@ async function saveWorktreeUploads(worktreeId4, fileParts) {
|
|
|
96330
96835
|
await host.fs.mkdir(dir, { recursive: true });
|
|
96331
96836
|
const saved = [];
|
|
96332
96837
|
for (const part of decodeParts(fileParts)) {
|
|
96333
|
-
const filePath =
|
|
96838
|
+
const filePath = join47(dir, part.storedName);
|
|
96334
96839
|
await host.fs.writeFile(filePath, part.buffer, { exclusive: true, mode: 384 });
|
|
96335
96840
|
saved.push({
|
|
96336
96841
|
path: filePath,
|
|
@@ -96346,19 +96851,19 @@ async function uploadPathFromUrl(worktreeId4, url3) {
|
|
|
96346
96851
|
const host = hostRegistry.hostFor(worktreeId4);
|
|
96347
96852
|
const match = url3.match(/^\/api\/uploads\/(.+)$/);
|
|
96348
96853
|
if (!match) return null;
|
|
96349
|
-
if (host.id === hostRegistry.local.id) return
|
|
96854
|
+
if (host.id === hostRegistry.local.id) return join47(bandHome(), "uploads", match[1]);
|
|
96350
96855
|
const rest = match[1].split("/");
|
|
96351
96856
|
if (rest.length !== 2) return null;
|
|
96352
96857
|
try {
|
|
96353
96858
|
if (decodeURIComponent(rest[0]) !== worktreeId4) return null;
|
|
96354
|
-
return
|
|
96859
|
+
return join47(await remoteUploadDir(host, worktreeId4), decodeURIComponent(rest[1]));
|
|
96355
96860
|
} catch {
|
|
96356
96861
|
return null;
|
|
96357
96862
|
}
|
|
96358
96863
|
}
|
|
96359
96864
|
async function isWithinUploads(worktreeId4, path2) {
|
|
96360
96865
|
const host = hostRegistry.hostFor(worktreeId4);
|
|
96361
|
-
const dir = host.id === hostRegistry.local.id ?
|
|
96866
|
+
const dir = host.id === hostRegistry.local.id ? join47(bandHome(), "uploads") : await remoteUploadDir(host, worktreeId4).catch(() => null);
|
|
96362
96867
|
if (!dir) return false;
|
|
96363
96868
|
const normalized2 = resolve8(path2);
|
|
96364
96869
|
return normalized2 === dir || normalized2.startsWith(dir + sep5);
|
|
@@ -96410,8 +96915,8 @@ init_src4();
|
|
|
96410
96915
|
init_src2();
|
|
96411
96916
|
init_src();
|
|
96412
96917
|
import { createHash as createHash12, randomBytes as randomBytes15 } from "node:crypto";
|
|
96413
|
-
import { mkdir as mkdir9, readFile as
|
|
96414
|
-
import { join as
|
|
96918
|
+
import { mkdir as mkdir9, readFile as readFile13, rm as rm3, writeFile as writeFile7 } from "node:fs/promises";
|
|
96919
|
+
import { join as join50, posix as posix8 } from "node:path";
|
|
96415
96920
|
init_repo_hosts();
|
|
96416
96921
|
init_worktree_id();
|
|
96417
96922
|
init_errors6();
|
|
@@ -96480,7 +96985,7 @@ init_remote_worktrees();
|
|
|
96480
96985
|
init_repo_host_policy();
|
|
96481
96986
|
init_ephemeral_lifecycle_service();
|
|
96482
96987
|
import { existsSync as existsSync16 } from "node:fs";
|
|
96483
|
-
import { basename as basename2, join as
|
|
96988
|
+
import { basename as basename2, join as join49, posix as posix7, resolve as resolve9 } from "node:path";
|
|
96484
96989
|
|
|
96485
96990
|
// src/server/services/repo-avatar-service.ts
|
|
96486
96991
|
init_src3();
|
|
@@ -96488,8 +96993,8 @@ init_git_client();
|
|
|
96488
96993
|
init_src();
|
|
96489
96994
|
init_repos();
|
|
96490
96995
|
init_settings();
|
|
96491
|
-
import { mkdir as mkdir8, readFile as
|
|
96492
|
-
import { join as
|
|
96996
|
+
import { mkdir as mkdir8, readFile as readFile12, rename as rename4, writeFile as writeFile6 } from "node:fs/promises";
|
|
96997
|
+
import { join as join48 } from "node:path";
|
|
96493
96998
|
|
|
96494
96999
|
// src/server/infra/github/github-client.ts
|
|
96495
97000
|
var FETCH_TIMEOUT_MS2 = 1e4;
|
|
@@ -96639,7 +97144,7 @@ var RepoAvatarService = class {
|
|
|
96639
97144
|
return null;
|
|
96640
97145
|
}
|
|
96641
97146
|
await mkdir8(cacheDir(), { recursive: true });
|
|
96642
|
-
const imagePath =
|
|
97147
|
+
const imagePath = join48(cacheDir(), `${key2}.img`);
|
|
96643
97148
|
await writeFile6(`${imagePath}.tmp`, result.bytes);
|
|
96644
97149
|
await rename4(`${imagePath}.tmp`, imagePath);
|
|
96645
97150
|
await this.writeMeta(key2, entry, {
|
|
@@ -96657,7 +97162,7 @@ var RepoAvatarService = class {
|
|
|
96657
97162
|
async readCached(key2, meta3) {
|
|
96658
97163
|
if (meta3?.status !== "ok" || !meta3.contentType) return null;
|
|
96659
97164
|
try {
|
|
96660
|
-
const bytes = await
|
|
97165
|
+
const bytes = await readFile12(join48(cacheDir(), `${key2}.img`));
|
|
96661
97166
|
return { bytes, contentType: meta3.contentType };
|
|
96662
97167
|
} catch {
|
|
96663
97168
|
return null;
|
|
@@ -96667,7 +97172,7 @@ var RepoAvatarService = class {
|
|
|
96667
97172
|
entry.meta = meta3;
|
|
96668
97173
|
entry.retryAfter = 0;
|
|
96669
97174
|
await mkdir8(cacheDir(), { recursive: true });
|
|
96670
|
-
await writeFile6(
|
|
97175
|
+
await writeFile6(join48(cacheDir(), `${key2}.json`), JSON.stringify(meta3));
|
|
96671
97176
|
}
|
|
96672
97177
|
/** In-memory view of one owner's cache sidecar, loaded from disk once. */
|
|
96673
97178
|
async entry(ref) {
|
|
@@ -96676,7 +97181,7 @@ var RepoAvatarService = class {
|
|
|
96676
97181
|
if (entry) return entry;
|
|
96677
97182
|
let meta3 = null;
|
|
96678
97183
|
try {
|
|
96679
|
-
meta3 = JSON.parse(await
|
|
97184
|
+
meta3 = JSON.parse(await readFile12(join48(cacheDir(), `${key2}.json`), "utf-8"));
|
|
96680
97185
|
} catch {
|
|
96681
97186
|
}
|
|
96682
97187
|
entry = this.entries.get(key2) ?? { meta: meta3, retryAfter: 0 };
|
|
@@ -96698,7 +97203,7 @@ var RepoAvatarService = class {
|
|
|
96698
97203
|
}
|
|
96699
97204
|
};
|
|
96700
97205
|
function cacheDir() {
|
|
96701
|
-
return
|
|
97206
|
+
return join48(bandHome(), "cache", "github-avatars");
|
|
96702
97207
|
}
|
|
96703
97208
|
function cacheKey(ref) {
|
|
96704
97209
|
return `${ref.host.replace(/[^a-z0-9.-]/g, "_")}__${ref.owner.toLowerCase()}`;
|
|
@@ -96868,7 +97373,7 @@ var RepoService = class {
|
|
|
96868
97373
|
throw new Error(`Repo "${name5}" already registered`);
|
|
96869
97374
|
}
|
|
96870
97375
|
const resolvedPath = resolve9(path2);
|
|
96871
|
-
const kind = existsSync16(
|
|
97376
|
+
const kind = existsSync16(join49(resolvedPath, ".git")) ? "git" : "plain";
|
|
96872
97377
|
let defaultBranch = "main";
|
|
96873
97378
|
let worktrees2 = [];
|
|
96874
97379
|
if (kind === "git") {
|
|
@@ -97503,10 +98008,10 @@ function sessionsHashOf(files) {
|
|
|
97503
98008
|
}
|
|
97504
98009
|
return hash2.digest("hex");
|
|
97505
98010
|
}
|
|
97506
|
-
async function retryRefLock(
|
|
98011
|
+
async function retryRefLock(run4) {
|
|
97507
98012
|
for (let attempt = 1; ; attempt++) {
|
|
97508
98013
|
try {
|
|
97509
|
-
return await
|
|
98014
|
+
return await run4();
|
|
97510
98015
|
} catch (err) {
|
|
97511
98016
|
if (attempt >= 4 || !/cannot lock ref/i.test(errorText3(err))) throw err;
|
|
97512
98017
|
await new Promise((r) => setTimeout(r, 50 * attempt));
|
|
@@ -97614,13 +98119,13 @@ var CheckpointService = class {
|
|
|
97614
98119
|
*/
|
|
97615
98120
|
take(worktreeId4, trigger, opts = {}) {
|
|
97616
98121
|
const previous = this.inflight.get(worktreeId4) ?? Promise.resolve();
|
|
97617
|
-
const
|
|
97618
|
-
this.inflight.set(worktreeId4,
|
|
98122
|
+
const run4 = previous.catch(() => void 0).then(() => this.doTake(worktreeId4, trigger, opts));
|
|
98123
|
+
this.inflight.set(worktreeId4, run4);
|
|
97619
98124
|
const clear = () => {
|
|
97620
|
-
if (this.inflight.get(worktreeId4) ===
|
|
98125
|
+
if (this.inflight.get(worktreeId4) === run4) this.inflight.delete(worktreeId4);
|
|
97621
98126
|
};
|
|
97622
|
-
|
|
97623
|
-
return
|
|
98127
|
+
run4.then(clear, clear);
|
|
98128
|
+
return run4;
|
|
97624
98129
|
}
|
|
97625
98130
|
async takeAllOn(hostId2, trigger) {
|
|
97626
98131
|
let stored = 0;
|
|
@@ -97733,12 +98238,12 @@ var CheckpointService = class {
|
|
|
97733
98238
|
try {
|
|
97734
98239
|
await mkdir9(dir, { recursive: true, mode: 448 });
|
|
97735
98240
|
if (hasBundle) {
|
|
97736
|
-
await writeFile7(
|
|
98241
|
+
await writeFile7(join50(dir, "bundle.pack"), await host.fs.readFile(remoteBundle), {
|
|
97737
98242
|
mode: 384
|
|
97738
98243
|
});
|
|
97739
98244
|
}
|
|
97740
98245
|
if (sessionsJson)
|
|
97741
|
-
await writeFile7(
|
|
98246
|
+
await writeFile7(join50(dir, "sessions.json"), sessionsJson, { mode: 384 });
|
|
97742
98247
|
} catch (err) {
|
|
97743
98248
|
await rm3(dir, { recursive: true, force: true }).catch(() => void 0);
|
|
97744
98249
|
throw new CheckpointError(
|
|
@@ -97856,7 +98361,7 @@ var CheckpointService = class {
|
|
|
97856
98361
|
}
|
|
97857
98362
|
await this.withViewLock(
|
|
97858
98363
|
worktreeId4,
|
|
97859
|
-
() => rm3(
|
|
98364
|
+
() => rm3(join50(worktreeCheckpointDir(worktreeId4), "view.git"), {
|
|
97860
98365
|
recursive: true,
|
|
97861
98366
|
force: true
|
|
97862
98367
|
}).catch(() => void 0)
|
|
@@ -97929,8 +98434,8 @@ ${diff}`).digest("hex");
|
|
|
97929
98434
|
/** Builds and removals of one worktree's view repo run one at a time, because parallel fetches into a bare repo can fail on ref locks. */
|
|
97930
98435
|
withViewLock(worktreeId4, fn) {
|
|
97931
98436
|
const previous = this.viewLocks.get(worktreeId4) ?? Promise.resolve();
|
|
97932
|
-
const
|
|
97933
|
-
const tail =
|
|
98437
|
+
const run4 = previous.then(fn, fn);
|
|
98438
|
+
const tail = run4.then(
|
|
97934
98439
|
() => void 0,
|
|
97935
98440
|
() => void 0
|
|
97936
98441
|
);
|
|
@@ -97938,11 +98443,11 @@ ${diff}`).digest("hex");
|
|
|
97938
98443
|
void tail.then(() => {
|
|
97939
98444
|
if (this.viewLocks.get(worktreeId4) === tail) this.viewLocks.delete(worktreeId4);
|
|
97940
98445
|
});
|
|
97941
|
-
return
|
|
98446
|
+
return run4;
|
|
97942
98447
|
}
|
|
97943
98448
|
async buildViewRepo(worktreeId4, row) {
|
|
97944
98449
|
const local = hostRegistry.local;
|
|
97945
|
-
const dir =
|
|
98450
|
+
const dir = join50(worktreeCheckpointDir(worktreeId4), "view.git");
|
|
97946
98451
|
const git2 = gitIn(local, dir);
|
|
97947
98452
|
await mkdir9(dir, { recursive: true, mode: 448 });
|
|
97948
98453
|
const hasRef = async () => git2(["cat-file", "-e", `${row.snapshotSha}^{commit}`]).then(
|
|
@@ -97968,7 +98473,7 @@ ${diff}`).digest("hex");
|
|
|
97968
98473
|
"fetch",
|
|
97969
98474
|
"-q",
|
|
97970
98475
|
"--force",
|
|
97971
|
-
|
|
98476
|
+
join50(checkpointDir(worktreeId4, r.id), "bundle.pack"),
|
|
97972
98477
|
`refs/band/wip/${worktreeId4}:refs/checkpoints/${r.id}`
|
|
97973
98478
|
]).catch((err) => {
|
|
97974
98479
|
log58.debug(
|
|
@@ -98213,7 +98718,7 @@ ${diff}`).digest("hex");
|
|
|
98213
98718
|
const bundle = posix8.join(wipDir, `${newId}.restore.bundle`);
|
|
98214
98719
|
await host.fs.writeFile(
|
|
98215
98720
|
bundle,
|
|
98216
|
-
await
|
|
98721
|
+
await readFile13(join50(checkpointDir(worktreeId4, row.id), "bundle.pack"))
|
|
98217
98722
|
);
|
|
98218
98723
|
try {
|
|
98219
98724
|
await retryRefLock(
|
|
@@ -98355,7 +98860,7 @@ ${diff}`).digest("hex");
|
|
|
98355
98860
|
let files;
|
|
98356
98861
|
try {
|
|
98357
98862
|
files = JSON.parse(
|
|
98358
|
-
await
|
|
98863
|
+
await readFile13(join50(checkpointDir(row.worktreeId, row.id), "sessions.json"), "utf8")
|
|
98359
98864
|
).files;
|
|
98360
98865
|
} catch (err) {
|
|
98361
98866
|
log58.warn(
|
|
@@ -99075,9 +99580,9 @@ var FollowService = class {
|
|
|
99075
99580
|
continueOn(input3) {
|
|
99076
99581
|
const running = this.inflight.get(input3.worktreeId);
|
|
99077
99582
|
if (running) return running;
|
|
99078
|
-
const
|
|
99079
|
-
this.inflight.set(input3.worktreeId,
|
|
99080
|
-
return
|
|
99583
|
+
const run4 = this.doContinue(input3).finally(() => this.inflight.delete(input3.worktreeId));
|
|
99584
|
+
this.inflight.set(input3.worktreeId, run4);
|
|
99585
|
+
return run4;
|
|
99081
99586
|
}
|
|
99082
99587
|
async doContinue(input3) {
|
|
99083
99588
|
const { worktreeId: worktreeId4 } = input3;
|
|
@@ -100314,7 +100819,7 @@ var cidrv43 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5
|
|
|
100314
100819
|
var cidrv63 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
|
|
100315
100820
|
var base643 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;
|
|
100316
100821
|
var base64url3 = /^[A-Za-z0-9_-]*$/;
|
|
100317
|
-
var
|
|
100822
|
+
var hostname6 = /^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+$/;
|
|
100318
100823
|
var e1643 = /^\+(?:[0-9]){6,14}[0-9]$/;
|
|
100319
100824
|
var dateSource2 = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`;
|
|
100320
100825
|
var date6 = /* @__PURE__ */ new RegExp(`^${dateSource2}$`);
|
|
@@ -100927,7 +101432,7 @@ var $ZodURL2 = /* @__PURE__ */ $constructor2("$ZodURL", (inst, def) => {
|
|
|
100927
101432
|
code: "invalid_format",
|
|
100928
101433
|
format: "url",
|
|
100929
101434
|
note: "Invalid hostname",
|
|
100930
|
-
pattern:
|
|
101435
|
+
pattern: hostname6.source,
|
|
100931
101436
|
input: payload.value,
|
|
100932
101437
|
inst,
|
|
100933
101438
|
continue: !def.abort
|
|
@@ -111423,8 +111928,6 @@ var agentSessionsRouter = t.router({
|
|
|
111423
111928
|
// src/server/api/browser-host/router.ts
|
|
111424
111929
|
init_src();
|
|
111425
111930
|
init_zod();
|
|
111426
|
-
import { constants as fsConstants, open as open3 } from "node:fs/promises";
|
|
111427
|
-
import { extname as extname2, isAbsolute as isAbsolute3 } from "node:path";
|
|
111428
111931
|
|
|
111429
111932
|
// src/server/infra/browser-host/host-state.ts
|
|
111430
111933
|
init_src();
|
|
@@ -111560,123 +112063,6 @@ var browserHostService = new BrowserHostService();
|
|
|
111560
112063
|
|
|
111561
112064
|
// src/server/api/browser-host/router.ts
|
|
111562
112065
|
var log63 = createLogger("trpc.browser-host");
|
|
111563
|
-
var MAX_FILE_SIZE = 1024 * 1024;
|
|
111564
|
-
var LANG_MAP = {
|
|
111565
|
-
".js": "javascript",
|
|
111566
|
-
".jsx": "jsx",
|
|
111567
|
-
".ts": "typescript",
|
|
111568
|
-
".tsx": "tsx",
|
|
111569
|
-
".mjs": "javascript",
|
|
111570
|
-
".cjs": "javascript",
|
|
111571
|
-
".json": "json",
|
|
111572
|
-
".html": "html",
|
|
111573
|
-
".css": "css",
|
|
111574
|
-
".scss": "scss",
|
|
111575
|
-
".md": "markdown",
|
|
111576
|
-
".yaml": "yaml",
|
|
111577
|
-
".yml": "yaml",
|
|
111578
|
-
".toml": "toml",
|
|
111579
|
-
".py": "python",
|
|
111580
|
-
".rb": "ruby",
|
|
111581
|
-
".rs": "rust",
|
|
111582
|
-
".go": "go",
|
|
111583
|
-
".java": "java",
|
|
111584
|
-
".swift": "swift",
|
|
111585
|
-
".c": "c",
|
|
111586
|
-
".cpp": "cpp",
|
|
111587
|
-
".sh": "bash",
|
|
111588
|
-
".sql": "sql",
|
|
111589
|
-
".graphql": "graphql",
|
|
111590
|
-
".vue": "vue",
|
|
111591
|
-
".svelte": "svelte",
|
|
111592
|
-
".diff": "diff"
|
|
111593
|
-
};
|
|
111594
|
-
function mapFsError(err) {
|
|
111595
|
-
const code = err.code;
|
|
111596
|
-
if (code === "ENOENT") return new Error("File not found");
|
|
111597
|
-
if (code === "ELOOP") return new Error("Symbolic links are not allowed");
|
|
111598
|
-
if (code === "EACCES" || code === "EPERM") return new Error("Permission denied");
|
|
111599
|
-
if (code === "EISDIR") return new Error("Cannot operate on a directory");
|
|
111600
|
-
return err instanceof Error ? err : new Error(String(err));
|
|
111601
|
-
}
|
|
111602
|
-
var hostRouter = t.router({
|
|
111603
|
-
readFile: publicProcedure.input(external_exports2.object({ absolutePath: external_exports2.string().min(1) })).query(async ({ input: input3 }) => {
|
|
111604
|
-
const target = input3.absolutePath;
|
|
111605
|
-
if (!isAbsolute3(target)) {
|
|
111606
|
-
throw new Error("Absolute path required");
|
|
111607
|
-
}
|
|
111608
|
-
let fh;
|
|
111609
|
-
try {
|
|
111610
|
-
fh = await open3(target, fsConstants.O_RDONLY | fsConstants.O_NOFOLLOW);
|
|
111611
|
-
} catch (err) {
|
|
111612
|
-
throw mapFsError(err);
|
|
111613
|
-
}
|
|
111614
|
-
try {
|
|
111615
|
-
const stats = await fh.stat();
|
|
111616
|
-
if (stats.isDirectory()) {
|
|
111617
|
-
throw new Error("Cannot operate on a directory");
|
|
111618
|
-
}
|
|
111619
|
-
if (!stats.isFile()) {
|
|
111620
|
-
throw new Error("Not a regular file");
|
|
111621
|
-
}
|
|
111622
|
-
const size = stats.size;
|
|
111623
|
-
if (size > MAX_FILE_SIZE) {
|
|
111624
|
-
return { tooLarge: true, size };
|
|
111625
|
-
}
|
|
111626
|
-
const sampleLen = Math.min(8192, size);
|
|
111627
|
-
const sample = Buffer.alloc(sampleLen);
|
|
111628
|
-
if (sampleLen > 0) {
|
|
111629
|
-
await fh.read(sample, 0, sampleLen, 0);
|
|
111630
|
-
if (sample.includes(0)) {
|
|
111631
|
-
return { binary: true, size };
|
|
111632
|
-
}
|
|
111633
|
-
}
|
|
111634
|
-
const buffer = await fh.readFile();
|
|
111635
|
-
const ext = extname2(target).toLowerCase();
|
|
111636
|
-
const language = LANG_MAP[ext];
|
|
111637
|
-
return {
|
|
111638
|
-
content: buffer.toString("utf-8"),
|
|
111639
|
-
size,
|
|
111640
|
-
language
|
|
111641
|
-
};
|
|
111642
|
-
} finally {
|
|
111643
|
-
await fh.close();
|
|
111644
|
-
}
|
|
111645
|
-
}),
|
|
111646
|
-
saveFile: publicProcedure.input(
|
|
111647
|
-
external_exports2.object({
|
|
111648
|
-
absolutePath: external_exports2.string().min(1),
|
|
111649
|
-
// Match the read-side cap so a misbehaving client can't fill
|
|
111650
|
-
// disk via the save endpoint while the read endpoint refuses
|
|
111651
|
-
// anything that wide.
|
|
111652
|
-
content: external_exports2.string().max(MAX_FILE_SIZE)
|
|
111653
|
-
})
|
|
111654
|
-
).mutation(async ({ input: input3 }) => {
|
|
111655
|
-
const target = input3.absolutePath;
|
|
111656
|
-
if (!isAbsolute3(target)) {
|
|
111657
|
-
throw new Error("Absolute path required");
|
|
111658
|
-
}
|
|
111659
|
-
let fh;
|
|
111660
|
-
try {
|
|
111661
|
-
fh = await open3(
|
|
111662
|
-
target,
|
|
111663
|
-
fsConstants.O_WRONLY | fsConstants.O_TRUNC | fsConstants.O_NOFOLLOW
|
|
111664
|
-
);
|
|
111665
|
-
} catch (err) {
|
|
111666
|
-
throw mapFsError(err);
|
|
111667
|
-
}
|
|
111668
|
-
try {
|
|
111669
|
-
const stats = await fh.stat();
|
|
111670
|
-
if (!stats.isFile()) {
|
|
111671
|
-
throw new Error("Not a regular file");
|
|
111672
|
-
}
|
|
111673
|
-
await fh.writeFile(input3.content, "utf-8");
|
|
111674
|
-
} finally {
|
|
111675
|
-
await fh.close();
|
|
111676
|
-
}
|
|
111677
|
-
return { ok: true };
|
|
111678
|
-
})
|
|
111679
|
-
});
|
|
111680
112066
|
var browserHostRouter = t.router({
|
|
111681
112067
|
// Diagnostic: the desktop's BrowserHostBridge calls this on mount so we
|
|
111682
112068
|
// can confirm in the server log that the bridge component actually
|
|
@@ -112434,7 +112820,7 @@ init_zod();
|
|
|
112434
112820
|
// src/server/services/cli-service.ts
|
|
112435
112821
|
init_cli_binary();
|
|
112436
112822
|
init_local_host_enabled();
|
|
112437
|
-
import { execFile as
|
|
112823
|
+
import { execFile as execFile17 } from "node:child_process";
|
|
112438
112824
|
import {
|
|
112439
112825
|
accessSync as accessSync3,
|
|
112440
112826
|
constants as constants3,
|
|
@@ -112448,12 +112834,12 @@ import {
|
|
|
112448
112834
|
writeFileSync as writeFileSync7
|
|
112449
112835
|
} from "node:fs";
|
|
112450
112836
|
import { homedir as homedir17, platform as platform2 } from "node:os";
|
|
112451
|
-
import { basename as basename3, dirname as dirname14, join as
|
|
112837
|
+
import { basename as basename3, dirname as dirname14, join as join51 } from "node:path";
|
|
112452
112838
|
function windowsBinDir() {
|
|
112453
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
112454
|
-
return
|
|
112839
|
+
const localAppData = process.env.LOCALAPPDATA || join51(homedir17(), "AppData", "Local");
|
|
112840
|
+
return join51(localAppData, "band", "bin");
|
|
112455
112841
|
}
|
|
112456
|
-
var SYMLINK_PATH = platform2() === "win32" ?
|
|
112842
|
+
var SYMLINK_PATH = platform2() === "win32" ? join51(windowsBinDir(), "band.cmd") : "/usr/local/bin/band";
|
|
112457
112843
|
function symlinkPath() {
|
|
112458
112844
|
if (platform2() === "win32") return SYMLINK_PATH;
|
|
112459
112845
|
return process.env.BAND_CLI_SYMLINK_PATH?.trim() || SYMLINK_PATH;
|
|
@@ -112482,8 +112868,8 @@ async function checkCli() {
|
|
|
112482
112868
|
}
|
|
112483
112869
|
const linkPath = symlinkPath();
|
|
112484
112870
|
try {
|
|
112485
|
-
const
|
|
112486
|
-
if (!
|
|
112871
|
+
const stat9 = lstatSync4(linkPath);
|
|
112872
|
+
if (!stat9.isSymbolicLink()) {
|
|
112487
112873
|
return "ConflictingBinary";
|
|
112488
112874
|
}
|
|
112489
112875
|
let target;
|
|
@@ -112492,8 +112878,8 @@ async function checkCli() {
|
|
|
112492
112878
|
} catch {
|
|
112493
112879
|
return "NotInstalled";
|
|
112494
112880
|
}
|
|
112495
|
-
const isCargoBuild = target.includes(
|
|
112496
|
-
const isElectronSidecar = target.endsWith(
|
|
112881
|
+
const isCargoBuild = target.includes(join51("apps", "cli", "target"));
|
|
112882
|
+
const isElectronSidecar = target.endsWith(join51("binaries", "band"));
|
|
112497
112883
|
if (isCargoBuild || isElectronSidecar) {
|
|
112498
112884
|
return "Installed";
|
|
112499
112885
|
}
|
|
@@ -112543,7 +112929,7 @@ function noBinaryError(env = process.env) {
|
|
|
112543
112929
|
}
|
|
112544
112930
|
function runReg(args) {
|
|
112545
112931
|
return new Promise((resolve16) => {
|
|
112546
|
-
|
|
112932
|
+
execFile17("reg", args, { windowsHide: true }, (err, stdout) => {
|
|
112547
112933
|
resolve16(err ? "" : stdout ?? "");
|
|
112548
112934
|
});
|
|
112549
112935
|
});
|
|
@@ -112757,7 +113143,7 @@ function formatFileLocation(filePath, line2, options) {
|
|
|
112757
113143
|
|
|
112758
113144
|
// ../../packages/worktree-ops/src/resolve-path.ts
|
|
112759
113145
|
init_resolver();
|
|
112760
|
-
import { isAbsolute as
|
|
113146
|
+
import { isAbsolute as isAbsolute3, join as join52, resolve as resolve10, sep as sep6 } from "node:path";
|
|
112761
113147
|
var PathsService = class {
|
|
112762
113148
|
constructor(worktrees2) {
|
|
112763
113149
|
this.worktrees = worktrees2;
|
|
@@ -112775,7 +113161,7 @@ var PathsService = class {
|
|
|
112775
113161
|
}
|
|
112776
113162
|
};
|
|
112777
113163
|
async function resolveTarget(fs3, root, filePath) {
|
|
112778
|
-
const absoluteTarget =
|
|
113164
|
+
const absoluteTarget = isAbsolute3(filePath) ? resolve10(filePath) : resolve10(root, filePath);
|
|
112779
113165
|
let canonicalRoot = root;
|
|
112780
113166
|
try {
|
|
112781
113167
|
canonicalRoot = await fs3.realpath(root);
|
|
@@ -112808,7 +113194,7 @@ async function canonicalizeMaybeMissing(fs3, p2) {
|
|
|
112808
113194
|
const prefix = parts.slice(0, i).join(sep6) || sep6;
|
|
112809
113195
|
try {
|
|
112810
113196
|
const canonicalPrefix = await fs3.realpath(prefix);
|
|
112811
|
-
return
|
|
113197
|
+
return join52(canonicalPrefix, ...parts.slice(i));
|
|
112812
113198
|
} catch {
|
|
112813
113199
|
}
|
|
112814
113200
|
}
|
|
@@ -112890,10 +113276,10 @@ async function pumpChanges(worktreeId4, entry, host, root) {
|
|
|
112890
113276
|
for (const listener of entry.listeners) listener(null);
|
|
112891
113277
|
stopWatcher(worktreeId4, entry);
|
|
112892
113278
|
}
|
|
112893
|
-
function subscribeToFileChanges(worktreeId4,
|
|
113279
|
+
function subscribeToFileChanges(worktreeId4, open3, listener) {
|
|
112894
113280
|
let entry = watchers.get(worktreeId4);
|
|
112895
113281
|
if (!entry) {
|
|
112896
|
-
const target =
|
|
113282
|
+
const target = open3();
|
|
112897
113283
|
if (!target) return () => {
|
|
112898
113284
|
};
|
|
112899
113285
|
entry = { controller: new AbortController(), listeners: /* @__PURE__ */ new Set(), pendingTimers: /* @__PURE__ */ new Map() };
|
|
@@ -112924,7 +113310,7 @@ function subscribeToFileChanges2(worktreeId4, listener) {
|
|
|
112924
113310
|
// src/server/services/formatter.ts
|
|
112925
113311
|
init_src();
|
|
112926
113312
|
init_registry();
|
|
112927
|
-
import { basename as basename4, dirname as dirname15, isAbsolute as
|
|
113313
|
+
import { basename as basename4, dirname as dirname15, isAbsolute as isAbsolute4, join as join53, resolve as resolvePath3 } from "node:path";
|
|
112928
113314
|
import prettier from "prettier";
|
|
112929
113315
|
var log65 = createLogger("formatter");
|
|
112930
113316
|
var FormatterError = class extends Error {
|
|
@@ -112940,7 +113326,7 @@ var FormatterError = class extends Error {
|
|
|
112940
113326
|
async function formatFile(worktreePath, filePath, content, options = {}) {
|
|
112941
113327
|
const fs3 = options.fs ?? hostRegistry.local.fs;
|
|
112942
113328
|
const onHub = fs3 === hostRegistry.local.fs;
|
|
112943
|
-
const absFile =
|
|
113329
|
+
const absFile = isAbsolute4(filePath) ? filePath : resolvePath3(worktreePath, filePath);
|
|
112944
113330
|
if (!await isInsideWorktree(fs3, absFile, worktreePath)) {
|
|
112945
113331
|
throw new FormatterError(
|
|
112946
113332
|
"FILE_NOT_IN_WORKTREE",
|
|
@@ -113006,10 +113392,10 @@ async function resolveConfigOnHost(fs3, absFile, worktreePath) {
|
|
|
113006
113392
|
let dir = dirname15(absFile);
|
|
113007
113393
|
for (; ; ) {
|
|
113008
113394
|
for (const name5 of JSON_CONFIGS) {
|
|
113009
|
-
const parsed = await readJson2(fs3,
|
|
113395
|
+
const parsed = await readJson2(fs3, join53(dir, name5));
|
|
113010
113396
|
if (parsed && typeof parsed === "object") return withoutPlugins(parsed);
|
|
113011
113397
|
}
|
|
113012
|
-
const pkg = await readJson2(fs3,
|
|
113398
|
+
const pkg = await readJson2(fs3, join53(dir, "package.json"));
|
|
113013
113399
|
if (pkg && typeof pkg.prettier === "object" && pkg.prettier !== null) {
|
|
113014
113400
|
return withoutPlugins(pkg.prettier);
|
|
113015
113401
|
}
|
|
@@ -113047,7 +113433,7 @@ async function isInsideWorktree(fs3, absFile, worktreePath) {
|
|
|
113047
113433
|
realFile = await fs3.realpath(absFile);
|
|
113048
113434
|
} catch {
|
|
113049
113435
|
try {
|
|
113050
|
-
realFile =
|
|
113436
|
+
realFile = join53(await fs3.realpath(dirname15(absFile)), basename4(absFile));
|
|
113051
113437
|
} catch {
|
|
113052
113438
|
realFile = absFile;
|
|
113053
113439
|
}
|
|
@@ -113230,7 +113616,7 @@ init_environment_build_service();
|
|
|
113230
113616
|
init_src6();
|
|
113231
113617
|
init_dist();
|
|
113232
113618
|
init_registry();
|
|
113233
|
-
import { basename as basename5, dirname as dirname16, isAbsolute as
|
|
113619
|
+
import { basename as basename5, dirname as dirname16, isAbsolute as isAbsolute5 } from "node:path";
|
|
113234
113620
|
init_token_service();
|
|
113235
113621
|
var EnvironmentService = class {
|
|
113236
113622
|
/** The environment of a repo's main checkout, and which hosts meet its `requires`. */
|
|
@@ -113245,7 +113631,7 @@ var EnvironmentService = class {
|
|
|
113245
113631
|
* name the `.band/environment.json` file itself.
|
|
113246
113632
|
*/
|
|
113247
113633
|
async validatePath(path2) {
|
|
113248
|
-
if (!
|
|
113634
|
+
if (!isAbsolute5(path2)) {
|
|
113249
113635
|
throw new TRPCError({ code: "BAD_REQUEST", message: "path must be absolute" });
|
|
113250
113636
|
}
|
|
113251
113637
|
const isFile2 = basename5(path2) === "environment.json" && basename5(dirname16(path2)) === ".band";
|
|
@@ -113306,8 +113692,8 @@ init_http_files();
|
|
|
113306
113692
|
init_settings();
|
|
113307
113693
|
import { createHash as createHash13, randomBytes as randomBytes16 } from "node:crypto";
|
|
113308
113694
|
import { createReadStream as createReadStream4 } from "node:fs";
|
|
113309
|
-
import { mkdir as mkdir10, readdir as
|
|
113310
|
-
import { dirname as dirname17, join as
|
|
113695
|
+
import { mkdir as mkdir10, readdir as readdir9, readFile as readFile14, realpath as realpath4, rename as rename5, rm as rm4, stat as stat8, writeFile as writeFile8 } from "node:fs/promises";
|
|
113696
|
+
import { dirname as dirname17, join as join54, sep as sep7 } from "node:path";
|
|
113311
113697
|
|
|
113312
113698
|
// src/server/services/_utils/tar-extract.ts
|
|
113313
113699
|
import { gunzipSync } from "node:zlib";
|
|
@@ -113413,7 +113799,7 @@ var ExtensionService = class {
|
|
|
113413
113799
|
/** Counts scans started. Only the newest scan may replace `loaded`. */
|
|
113414
113800
|
scanSeq = 0;
|
|
113415
113801
|
root() {
|
|
113416
|
-
return
|
|
113802
|
+
return join54(bandHome(), "extensions");
|
|
113417
113803
|
}
|
|
113418
113804
|
/** Reads every manifest again. A manifest that fails validation is skipped and listed as an error. */
|
|
113419
113805
|
async reload() {
|
|
@@ -113443,7 +113829,7 @@ var ExtensionService = class {
|
|
|
113443
113829
|
const errors = [];
|
|
113444
113830
|
let folders;
|
|
113445
113831
|
try {
|
|
113446
|
-
folders = (await
|
|
113832
|
+
folders = (await readdir9(this.root(), { withFileTypes: true })).filter((d) => (d.isDirectory() || d.isSymbolicLink()) && !d.name.startsWith(".")).map((d) => d.name).sort();
|
|
113447
113833
|
} catch {
|
|
113448
113834
|
return { extensions, errors };
|
|
113449
113835
|
}
|
|
@@ -113454,7 +113840,7 @@ var ExtensionService = class {
|
|
|
113454
113840
|
};
|
|
113455
113841
|
let raw;
|
|
113456
113842
|
try {
|
|
113457
|
-
raw = await
|
|
113843
|
+
raw = await readFile14(join54(this.root(), folder, MANIFEST_FILE), "utf8");
|
|
113458
113844
|
} catch {
|
|
113459
113845
|
problem2(`${MANIFEST_FILE} not found`);
|
|
113460
113846
|
continue;
|
|
@@ -113554,12 +113940,12 @@ var ExtensionService = class {
|
|
|
113554
113940
|
}
|
|
113555
113941
|
const root = this.root();
|
|
113556
113942
|
const tag = randomBytes16(6).toString("hex");
|
|
113557
|
-
const staging =
|
|
113558
|
-
const target =
|
|
113559
|
-
const backup =
|
|
113943
|
+
const staging = join54(root, `.install-${tag}`);
|
|
113944
|
+
const target = join54(root, folder);
|
|
113945
|
+
const backup = join54(root, `.old-${tag}`);
|
|
113560
113946
|
try {
|
|
113561
113947
|
for (const file3 of files) {
|
|
113562
|
-
const dest =
|
|
113948
|
+
const dest = join54(staging, file3.path);
|
|
113563
113949
|
await mkdir10(dirname17(dest), { recursive: true });
|
|
113564
113950
|
await writeFile8(dest, file3.data, { mode: 420 });
|
|
113565
113951
|
}
|
|
@@ -113570,7 +113956,7 @@ var ExtensionService = class {
|
|
|
113570
113956
|
} catch {
|
|
113571
113957
|
}
|
|
113572
113958
|
try {
|
|
113573
|
-
await rename5(
|
|
113959
|
+
await rename5(join54(staging, folder), target);
|
|
113574
113960
|
} catch (err) {
|
|
113575
113961
|
if (hadOld) await rename5(backup, target).catch(() => {
|
|
113576
113962
|
});
|
|
@@ -113588,9 +113974,9 @@ var ExtensionService = class {
|
|
|
113588
113974
|
async remove(id) {
|
|
113589
113975
|
if (!ID_PATTERN.test(id))
|
|
113590
113976
|
throw new ExtensionInstallError(`"${id}" is not a valid extension id`);
|
|
113591
|
-
const dir =
|
|
113977
|
+
const dir = join54(this.root(), id);
|
|
113592
113978
|
try {
|
|
113593
|
-
await
|
|
113979
|
+
await stat8(dir);
|
|
113594
113980
|
} catch {
|
|
113595
113981
|
throw new ExtensionInstallError(`No extension "${id}" is installed`);
|
|
113596
113982
|
}
|
|
@@ -113608,7 +113994,7 @@ var ExtensionService = class {
|
|
|
113608
113994
|
if (segments.some((s2) => s2 === ".." || s2 === "." || s2 === "")) return void 0;
|
|
113609
113995
|
let dir;
|
|
113610
113996
|
try {
|
|
113611
|
-
dir = await realpath4(
|
|
113997
|
+
dir = await realpath4(join54(this.root(), id));
|
|
113612
113998
|
} catch {
|
|
113613
113999
|
return void 0;
|
|
113614
114000
|
}
|
|
@@ -113618,11 +114004,11 @@ var ExtensionService = class {
|
|
|
113618
114004
|
if (/\bgzip\b/.test(acceptEncoding)) wanted.push({ suffix: ".gz", encoding: "gzip" });
|
|
113619
114005
|
wanted.push({ suffix: "" });
|
|
113620
114006
|
for (const { suffix, encoding } of wanted) {
|
|
113621
|
-
const candidate =
|
|
114007
|
+
const candidate = join54(dir, ...segments) + suffix;
|
|
113622
114008
|
try {
|
|
113623
114009
|
const real4 = await realpath4(candidate);
|
|
113624
114010
|
if (!real4.startsWith(dir + sep7)) return void 0;
|
|
113625
|
-
const info = await
|
|
114011
|
+
const info = await stat8(real4);
|
|
113626
114012
|
if (!info.isFile()) continue;
|
|
113627
114013
|
return { stream: createReadStream4(real4), size: info.size, contentType, encoding };
|
|
113628
114014
|
} catch {
|
|
@@ -113696,9 +114082,9 @@ async function downloadChecksum(url3) {
|
|
|
113696
114082
|
var extensionService = new ExtensionService();
|
|
113697
114083
|
|
|
113698
114084
|
// src/server/api/extensions/router.ts
|
|
113699
|
-
async function refuse(
|
|
114085
|
+
async function refuse(run4) {
|
|
113700
114086
|
try {
|
|
113701
|
-
return await
|
|
114087
|
+
return await run4();
|
|
113702
114088
|
} catch (err) {
|
|
113703
114089
|
if (err instanceof ExtensionInstallError) {
|
|
113704
114090
|
throw new TRPCError({ code: "BAD_REQUEST", message: err.message });
|
|
@@ -114345,7 +114731,7 @@ init_registry();
|
|
|
114345
114731
|
// package.json
|
|
114346
114732
|
var package_default = {
|
|
114347
114733
|
name: "@band-app/server",
|
|
114348
|
-
version: "0.
|
|
114734
|
+
version: "0.60.0",
|
|
114349
114735
|
type: "module",
|
|
114350
114736
|
types: "src/index.ts",
|
|
114351
114737
|
exports: {
|
|
@@ -114637,7 +115023,7 @@ import {
|
|
|
114637
115023
|
rmSync as rmSync7,
|
|
114638
115024
|
writeFileSync as writeFileSync8
|
|
114639
115025
|
} from "node:fs";
|
|
114640
|
-
import { join as
|
|
115026
|
+
import { join as join55 } from "node:path";
|
|
114641
115027
|
init_settings();
|
|
114642
115028
|
init_agent_session_service();
|
|
114643
115029
|
|
|
@@ -114745,10 +115131,10 @@ var HubUpdateError = class extends Error {
|
|
|
114745
115131
|
};
|
|
114746
115132
|
var HubUpdateService = class {
|
|
114747
115133
|
runPath() {
|
|
114748
|
-
return
|
|
115134
|
+
return join55(bandHome(), "hub-update.json");
|
|
114749
115135
|
}
|
|
114750
115136
|
logPath() {
|
|
114751
|
-
return
|
|
115137
|
+
return join55(bandHome(), "hub-update.log");
|
|
114752
115138
|
}
|
|
114753
115139
|
read() {
|
|
114754
115140
|
try {
|
|
@@ -114758,8 +115144,8 @@ var HubUpdateService = class {
|
|
|
114758
115144
|
return null;
|
|
114759
115145
|
}
|
|
114760
115146
|
}
|
|
114761
|
-
write(
|
|
114762
|
-
writeFileSync8(this.runPath(), JSON.stringify(
|
|
115147
|
+
write(run4) {
|
|
115148
|
+
writeFileSync8(this.runPath(), JSON.stringify(run4), { mode: 384 });
|
|
114763
115149
|
}
|
|
114764
115150
|
command() {
|
|
114765
115151
|
const raw = settingsService.get().hubUpdate?.command;
|
|
@@ -114774,12 +115160,12 @@ var HubUpdateService = class {
|
|
|
114774
115160
|
return "";
|
|
114775
115161
|
}
|
|
114776
115162
|
}
|
|
114777
|
-
failed(
|
|
115163
|
+
failed(run4, message) {
|
|
114778
115164
|
const tail = this.logTail();
|
|
114779
115165
|
return {
|
|
114780
115166
|
configured: this.command() !== null,
|
|
114781
115167
|
state: "failed",
|
|
114782
|
-
target:
|
|
115168
|
+
target: run4.target,
|
|
114783
115169
|
error: tail ? `${message}
|
|
114784
115170
|
${tail}` : message
|
|
114785
115171
|
};
|
|
@@ -114787,21 +115173,21 @@ ${tail}` : message
|
|
|
114787
115173
|
/** Where the run stands. Reads the state file, so it also answers after the hub restarted. */
|
|
114788
115174
|
status() {
|
|
114789
115175
|
const configured = this.command() !== null;
|
|
114790
|
-
const
|
|
114791
|
-
if (!
|
|
114792
|
-
if ((compareVersions(HUB_VERSION,
|
|
115176
|
+
const run4 = this.read();
|
|
115177
|
+
if (!run4) return { configured, state: "idle", target: null, error: null };
|
|
115178
|
+
if ((compareVersions(HUB_VERSION, run4.target) ?? -1) >= 0) {
|
|
114793
115179
|
rmSync7(this.runPath(), { force: true });
|
|
114794
115180
|
return { configured, state: "idle", target: null, error: null };
|
|
114795
115181
|
}
|
|
114796
|
-
if (
|
|
114797
|
-
if (BOOT_AT >
|
|
114798
|
-
return this.failed(
|
|
115182
|
+
if (run4.failure) return this.failed(run4, run4.failure);
|
|
115183
|
+
if (BOOT_AT > run4.startedAt) {
|
|
115184
|
+
return this.failed(run4, `The hub restarted on ${HUB_VERSION}, not ${run4.target}.`);
|
|
114799
115185
|
}
|
|
114800
115186
|
const wait = Number(process.env.BAND_HUB_UPDATE_TIMEOUT_MS);
|
|
114801
|
-
if (Date.now() -
|
|
114802
|
-
return this.failed(
|
|
115187
|
+
if (Date.now() - run4.startedAt > (wait > 0 ? wait : DEFAULT_TIMEOUT_MS2)) {
|
|
115188
|
+
return this.failed(run4, `The hub did not come back on ${run4.target} in time.`);
|
|
114803
115189
|
}
|
|
114804
|
-
return { configured, state: "updating", target:
|
|
115190
|
+
return { configured, state: "updating", target: run4.target, error: null };
|
|
114805
115191
|
}
|
|
114806
115192
|
/**
|
|
114807
115193
|
* The agents a hub restart ends, on every worker. A hub restart stops every agent it runs,
|
|
@@ -114829,8 +115215,8 @@ ${tail}` : message
|
|
|
114829
115215
|
);
|
|
114830
115216
|
}
|
|
114831
115217
|
mkdirSync10(bandHome(), { recursive: true });
|
|
114832
|
-
const
|
|
114833
|
-
this.write(
|
|
115218
|
+
const run4 = { target, startedAt: Date.now() };
|
|
115219
|
+
this.write(run4);
|
|
114834
115220
|
const fd = openSync5(this.logPath(), "w", 384);
|
|
114835
115221
|
try {
|
|
114836
115222
|
writeFileSync8(fd, `$ ${command2}
|
|
@@ -114856,12 +115242,12 @@ ${tail}` : message
|
|
|
114856
115242
|
env
|
|
114857
115243
|
});
|
|
114858
115244
|
child.on("error", (err) => {
|
|
114859
|
-
this.write({ ...
|
|
115245
|
+
this.write({ ...run4, failure: `The command could not start: ${err.message}` });
|
|
114860
115246
|
});
|
|
114861
115247
|
child.on("exit", (code, signal) => {
|
|
114862
115248
|
if (code === 0) return;
|
|
114863
115249
|
this.write({
|
|
114864
|
-
...
|
|
115250
|
+
...run4,
|
|
114865
115251
|
failure: `The command ${signal ? `was stopped by ${signal}` : `exited with code ${code}`}.`
|
|
114866
115252
|
});
|
|
114867
115253
|
});
|
|
@@ -119012,10 +119398,10 @@ var pluginsRouter = t.router({
|
|
|
119012
119398
|
});
|
|
119013
119399
|
|
|
119014
119400
|
// ../../packages/host-local/src/process/install.ts
|
|
119015
|
-
import { execFile as
|
|
119401
|
+
import { execFile as execFile18 } from "node:child_process";
|
|
119016
119402
|
async function brewInstall(pkg, resolvedPath) {
|
|
119017
119403
|
await new Promise((resolve16, reject) => {
|
|
119018
|
-
|
|
119404
|
+
execFile18(
|
|
119019
119405
|
"brew",
|
|
119020
119406
|
["install", pkg],
|
|
119021
119407
|
{ env: { ...process.env, PATH: resolvedPath }, timeout: 12e4 },
|
|
@@ -119150,7 +119536,7 @@ init_src();
|
|
|
119150
119536
|
init_dist();
|
|
119151
119537
|
import { createHash as createHash14, randomBytes as randomBytes17, randomUUID as randomUUID19 } from "node:crypto";
|
|
119152
119538
|
import { createReadStream as createReadStream5, existsSync as existsSync19, mkdirSync as mkdirSync11, rmSync as rmSync8, statSync as statSync15 } from "node:fs";
|
|
119153
|
-
import { join as
|
|
119539
|
+
import { join as join56 } from "node:path";
|
|
119154
119540
|
|
|
119155
119541
|
// src/server/infra/db/queries/provisions.ts
|
|
119156
119542
|
init_drizzle_orm2();
|
|
@@ -119470,8 +119856,8 @@ function sha2562(text4) {
|
|
|
119470
119856
|
function newSecret(prefix) {
|
|
119471
119857
|
return `${prefix}${randomBytes17(32).toString("base64url")}`;
|
|
119472
119858
|
}
|
|
119473
|
-
function isLoopbackHost2(
|
|
119474
|
-
const h =
|
|
119859
|
+
function isLoopbackHost2(hostname7) {
|
|
119860
|
+
const h = hostname7.replace(/^\[|\]$/g, "").toLowerCase();
|
|
119475
119861
|
return h === "localhost" || h === "::1" || /^127\.\d+\.\d+\.\d+$/.test(h);
|
|
119476
119862
|
}
|
|
119477
119863
|
function checkHubUrl(input3) {
|
|
@@ -119508,7 +119894,7 @@ var ProvisioningService = class {
|
|
|
119508
119894
|
return Date.now();
|
|
119509
119895
|
}
|
|
119510
119896
|
dir(id) {
|
|
119511
|
-
return
|
|
119897
|
+
return join56(bandHome(), "provisioning", id);
|
|
119512
119898
|
}
|
|
119513
119899
|
settings() {
|
|
119514
119900
|
const s2 = settingsService.get().provisioning ?? {};
|
|
@@ -119628,7 +120014,7 @@ var ProvisioningService = class {
|
|
|
119628
120014
|
/** The bundle file and size for a code, once its run token is shown. */
|
|
119629
120015
|
bundle(code, runToken) {
|
|
119630
120016
|
const row = this.authorize(code, runToken);
|
|
119631
|
-
const file3 =
|
|
120017
|
+
const file3 = join56(this.dir(row.id), "bundle.tgz");
|
|
119632
120018
|
if (!row.repoUrl || !existsSync19(file3)) throw new ProvisionAuthError();
|
|
119633
120019
|
return { stream: createReadStream5(file3), size: statSync15(file3).size };
|
|
119634
120020
|
}
|
|
@@ -119707,7 +120093,7 @@ band provision: the worker did not say hello within ${minutes} min. Marked faile
|
|
|
119707
120093
|
async buildBundle(id, settings3) {
|
|
119708
120094
|
const dir = this.dir(id);
|
|
119709
120095
|
mkdirSync11(dir, { recursive: true });
|
|
119710
|
-
const src =
|
|
120096
|
+
const src = join56(dir, "src");
|
|
119711
120097
|
const host = hostRegistry.local;
|
|
119712
120098
|
const env = { GIT_TERMINAL_PROMPT: "0" };
|
|
119713
120099
|
const key2 = parseRemoteUrl2(settings3.repoUrl);
|
|
@@ -119729,10 +120115,10 @@ band provision: the worker did not say hello within ${minutes} min. Marked faile
|
|
|
119729
120115
|
await host.exec("git", args, { env, timeoutMs: 12e4 });
|
|
119730
120116
|
const sha = (await host.exec("git", ["-C", src, "rev-parse", "HEAD"], { env })).stdout.trim();
|
|
119731
120117
|
const command2 = settings3.command || DEFAULT_START_COMMAND;
|
|
119732
|
-
if (!existsSync19(
|
|
120118
|
+
if (!existsSync19(join56(src, command2))) {
|
|
119733
120119
|
throw new Error(`the repo at ${sha.slice(0, 12)} has no ${command2}`);
|
|
119734
120120
|
}
|
|
119735
|
-
await host.exec("tar", ["-czf",
|
|
120121
|
+
await host.exec("tar", ["-czf", join56(dir, "bundle.tgz"), "--exclude=.git", "-C", src, "."], {
|
|
119736
120122
|
timeoutMs: 12e4
|
|
119737
120123
|
});
|
|
119738
120124
|
rmSync8(src, { recursive: true, force: true });
|
|
@@ -119825,7 +120211,7 @@ init_zod();
|
|
|
119825
120211
|
init_registry();
|
|
119826
120212
|
init_queued_message_store();
|
|
119827
120213
|
import { realpathSync as realpathSync6 } from "node:fs";
|
|
119828
|
-
import { join as
|
|
120214
|
+
import { join as join57, resolve as resolve11, sep as sep8 } from "node:path";
|
|
119829
120215
|
init_chat_ownership_service();
|
|
119830
120216
|
init_chat_service();
|
|
119831
120217
|
init_state();
|
|
@@ -119838,7 +120224,7 @@ var queuedFileSchema = external_exports2.object({
|
|
|
119838
120224
|
filename: external_exports2.string().optional()
|
|
119839
120225
|
});
|
|
119840
120226
|
function isPathWithinUploadDir(p2) {
|
|
119841
|
-
const uploadDir =
|
|
120227
|
+
const uploadDir = join57(bandHome(), "uploads");
|
|
119842
120228
|
const normalized2 = resolve11(p2);
|
|
119843
120229
|
if (normalized2 !== uploadDir && !normalized2.startsWith(uploadDir + sep8)) {
|
|
119844
120230
|
return false;
|
|
@@ -120651,6 +121037,186 @@ var reposRouter = t.router({
|
|
|
120651
121037
|
})
|
|
120652
121038
|
});
|
|
120653
121039
|
|
|
121040
|
+
// src/server/api/resources/router.ts
|
|
121041
|
+
init_dist();
|
|
121042
|
+
init_zod();
|
|
121043
|
+
|
|
121044
|
+
// src/server/services/resources-service.ts
|
|
121045
|
+
init_worktree_id();
|
|
121046
|
+
init_registry();
|
|
121047
|
+
init_agent_session_service();
|
|
121048
|
+
init_chat_service();
|
|
121049
|
+
init_state();
|
|
121050
|
+
init_task_service();
|
|
121051
|
+
init_token_service();
|
|
121052
|
+
var LOCAL_HOST_ID13 = "local";
|
|
121053
|
+
var SNAPSHOT_TIMEOUT_MS = 8e3;
|
|
121054
|
+
var IDLE_AGENT_MS = 60 * 6e4;
|
|
121055
|
+
function withTimeout3(promise2, ms) {
|
|
121056
|
+
return new Promise((resolve16, reject) => {
|
|
121057
|
+
const timer = setTimeout(() => reject(new Error("timed out")), ms);
|
|
121058
|
+
promise2.then(
|
|
121059
|
+
(v2) => {
|
|
121060
|
+
clearTimeout(timer);
|
|
121061
|
+
resolve16(v2);
|
|
121062
|
+
},
|
|
121063
|
+
(e) => {
|
|
121064
|
+
clearTimeout(timer);
|
|
121065
|
+
reject(e);
|
|
121066
|
+
}
|
|
121067
|
+
);
|
|
121068
|
+
});
|
|
121069
|
+
}
|
|
121070
|
+
function knownWorktrees() {
|
|
121071
|
+
const out = [];
|
|
121072
|
+
for (const repo of loadState().repos) {
|
|
121073
|
+
for (const wt of repo.worktrees) {
|
|
121074
|
+
const hostId2 = wt.hostId ?? LOCAL_HOST_ID13;
|
|
121075
|
+
out.push({
|
|
121076
|
+
id: toWorktreeId(repo.name, wt.name, wt.hostId),
|
|
121077
|
+
repo: repo.name,
|
|
121078
|
+
branch: wt.branch,
|
|
121079
|
+
title: wt.title ?? null,
|
|
121080
|
+
hostId: hostId2,
|
|
121081
|
+
path: wt.path
|
|
121082
|
+
});
|
|
121083
|
+
}
|
|
121084
|
+
}
|
|
121085
|
+
return out;
|
|
121086
|
+
}
|
|
121087
|
+
function refOf(w2) {
|
|
121088
|
+
return { id: w2.id, repo: w2.repo, branch: w2.branch, title: w2.title };
|
|
121089
|
+
}
|
|
121090
|
+
function worktreeOf(proc, hostId2, worktrees2) {
|
|
121091
|
+
if (proc.worktreeId) {
|
|
121092
|
+
const byId = worktrees2.find((w2) => w2.id === proc.worktreeId);
|
|
121093
|
+
if (byId) return refOf(byId);
|
|
121094
|
+
}
|
|
121095
|
+
if (!proc.cwd) return void 0;
|
|
121096
|
+
const cwd = proc.cwd;
|
|
121097
|
+
let best;
|
|
121098
|
+
for (const w2 of worktrees2) {
|
|
121099
|
+
if (w2.hostId !== hostId2 || !w2.path) continue;
|
|
121100
|
+
if (cwd === w2.path || cwd.startsWith(`${w2.path}/`)) {
|
|
121101
|
+
if (!best || w2.path.length > best.path.length) best = w2;
|
|
121102
|
+
}
|
|
121103
|
+
}
|
|
121104
|
+
return best ? refOf(best) : void 0;
|
|
121105
|
+
}
|
|
121106
|
+
function chatOf(chatId, now) {
|
|
121107
|
+
if (!chatId) return void 0;
|
|
121108
|
+
const chat = chatService.get(chatId);
|
|
121109
|
+
if (!chat) return void 0;
|
|
121110
|
+
const running = hasRunningTask(chatId);
|
|
121111
|
+
const last = agentSessionService.lastActivityAt(chatId);
|
|
121112
|
+
const idleMs2 = last === null ? null : Math.max(0, now - last);
|
|
121113
|
+
return {
|
|
121114
|
+
id: chat.id,
|
|
121115
|
+
name: chat.name,
|
|
121116
|
+
agent: chat.agent,
|
|
121117
|
+
running,
|
|
121118
|
+
idleMs: idleMs2,
|
|
121119
|
+
idle: !running && idleMs2 !== null && idleMs2 >= IDLE_AGENT_MS
|
|
121120
|
+
};
|
|
121121
|
+
}
|
|
121122
|
+
function chatIdOf(p2, hostId2, pids) {
|
|
121123
|
+
if (p2.chatId) return p2.chatId;
|
|
121124
|
+
if (p2.kind !== "agent") return void 0;
|
|
121125
|
+
return pids.find(
|
|
121126
|
+
(a) => a.pid === p2.pid && (hostRegistry.hostIdOfScope(a.worktreeId) ?? LOCAL_HOST_ID13) === hostId2
|
|
121127
|
+
)?.chatId;
|
|
121128
|
+
}
|
|
121129
|
+
async function readMachine(host, builtInWorker, worktrees2, now, agentPids) {
|
|
121130
|
+
const isLocal = host.id === LOCAL_HOST_ID13;
|
|
121131
|
+
const base = {
|
|
121132
|
+
id: host.id,
|
|
121133
|
+
role: isLocal ? "hub" : "worker",
|
|
121134
|
+
name: isLocal ? "Hub" : host.name,
|
|
121135
|
+
version: host.version,
|
|
121136
|
+
builtInWorker: isLocal && builtInWorker,
|
|
121137
|
+
onBattery: null
|
|
121138
|
+
};
|
|
121139
|
+
if (!isLocal && host.status !== "online") {
|
|
121140
|
+
return { ...base, status: "unavailable", reason: "offline", snapshot: null };
|
|
121141
|
+
}
|
|
121142
|
+
try {
|
|
121143
|
+
const target = hostRegistry.hostById(host.id);
|
|
121144
|
+
const snap = await withTimeout3(target.resources.snapshot(), SNAPSHOT_TIMEOUT_MS);
|
|
121145
|
+
const processes = snap.processes.map((p2) => {
|
|
121146
|
+
const chatId = chatIdOf(p2, host.id, agentPids);
|
|
121147
|
+
const worktree = worktreeOf(
|
|
121148
|
+
chatId && !p2.worktreeId ? { ...p2, worktreeId: chatService.get(chatId)?.worktreeId ?? p2.worktreeId } : p2,
|
|
121149
|
+
host.id,
|
|
121150
|
+
worktrees2
|
|
121151
|
+
);
|
|
121152
|
+
const chat = chatOf(chatId, now);
|
|
121153
|
+
const { command: _command, cwd: _cwd, ...rest } = p2;
|
|
121154
|
+
return { ...rest, ...worktree ? { worktree } : {}, ...chat ? { chat } : {} };
|
|
121155
|
+
});
|
|
121156
|
+
return { ...base, status: "ok", reason: null, snapshot: { ...snap, processes } };
|
|
121157
|
+
} catch {
|
|
121158
|
+
return { ...base, status: "unavailable", reason: "no-answer", snapshot: null };
|
|
121159
|
+
}
|
|
121160
|
+
}
|
|
121161
|
+
async function listResources() {
|
|
121162
|
+
const now = Date.now();
|
|
121163
|
+
const worktrees2 = knownWorktrees();
|
|
121164
|
+
const agentPids = agentSessionService.agentPids();
|
|
121165
|
+
const hosts3 = tokenService.listHosts();
|
|
121166
|
+
const builtIn = hosts3.find((h) => h.id === LOCAL_HOST_ID13)?.usable ?? false;
|
|
121167
|
+
const wanted = hosts3.filter((h) => h.id !== LOCAL_HOST_ID13);
|
|
121168
|
+
const local = hosts3.find((h) => h.id === LOCAL_HOST_ID13) ?? {
|
|
121169
|
+
id: LOCAL_HOST_ID13,
|
|
121170
|
+
name: "Hub",
|
|
121171
|
+
version: null,
|
|
121172
|
+
status: "online"
|
|
121173
|
+
};
|
|
121174
|
+
const machines = await Promise.all(
|
|
121175
|
+
[local, ...wanted].map(
|
|
121176
|
+
(h) => readMachine(
|
|
121177
|
+
{ id: h.id, name: h.name, version: h.version ?? null, status: h.status },
|
|
121178
|
+
builtIn,
|
|
121179
|
+
worktrees2,
|
|
121180
|
+
now,
|
|
121181
|
+
agentPids
|
|
121182
|
+
)
|
|
121183
|
+
)
|
|
121184
|
+
);
|
|
121185
|
+
return { takenAt: now, machines };
|
|
121186
|
+
}
|
|
121187
|
+
async function resourceStorage(hostId2) {
|
|
121188
|
+
const worktrees2 = knownWorktrees().filter((w2) => w2.hostId === hostId2 && w2.path);
|
|
121189
|
+
const host = hostRegistry.hostById(hostId2);
|
|
121190
|
+
const result = await host.resources.storage({
|
|
121191
|
+
worktrees: worktrees2.map((w2) => ({ id: w2.id, path: w2.path }))
|
|
121192
|
+
});
|
|
121193
|
+
const byId = new Map(worktrees2.map((w2) => [w2.id, w2]));
|
|
121194
|
+
return {
|
|
121195
|
+
worktrees: result.worktrees.flatMap((r) => {
|
|
121196
|
+
const w2 = byId.get(r.id);
|
|
121197
|
+
return w2 ? [{ ...refOf(w2), sizeBytes: r.sizeBytes, ...r.error ? { error: r.error } : {} }] : [];
|
|
121198
|
+
}),
|
|
121199
|
+
state: result.state,
|
|
121200
|
+
disk: result.disk
|
|
121201
|
+
};
|
|
121202
|
+
}
|
|
121203
|
+
|
|
121204
|
+
// src/server/api/resources/router.ts
|
|
121205
|
+
var resourcesRouter = t.router({
|
|
121206
|
+
snapshot: publicProcedure.query(() => listResources()),
|
|
121207
|
+
storage: publicProcedure.input(external_exports2.object({ hostId: external_exports2.string().min(1) })).query(async ({ input: input3 }) => {
|
|
121208
|
+
try {
|
|
121209
|
+
return await resourceStorage(input3.hostId);
|
|
121210
|
+
} catch (err) {
|
|
121211
|
+
console.error(`[resources] storage on ${input3.hostId} failed:`, err);
|
|
121212
|
+
throw new TRPCError({
|
|
121213
|
+
code: "SERVICE_UNAVAILABLE",
|
|
121214
|
+
message: `Could not measure storage on ${input3.hostId}`
|
|
121215
|
+
});
|
|
121216
|
+
}
|
|
121217
|
+
})
|
|
121218
|
+
});
|
|
121219
|
+
|
|
120654
121220
|
// src/server/api/reviews/router.ts
|
|
120655
121221
|
init_dist();
|
|
120656
121222
|
init_zod();
|
|
@@ -120703,12 +121269,12 @@ function allowed(args) {
|
|
|
120703
121269
|
var UNAUTHENTICATED2 = /gh auth login|GH_TOKEN|GITHUB_TOKEN|authentication|HTTP 401|bad credentials/i;
|
|
120704
121270
|
var MISSING_GH = /ENOENT|command not found|executable file not found|no such file/i;
|
|
120705
121271
|
var GH_TIMEOUT_MS2 = 3e4;
|
|
120706
|
-
function
|
|
121272
|
+
function withTimeout4(run4) {
|
|
120707
121273
|
let timer;
|
|
120708
121274
|
const timeout = new Promise((_2, reject) => {
|
|
120709
121275
|
timer = setTimeout(() => reject(new Error("gh timed out")), GH_TIMEOUT_MS2);
|
|
120710
121276
|
});
|
|
120711
|
-
return Promise.race([
|
|
121277
|
+
return Promise.race([run4, timeout]).finally(() => clearTimeout(timer));
|
|
120712
121278
|
}
|
|
120713
121279
|
function firstLine2(err) {
|
|
120714
121280
|
return (err instanceof Error ? err.message : String(err)).split("\n")[0];
|
|
@@ -120735,17 +121301,17 @@ function fallbackGh(args, cwd) {
|
|
|
120735
121301
|
function worktreeGh(host, localHostId, cwd) {
|
|
120736
121302
|
return async (args) => {
|
|
120737
121303
|
if (!allowed(args)) throw new Error(`gh ${args.slice(0, 2).join(" ")} is not allowed here`);
|
|
120738
|
-
if (host.id === localHostId) return
|
|
121304
|
+
if (host.id === localHostId) return withTimeout4(localGh(args, cwd));
|
|
120739
121305
|
let hostError;
|
|
120740
121306
|
try {
|
|
120741
|
-
return (await
|
|
121307
|
+
return (await withTimeout4(host.git.gh(args, cwd))).stdout;
|
|
120742
121308
|
} catch (err) {
|
|
120743
121309
|
if (err instanceof Error) err.message = err.message.trim();
|
|
120744
121310
|
if (!hostCannotAnswer(err)) throw err;
|
|
120745
121311
|
hostError = err;
|
|
120746
121312
|
}
|
|
120747
121313
|
try {
|
|
120748
|
-
return await
|
|
121314
|
+
return await withTimeout4(fallbackGh(args, tmpdir5()));
|
|
120749
121315
|
} catch (hubError) {
|
|
120750
121316
|
if (!hostCannotAnswer(hubError)) throw hubError;
|
|
120751
121317
|
throw new Error(
|
|
@@ -122559,7 +123125,7 @@ init_speech_transcription();
|
|
|
122559
123125
|
init_registry();
|
|
122560
123126
|
init_settings_service();
|
|
122561
123127
|
init_vault_service();
|
|
122562
|
-
var
|
|
123128
|
+
var LOCAL_HOST_ID14 = "local";
|
|
122563
123129
|
function readConfig2() {
|
|
122564
123130
|
return settingsService.get().voice ?? {};
|
|
122565
123131
|
}
|
|
@@ -122609,7 +123175,7 @@ var VoiceService = class {
|
|
|
122609
123175
|
}
|
|
122610
123176
|
if (!config3.model?.trim()) throw new SpeechError("not_configured", "Enter a model first.");
|
|
122611
123177
|
await this.send(config3, silentWav(1), "audio/wav");
|
|
122612
|
-
return { ok: true, hostId: config3.hostId ||
|
|
123178
|
+
return { ok: true, hostId: config3.hostId || LOCAL_HOST_ID14 };
|
|
122613
123179
|
}
|
|
122614
123180
|
async send(config3, audio, mimeType) {
|
|
122615
123181
|
if (audio.byteLength === 0) throw new SpeechError("bad_response", "The recording is empty.");
|
|
@@ -122622,7 +123188,7 @@ var VoiceService = class {
|
|
|
122622
123188
|
const apiKey = await this.apiKey(config3.apiKeyItemId);
|
|
122623
123189
|
try {
|
|
122624
123190
|
const hostId2 = config3.hostId?.trim();
|
|
122625
|
-
if (!hostId2 || hostId2 ===
|
|
123191
|
+
if (!hostId2 || hostId2 === LOCAL_HOST_ID14) {
|
|
122626
123192
|
return await requestTranscription({ baseUrl, apiKey, model, language, audio, mimeType });
|
|
122627
123193
|
}
|
|
122628
123194
|
let host;
|
|
@@ -122633,7 +123199,7 @@ var VoiceService = class {
|
|
|
122633
123199
|
}
|
|
122634
123200
|
let result;
|
|
122635
123201
|
try {
|
|
122636
|
-
result = await
|
|
123202
|
+
result = await withTimeout5(
|
|
122637
123203
|
host.speech.transcribe({ baseUrl, apiKey, model, language, audio, mimeType }),
|
|
122638
123204
|
WORKER_TRANSCRIBE_TIMEOUT_MS
|
|
122639
123205
|
);
|
|
@@ -122678,7 +123244,7 @@ var VoiceService = class {
|
|
|
122678
123244
|
function scrub2(message, apiKey) {
|
|
122679
123245
|
return scrubSecrets(message, apiKey);
|
|
122680
123246
|
}
|
|
122681
|
-
function
|
|
123247
|
+
function withTimeout5(promise2, ms) {
|
|
122682
123248
|
let timer;
|
|
122683
123249
|
const timeout = new Promise((_2, reject) => {
|
|
122684
123250
|
timer = setTimeout(
|
|
@@ -122936,7 +123502,7 @@ function verifyWorktreePreviewGrant(worktreeId4, grant, filePath, now = Date.now
|
|
|
122936
123502
|
init_src3();
|
|
122937
123503
|
init_src();
|
|
122938
123504
|
init_resolver();
|
|
122939
|
-
import { join as
|
|
123505
|
+
import { join as join58, resolve as resolve12, sep as sep9 } from "node:path";
|
|
122940
123506
|
var log82 = createLogger("diff-service");
|
|
122941
123507
|
var EMPTY_TREE_ARGS = ["hash-object", "-t", "tree", "/dev/null"];
|
|
122942
123508
|
var DEFAULT_BRANCH_LIMIT = 50;
|
|
@@ -123033,7 +123599,7 @@ function parseFileStatuses(nameStatusOutput) {
|
|
|
123033
123599
|
return fileStatuses;
|
|
123034
123600
|
}
|
|
123035
123601
|
function assertWorktreeRelative(cwd, filePath) {
|
|
123036
|
-
const target = resolve12(
|
|
123602
|
+
const target = resolve12(join58(cwd, filePath));
|
|
123037
123603
|
if (target !== cwd && !target.startsWith(cwd + sep9)) {
|
|
123038
123604
|
throw new Error("Invalid path");
|
|
123039
123605
|
}
|
|
@@ -123048,7 +123614,7 @@ function assertWorktreeRelative(cwd, filePath) {
|
|
|
123048
123614
|
}
|
|
123049
123615
|
async function readUntrackedFileLines(host, cwd, file3) {
|
|
123050
123616
|
try {
|
|
123051
|
-
const content = new TextDecoder().decode(await host.fs.readFile(
|
|
123617
|
+
const content = new TextDecoder().decode(await host.fs.readFile(join58(cwd, file3)));
|
|
123052
123618
|
const lines = content.split("\n");
|
|
123053
123619
|
if (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
123054
123620
|
lines.pop();
|
|
@@ -123395,7 +123961,7 @@ var DiffService = class {
|
|
|
123395
123961
|
const compareBranch = options.compareBranch ?? defaultBranch;
|
|
123396
123962
|
const cwd = worktree.worktree.path;
|
|
123397
123963
|
const execGit2 = gitRunner(worktree.host);
|
|
123398
|
-
const hasGit = await worktree.host.fs.stat(
|
|
123964
|
+
const hasGit = await worktree.host.fs.stat(join58(cwd, ".git")).then(
|
|
123399
123965
|
() => true,
|
|
123400
123966
|
(err) => {
|
|
123401
123967
|
if (err instanceof HostOfflineError || err instanceof HostTimeoutError) throw err;
|
|
@@ -123433,7 +123999,7 @@ var DiffService = class {
|
|
|
123433
123999
|
applyLineCounts(status.staged, parseNumstat(stagedNumstat));
|
|
123434
124000
|
await Promise.all(
|
|
123435
124001
|
status.untracked.map(async (entry) => {
|
|
123436
|
-
const lines = await countUntrackedLines(worktree.host,
|
|
124002
|
+
const lines = await countUntrackedLines(worktree.host, join58(cwd, entry.path));
|
|
123437
124003
|
if (lines !== null) {
|
|
123438
124004
|
entry.additions = lines;
|
|
123439
124005
|
entry.deletions = 0;
|
|
@@ -123635,9 +124201,95 @@ var DirectAccessService = class {
|
|
|
123635
124201
|
};
|
|
123636
124202
|
var directAccessService = new DirectAccessService();
|
|
123637
124203
|
|
|
124204
|
+
// src/server/services/external-file-service.ts
|
|
124205
|
+
init_errors6();
|
|
124206
|
+
init_worktree_service();
|
|
124207
|
+
import { extname as extname2, isAbsolute as isAbsolute6 } from "node:path";
|
|
124208
|
+
var MAX_FILE_SIZE = 1024 * 1024;
|
|
124209
|
+
var LANG_MAP = {
|
|
124210
|
+
".js": "javascript",
|
|
124211
|
+
".jsx": "jsx",
|
|
124212
|
+
".ts": "typescript",
|
|
124213
|
+
".tsx": "tsx",
|
|
124214
|
+
".mjs": "javascript",
|
|
124215
|
+
".cjs": "javascript",
|
|
124216
|
+
".json": "json",
|
|
124217
|
+
".html": "html",
|
|
124218
|
+
".css": "css",
|
|
124219
|
+
".scss": "scss",
|
|
124220
|
+
".md": "markdown",
|
|
124221
|
+
".yaml": "yaml",
|
|
124222
|
+
".yml": "yaml",
|
|
124223
|
+
".toml": "toml",
|
|
124224
|
+
".py": "python",
|
|
124225
|
+
".rb": "ruby",
|
|
124226
|
+
".rs": "rust",
|
|
124227
|
+
".go": "go",
|
|
124228
|
+
".java": "java",
|
|
124229
|
+
".swift": "swift",
|
|
124230
|
+
".c": "c",
|
|
124231
|
+
".cpp": "cpp",
|
|
124232
|
+
".sh": "bash",
|
|
124233
|
+
".sql": "sql",
|
|
124234
|
+
".graphql": "graphql",
|
|
124235
|
+
".vue": "vue",
|
|
124236
|
+
".svelte": "svelte",
|
|
124237
|
+
".diff": "diff"
|
|
124238
|
+
};
|
|
124239
|
+
function hostFor2(worktreeId4) {
|
|
124240
|
+
const resolved = worktreeService.resolve(worktreeId4);
|
|
124241
|
+
if (!resolved) throw new WorktreeNotFoundError(worktreeId4);
|
|
124242
|
+
return resolved.host;
|
|
124243
|
+
}
|
|
124244
|
+
async function statFile(fs3, path2) {
|
|
124245
|
+
try {
|
|
124246
|
+
return await fs3.stat(path2);
|
|
124247
|
+
} catch (err) {
|
|
124248
|
+
const text4 = err instanceof Error ? `${err.code ?? ""} ${err.message}` : "";
|
|
124249
|
+
if (/ENOENT|no such file|not found/i.test(text4)) throw new Error("File not found");
|
|
124250
|
+
throw err;
|
|
124251
|
+
}
|
|
124252
|
+
}
|
|
124253
|
+
function assertAbsolute(path2) {
|
|
124254
|
+
if (!isAbsolute6(path2)) throw new Error("Absolute path required");
|
|
124255
|
+
}
|
|
124256
|
+
var ExternalFileService = class {
|
|
124257
|
+
async read(worktreeId4, absolutePath) {
|
|
124258
|
+
assertAbsolute(absolutePath);
|
|
124259
|
+
const { fs: fs3 } = hostFor2(worktreeId4);
|
|
124260
|
+
const stat9 = await statFile(fs3, absolutePath);
|
|
124261
|
+
if (stat9.kind === "symlink") throw new Error("Symbolic links are not allowed");
|
|
124262
|
+
if (stat9.kind === "directory") throw new Error("Cannot operate on a directory");
|
|
124263
|
+
if (stat9.kind !== "file") throw new Error("Not a regular file");
|
|
124264
|
+
if (stat9.size > MAX_FILE_SIZE) return { tooLarge: true, size: stat9.size };
|
|
124265
|
+
const bytes = await fs3.readFile(absolutePath);
|
|
124266
|
+
const buffer = Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
124267
|
+
if (buffer.subarray(0, 8192).includes(0)) return { binary: true, size: stat9.size };
|
|
124268
|
+
return {
|
|
124269
|
+
content: buffer.toString("utf-8"),
|
|
124270
|
+
size: stat9.size,
|
|
124271
|
+
language: LANG_MAP[extname2(absolutePath).toLowerCase()]
|
|
124272
|
+
};
|
|
124273
|
+
}
|
|
124274
|
+
async save(worktreeId4, absolutePath, content) {
|
|
124275
|
+
assertAbsolute(absolutePath);
|
|
124276
|
+
if (Buffer.byteLength(content, "utf-8") > MAX_FILE_SIZE) throw new Error("File too large");
|
|
124277
|
+
const { fs: fs3 } = hostFor2(worktreeId4);
|
|
124278
|
+
const stat9 = await statFile(fs3, absolutePath);
|
|
124279
|
+
if (stat9.kind === "symlink") throw new Error("Symbolic links are not allowed");
|
|
124280
|
+
if (stat9.kind !== "file") throw new Error("Not a regular file");
|
|
124281
|
+
if (absolutePath.split(/[\\/]/).includes(".git")) {
|
|
124282
|
+
throw new Error("Refusing to write inside a .git folder");
|
|
124283
|
+
}
|
|
124284
|
+
await fs3.writeFile(absolutePath, content);
|
|
124285
|
+
return { ok: true };
|
|
124286
|
+
}
|
|
124287
|
+
};
|
|
124288
|
+
var externalFileService = new ExternalFileService();
|
|
124289
|
+
|
|
123638
124290
|
// ../../packages/worktree-ops/src/files.ts
|
|
123639
124291
|
init_resolver();
|
|
123640
|
-
import { dirname as dirname18, extname as extname3, join as
|
|
124292
|
+
import { dirname as dirname18, extname as extname3, join as join59, resolve as resolve13, sep as sep10 } from "node:path";
|
|
123641
124293
|
var MAX_FILE_SIZE2 = 1024 * 1024;
|
|
123642
124294
|
var LANG_MAP2 = {
|
|
123643
124295
|
".js": "javascript",
|
|
@@ -123704,7 +124356,7 @@ var FilesService = class {
|
|
|
123704
124356
|
throw new WorktreeNotFoundError(worktreeId4);
|
|
123705
124357
|
}
|
|
123706
124358
|
const root = worktree.worktree.path;
|
|
123707
|
-
const target = resolve13(
|
|
124359
|
+
const target = resolve13(join59(root, relative2));
|
|
123708
124360
|
const insideRoot = target === root || target.startsWith(root + sep10);
|
|
123709
124361
|
if (!insideRoot) {
|
|
123710
124362
|
throw new Error("Invalid path");
|
|
@@ -125288,6 +125940,20 @@ var worktreeRouter = t.router({
|
|
|
125288
125940
|
listFiles: publicProcedure.input(directOps["worktree.listFiles"].input).query(({ input: input3 }) => directOps["worktree.listFiles"].run(worktreeOps, input3)),
|
|
125289
125941
|
getFile: publicProcedure.input(directOps["worktree.getFile"].input).query(({ input: input3 }) => directOps["worktree.getFile"].run(worktreeOps, input3)),
|
|
125290
125942
|
saveFile: publicProcedure.input(directOps["worktree.saveFile"].input).mutation(({ input: input3 }) => directOps["worktree.saveFile"].run(worktreeOps, input3)),
|
|
125943
|
+
/**
|
|
125944
|
+
* A file outside the worktree, read on the worktree's own worker (never the
|
|
125945
|
+
* hub's disk). Left out of the relay and the direct path: device tokens only.
|
|
125946
|
+
*/
|
|
125947
|
+
readExternalFile: publicProcedure.input(external_exports2.object({ worktreeId: external_exports2.string().min(1), absolutePath: external_exports2.string().min(1) })).query(({ input: input3 }) => externalFileService.read(input3.worktreeId, input3.absolutePath)),
|
|
125948
|
+
saveExternalFile: publicProcedure.input(
|
|
125949
|
+
external_exports2.object({
|
|
125950
|
+
worktreeId: external_exports2.string().min(1),
|
|
125951
|
+
absolutePath: external_exports2.string().min(1),
|
|
125952
|
+
content: external_exports2.string()
|
|
125953
|
+
})
|
|
125954
|
+
).mutation(
|
|
125955
|
+
({ input: input3 }) => externalFileService.save(input3.worktreeId, input3.absolutePath, input3.content)
|
|
125956
|
+
),
|
|
125291
125957
|
createFile: publicProcedure.input(directOps["worktree.createFile"].input).mutation(({ input: input3 }) => directOps["worktree.createFile"].run(worktreeOps, input3)),
|
|
125292
125958
|
createDirectory: publicProcedure.input(directOps["worktree.createDirectory"].input).mutation(({ input: input3 }) => directOps["worktree.createDirectory"].run(worktreeOps, input3)),
|
|
125293
125959
|
deletePath: publicProcedure.input(directOps["worktree.deletePath"].input).mutation(({ input: input3 }) => directOps["worktree.deletePath"].run(worktreeOps, input3)),
|
|
@@ -125312,7 +125978,7 @@ var worktreeRouter = t.router({
|
|
|
125312
125978
|
// path an authenticated caller supplies (not just in-worktree ones), so it
|
|
125313
125979
|
// is a filesystem-existence oracle. That is acceptable under Band's threat
|
|
125314
125980
|
// model — the same auth scope already reads arbitrary absolute paths via
|
|
125315
|
-
// `
|
|
125981
|
+
// `worktree.readExternalFile` — and the `external` flag is load-bearing, not dead code:
|
|
125316
125982
|
// it's how the client decides between a worktree-relative and an external
|
|
125317
125983
|
// tab. Do not "harden" this by dropping the out-of-worktree classification.
|
|
125318
125984
|
resolvePath: publicProcedure.input(resolvePathInput).query(
|
|
@@ -125448,8 +126114,8 @@ var appRouter = t.router({
|
|
|
125448
126114
|
...terminalsRouters,
|
|
125449
126115
|
cli: cliRouter,
|
|
125450
126116
|
accountUsage: accountUsageRouter,
|
|
126117
|
+
resources: resourcesRouter,
|
|
125451
126118
|
hooks: hooksRouter,
|
|
125452
|
-
host: hostRouter,
|
|
125453
126119
|
workers: hostsRouter,
|
|
125454
126120
|
// Old name, kept for desktop, mobile and CLI builds that still call it.
|
|
125455
126121
|
hosts: hostsRouter,
|
|
@@ -125495,12 +126161,14 @@ function discoverProcedures() {
|
|
|
125495
126161
|
for (const [path2, procedure] of Object.entries(procRecord)) {
|
|
125496
126162
|
const type = procedure._def.type;
|
|
125497
126163
|
if (type === "subscription") continue;
|
|
125498
|
-
if (path2.startsWith("tokens.") || path2.startsWith("vault.") || path2.startsWith("agentLogins.") || path2.startsWith("checkpoints.") || path2.startsWith("follow.") || path2.startsWith("mcp.") || path2.startsWith("hosts.") && path2 !== "hosts.forAgents" || path2.startsWith("workers.") && path2 !== "workers.forAgents" || path2.startsWith("hostRequests.") || path2.startsWith("runners.") || path2.startsWith("accountUsage.") || // The
|
|
126164
|
+
if (path2.startsWith("tokens.") || path2.startsWith("vault.") || path2.startsWith("agentLogins.") || path2.startsWith("checkpoints.") || path2.startsWith("follow.") || path2.startsWith("mcp.") || path2.startsWith("hosts.") && path2 !== "hosts.forAgents" || path2.startsWith("workers.") && path2 !== "workers.forAgents" || path2.startsWith("hostRequests.") || path2.startsWith("runners.") || path2.startsWith("accountUsage.") || // The machine's process table and disk use are a person's page, not an agent's tool.
|
|
126165
|
+
path2.startsWith("resources.") || // The Simulator tab is a person's; an agent uses the simulator_* tools.
|
|
125499
126166
|
path2.startsWith("simulators.") || path2.startsWith("voice.") || path2.startsWith("extensions.") || path2.startsWith("provisioning.") || // Writes ~/.claude/settings.json on a host; only a person's click may.
|
|
125500
126167
|
path2.startsWith("hooks."))
|
|
125501
126168
|
continue;
|
|
125502
126169
|
if (path2 === "worktree.previewUrl") continue;
|
|
125503
126170
|
if (path2 === "worktree.directAccess") continue;
|
|
126171
|
+
if (path2 === "worktree.readExternalFile" || path2 === "worktree.saveExternalFile") continue;
|
|
125504
126172
|
if (path2 === "environment.validate") continue;
|
|
125505
126173
|
if (path2 === "repos.addFromWorker") continue;
|
|
125506
126174
|
if (path2 === "repos.addByUrl") continue;
|
|
@@ -125979,12 +126647,12 @@ function lookUpToolsOnce(server, listPage) {
|
|
|
125979
126647
|
if (running) return running;
|
|
125980
126648
|
const last = lookupMissedAt.get(server.id);
|
|
125981
126649
|
if (last !== void 0 && Date.now() - last < LOOKUP_COOLDOWN_MS) return Promise.resolve();
|
|
125982
|
-
const
|
|
126650
|
+
const run4 = lookUpTools(server, listPage).catch(() => void 0).finally(() => {
|
|
125983
126651
|
lookupsInFlight.delete(server.id);
|
|
125984
126652
|
lookupMissedAt.set(server.id, Date.now());
|
|
125985
126653
|
});
|
|
125986
|
-
lookupsInFlight.set(server.id,
|
|
125987
|
-
return
|
|
126654
|
+
lookupsInFlight.set(server.id, run4);
|
|
126655
|
+
return run4;
|
|
125988
126656
|
}
|
|
125989
126657
|
async function lookUpTools(server, listPage) {
|
|
125990
126658
|
const tools = /* @__PURE__ */ new Map();
|
|
@@ -126683,7 +127351,7 @@ function parseModeRequest(text4) {
|
|
|
126683
127351
|
}
|
|
126684
127352
|
return null;
|
|
126685
127353
|
}
|
|
126686
|
-
async function bridgePluginStream(ws, label2,
|
|
127354
|
+
async function bridgePluginStream(ws, label2, open3, onOpenFailed) {
|
|
126687
127355
|
let controlling = false;
|
|
126688
127356
|
let stream = null;
|
|
126689
127357
|
ws.on("message", (data, isBinary) => {
|
|
@@ -126701,7 +127369,7 @@ async function bridgePluginStream(ws, label2, open4, onOpenFailed) {
|
|
|
126701
127369
|
});
|
|
126702
127370
|
ws.once("close", () => stream?.close());
|
|
126703
127371
|
try {
|
|
126704
|
-
stream = await
|
|
127372
|
+
stream = await open3();
|
|
126705
127373
|
} catch (err) {
|
|
126706
127374
|
const message = err instanceof Error ? err.message : String(err);
|
|
126707
127375
|
log87.warn("%s is unavailable: %s", label2, message);
|
|
@@ -127335,14 +128003,14 @@ async function handleVoiceTranscribe(req, res) {
|
|
|
127335
128003
|
|
|
127336
128004
|
// src/server/api/web-app-manifest.ts
|
|
127337
128005
|
import { createReadStream as createReadStream6, statSync as statSync16 } from "node:fs";
|
|
127338
|
-
import { join as
|
|
128006
|
+
import { join as join60 } from "node:path";
|
|
127339
128007
|
var WEB_APP_MANIFEST_PATH = "/manifest.webmanifest";
|
|
127340
128008
|
var ICON_FILES = ["band-192.png", "band-512.png", "apple-touch-icon.png"];
|
|
127341
128009
|
function handleWebAppManifest(req, res, publicDir) {
|
|
127342
128010
|
if (req.method !== "GET" && req.method !== "HEAD") return false;
|
|
127343
128011
|
const pathname = req.url?.split("?")[0];
|
|
127344
128012
|
if (pathname === WEB_APP_MANIFEST_PATH) {
|
|
127345
|
-
sendFile(req, res,
|
|
128013
|
+
sendFile(req, res, join60(publicDir, "manifest.webmanifest"), {
|
|
127346
128014
|
"Content-Type": "application/manifest+json",
|
|
127347
128015
|
"Cache-Control": "no-cache"
|
|
127348
128016
|
});
|
|
@@ -127350,7 +128018,7 @@ function handleWebAppManifest(req, res, publicDir) {
|
|
|
127350
128018
|
}
|
|
127351
128019
|
const icon = ICON_FILES.find((name5) => pathname === `/icons/${name5}`);
|
|
127352
128020
|
if (!icon) return false;
|
|
127353
|
-
sendFile(req, res,
|
|
128021
|
+
sendFile(req, res, join60(publicDir, "icons", icon), {
|
|
127354
128022
|
"Content-Type": "image/png",
|
|
127355
128023
|
"Cache-Control": "public, max-age=86400"
|
|
127356
128024
|
});
|
|
@@ -127602,18 +128270,18 @@ async function bridgeRemote(ws, worktreeId4) {
|
|
|
127602
128270
|
ws.removeAllListeners("message");
|
|
127603
128271
|
return pending2;
|
|
127604
128272
|
}
|
|
127605
|
-
const
|
|
128273
|
+
const open3 = cdp;
|
|
127606
128274
|
if (ws.readyState !== ws.OPEN) {
|
|
127607
|
-
|
|
128275
|
+
open3.close();
|
|
127608
128276
|
return true;
|
|
127609
128277
|
}
|
|
127610
|
-
for (const msg of pending2)
|
|
128278
|
+
for (const msg of pending2) open3.send(msg);
|
|
127611
128279
|
pending2.length = 0;
|
|
127612
|
-
ws.on("close", () =>
|
|
127613
|
-
ws.on("error", () =>
|
|
128280
|
+
ws.on("close", () => open3.close());
|
|
128281
|
+
ws.on("error", () => open3.close());
|
|
127614
128282
|
void (async () => {
|
|
127615
128283
|
try {
|
|
127616
|
-
for await (const message of
|
|
128284
|
+
for await (const message of open3.messages) {
|
|
127617
128285
|
if (ws.readyState === ws.OPEN) ws.send(message);
|
|
127618
128286
|
}
|
|
127619
128287
|
} catch (err) {
|
|
@@ -128143,7 +128811,7 @@ init_http_files();
|
|
|
128143
128811
|
|
|
128144
128812
|
// src/server/services/_utils/hosted-file.ts
|
|
128145
128813
|
init_registry();
|
|
128146
|
-
import { basename as basename6, dirname as dirname19, join as
|
|
128814
|
+
import { basename as basename6, dirname as dirname19, join as join61 } from "node:path";
|
|
128147
128815
|
async function openHostedFile(kind, worktreeId4, rawName, chatId) {
|
|
128148
128816
|
const host = hostRegistry.hostFor(worktreeId4);
|
|
128149
128817
|
if (host.id === hostRegistry.local.id) return null;
|
|
@@ -128157,12 +128825,12 @@ async function openHostedFile(kind, worktreeId4, rawName, chatId) {
|
|
|
128157
128825
|
try {
|
|
128158
128826
|
const dirs = (await host.info()).dirs;
|
|
128159
128827
|
if (!dirs) return null;
|
|
128160
|
-
const path2 = chatId ?
|
|
128828
|
+
const path2 = chatId ? join61(dirs[kind], worktreeId4, chatId, name5) : join61(dirs[kind], worktreeId4, name5);
|
|
128161
128829
|
const dir = await host.fs.realpath(dirname19(path2));
|
|
128162
128830
|
if (!(await host.fs.realpath(path2)).startsWith(`${dir}/`)) return null;
|
|
128163
|
-
const
|
|
128164
|
-
if (
|
|
128165
|
-
return { size:
|
|
128831
|
+
const stat9 = await host.fs.stat(path2, { followSymlinks: true });
|
|
128832
|
+
if (stat9.kind !== "file") return null;
|
|
128833
|
+
return { size: stat9.size, stream: host.fs.readStream(path2) };
|
|
128166
128834
|
} catch {
|
|
128167
128835
|
return null;
|
|
128168
128836
|
}
|
|
@@ -136525,7 +137193,7 @@ init_worktree_service();
|
|
|
136525
137193
|
function logCrash(message) {
|
|
136526
137194
|
try {
|
|
136527
137195
|
mkdirSync12(bandHome(), { recursive: true });
|
|
136528
|
-
appendFileSync2(
|
|
137196
|
+
appendFileSync2(join62(bandHome(), "server.log"), message, "utf-8");
|
|
136529
137197
|
} catch {
|
|
136530
137198
|
}
|
|
136531
137199
|
}
|
|
@@ -136565,9 +137233,9 @@ function resolveUiDir() {
|
|
|
136565
137233
|
if (explicit) return resolve15(explicit);
|
|
136566
137234
|
const candidates = [
|
|
136567
137235
|
resolve15(SERVER_ROOT, "..", "..", "web", "dist", "client"),
|
|
136568
|
-
|
|
137236
|
+
join62(SERVER_ROOT, "client")
|
|
136569
137237
|
];
|
|
136570
|
-
return candidates.find((dir) => existsSync20(
|
|
137238
|
+
return candidates.find((dir) => existsSync20(join62(dir, "_shell.html"))) ?? candidates[1];
|
|
136571
137239
|
}
|
|
136572
137240
|
var clientDir = resolveUiDir();
|
|
136573
137241
|
var uiRoot = process.env.BAND_UI_ROOT ? resolve15(process.env.BAND_UI_ROOT) : resolve15(SERVER_ROOT, "..", "web");
|
|
@@ -136618,7 +137286,7 @@ function getOpenApiSpec() {
|
|
|
136618
137286
|
if (isDev) {
|
|
136619
137287
|
const { generateOpenAPIDocument } = await import("@trpc/openapi");
|
|
136620
137288
|
const doc = await generateOpenAPIDocument(
|
|
136621
|
-
|
|
137289
|
+
join62(SERVER_ROOT, "src", "server", "api", "router.ts"),
|
|
136622
137290
|
{
|
|
136623
137291
|
title: "Band API",
|
|
136624
137292
|
version: "1.0.0"
|
|
@@ -136627,7 +137295,7 @@ function getOpenApiSpec() {
|
|
|
136627
137295
|
doc.servers = [{ url: "/trpc" }];
|
|
136628
137296
|
return JSON.stringify(doc, null, 2);
|
|
136629
137297
|
}
|
|
136630
|
-
const openApiDoc = JSON.parse(readFileSync14(
|
|
137298
|
+
const openApiDoc = JSON.parse(readFileSync14(join62(SERVER_ROOT, "openapi.json"), "utf-8"));
|
|
136631
137299
|
openApiDoc.servers = [{ url: "/trpc" }];
|
|
136632
137300
|
return JSON.stringify(openApiDoc, null, 2);
|
|
136633
137301
|
})().catch((err) => {
|
|
@@ -136650,9 +137318,9 @@ function serveStaticFile(res, root, subdir, rawFilename) {
|
|
|
136650
137318
|
res.end("Bad request");
|
|
136651
137319
|
return;
|
|
136652
137320
|
}
|
|
136653
|
-
const filePath =
|
|
137321
|
+
const filePath = join62(root, subdir, filename);
|
|
136654
137322
|
try {
|
|
136655
|
-
const dir = realpathSync7(
|
|
137323
|
+
const dir = realpathSync7(join62(root, subdir));
|
|
136656
137324
|
if (!realpathSync7(filePath).startsWith(dir + sep12)) {
|
|
136657
137325
|
res.writeHead(404);
|
|
136658
137326
|
res.end("Not found");
|
|
@@ -136703,7 +137371,7 @@ async function serveWorktreeFile(res, worktreeId4, rawPath, extraHeaders = {}, v
|
|
|
136703
137371
|
return;
|
|
136704
137372
|
}
|
|
136705
137373
|
const root = worktree.worktree.path;
|
|
136706
|
-
const target = resolve15(
|
|
137374
|
+
const target = resolve15(join62(root, rawPath));
|
|
136707
137375
|
if (!target.startsWith(root + sep12) && target !== root) {
|
|
136708
137376
|
res.writeHead(400);
|
|
136709
137377
|
res.end("Bad request");
|
|
@@ -137036,7 +137704,7 @@ async function main() {
|
|
|
137036
137704
|
res.end(JSON.stringify({ status: "ok", app: "band-web-server" }));
|
|
137037
137705
|
return;
|
|
137038
137706
|
}
|
|
137039
|
-
if (handleWebAppManifest(req, res, isDev ?
|
|
137707
|
+
if (handleWebAppManifest(req, res, isDev ? join62(uiRoot, "public") : clientDir)) return;
|
|
137040
137708
|
if (req.url?.split("?")[0] === WORKER_EXCHANGE_PATH) {
|
|
137041
137709
|
await workerLinkService.handleExchange(req, res);
|
|
137042
137710
|
return;
|
|
@@ -137148,7 +137816,7 @@ async function main() {
|
|
|
137148
137816
|
const encodedName = encodeURIComponent(parsed.name);
|
|
137149
137817
|
if (await serveHostedFile(res, "shared", parsed.worktreeId, encodedName, parsed.chatId))
|
|
137150
137818
|
return;
|
|
137151
|
-
const subdir = parsed.chatId ?
|
|
137819
|
+
const subdir = parsed.chatId ? join62("shared", parsed.worktreeId, parsed.chatId) : join62("shared", parsed.worktreeId);
|
|
137152
137820
|
serveStaticFile(res, bandHome(), subdir, encodedName);
|
|
137153
137821
|
return;
|
|
137154
137822
|
}
|
|
@@ -137374,7 +138042,7 @@ async function main() {
|
|
|
137374
138042
|
if (pathname.startsWith("/_shell")) res.setHeader("Cache-Control", "no-cache");
|
|
137375
138043
|
}
|
|
137376
138044
|
});
|
|
137377
|
-
const shellPath2 =
|
|
138045
|
+
const shellPath2 = join62(clientDir, "_shell.html");
|
|
137378
138046
|
if (!existsSync20(shellPath2)) {
|
|
137379
138047
|
throw new Error(
|
|
137380
138048
|
`UI build not found at ${clientDir} (no _shell.html). Run \`pnpm build\` or pass --ui-dir <path>.`
|