@band-app/server 0.54.0 → 0.54.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/_shell.html +0 -0
- package/dist/client/assets/{TerminalPanel-RYLpWa8Q.js → TerminalPanel-CfzL015Z.js} +1 -1
- package/dist/client/assets/{_basePickBy-D-5MXYU_.js → _basePickBy-DCBI2ZYZ.js} +1 -1
- package/dist/client/assets/{_baseUniq-DYuk2xMI.js → _baseUniq-DcG-qGfl.js} +1 -1
- package/dist/client/assets/{arc-dXtOms1t.js → arc-Dtd3NOeG.js} +1 -1
- package/dist/client/assets/{architectureDiagram-VXUJARFQ-CsyRS4YA.js → architectureDiagram-VXUJARFQ-_4wJCo66.js} +1 -1
- package/dist/client/assets/{blockDiagram-VD42YOAC-DKwcsJ3k.js → blockDiagram-VD42YOAC-BLg8A5DO.js} +1 -1
- package/dist/client/assets/{c4Diagram-YG6GDRKO-B-1bWrTm.js → c4Diagram-YG6GDRKO-1o6lovC1.js} +1 -1
- package/dist/client/assets/channel-CXnvJLnE.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-Lx4boQMz.js → chunk-4BX2VUAB-pUhlexDl.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-C4WK81Kx.js → chunk-55IACEB6-DIOOkGXI.js} +1 -1
- package/dist/client/assets/{chunk-B4BG7PRW-awrixx-i.js → chunk-B4BG7PRW-betJcaMy.js} +1 -1
- package/dist/client/assets/{chunk-DI55MBZ5-BXvp16cX.js → chunk-DI55MBZ5-Du6zLzqO.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-DyY6khot.js → chunk-FMBD7UC4-jlnPGz3-.js} +1 -1
- package/dist/client/assets/{chunk-QN33PNHL-BMvkmzKw.js → chunk-QN33PNHL-BtZcZKWT.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-CWY-fLAo.js → chunk-QZHKN3VN-CCXlh8PQ.js} +1 -1
- package/dist/client/assets/{chunk-TZMSLE5B-BE-ngWv6.js → chunk-TZMSLE5B-EGqxu3bA.js} +1 -1
- package/dist/client/assets/classDiagram-2ON5EDUG-Dp5-cWrq.js +1 -0
- package/dist/client/assets/classDiagram-v2-WZHVMYZB-Dp5-cWrq.js +1 -0
- package/dist/client/assets/clone-D5FdW0HP.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-DJ8h3kKA.js → cose-bilkent-S5V4N54A-CiQDuqKy.js} +1 -1
- package/dist/client/assets/{dagre-6UL2VRFP-Bd1qWRGC.js → dagre-6UL2VRFP-BV1RIA6i.js} +1 -1
- package/dist/client/assets/{diagram-PSM6KHXK-BR64_p5f.js → diagram-PSM6KHXK-oZBpmBZ4.js} +1 -1
- package/dist/client/assets/{diagram-QEK2KX5R-DFQt3gYM.js → diagram-QEK2KX5R-BvBvt_5J.js} +1 -1
- package/dist/client/assets/{diagram-S2PKOQOG-C8HaYYzZ.js → diagram-S2PKOQOG-sjeU7pbV.js} +1 -1
- package/dist/client/assets/{erDiagram-Q2GNP2WA-CS64Rcxd.js → erDiagram-Q2GNP2WA-DnmU3JYj.js} +1 -1
- package/dist/client/assets/{flowDiagram-NV44I4VS-C-lDTK_F.js → flowDiagram-NV44I4VS-vWTy8wO1.js} +1 -1
- package/dist/client/assets/{ganttDiagram-JELNMOA3-mfB20mUi.js → ganttDiagram-JELNMOA3-C8UgEfn6.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-DIT7OOcN.js → gitGraphDiagram-V2S2FVAM-D4Y2-pQd.js} +1 -1
- package/dist/client/assets/{graph-CuDWaZgk.js → graph-wAJZ-snQ.js} +1 -1
- package/dist/client/assets/{highlighted-body-B3W2YXNL-CEukDjjL.js → highlighted-body-B3W2YXNL-BS1x7lkZ.js} +1 -1
- package/dist/client/assets/{index-B7yHTHBd.js → index-21p4gEDF.js} +1 -1
- package/dist/client/assets/{index-BAlhbw5A.js → index-B52rCane.js} +1 -1
- package/dist/client/assets/{index-CzkjYgaV.js → index-BMcO1RPX.js} +1 -1
- package/dist/client/assets/{index-CiKJmP62.js → index-BULPK8ND.js} +1 -1
- package/dist/client/assets/{index-BAFH952I.js → index-CDRJgI3A.js} +1 -1
- package/dist/client/assets/{index-CQknVNu4.js → index-ClYtumza.js} +1 -1
- package/dist/client/assets/{index-CwJX9TIf.js → index-CxNXgFPY.js} +1 -1
- package/dist/client/assets/{index-DFdFKost.js → index-DIelkckr.js} +1 -1
- package/dist/client/assets/{index-BAJM6NLC.js → index-DRo8uUPl.js} +1 -1
- package/dist/client/assets/{index-CQfVS8uj.js → index-DvCvhnCb.js} +1 -1
- package/dist/client/assets/{index-BMcFlUOo.js → index-Hh-Dy8VL.js} +1 -1
- package/dist/client/assets/{index-DV3p0C-w.js → index-ZYHE2FSs.js} +1 -1
- package/dist/client/assets/{index-B7DmSLZ5.js → index-g0Sr5h74.js} +1 -1
- package/dist/client/assets/{infoDiagram-HS3SLOUP-BJFhYv2N.js → infoDiagram-HS3SLOUP-CmZ04ZX2.js} +1 -1
- package/dist/client/assets/{journeyDiagram-XKPGCS4Q-CtemPXmL.js → journeyDiagram-XKPGCS4Q-CyBTVa_6.js} +1 -1
- package/dist/client/assets/{kanban-definition-3W4ZIXB7-C9Xu3EkY.js → kanban-definition-3W4ZIXB7-C6sCohDW.js} +1 -1
- package/dist/client/assets/{layout-DtMsQ09j.js → layout-DbAdffkE.js} +1 -1
- package/dist/client/assets/main-BYKQWpTo.css +1 -0
- package/dist/client/assets/{main-DashEqVP.js → main-DfjP5I-Q.js} +253 -253
- package/dist/client/assets/{mindmap-definition-VGOIOE7T-C_FSSv6y.js → mindmap-definition-VGOIOE7T-D4byQ-t_.js} +1 -1
- package/dist/client/assets/{pieDiagram-ADFJNKIX-BdDAYUXV.js → pieDiagram-ADFJNKIX-SdHTH4tD.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-AYHSOK5B-B5g2nuTP.js → quadrantDiagram-AYHSOK5B-CctaxdVX.js} +1 -1
- package/dist/client/assets/{requirementDiagram-UZGBJVZJ-BYa9pNRf.js → requirementDiagram-UZGBJVZJ-BiuKR3TQ.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-TZEHDZUN-Co2c_zNW.js → sankeyDiagram-TZEHDZUN-BTpPs36c.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-WL72ISMW-eShduLQR.js → sequenceDiagram-WL72ISMW-BRAorH_1.js} +1 -1
- package/dist/client/assets/{stateDiagram-FKZM4ZOC-53kPEZua.js → stateDiagram-FKZM4ZOC-BtHKF925.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-4FDKWEC3-B40ZaZyn.js +1 -0
- package/dist/client/assets/{timeline-definition-IT6M3QCI-CZjtXE9X.js → timeline-definition-IT6M3QCI-BxQS_MT5.js} +1 -1
- package/dist/client/assets/{treemap-GDKQZRPO-DOvJYPBs.js → treemap-GDKQZRPO-DdrDkT5H.js} +1 -1
- package/dist/client/assets/{worktree._worktreeId-CvNxzyR7.js → worktree._worktreeId-C2psBRXR.js} +1 -1
- package/dist/client/assets/{worktree._worktreeId-BUGQ0lrG.js → worktree._worktreeId-CVx6cyp5.js} +1 -1
- package/dist/client/assets/{xychartDiagram-PRI3JC2R-BwZe0MO_.js → xychartDiagram-PRI3JC2R-R2Q9xRsW.js} +1 -1
- package/dist/start-server.mjs +285 -364
- package/package.json +6 -5
- package/dist/client/assets/channel-B8VkZiqn.js +0 -1
- package/dist/client/assets/classDiagram-2ON5EDUG-CePVU31o.js +0 -1
- package/dist/client/assets/classDiagram-v2-WZHVMYZB-CePVU31o.js +0 -1
- package/dist/client/assets/clone-BGTwLCsr.js +0 -1
- package/dist/client/assets/main-sOkcigfk.css +0 -1
- package/dist/client/assets/stateDiagram-v2-4FDKWEC3-BOfSj2dL.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: join59 } = __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"] || join59(__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: createRequire2 } = __require("module");
|
|
2560
2560
|
var getCallers = require_caller();
|
|
2561
|
-
var { join:
|
|
2561
|
+
var { join: join59, isAbsolute: isAbsolute7, sep: sep11 } = __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"] || join59(__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 (pipeline3) {
|
|
2642
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
2642
|
+
target = bundlerOverrides["pino-worker"] || join59(__dirname, "worker.js");
|
|
2643
2643
|
options.pipelines = [pipeline3.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 join59(__dirname, "..", "file.js");
|
|
2665
2665
|
}
|
|
2666
2666
|
let fixTarget2;
|
|
2667
2667
|
for (const filePath of callers) {
|
|
@@ -2989,11 +2989,11 @@ var require_tools = __commonJS({
|
|
|
2989
2989
|
}
|
|
2990
2990
|
}
|
|
2991
2991
|
}
|
|
2992
|
-
function buildFormatters(level, bindings,
|
|
2992
|
+
function buildFormatters(level, bindings, log90) {
|
|
2993
2993
|
return {
|
|
2994
2994
|
level,
|
|
2995
2995
|
bindings,
|
|
2996
|
-
log:
|
|
2996
|
+
log: log90
|
|
2997
2997
|
};
|
|
2998
2998
|
}
|
|
2999
2999
|
function normalizeDestFileDescriptor(destination) {
|
|
@@ -3376,11 +3376,11 @@ var require_proto = __commonJS({
|
|
|
3376
3376
|
}
|
|
3377
3377
|
} else instance[serializersSym] = serializers;
|
|
3378
3378
|
if (options.hasOwnProperty("formatters")) {
|
|
3379
|
-
const { level, bindings: chindings, log:
|
|
3379
|
+
const { level, bindings: chindings, log: log90 } = options.formatters;
|
|
3380
3380
|
instance[formattersSym] = buildFormatters(
|
|
3381
3381
|
level || formatters.level,
|
|
3382
3382
|
chindings || resetChildingsFormatter,
|
|
3383
|
-
|
|
3383
|
+
log90 || formatters.log
|
|
3384
3384
|
);
|
|
3385
3385
|
} else {
|
|
3386
3386
|
instance[formattersSym] = buildFormatters(
|
|
@@ -3650,7 +3650,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
3650
3650
|
return circularValue;
|
|
3651
3651
|
}
|
|
3652
3652
|
let res = "";
|
|
3653
|
-
let
|
|
3653
|
+
let join59 = ",";
|
|
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
|
+
join59 = `,
|
|
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 += join59;
|
|
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 += `${join59}"... ${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
|
+
join59 = `,
|
|
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 = join59;
|
|
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 = join59;
|
|
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 join59 = ",";
|
|
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
|
+
join59 = `,
|
|
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 += join59;
|
|
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 += `${join59}"... ${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
|
+
join59 = `,
|
|
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 = join59;
|
|
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 join60 = `,
|
|
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 += join60;
|
|
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 += `${join60}"... ${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 join59 = `,
|
|
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, join59, maximumBreadth);
|
|
3906
3906
|
keys = keys.slice(value.length);
|
|
3907
3907
|
maximumPropertiesToStringify -= value.length;
|
|
3908
|
-
separator =
|
|
3908
|
+
separator = join59;
|
|
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 = join59;
|
|
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 = join59;
|
|
3926
3926
|
}
|
|
3927
3927
|
if (separator !== "") {
|
|
3928
3928
|
res = `
|
|
@@ -14699,7 +14699,7 @@ var require_websocket = __commonJS({
|
|
|
14699
14699
|
var http = __require("http");
|
|
14700
14700
|
var net = __require("net");
|
|
14701
14701
|
var tls = __require("tls");
|
|
14702
|
-
var { randomBytes: randomBytes17, createHash:
|
|
14702
|
+
var { randomBytes: randomBytes17, createHash: createHash14 } = __require("crypto");
|
|
14703
14703
|
var { Duplex, Readable: Readable3 } = __require("stream");
|
|
14704
14704
|
var { URL: URL2 } = __require("url");
|
|
14705
14705
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -15359,7 +15359,7 @@ var require_websocket = __commonJS({
|
|
|
15359
15359
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
15360
15360
|
return;
|
|
15361
15361
|
}
|
|
15362
|
-
const digest2 =
|
|
15362
|
+
const digest2 = createHash14("sha1").update(key2 + GUID).digest("base64");
|
|
15363
15363
|
if (res.headers["sec-websocket-accept"] !== digest2) {
|
|
15364
15364
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
15365
15365
|
return;
|
|
@@ -15726,7 +15726,7 @@ var require_websocket_server = __commonJS({
|
|
|
15726
15726
|
var EventEmitter4 = __require("events");
|
|
15727
15727
|
var http = __require("http");
|
|
15728
15728
|
var { Duplex } = __require("stream");
|
|
15729
|
-
var { createHash:
|
|
15729
|
+
var { createHash: createHash14 } = __require("crypto");
|
|
15730
15730
|
var extension = require_extension();
|
|
15731
15731
|
var PerMessageDeflate = require_permessage_deflate();
|
|
15732
15732
|
var subprotocol = require_subprotocol();
|
|
@@ -16027,7 +16027,7 @@ var require_websocket_server = __commonJS({
|
|
|
16027
16027
|
);
|
|
16028
16028
|
}
|
|
16029
16029
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
16030
|
-
const digest2 =
|
|
16030
|
+
const digest2 = createHash14("sha1").update(key2 + GUID).digest("base64");
|
|
16031
16031
|
const headers = [
|
|
16032
16032
|
"HTTP/1.1 101 Switching Protocols",
|
|
16033
16033
|
"Upgrade: websocket",
|
|
@@ -41799,7 +41799,7 @@ var init_sql = __esm({
|
|
|
41799
41799
|
return new SQL([new StringChunk(str4)]);
|
|
41800
41800
|
}
|
|
41801
41801
|
_sql.raw = raw;
|
|
41802
|
-
function
|
|
41802
|
+
function join59(chunks, separator) {
|
|
41803
41803
|
const result = [];
|
|
41804
41804
|
for (const [i, chunk] of chunks.entries()) {
|
|
41805
41805
|
if (i > 0 && separator !== void 0) result.push(separator);
|
|
@@ -41807,7 +41807,7 @@ var init_sql = __esm({
|
|
|
41807
41807
|
}
|
|
41808
41808
|
return new SQL(result);
|
|
41809
41809
|
}
|
|
41810
|
-
_sql.join =
|
|
41810
|
+
_sql.join = join59;
|
|
41811
41811
|
function identifier(value) {
|
|
41812
41812
|
return new Name(value);
|
|
41813
41813
|
}
|
|
@@ -43735,7 +43735,7 @@ var init_sql2 = __esm({
|
|
|
43735
43735
|
return new SQL3([new StringChunk2(str4)]);
|
|
43736
43736
|
}
|
|
43737
43737
|
_sql.raw = raw;
|
|
43738
|
-
function
|
|
43738
|
+
function join59(chunks, separator) {
|
|
43739
43739
|
const result = [];
|
|
43740
43740
|
for (const [i, chunk] of chunks.entries()) {
|
|
43741
43741
|
if (i > 0 && separator !== void 0) result.push(separator);
|
|
@@ -43743,7 +43743,7 @@ var init_sql2 = __esm({
|
|
|
43743
43743
|
}
|
|
43744
43744
|
return new SQL3(result);
|
|
43745
43745
|
}
|
|
43746
|
-
_sql.join =
|
|
43746
|
+
_sql.join = join59;
|
|
43747
43747
|
function identifier(value) {
|
|
43748
43748
|
return new Name2(value);
|
|
43749
43749
|
}
|
|
@@ -48936,7 +48936,7 @@ var init_select3 = __esm({
|
|
|
48936
48936
|
const baseTableName = this.tableName;
|
|
48937
48937
|
const tableName = getTableLikeName(table);
|
|
48938
48938
|
for (const item of extractUsedTable(table)) this.usedTables.add(item);
|
|
48939
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
48939
|
+
if (typeof tableName === "string" && this.config.joins?.some((join59) => join59.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
48940
48940
|
if (!this.isPartialSelect) {
|
|
48941
48941
|
if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
|
|
48942
48942
|
if (typeof tableName === "string" && !is2(table, SQL3)) {
|
|
@@ -50201,7 +50201,7 @@ var init_dialect = __esm({
|
|
|
50201
50201
|
if (!joins2) return;
|
|
50202
50202
|
const withEntries = Object.entries(joins2).filter(([_2, v2]) => v2);
|
|
50203
50203
|
if (!withEntries.length) return;
|
|
50204
|
-
return sql2.join(withEntries.map(([k2,
|
|
50204
|
+
return sql2.join(withEntries.map(([k2, join59]) => {
|
|
50205
50205
|
const relation = tableConfig.relations[k2];
|
|
50206
50206
|
const isSingle2 = is2(relation, One);
|
|
50207
50207
|
const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
|
|
@@ -50212,7 +50212,7 @@ var init_dialect = __esm({
|
|
|
50212
50212
|
table: targetTable,
|
|
50213
50213
|
mode: isSingle2 ? "first" : "many",
|
|
50214
50214
|
schema,
|
|
50215
|
-
queryConfig:
|
|
50215
|
+
queryConfig: join59,
|
|
50216
50216
|
tableConfig: schema[relation.targetTableName],
|
|
50217
50217
|
relationWhere: filter,
|
|
50218
50218
|
isNested: true,
|
|
@@ -50226,7 +50226,7 @@ var init_dialect = __esm({
|
|
|
50226
50226
|
key: k2,
|
|
50227
50227
|
selection: innerQuery.selection,
|
|
50228
50228
|
isArray: !isSingle2,
|
|
50229
|
-
isOptional: (relation.optional ?? false) ||
|
|
50229
|
+
isOptional: (relation.optional ?? false) || join59 !== true && !!join59.where
|
|
50230
50230
|
});
|
|
50231
50231
|
const jsonColumns = sql2.join(innerQuery.selection.map((s2) => {
|
|
50232
50232
|
return sql2`${sql2.raw(this.escapeString(s2.key))}, ${s2.selection ? sql2`${jsonb2}(${sql2.identifier(s2.key)})` : sql2.identifier(s2.key)}`;
|
|
@@ -50745,7 +50745,7 @@ var init_update = __esm({
|
|
|
50745
50745
|
createJoin(joinType) {
|
|
50746
50746
|
return ((table, on) => {
|
|
50747
50747
|
const tableName = getTableLikeName(table);
|
|
50748
|
-
if (typeof tableName === "string" && this.config.joins.some((
|
|
50748
|
+
if (typeof tableName === "string" && this.config.joins.some((join59) => join59.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
50749
50749
|
if (typeof on === "function") {
|
|
50750
50750
|
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;
|
|
50751
50751
|
on = on(new Proxy(this.config.table[Table2.Symbol.Columns], new SelectionProxyHandler({
|
|
@@ -69157,7 +69157,7 @@ var init_payload = __esm({
|
|
|
69157
69157
|
});
|
|
69158
69158
|
|
|
69159
69159
|
// ../../packages/link/src/relay.ts
|
|
69160
|
-
var METHOD_RELAY_REGISTER, METHOD_RELAY_REVOKE, METHOD_RELAY_HTTP, RELAY_MAX_BODY_BYTES,
|
|
69160
|
+
var METHOD_RELAY_REGISTER, METHOD_RELAY_REVOKE, METHOD_RELAY_HTTP, RELAY_MAX_BODY_BYTES, METHOD_LIFECYCLE_IDLE, METHOD_LIFECYCLE_POLICY, METHOD_LIFECYCLE_SLEEP, METHOD_LIFECYCLE_SHUTDOWN, METHOD_LIFECYCLE_EXPORT_SESSIONS, METHOD_LIFECYCLE_IMPORT_SESSIONS, METHOD_GIT_CREDENTIAL, METHOD_GH_TOKEN, METHOD_LEASE_RENEW, METHOD_WORKER_UPDATE;
|
|
69161
69161
|
var init_relay = __esm({
|
|
69162
69162
|
"../../packages/link/src/relay.ts"() {
|
|
69163
69163
|
"use strict";
|
|
@@ -69165,7 +69165,6 @@ var init_relay = __esm({
|
|
|
69165
69165
|
METHOD_RELAY_REVOKE = "relay.revoke";
|
|
69166
69166
|
METHOD_RELAY_HTTP = "relay.http";
|
|
69167
69167
|
RELAY_MAX_BODY_BYTES = 512 * 1024;
|
|
69168
|
-
METHOD_CLI_FETCH = "cli.fetch";
|
|
69169
69168
|
METHOD_LIFECYCLE_IDLE = "lifecycle.idle";
|
|
69170
69169
|
METHOD_LIFECYCLE_POLICY = "lifecycle.policy";
|
|
69171
69170
|
METHOD_LIFECYCLE_SLEEP = "lifecycle.sleep";
|
|
@@ -72246,8 +72245,8 @@ var init_environment_builds = __esm({
|
|
|
72246
72245
|
get(id) {
|
|
72247
72246
|
return getDb().select().from(environmentBuilds).where(eq2(environmentBuilds.id, id)).get();
|
|
72248
72247
|
}
|
|
72249
|
-
setLog(id,
|
|
72250
|
-
getDb().update(environmentBuilds).set({ log:
|
|
72248
|
+
setLog(id, log90) {
|
|
72249
|
+
getDb().update(environmentBuilds).set({ log: log90 }).where(eq2(environmentBuilds.id, id)).run();
|
|
72251
72250
|
}
|
|
72252
72251
|
finish(id, result) {
|
|
72253
72252
|
getDb().update(environmentBuilds).set({
|
|
@@ -72615,32 +72614,32 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72615
72614
|
}
|
|
72616
72615
|
// ---- running ---------------------------------------------------------------
|
|
72617
72616
|
async run(row, plan) {
|
|
72618
|
-
const
|
|
72617
|
+
const log90 = new BuildLog(row.id, (id, text4) => this.queries.setLog(id, text4));
|
|
72619
72618
|
let tmp = null;
|
|
72620
72619
|
const container = `band-env-${row.id.slice(0, 12)}`;
|
|
72621
72620
|
let failure4 = null;
|
|
72622
72621
|
try {
|
|
72623
|
-
|
|
72624
|
-
|
|
72622
|
+
log90.add(`Building ${plan.tag} for ${plan.repo} at ${plan.ref} (${plan.commit.slice(0, 12)})`);
|
|
72623
|
+
log90.flush();
|
|
72625
72624
|
tmp = await plan.host.fs.mkdtemp("band-env-");
|
|
72626
|
-
await this.exportCheckout(plan, tmp,
|
|
72627
|
-
const toolchain = await this.buildToolchain(plan, tmp,
|
|
72628
|
-
const layered = await this.addWorkerLayer(plan, tmp, toolchain,
|
|
72629
|
-
await this.install(plan, tmp, layered, container,
|
|
72630
|
-
if (plan.registry) await this.push(plan,
|
|
72631
|
-
|
|
72625
|
+
await this.exportCheckout(plan, tmp, log90);
|
|
72626
|
+
const toolchain = await this.buildToolchain(plan, tmp, log90);
|
|
72627
|
+
const layered = await this.addWorkerLayer(plan, tmp, toolchain, log90);
|
|
72628
|
+
await this.install(plan, tmp, layered, container, log90);
|
|
72629
|
+
if (plan.registry) await this.push(plan, log90);
|
|
72630
|
+
log90.add(`Done: ${plan.tag}`);
|
|
72632
72631
|
} catch (err) {
|
|
72633
72632
|
failure4 = err.message;
|
|
72634
|
-
|
|
72633
|
+
log90.add(`FAILED: ${failure4}`);
|
|
72635
72634
|
}
|
|
72636
|
-
await this.exec(plan.host, "docker", ["rm", "--force", container],
|
|
72635
|
+
await this.exec(plan.host, "docker", ["rm", "--force", container], log90, { quiet: true }).catch(
|
|
72637
72636
|
() => void 0
|
|
72638
72637
|
);
|
|
72639
72638
|
await this.exec(
|
|
72640
72639
|
plan.host,
|
|
72641
72640
|
"docker",
|
|
72642
72641
|
["rmi", toolchainTag(plan.repo, plan.key), layeredTag(plan.repo, plan.key)],
|
|
72643
|
-
|
|
72642
|
+
log90,
|
|
72644
72643
|
{ quiet: true }
|
|
72645
72644
|
).catch(() => void 0);
|
|
72646
72645
|
if (tmp) await plan.host.fs.rm(tmp, { recursive: true, force: true }).catch(() => void 0);
|
|
@@ -72649,14 +72648,14 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72649
72648
|
this.queries.finish(row.id, {
|
|
72650
72649
|
status: "ready",
|
|
72651
72650
|
image: plan.tag,
|
|
72652
|
-
log:
|
|
72651
|
+
log: log90.toString(),
|
|
72653
72652
|
at: Date.now()
|
|
72654
72653
|
});
|
|
72655
72654
|
} else {
|
|
72656
72655
|
this.queries.finish(row.id, {
|
|
72657
72656
|
status: "failed",
|
|
72658
72657
|
error: failure4.slice(0, 2e3),
|
|
72659
|
-
log:
|
|
72658
|
+
log: log90.toString(),
|
|
72660
72659
|
at: Date.now()
|
|
72661
72660
|
});
|
|
72662
72661
|
}
|
|
@@ -72665,9 +72664,9 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72665
72664
|
}
|
|
72666
72665
|
}
|
|
72667
72666
|
/** Runs a command on the builder host, adding it and its output to the log. */
|
|
72668
|
-
async exec(host, tool, args,
|
|
72667
|
+
async exec(host, tool, args, log90, options = {}) {
|
|
72669
72668
|
const bin = tool === "docker" ? this.dockerBin(host) : tool === "devcontainer" ? this.devcontainerBin(host) : "git";
|
|
72670
|
-
if (!options.quiet)
|
|
72669
|
+
if (!options.quiet) log90.add(`$ ${tool} ${args.join(" ")}`);
|
|
72671
72670
|
try {
|
|
72672
72671
|
const out = await host.exec(bin, args, {
|
|
72673
72672
|
cwd: options.cwd,
|
|
@@ -72675,35 +72674,35 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72675
72674
|
timeoutMs: envNumber("BAND_ENVIRONMENT_BUILD_TIMEOUT_MS", DEFAULT_STEP_TIMEOUT_MS)
|
|
72676
72675
|
});
|
|
72677
72676
|
if (!options.quiet) {
|
|
72678
|
-
if (out.stdout.trim())
|
|
72679
|
-
if (out.stderr.trim())
|
|
72680
|
-
|
|
72677
|
+
if (out.stdout.trim()) log90.add(out.stdout.trimEnd());
|
|
72678
|
+
if (out.stderr.trim()) log90.add(out.stderr.trimEnd());
|
|
72679
|
+
log90.flush();
|
|
72681
72680
|
}
|
|
72682
72681
|
return out.stdout;
|
|
72683
72682
|
} catch (err) {
|
|
72684
72683
|
if (!options.quiet) {
|
|
72685
|
-
|
|
72686
|
-
|
|
72684
|
+
log90.add(err.message);
|
|
72685
|
+
log90.flush();
|
|
72687
72686
|
}
|
|
72688
72687
|
throw new Error(`${tool} ${args[0] ?? ""} failed: ${firstLine(err.message)}`);
|
|
72689
72688
|
}
|
|
72690
72689
|
}
|
|
72691
72690
|
/** Writes the default branch's files, with no `.git`, to `<tmp>/src`. */
|
|
72692
|
-
async exportCheckout(plan, tmp,
|
|
72691
|
+
async exportCheckout(plan, tmp, log90) {
|
|
72693
72692
|
const src = posix4.join(tmp, "src");
|
|
72694
72693
|
await plan.host.fs.mkdir(src);
|
|
72695
72694
|
const index3 = posix4.join(tmp, "index");
|
|
72696
|
-
await this.exec(plan.host, "git", ["read-tree", plan.ref],
|
|
72695
|
+
await this.exec(plan.host, "git", ["read-tree", plan.ref], log90, {
|
|
72697
72696
|
cwd: plan.repoPath,
|
|
72698
72697
|
env: { GIT_INDEX_FILE: index3 }
|
|
72699
72698
|
});
|
|
72700
|
-
await this.exec(plan.host, "git", ["checkout-index", "--all", `--prefix=${src}/`],
|
|
72699
|
+
await this.exec(plan.host, "git", ["checkout-index", "--all", `--prefix=${src}/`], log90, {
|
|
72701
72700
|
cwd: plan.repoPath,
|
|
72702
72701
|
env: { GIT_INDEX_FILE: index3 }
|
|
72703
72702
|
});
|
|
72704
72703
|
}
|
|
72705
72704
|
/** Layer 2: returns the tag of an image holding the repo's toolchain. */
|
|
72706
|
-
async buildToolchain(plan, tmp,
|
|
72705
|
+
async buildToolchain(plan, tmp, log90) {
|
|
72707
72706
|
const build = plan.environment.build;
|
|
72708
72707
|
const src = posix4.join(tmp, "src");
|
|
72709
72708
|
const tag = toolchainTag(plan.repo, plan.key);
|
|
@@ -72712,7 +72711,7 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72712
72711
|
plan.host,
|
|
72713
72712
|
"docker",
|
|
72714
72713
|
dockerBuildArgs({ checkout: src, dockerfile: build.dockerfile, tag }),
|
|
72715
|
-
|
|
72714
|
+
log90
|
|
72716
72715
|
);
|
|
72717
72716
|
return tag;
|
|
72718
72717
|
}
|
|
@@ -72722,7 +72721,7 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72722
72721
|
plan.host,
|
|
72723
72722
|
"devcontainer",
|
|
72724
72723
|
devcontainerBuildArgs({ checkout: src, config: build.devcontainer, tag }),
|
|
72725
|
-
|
|
72724
|
+
log90
|
|
72726
72725
|
);
|
|
72727
72726
|
} catch (err) {
|
|
72728
72727
|
throw new Error(
|
|
@@ -72732,11 +72731,11 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72732
72731
|
return tag;
|
|
72733
72732
|
}
|
|
72734
72733
|
const image = build?.image;
|
|
72735
|
-
await this.exec(plan.host, "docker", ["pull", image],
|
|
72734
|
+
await this.exec(plan.host, "docker", ["pull", image], log90);
|
|
72736
72735
|
return image;
|
|
72737
72736
|
}
|
|
72738
72737
|
/** Layer 1 on top of layer 2: copies the worker from the worker base image. */
|
|
72739
|
-
async addWorkerLayer(plan, tmp, toolchain,
|
|
72738
|
+
async addWorkerLayer(plan, tmp, toolchain, log90) {
|
|
72740
72739
|
const dir = posix4.join(tmp, "layer");
|
|
72741
72740
|
await plan.host.fs.mkdir(dir);
|
|
72742
72741
|
await plan.host.fs.writeFile(
|
|
@@ -72748,38 +72747,38 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72748
72747
|
});
|
|
72749
72748
|
await plan.host.fs.mkdir(posix4.join(dir, "root", "work"), { recursive: true });
|
|
72750
72749
|
const tag = layeredTag(plan.repo, plan.key);
|
|
72751
|
-
await this.exec(plan.host, "docker", ["build", "--tag", tag, dir],
|
|
72750
|
+
await this.exec(plan.host, "docker", ["build", "--tag", tag, dir], log90);
|
|
72752
72751
|
return tag;
|
|
72753
72752
|
}
|
|
72754
72753
|
/** Runs `install` at the default branch inside the image and commits the result as the final tag. */
|
|
72755
|
-
async install(plan, tmp, layered, container,
|
|
72754
|
+
async install(plan, tmp, layered, container, log90) {
|
|
72756
72755
|
const install = plan.environment.install;
|
|
72757
72756
|
if (install === void 0) {
|
|
72758
|
-
await this.exec(plan.host, "docker", ["tag", layered, plan.tag],
|
|
72757
|
+
await this.exec(plan.host, "docker", ["tag", layered, plan.tag], log90);
|
|
72759
72758
|
return;
|
|
72760
72759
|
}
|
|
72761
72760
|
await this.exec(
|
|
72762
72761
|
plan.host,
|
|
72763
72762
|
"docker",
|
|
72764
72763
|
installCreateArgs({ name: container, image: layered, install }),
|
|
72765
|
-
|
|
72764
|
+
log90
|
|
72766
72765
|
);
|
|
72767
72766
|
await this.exec(
|
|
72768
72767
|
plan.host,
|
|
72769
72768
|
"docker",
|
|
72770
72769
|
["cp", `${posix4.join(tmp, "src")}/.`, `${container}:${IMAGE_WORKDIR}`],
|
|
72771
|
-
|
|
72770
|
+
log90
|
|
72772
72771
|
);
|
|
72773
|
-
await this.exec(plan.host, "docker", ["start", "--attach", container],
|
|
72772
|
+
await this.exec(plan.host, "docker", ["start", "--attach", container], log90);
|
|
72774
72773
|
await this.exec(
|
|
72775
72774
|
plan.host,
|
|
72776
72775
|
"docker",
|
|
72777
72776
|
commitArgs({ container, tag: plan.tag, key: plan.key, commit: plan.commit }),
|
|
72778
|
-
|
|
72777
|
+
log90
|
|
72779
72778
|
);
|
|
72780
72779
|
}
|
|
72781
|
-
async push(plan,
|
|
72782
|
-
await this.exec(plan.host, "docker", ["push", plan.tag],
|
|
72780
|
+
async push(plan, log90) {
|
|
72781
|
+
await this.exec(plan.host, "docker", ["push", plan.tag], log90);
|
|
72783
72782
|
}
|
|
72784
72783
|
// ---- auto trigger ----------------------------------------------------------
|
|
72785
72784
|
/**
|
|
@@ -88196,11 +88195,11 @@ var require_core = __commonJS({
|
|
|
88196
88195
|
Ajv2.ValidationError = validation_error_1.default;
|
|
88197
88196
|
Ajv2.MissingRefError = ref_error_1.default;
|
|
88198
88197
|
exports.default = Ajv2;
|
|
88199
|
-
function checkOptions(checkOpts, options, msg,
|
|
88198
|
+
function checkOptions(checkOpts, options, msg, log90 = "error") {
|
|
88200
88199
|
for (const key2 in checkOpts) {
|
|
88201
88200
|
const opt = key2;
|
|
88202
88201
|
if (opt in options)
|
|
88203
|
-
this.logger[
|
|
88202
|
+
this.logger[log90](`${msg}: option ${key2}. ${checkOpts[opt]}`);
|
|
88204
88203
|
}
|
|
88205
88204
|
}
|
|
88206
88205
|
function getSchEnv(keyRef) {
|
|
@@ -90693,7 +90692,7 @@ import {
|
|
|
90693
90692
|
statSync as statSync16
|
|
90694
90693
|
} from "node:fs";
|
|
90695
90694
|
import { createServer as createServer3 } from "node:http";
|
|
90696
|
-
import { basename as basename7, join as
|
|
90695
|
+
import { basename as basename7, join as join58, resolve as resolve14, sep as sep10 } from "node:path";
|
|
90697
90696
|
import { pipeline as pipeline2, Readable as Readable2 } from "node:stream";
|
|
90698
90697
|
import { parseArgs } from "node:util";
|
|
90699
90698
|
|
|
@@ -111704,7 +111703,7 @@ init_registry();
|
|
|
111704
111703
|
// package.json
|
|
111705
111704
|
var package_default = {
|
|
111706
111705
|
name: "@band-app/server",
|
|
111707
|
-
version: "0.54.
|
|
111706
|
+
version: "0.54.1",
|
|
111708
111707
|
type: "module",
|
|
111709
111708
|
types: "src/index.ts",
|
|
111710
111709
|
exports: {
|
|
@@ -111744,6 +111743,7 @@ var package_default = {
|
|
|
111744
111743
|
"@agentclientprotocol/claude-agent-acp": "0.81.2",
|
|
111745
111744
|
"@agentclientprotocol/codex-acp": "1.13.1",
|
|
111746
111745
|
"@agentclientprotocol/sdk": "1.5.0",
|
|
111746
|
+
"@anthropic-ai/sdk": "1.1.0",
|
|
111747
111747
|
"@vscode/ripgrep": "^1.18.0",
|
|
111748
111748
|
"node-pty": "^1.1.0",
|
|
111749
111749
|
prettier: "^3.8.3",
|
|
@@ -112721,84 +112721,6 @@ init_git_credential_service();
|
|
|
112721
112721
|
init_placement_service();
|
|
112722
112722
|
init_token_service();
|
|
112723
112723
|
init_watcher_service();
|
|
112724
|
-
|
|
112725
|
-
// src/server/services/worker-cli-service.ts
|
|
112726
|
-
init_cli_binary();
|
|
112727
|
-
init_src7();
|
|
112728
|
-
init_src();
|
|
112729
|
-
import { createHash as createHash12 } from "node:crypto";
|
|
112730
|
-
import { readFile as readFile12 } from "node:fs/promises";
|
|
112731
|
-
import { join as join52 } from "node:path";
|
|
112732
|
-
var log65 = createLogger("worker-cli");
|
|
112733
|
-
var RPC_INVALID_PARAMS2 = -32602;
|
|
112734
|
-
var PLATFORM_NAME = /^[a-z0-9_]{1,16}$/;
|
|
112735
|
-
function candidatesFor(platform3, arch) {
|
|
112736
|
-
const out = [];
|
|
112737
|
-
const dir = process.env.BAND_CLI_BINARIES_DIR;
|
|
112738
|
-
if (dir) out.push(join52(dir, `band-${platform3}-${arch}${platform3 === "win32" ? ".exe" : ""}`));
|
|
112739
|
-
if (platform3 === process.platform && arch === process.arch) {
|
|
112740
|
-
const own2 = findCliBinary();
|
|
112741
|
-
if (own2) out.push(own2);
|
|
112742
|
-
}
|
|
112743
|
-
return out;
|
|
112744
|
-
}
|
|
112745
|
-
async function readFirst(paths) {
|
|
112746
|
-
for (const path2 of paths) {
|
|
112747
|
-
const data = await readFile12(path2).catch(() => null);
|
|
112748
|
-
if (data) return data;
|
|
112749
|
-
}
|
|
112750
|
-
return null;
|
|
112751
|
-
}
|
|
112752
|
-
var WorkerCliService = class {
|
|
112753
|
-
/** Answers `cli.fetch` on a worker's session. */
|
|
112754
|
-
attach(session) {
|
|
112755
|
-
session.handle(METHOD_CLI_FETCH, (params) => this.handle(session, params));
|
|
112756
|
-
}
|
|
112757
|
-
async handle(session, params) {
|
|
112758
|
-
const { platform: platform3, arch, have } = parseParams3(params);
|
|
112759
|
-
const data = await readFirst(candidatesFor(platform3, arch));
|
|
112760
|
-
if (!data) {
|
|
112761
|
-
return {
|
|
112762
|
-
available: false,
|
|
112763
|
-
reason: `the hub has no band CLI for ${platform3}-${arch}`
|
|
112764
|
-
};
|
|
112765
|
-
}
|
|
112766
|
-
const sha2563 = createHash12("sha256").update(data).digest("hex");
|
|
112767
|
-
if (have === sha2563) return { available: true, sha256: sha2563, size: data.length };
|
|
112768
|
-
log65.info(
|
|
112769
|
-
`sending the band CLI (${platform3}-${arch}, ${data.length} bytes) to ${session.workerId}`
|
|
112770
|
-
);
|
|
112771
|
-
const ch = session.openChannel("cli.body", { platform: platform3, arch });
|
|
112772
|
-
void (async () => {
|
|
112773
|
-
try {
|
|
112774
|
-
await ch.send(data);
|
|
112775
|
-
ch.end();
|
|
112776
|
-
const drained = setTimeout(() => ch.reset("the worker did not close the channel"), 3e4);
|
|
112777
|
-
drained.unref?.();
|
|
112778
|
-
await ch.readAll().finally(() => clearTimeout(drained));
|
|
112779
|
-
} catch (err) {
|
|
112780
|
-
ch.reset(err instanceof Error ? err.message : "cli transfer failed");
|
|
112781
|
-
}
|
|
112782
|
-
})();
|
|
112783
|
-
return { available: true, sha256: sha2563, size: data.length, chan: ch.id };
|
|
112784
|
-
}
|
|
112785
|
-
};
|
|
112786
|
-
function parseParams3(params) {
|
|
112787
|
-
const p2 = params ?? {};
|
|
112788
|
-
if (typeof p2.platform !== "string" || !PLATFORM_NAME.test(p2.platform)) {
|
|
112789
|
-
throw new RpcError(RPC_INVALID_PARAMS2, "platform must be a short lowercase name");
|
|
112790
|
-
}
|
|
112791
|
-
if (typeof p2.arch !== "string" || !PLATFORM_NAME.test(p2.arch)) {
|
|
112792
|
-
throw new RpcError(RPC_INVALID_PARAMS2, "arch must be a short lowercase name");
|
|
112793
|
-
}
|
|
112794
|
-
if (p2.have !== void 0 && typeof p2.have !== "string") {
|
|
112795
|
-
throw new RpcError(RPC_INVALID_PARAMS2, "have must be a string");
|
|
112796
|
-
}
|
|
112797
|
-
return { platform: p2.platform, arch: p2.arch, have: p2.have };
|
|
112798
|
-
}
|
|
112799
|
-
var workerCliService = new WorkerCliService();
|
|
112800
|
-
|
|
112801
|
-
// src/server/services/worker-link-service.ts
|
|
112802
112724
|
init_worker_lease_service();
|
|
112803
112725
|
|
|
112804
112726
|
// src/server/services/worker-relay-service.ts
|
|
@@ -112858,7 +112780,7 @@ function repoHostRefusal(repo, callerHostId) {
|
|
|
112858
112780
|
init_state();
|
|
112859
112781
|
init_subscription_service();
|
|
112860
112782
|
init_terminal_service();
|
|
112861
|
-
var
|
|
112783
|
+
var log65 = createLogger("worker-relay");
|
|
112862
112784
|
var REPLY_HEADERS = ["content-type", "cache-control", "mcp-session-id"];
|
|
112863
112785
|
var FORWARDED_HEADERS = [
|
|
112864
112786
|
"content-type",
|
|
@@ -112867,7 +112789,7 @@ var FORWARDED_HEADERS = [
|
|
|
112867
112789
|
"mcp-session-id",
|
|
112868
112790
|
"last-event-id"
|
|
112869
112791
|
];
|
|
112870
|
-
var
|
|
112792
|
+
var RPC_INVALID_PARAMS2 = -32602;
|
|
112871
112793
|
var defaultLookups = {
|
|
112872
112794
|
hostOfWorktree: (id) => hostRegistry.hostIdOfScope(id),
|
|
112873
112795
|
worktreeOfChat: (id) => {
|
|
@@ -112899,7 +112821,7 @@ var WorkerRelayService = class {
|
|
|
112899
112821
|
let request = parseRequest(params);
|
|
112900
112822
|
const verdict = checkRelayRequest(request, session.workerId, this.lookups);
|
|
112901
112823
|
if (!verdict.ok) {
|
|
112902
|
-
|
|
112824
|
+
log65.warn(
|
|
112903
112825
|
`refused ${request.method} ${request.path.split("?")[0]} from ${session.workerId}: ${verdict.reason}`
|
|
112904
112826
|
);
|
|
112905
112827
|
return this.answer(session, verdict.status, refusalBody(request, verdict));
|
|
@@ -112912,7 +112834,7 @@ var WorkerRelayService = class {
|
|
|
112912
112834
|
chatId: request.scope.chatId,
|
|
112913
112835
|
...entry
|
|
112914
112836
|
});
|
|
112915
|
-
|
|
112837
|
+
log65.info(
|
|
112916
112838
|
`admin host ${session.workerId} called ${entry.procedure}${entry.targetHostId ? ` on ${entry.targetHostId}` : ""}`
|
|
112917
112839
|
);
|
|
112918
112840
|
}
|
|
@@ -112945,7 +112867,7 @@ var WorkerRelayService = class {
|
|
|
112945
112867
|
redirect: "manual"
|
|
112946
112868
|
});
|
|
112947
112869
|
} catch (err) {
|
|
112948
|
-
|
|
112870
|
+
log65.warn(`relay call failed: ${err instanceof Error ? err.message : err}`);
|
|
112949
112871
|
return this.answer(session, 502, { error: "The hub could not answer" });
|
|
112950
112872
|
}
|
|
112951
112873
|
const replyHeaders = {};
|
|
@@ -112962,7 +112884,7 @@ var WorkerRelayService = class {
|
|
|
112962
112884
|
try {
|
|
112963
112885
|
return this.answer(session, upstream.status, redactSettingsReply(await upstream.json()));
|
|
112964
112886
|
} catch (err) {
|
|
112965
|
-
|
|
112887
|
+
log65.warn(`relay call failed: ${err instanceof Error ? err.message : err}`);
|
|
112966
112888
|
return this.answer(session, 502, { error: "The hub could not answer" });
|
|
112967
112889
|
}
|
|
112968
112890
|
}
|
|
@@ -112971,7 +112893,7 @@ var WorkerRelayService = class {
|
|
|
112971
112893
|
const filtered = filterReposReply(await upstream.json(), session.workerId);
|
|
112972
112894
|
return this.answer(session, upstream.status, filtered);
|
|
112973
112895
|
} catch (err) {
|
|
112974
|
-
|
|
112896
|
+
log65.warn(`relay call failed: ${err instanceof Error ? err.message : err}`);
|
|
112975
112897
|
return this.answer(session, 502, { error: "The hub could not answer" });
|
|
112976
112898
|
}
|
|
112977
112899
|
}
|
|
@@ -112979,7 +112901,7 @@ var WorkerRelayService = class {
|
|
|
112979
112901
|
try {
|
|
112980
112902
|
return this.answer(session, upstream.status, redactHostsReply(await upstream.json()));
|
|
112981
112903
|
} catch (err) {
|
|
112982
|
-
|
|
112904
|
+
log65.warn(`relay call failed: ${err instanceof Error ? err.message : err}`);
|
|
112983
112905
|
return this.answer(session, 502, { error: "The hub could not answer" });
|
|
112984
112906
|
}
|
|
112985
112907
|
}
|
|
@@ -113024,7 +112946,7 @@ function parseRequest(params) {
|
|
|
113024
112946
|
const p2 = params;
|
|
113025
112947
|
const scope3 = p2?.scope;
|
|
113026
112948
|
if (!p2 || typeof p2.method !== "string" || typeof p2.path !== "string" || typeof scope3?.worktreeId !== "string" || scope3.chatId !== void 0 && typeof scope3.chatId !== "string" || scope3.terminalId !== void 0 && typeof scope3.terminalId !== "string" || !/^\/(?![/\\])/.test(p2.path) || !["GET", "POST", "DELETE", "OPTIONS", "HEAD"].includes(p2.method) || typeof p2.headers !== "object" || p2.headers === null || Object.values(p2.headers).some((v2) => typeof v2 !== "string") || p2.body !== void 0 && typeof p2.body !== "string") {
|
|
113027
|
-
throw new RpcError(
|
|
112949
|
+
throw new RpcError(RPC_INVALID_PARAMS2, "bad relay.http params");
|
|
113028
112950
|
}
|
|
113029
112951
|
return p2;
|
|
113030
112952
|
}
|
|
@@ -113032,7 +112954,7 @@ var workerRelayService = new WorkerRelayService();
|
|
|
113032
112954
|
|
|
113033
112955
|
// src/server/services/worker-link-service.ts
|
|
113034
112956
|
init_worktree_service();
|
|
113035
|
-
var
|
|
112957
|
+
var log66 = createLogger("worker-link");
|
|
113036
112958
|
var repoQueries5 = new RepoQueries();
|
|
113037
112959
|
var LOCAL_HOST_ID12 = "local";
|
|
113038
112960
|
var CAPABILITY_REFRESH_MS = 3 * 6e4;
|
|
@@ -113063,7 +112985,7 @@ var WorkerLinkService = class {
|
|
|
113063
112985
|
this.server.on("disconnected", (session) => {
|
|
113064
112986
|
const close = session.lastClose;
|
|
113065
112987
|
if (close) {
|
|
113066
|
-
|
|
112988
|
+
log66.info(
|
|
113067
112989
|
`link of ${session.workerId} closed (code ${close.code}${close.reason ? `, ${close.reason}` : ""})`
|
|
113068
112990
|
);
|
|
113069
112991
|
}
|
|
@@ -113071,7 +112993,7 @@ var WorkerLinkService = class {
|
|
|
113071
112993
|
});
|
|
113072
112994
|
this.server.on(
|
|
113073
112995
|
"fault",
|
|
113074
|
-
(session, reason) =>
|
|
112996
|
+
(session, reason) => log66.warn(`link of ${session.workerId}: ${reason}`)
|
|
113075
112997
|
);
|
|
113076
112998
|
this.server.on(
|
|
113077
112999
|
"lost",
|
|
@@ -113096,12 +113018,12 @@ var WorkerLinkService = class {
|
|
|
113096
113018
|
const problem2 = compatibilityProblem(version3, HUB_VERSION);
|
|
113097
113019
|
if (!problem2) return auth2;
|
|
113098
113020
|
if (HUB_VERSION_UNRELEASED) {
|
|
113099
|
-
|
|
113021
|
+
log66.info(
|
|
113100
113022
|
`worker ${hello.workerId} runs ${version3}, which would be refused by a released hub, but this hub runs from source (${HUB_VERSION}), so version checks are skipped`
|
|
113101
113023
|
);
|
|
113102
113024
|
return auth2;
|
|
113103
113025
|
}
|
|
113104
|
-
|
|
113026
|
+
log66.warn(`worker ${hello.workerId} refused: ${problem2}`);
|
|
113105
113027
|
if (this.server.getSession(hello.workerId)?.attached) {
|
|
113106
113028
|
return { ok: false, reason: problem2, code: VERSION_REFUSED_CODE };
|
|
113107
113029
|
}
|
|
@@ -113112,7 +113034,7 @@ var WorkerLinkService = class {
|
|
|
113112
113034
|
try {
|
|
113113
113035
|
this.queries.setHostRefusal(hello.workerId, { version: version3, reason: problem2 });
|
|
113114
113036
|
} catch (err) {
|
|
113115
|
-
|
|
113037
|
+
log66.warn(`could not record the refusal: ${err instanceof Error ? err.message : err}`);
|
|
113116
113038
|
}
|
|
113117
113039
|
this.publish(hello.workerId, "offline");
|
|
113118
113040
|
return { ok: false, reason: problem2, code: VERSION_REFUSED_CODE };
|
|
@@ -113135,7 +113057,7 @@ var WorkerLinkService = class {
|
|
|
113135
113057
|
this.refreshTimer.unref();
|
|
113136
113058
|
this.unsubscribeRevoke = this.tokens.onRevoked((row) => {
|
|
113137
113059
|
if (row.kind === "worker_session" && row.hostId) {
|
|
113138
|
-
if (this.server.drop(row.hostId, "token revoked"))
|
|
113060
|
+
if (this.server.drop(row.hostId, "token revoked")) log66.info(`cut link of ${row.hostId}`);
|
|
113139
113061
|
}
|
|
113140
113062
|
});
|
|
113141
113063
|
}
|
|
@@ -113165,7 +113087,7 @@ var WorkerLinkService = class {
|
|
|
113165
113087
|
this.queries.setHostInfo(row.id, stored);
|
|
113166
113088
|
if (changed) this.publish(row.id, "online");
|
|
113167
113089
|
} catch (err) {
|
|
113168
|
-
|
|
113090
|
+
log66.debug(
|
|
113169
113091
|
`could not refresh the report of ${row.id}: ${err instanceof Error ? err.message : err}`
|
|
113170
113092
|
);
|
|
113171
113093
|
}
|
|
@@ -113195,7 +113117,6 @@ var WorkerLinkService = class {
|
|
|
113195
113117
|
onSession(session) {
|
|
113196
113118
|
this.remoteHost(session.workerId).attachSession(session);
|
|
113197
113119
|
workerRelayService.attach(session);
|
|
113198
|
-
workerCliService.attach(session);
|
|
113199
113120
|
gitCredentialService.attach(session);
|
|
113200
113121
|
ephemeralLifecycleService.attach(session);
|
|
113201
113122
|
checkpointService.attach(session);
|
|
@@ -113209,7 +113130,7 @@ var WorkerLinkService = class {
|
|
|
113209
113130
|
try {
|
|
113210
113131
|
info = await this.remoteHost(workerId).info();
|
|
113211
113132
|
} catch (err) {
|
|
113212
|
-
|
|
113133
|
+
log66.warn(
|
|
113213
113134
|
`could not read host info from ${workerId}: ${err instanceof Error ? err.message : err}`
|
|
113214
113135
|
);
|
|
113215
113136
|
}
|
|
@@ -113229,37 +113150,37 @@ var WorkerLinkService = class {
|
|
|
113229
113150
|
const version3 = workerVersionOf(hello);
|
|
113230
113151
|
this.queries.markHostOnline(workerId, at, { info: stored, version: version3 ?? hello.buildId });
|
|
113231
113152
|
workerUpdateService.onConnected(workerId, version3);
|
|
113232
|
-
|
|
113153
|
+
log66.info(`worker ${workerId} is online`);
|
|
113233
113154
|
workerLeaseService.onConnected(session);
|
|
113234
113155
|
try {
|
|
113235
113156
|
seedCodingAgentsFromTypes(hello.agents);
|
|
113236
113157
|
} catch (err) {
|
|
113237
|
-
|
|
113158
|
+
log66.warn(`could not seed coding agents: ${err instanceof Error ? err.message : err}`);
|
|
113238
113159
|
}
|
|
113239
113160
|
this.publish(workerId, "online");
|
|
113240
113161
|
void repoService.backfillRemotesFromWorker(workerId).catch((err) => {
|
|
113241
|
-
|
|
113162
|
+
log66.warn(`remote backfill on ${workerId}: ${err instanceof Error ? err.message : err}`);
|
|
113242
113163
|
});
|
|
113243
113164
|
chatOwnershipService.onConnected(session);
|
|
113244
113165
|
void ephemeralLifecycleService.onConnected(session);
|
|
113245
113166
|
void followService.onHostReturned(workerId).catch((err) => {
|
|
113246
|
-
|
|
113167
|
+
log66.warn(`follow check on ${workerId}: ${err instanceof Error ? err.message : err}`);
|
|
113247
113168
|
});
|
|
113248
113169
|
placementService.onHostOnline(workerId);
|
|
113249
113170
|
void worktreeService.finishPendingRemovals(workerId).catch((err) => {
|
|
113250
|
-
|
|
113171
|
+
log66.warn(`pending removals on ${workerId}: ${err instanceof Error ? err.message : err}`);
|
|
113251
113172
|
});
|
|
113252
113173
|
}
|
|
113253
113174
|
setStatus(workerId, status, lastSeenAt) {
|
|
113254
113175
|
try {
|
|
113255
113176
|
this.queries.setHostStatus(workerId, status, lastSeenAt);
|
|
113256
113177
|
} catch (err) {
|
|
113257
|
-
|
|
113178
|
+
log66.warn(
|
|
113258
113179
|
`could not record ${workerId} as ${status}: ${err instanceof Error ? err.message : err}`
|
|
113259
113180
|
);
|
|
113260
113181
|
return;
|
|
113261
113182
|
}
|
|
113262
|
-
|
|
113183
|
+
log66.info(`worker ${workerId} is ${status}`);
|
|
113263
113184
|
this.publish(workerId, status);
|
|
113264
113185
|
}
|
|
113265
113186
|
publish(hostId2, hostStatus) {
|
|
@@ -113304,7 +113225,7 @@ var WorkerLinkService = class {
|
|
|
113304
113225
|
send3(200, out);
|
|
113305
113226
|
} catch (err) {
|
|
113306
113227
|
if (!(err instanceof TokenExchangeError)) throw err;
|
|
113307
|
-
|
|
113228
|
+
log66.warn(`bootstrap exchange refused: ${err.reason}`);
|
|
113308
113229
|
send3(401, { error: "invalid or expired token" });
|
|
113309
113230
|
}
|
|
113310
113231
|
}
|
|
@@ -113321,7 +113242,7 @@ function reportKey(report2) {
|
|
|
113321
113242
|
|
|
113322
113243
|
// src/server/services/worker-update-service.ts
|
|
113323
113244
|
init_worktree_service();
|
|
113324
|
-
var
|
|
113245
|
+
var log67 = createLogger("worker-update");
|
|
113325
113246
|
var INSTALL_TIMEOUT_MS = 11 * 6e4;
|
|
113326
113247
|
var RESTART_TIMEOUT_MS = 3 * 6e4;
|
|
113327
113248
|
var WorkerUpdateError = class extends Error {
|
|
@@ -113367,7 +113288,7 @@ var WorkerUpdateService = class {
|
|
|
113367
113288
|
throw new WorkerUpdateError("not-updatable", "The worker is not connected");
|
|
113368
113289
|
const target = view4.updateTarget;
|
|
113369
113290
|
this.set(hostId2, { target, state: "installing", error: null }, row.status);
|
|
113370
|
-
|
|
113291
|
+
log67.info(`updating worker ${hostId2} to ${target}`);
|
|
113371
113292
|
void this.run(hostId2, target, session, row.status);
|
|
113372
113293
|
return { target };
|
|
113373
113294
|
}
|
|
@@ -113381,7 +113302,7 @@ var WorkerUpdateService = class {
|
|
|
113381
113302
|
} catch (err) {
|
|
113382
113303
|
const message = this.describe(err, target);
|
|
113383
113304
|
this.set(hostId2, { target, state: "failed", error: message }, hostStatus);
|
|
113384
|
-
|
|
113305
|
+
log67.warn(`update of worker ${hostId2} failed: ${message}`);
|
|
113385
113306
|
return;
|
|
113386
113307
|
}
|
|
113387
113308
|
if (this.updates.get(hostId2)?.state !== "installing") return;
|
|
@@ -113418,7 +113339,7 @@ var WorkerUpdateService = class {
|
|
|
113418
113339
|
this.timers.delete(hostId2);
|
|
113419
113340
|
if (version3 === current3.target) {
|
|
113420
113341
|
this.updates.delete(hostId2);
|
|
113421
|
-
|
|
113342
|
+
log67.info(`worker ${hostId2} now runs ${version3}`);
|
|
113422
113343
|
} else {
|
|
113423
113344
|
this.set(
|
|
113424
113345
|
hostId2,
|
|
@@ -116243,9 +116164,9 @@ init_zod();
|
|
|
116243
116164
|
// src/server/services/provisioning-service.ts
|
|
116244
116165
|
init_src();
|
|
116245
116166
|
init_dist();
|
|
116246
|
-
import { createHash as
|
|
116167
|
+
import { createHash as createHash12, randomBytes as randomBytes16, randomUUID as randomUUID18 } from "node:crypto";
|
|
116247
116168
|
import { createReadStream as createReadStream4, existsSync as existsSync17, mkdirSync as mkdirSync10, rmSync as rmSync7, statSync as statSync14 } from "node:fs";
|
|
116248
|
-
import { join as
|
|
116169
|
+
import { join as join52 } from "node:path";
|
|
116249
116170
|
|
|
116250
116171
|
// src/server/infra/db/queries/provisions.ts
|
|
116251
116172
|
init_drizzle_orm2();
|
|
@@ -116272,11 +116193,11 @@ var ProvisionQueries = class {
|
|
|
116272
116193
|
const result = this.db().update(hostProvisions).set({ spentAt: at, hostId: hostId2, runHash, state: "running", updatedAt: at }).where(and2(eq2(hostProvisions.id, id), isNull2(hostProvisions.spentAt))).run();
|
|
116273
116194
|
return Number(result.changes ?? 0) > 0;
|
|
116274
116195
|
}
|
|
116275
|
-
setLog(id,
|
|
116276
|
-
this.db().update(hostProvisions).set({ log:
|
|
116196
|
+
setLog(id, log90, at) {
|
|
116197
|
+
this.db().update(hostProvisions).set({ log: log90, updatedAt: at }).where(eq2(hostProvisions.id, id)).run();
|
|
116277
116198
|
}
|
|
116278
|
-
finish(id, state2, exitCode,
|
|
116279
|
-
this.db().update(hostProvisions).set({ state: state2, exitCode, log:
|
|
116199
|
+
finish(id, state2, exitCode, log90, at) {
|
|
116200
|
+
this.db().update(hostProvisions).set({ state: state2, exitCode, log: log90, updatedAt: at }).where(eq2(hostProvisions.id, id)).run();
|
|
116280
116201
|
}
|
|
116281
116202
|
/** Ids of rows created before `at`, so their bundle files can be deleted. */
|
|
116282
116203
|
idsCreatedBefore(at) {
|
|
@@ -116528,7 +116449,7 @@ function renderProvisionScript(opts) {
|
|
|
116528
116449
|
init_settings_service();
|
|
116529
116450
|
init_token_service();
|
|
116530
116451
|
init_vault_service();
|
|
116531
|
-
var
|
|
116452
|
+
var log68 = createLogger("provisioning");
|
|
116532
116453
|
var DEFAULT_PROVISION_TTL_MS = 60 * 60 * 1e3;
|
|
116533
116454
|
var DEFAULT_START_COMMAND = "band/provision.sh";
|
|
116534
116455
|
var MAX_LOG_BYTES2 = 256 * 1024;
|
|
@@ -116560,7 +116481,7 @@ var ProvisionAuthError = class extends Error {
|
|
|
116560
116481
|
}
|
|
116561
116482
|
};
|
|
116562
116483
|
function sha2562(text4) {
|
|
116563
|
-
return
|
|
116484
|
+
return createHash12("sha256").update(text4).digest("hex");
|
|
116564
116485
|
}
|
|
116565
116486
|
function newSecret(prefix) {
|
|
116566
116487
|
return `${prefix}${randomBytes16(32).toString("base64url")}`;
|
|
@@ -116603,7 +116524,7 @@ var ProvisioningService = class {
|
|
|
116603
116524
|
return Date.now();
|
|
116604
116525
|
}
|
|
116605
116526
|
dir(id) {
|
|
116606
|
-
return
|
|
116527
|
+
return join52(bandHome(), "provisioning", id);
|
|
116607
116528
|
}
|
|
116608
116529
|
settings() {
|
|
116609
116530
|
const s2 = settingsService.get().provisioning ?? {};
|
|
@@ -116658,7 +116579,7 @@ var ProvisioningService = class {
|
|
|
116658
116579
|
spentAt: null,
|
|
116659
116580
|
updatedAt: at
|
|
116660
116581
|
});
|
|
116661
|
-
|
|
116582
|
+
log68.info(
|
|
116662
116583
|
`created provisioning command ${id}${commitSha ? ` at ${commitSha.slice(0, 12)}` : ""}`
|
|
116663
116584
|
);
|
|
116664
116585
|
const command2 = `curl -fsSL ${hubUrl}/api/provision/${code}/script | sh`;
|
|
@@ -116698,7 +116619,7 @@ var ProvisioningService = class {
|
|
|
116698
116619
|
tokenService.removeHost(boot.hostId);
|
|
116699
116620
|
throw new ProvisionExchangeError("used");
|
|
116700
116621
|
}
|
|
116701
|
-
|
|
116622
|
+
log68.info(`exchanged provisioning code ${row.id} for host ${boot.hostId}`);
|
|
116702
116623
|
const lines = [
|
|
116703
116624
|
`token=${boot.token}`,
|
|
116704
116625
|
`workerId=${boot.hostId}`,
|
|
@@ -116723,7 +116644,7 @@ var ProvisioningService = class {
|
|
|
116723
116644
|
/** The bundle file and size for a code, once its run token is shown. */
|
|
116724
116645
|
bundle(code, runToken) {
|
|
116725
116646
|
const row = this.authorize(code, runToken);
|
|
116726
|
-
const file3 =
|
|
116647
|
+
const file3 = join52(this.dir(row.id), "bundle.tgz");
|
|
116727
116648
|
if (!row.repoUrl || !existsSync17(file3)) throw new ProvisionAuthError();
|
|
116728
116649
|
return { stream: createReadStream4(file3), size: statSync14(file3).size };
|
|
116729
116650
|
}
|
|
@@ -116740,7 +116661,7 @@ var ProvisioningService = class {
|
|
|
116740
116661
|
return;
|
|
116741
116662
|
}
|
|
116742
116663
|
this.queries.finish(row.id, exit === 0 ? "done" : "failed", exit, next, at);
|
|
116743
|
-
if (exit !== 0)
|
|
116664
|
+
if (exit !== 0) log68.info(`provisioning ${row.id} failed with exit code ${exit}`);
|
|
116744
116665
|
}
|
|
116745
116666
|
status(id) {
|
|
116746
116667
|
const row = this.queries.findById(id);
|
|
@@ -116765,7 +116686,7 @@ band provision: the worker did not say hello within ${minutes} min. Marked faile
|
|
|
116765
116686
|
`;
|
|
116766
116687
|
const exitCode = row.exitCode ?? TIMEOUT_EXIT_CODE;
|
|
116767
116688
|
this.queries.finish(row.id, "failed", exitCode, row.log + note, at);
|
|
116768
|
-
|
|
116689
|
+
log68.info(`provisioning ${row.id} timed out waiting for host ${row.hostId}`);
|
|
116769
116690
|
return { ...row, state: "failed", exitCode, log: row.log + note };
|
|
116770
116691
|
}
|
|
116771
116692
|
view(spent) {
|
|
@@ -116802,7 +116723,7 @@ band provision: the worker did not say hello within ${minutes} min. Marked faile
|
|
|
116802
116723
|
async buildBundle(id, settings3) {
|
|
116803
116724
|
const dir = this.dir(id);
|
|
116804
116725
|
mkdirSync10(dir, { recursive: true });
|
|
116805
|
-
const src =
|
|
116726
|
+
const src = join52(dir, "src");
|
|
116806
116727
|
const host = hostRegistry.local;
|
|
116807
116728
|
const env = { GIT_TERMINAL_PROMPT: "0" };
|
|
116808
116729
|
const key2 = parseRemoteUrl2(settings3.repoUrl);
|
|
@@ -116824,10 +116745,10 @@ band provision: the worker did not say hello within ${minutes} min. Marked faile
|
|
|
116824
116745
|
await host.exec("git", args, { env, timeoutMs: 12e4 });
|
|
116825
116746
|
const sha = (await host.exec("git", ["-C", src, "rev-parse", "HEAD"], { env })).stdout.trim();
|
|
116826
116747
|
const command2 = settings3.command || DEFAULT_START_COMMAND;
|
|
116827
|
-
if (!existsSync17(
|
|
116748
|
+
if (!existsSync17(join52(src, command2))) {
|
|
116828
116749
|
throw new Error(`the repo at ${sha.slice(0, 12)} has no ${command2}`);
|
|
116829
116750
|
}
|
|
116830
|
-
await host.exec("tar", ["-czf",
|
|
116751
|
+
await host.exec("tar", ["-czf", join52(dir, "bundle.tgz"), "--exclude=.git", "-C", src, "."], {
|
|
116831
116752
|
timeoutMs: 12e4
|
|
116832
116753
|
});
|
|
116833
116754
|
rmSync7(src, { recursive: true, force: true });
|
|
@@ -116920,12 +116841,12 @@ init_zod();
|
|
|
116920
116841
|
init_registry();
|
|
116921
116842
|
init_queued_message_store();
|
|
116922
116843
|
import { realpathSync as realpathSync6 } from "node:fs";
|
|
116923
|
-
import { join as
|
|
116844
|
+
import { join as join53, resolve as resolve11, sep as sep7 } from "node:path";
|
|
116924
116845
|
init_chat_ownership_service();
|
|
116925
116846
|
init_chat_service();
|
|
116926
116847
|
init_state();
|
|
116927
116848
|
init_task_service();
|
|
116928
|
-
var
|
|
116849
|
+
var log69 = createLogger("trpc.queue");
|
|
116929
116850
|
var queuedFileSchema = external_exports2.object({
|
|
116930
116851
|
mediaType: external_exports2.string(),
|
|
116931
116852
|
url: external_exports2.string(),
|
|
@@ -116933,7 +116854,7 @@ var queuedFileSchema = external_exports2.object({
|
|
|
116933
116854
|
filename: external_exports2.string().optional()
|
|
116934
116855
|
});
|
|
116935
116856
|
function isPathWithinUploadDir(p2) {
|
|
116936
|
-
const uploadDir =
|
|
116857
|
+
const uploadDir = join53(bandHome(), "uploads");
|
|
116937
116858
|
const normalized2 = resolve11(p2);
|
|
116938
116859
|
if (normalized2 !== uploadDir && !normalized2.startsWith(uploadDir + sep7)) {
|
|
116939
116860
|
return false;
|
|
@@ -116958,7 +116879,7 @@ async function resolveQueuedFiles(chatId, worktreeId4, files) {
|
|
|
116958
116879
|
if (derivedPath) {
|
|
116959
116880
|
const inside = remote ? await isWithinUploads(worktreeId4, derivedPath) : isPathWithinUploadDir(derivedPath);
|
|
116960
116881
|
if (!inside) {
|
|
116961
|
-
|
|
116882
|
+
log69.warn(
|
|
116962
116883
|
{ chatId, path: derivedPath, filename: file3.filename },
|
|
116963
116884
|
"queue: dropping file with path outside uploads directory"
|
|
116964
116885
|
);
|
|
@@ -116983,7 +116904,7 @@ async function resolveQueuedFiles(chatId, worktreeId4, files) {
|
|
|
116983
116904
|
});
|
|
116984
116905
|
continue;
|
|
116985
116906
|
}
|
|
116986
|
-
|
|
116907
|
+
log69.warn(
|
|
116987
116908
|
{ chatId, url: file3.url, filename: file3.filename },
|
|
116988
116909
|
"queue: dropping file with no path and non-data URL \u2014 cannot recover disk path"
|
|
116989
116910
|
);
|
|
@@ -116991,7 +116912,7 @@ async function resolveQueuedFiles(chatId, worktreeId4, files) {
|
|
|
116991
116912
|
if (needsSave.length > 0) {
|
|
116992
116913
|
const saved = await saveWorktreeUploads(worktreeId4, needsSave);
|
|
116993
116914
|
if (saved.length !== needsSave.length) {
|
|
116994
|
-
|
|
116915
|
+
log69.error(
|
|
116995
116916
|
{ chatId, expected: needsSave.length, got: saved.length },
|
|
116996
116917
|
"queue: saveUploadedFilesDetailed returned unexpected count \u2014 dropping data-URL files (cannot map 1:1)"
|
|
116997
116918
|
);
|
|
@@ -117024,7 +116945,7 @@ var queueRouter = t.router({
|
|
|
117024
116945
|
try {
|
|
117025
116946
|
files = await resolveQueuedFiles(chatId, input2.worktreeId, input2.files);
|
|
117026
116947
|
} catch (err) {
|
|
117027
|
-
|
|
116948
|
+
log69.error(
|
|
117028
116949
|
{ chatId, err: err instanceof Error ? err.message : err },
|
|
117029
116950
|
"queue.push: failed to persist file uploads; enqueuing text only"
|
|
117030
116951
|
);
|
|
@@ -117074,7 +116995,7 @@ var queueRouter = t.router({
|
|
|
117074
116995
|
files: await resolveQueuedFiles(chatId, input2.worktreeId, m2.files)
|
|
117075
116996
|
};
|
|
117076
116997
|
} catch (err) {
|
|
117077
|
-
|
|
116998
|
+
log69.error(
|
|
117078
116999
|
{ chatId, messageId: m2.id, err: err instanceof Error ? err.message : err },
|
|
117079
117000
|
"queue: failed to resolve files for queued message; dropping its files"
|
|
117080
117001
|
);
|
|
@@ -117231,7 +117152,7 @@ function aggregateTurnsByHourAndModel(snap, provider) {
|
|
|
117231
117152
|
}
|
|
117232
117153
|
return Array.from(buckets.values());
|
|
117233
117154
|
}
|
|
117234
|
-
var
|
|
117155
|
+
var log70 = createLogger("usage-scanner");
|
|
117235
117156
|
var SCHEDULER_KEY2 = Symbol.for("band.usage-scanner");
|
|
117236
117157
|
var g7 = globalThis;
|
|
117237
117158
|
if (!g7[SCHEDULER_KEY2]) {
|
|
@@ -117293,14 +117214,14 @@ var UsageScannerService = class {
|
|
|
117293
117214
|
try {
|
|
117294
117215
|
totalRows += await this.scanPair(ws, a);
|
|
117295
117216
|
} catch (err) {
|
|
117296
|
-
|
|
117217
|
+
log70.warn(
|
|
117297
117218
|
{ err, worktreeId: ws.worktreeId, agentType: a.agentType },
|
|
117298
117219
|
"usage scanner pair failed"
|
|
117299
117220
|
);
|
|
117300
117221
|
}
|
|
117301
117222
|
}
|
|
117302
117223
|
}
|
|
117303
|
-
|
|
117224
|
+
log70.debug(
|
|
117304
117225
|
{ durationMs: this.now() - started, worktrees: worktrees2.length, rowsWritten: totalRows },
|
|
117305
117226
|
"usage scanner tick complete"
|
|
117306
117227
|
);
|
|
@@ -117345,7 +117266,7 @@ var UsageScannerService = class {
|
|
|
117345
117266
|
try {
|
|
117346
117267
|
reader = await this.getUsageReader(a, ws.hostId);
|
|
117347
117268
|
} catch (err) {
|
|
117348
|
-
|
|
117269
|
+
log70.debug({ err, agentId: a.agentId }, "failed to resolve usage reader for scan");
|
|
117349
117270
|
return 0;
|
|
117350
117271
|
}
|
|
117351
117272
|
if (!reader) return 0;
|
|
@@ -117354,7 +117275,7 @@ var UsageScannerService = class {
|
|
|
117354
117275
|
try {
|
|
117355
117276
|
sessions = await reader.listSessions(ws.worktreePath);
|
|
117356
117277
|
} catch (err) {
|
|
117357
|
-
|
|
117278
|
+
log70.debug(
|
|
117358
117279
|
{ err, agentId: a.agentId, worktreePath: ws.worktreePath },
|
|
117359
117280
|
"listSessions failed during usage scan"
|
|
117360
117281
|
);
|
|
@@ -117370,7 +117291,7 @@ var UsageScannerService = class {
|
|
|
117370
117291
|
try {
|
|
117371
117292
|
snap = await reader.getSessionUsage(s2.sessionId, ws.worktreePath);
|
|
117372
117293
|
} catch (err) {
|
|
117373
|
-
|
|
117294
|
+
log70.debug(
|
|
117374
117295
|
{ err, sessionId: s2.sessionId, agentType: a.agentType },
|
|
117375
117296
|
"getSessionUsage failed"
|
|
117376
117297
|
);
|
|
@@ -117409,7 +117330,7 @@ var UsageScannerService = class {
|
|
|
117409
117330
|
this.scanState.set(ws.worktreeId, a.agentType, maxObserved);
|
|
117410
117331
|
}
|
|
117411
117332
|
if (changed.length > slice.length) {
|
|
117412
|
-
|
|
117333
|
+
log70.debug(
|
|
117413
117334
|
{
|
|
117414
117335
|
worktreeId: ws.worktreeId,
|
|
117415
117336
|
agentType: a.agentType,
|
|
@@ -117476,11 +117397,11 @@ function startUsageScanner(options = {}) {
|
|
|
117476
117397
|
const intervalMs = options.intervalMs ?? USAGE_SCAN_INTERVAL_MS;
|
|
117477
117398
|
const svc = getUsageScannerService();
|
|
117478
117399
|
svc.tick().catch((err) => {
|
|
117479
|
-
|
|
117400
|
+
log70.warn({ err }, "initial usage scanner tick failed");
|
|
117480
117401
|
});
|
|
117481
117402
|
const timer = setInterval(() => {
|
|
117482
117403
|
svc.tick().catch((err) => {
|
|
117483
|
-
|
|
117404
|
+
log70.warn({ err }, "scheduled usage scanner tick failed");
|
|
117484
117405
|
});
|
|
117485
117406
|
}, intervalMs);
|
|
117486
117407
|
timer.unref();
|
|
@@ -117851,7 +117772,7 @@ function worktreeGh(host, localHostId, cwd) {
|
|
|
117851
117772
|
init_branch_status_poller();
|
|
117852
117773
|
init_plugin_host_service();
|
|
117853
117774
|
init_worktree_service();
|
|
117854
|
-
var
|
|
117775
|
+
var log71 = createLogger("review-service");
|
|
117855
117776
|
var NoOpenReviewError = class extends Error {
|
|
117856
117777
|
constructor(worktreeId4) {
|
|
117857
117778
|
super(`No open review to merge for worktree ${worktreeId4}`);
|
|
@@ -117892,7 +117813,7 @@ var ReviewService = class {
|
|
|
117892
117813
|
};
|
|
117893
117814
|
} catch (err) {
|
|
117894
117815
|
const message = err instanceof Error ? err.message : String(err);
|
|
117895
|
-
|
|
117816
|
+
log71.warn("Review lookup failed for %s (%s): %s", worktreeId4, provider.id, message);
|
|
117896
117817
|
return { status: "error", message };
|
|
117897
117818
|
}
|
|
117898
117819
|
}
|
|
@@ -118057,7 +117978,7 @@ init_ephemeral_lifecycle_service();
|
|
|
118057
117978
|
init_runner_service();
|
|
118058
117979
|
init_state();
|
|
118059
117980
|
init_token_service();
|
|
118060
|
-
var
|
|
117981
|
+
var log72 = createLogger("reaper");
|
|
118061
117982
|
var DEFAULT_INTERVAL_MS = 3e4;
|
|
118062
117983
|
var DEFAULT_HELLO_GRACE_MS = 6e4;
|
|
118063
117984
|
var DEFAULT_OFFLINE_MS = 12e4;
|
|
@@ -118154,12 +118075,12 @@ var RunnerReaperService = class {
|
|
|
118154
118075
|
try {
|
|
118155
118076
|
await this.reap(machine, Date.now());
|
|
118156
118077
|
} catch (err) {
|
|
118157
|
-
|
|
118078
|
+
log72.warn(`could not check machine ${machine.id}: ${errorText5(err)}`);
|
|
118158
118079
|
}
|
|
118159
118080
|
}
|
|
118160
118081
|
await this.reapOrphans();
|
|
118161
118082
|
} catch (err) {
|
|
118162
|
-
|
|
118083
|
+
log72.warn(`sweep failed: ${errorText5(err)}`);
|
|
118163
118084
|
} finally {
|
|
118164
118085
|
this.ticking = false;
|
|
118165
118086
|
}
|
|
@@ -118221,7 +118142,7 @@ var RunnerReaperService = class {
|
|
|
118221
118142
|
const deadline = machine.spawnedAt + lifetimeMs + runner.lifetimeGraceSec * 1e3;
|
|
118222
118143
|
if (machine.state === "running") {
|
|
118223
118144
|
this.machines.update(machine.id, { state: "stopping", stoppingSince: now });
|
|
118224
|
-
|
|
118145
|
+
log72.info(`machine ${machine.id} reached its maximum lifetime of ${runner.maxLifetimeSec}s`);
|
|
118225
118146
|
}
|
|
118226
118147
|
const reason = `maximum lifetime of ${runner.maxLifetimeSec}s reached`;
|
|
118227
118148
|
if (!online) {
|
|
@@ -118267,7 +118188,7 @@ var RunnerReaperService = class {
|
|
|
118267
118188
|
return;
|
|
118268
118189
|
}
|
|
118269
118190
|
const lost = this.unstored(machine.workerId);
|
|
118270
|
-
|
|
118191
|
+
log72.error(
|
|
118271
118192
|
`HARD DEADLINE: destroying machine ${machine.id} (${reason}) although worktree(s) ${lost.join(", ") || "of its worker"} were not stored`
|
|
118272
118193
|
);
|
|
118273
118194
|
await this.destroyNow(
|
|
@@ -118294,11 +118215,11 @@ var RunnerReaperService = class {
|
|
|
118294
118215
|
const key2 = `${machine.id}:${text4}`;
|
|
118295
118216
|
if (!this.warned.has(key2)) {
|
|
118296
118217
|
this.warned.add(key2);
|
|
118297
|
-
|
|
118218
|
+
log72.info(`machine ${machine.id}: ${text4}`);
|
|
118298
118219
|
}
|
|
118299
118220
|
}
|
|
118300
118221
|
async destroyNow(machine, reason, opts = {}) {
|
|
118301
|
-
|
|
118222
|
+
log72.info(`destroying machine ${machine.id} of runner ${machine.runnerId}: ${reason}`);
|
|
118302
118223
|
const task = this.runners.destroyMachine(machine.id, reason);
|
|
118303
118224
|
this.pending.add(task);
|
|
118304
118225
|
try {
|
|
@@ -118314,7 +118235,7 @@ var RunnerReaperService = class {
|
|
|
118314
118235
|
tokenService.removeHost(hostId2);
|
|
118315
118236
|
hostRegistry.unregister(hostId2);
|
|
118316
118237
|
} catch (err) {
|
|
118317
|
-
|
|
118238
|
+
log72.warn(`could not remove host ${hostId2}: ${errorText5(err)}`);
|
|
118318
118239
|
}
|
|
118319
118240
|
}
|
|
118320
118241
|
// ---- orphans ---------------------------------------------------------------
|
|
@@ -118333,7 +118254,7 @@ var RunnerReaperService = class {
|
|
|
118333
118254
|
try {
|
|
118334
118255
|
handles = await this.runners.listHandles(runner);
|
|
118335
118256
|
} catch (err) {
|
|
118336
|
-
|
|
118257
|
+
log72.warn(`status of runner ${runner.id} failed: ${errorText5(err)}`);
|
|
118337
118258
|
continue;
|
|
118338
118259
|
}
|
|
118339
118260
|
if (this.runners.hasAttemptInFlight(runner.id)) continue;
|
|
@@ -118345,10 +118266,10 @@ var RunnerReaperService = class {
|
|
|
118345
118266
|
if (nowKnown.has(handle)) continue;
|
|
118346
118267
|
const ok2 = await this.runners.destroyHandle(runner, handle, "no record of this machine");
|
|
118347
118268
|
if (ok2) {
|
|
118348
|
-
|
|
118269
|
+
log72.info(`destroyed orphan ${handle} of runner ${runner.id}`);
|
|
118349
118270
|
this.machines.settleHandle(runner.id, handle, "destroyed by the reaper as an orphan");
|
|
118350
118271
|
} else {
|
|
118351
|
-
|
|
118272
|
+
log72.warn(`could not destroy orphan ${handle} of runner ${runner.id}`);
|
|
118352
118273
|
}
|
|
118353
118274
|
}
|
|
118354
118275
|
}
|
|
@@ -118414,7 +118335,7 @@ init_errors6();
|
|
|
118414
118335
|
init_agent_session_service();
|
|
118415
118336
|
init_chat_service();
|
|
118416
118337
|
init_worktree_service();
|
|
118417
|
-
var
|
|
118338
|
+
var log73 = createLogger("session-service");
|
|
118418
118339
|
var SessionService = class {
|
|
118419
118340
|
/** Lists past sessions for a worktree's chat pane (default chat when
|
|
118420
118341
|
* `chatId` is undefined). */
|
|
@@ -118427,7 +118348,7 @@ var SessionService = class {
|
|
|
118427
118348
|
if (!chatService.get(chatId)) {
|
|
118428
118349
|
chatService.create(input2.worktreeId, { id: chatId, name: "Chat" });
|
|
118429
118350
|
}
|
|
118430
|
-
|
|
118351
|
+
log73.debug({ chatId, worktreeId: input2.worktreeId }, "listing past sessions for chat");
|
|
118431
118352
|
return agentSessionService.listSessions(chatId);
|
|
118432
118353
|
}
|
|
118433
118354
|
};
|
|
@@ -118754,7 +118675,7 @@ init_branch_status_poller();
|
|
|
118754
118675
|
init_client_activity_service();
|
|
118755
118676
|
init_state();
|
|
118756
118677
|
init_tunnel_service();
|
|
118757
|
-
var
|
|
118678
|
+
var log74 = createLogger("trpc.system");
|
|
118758
118679
|
var systemRouter = t.router({
|
|
118759
118680
|
/**
|
|
118760
118681
|
* Combined liveness probe — webserver is always true if this query
|
|
@@ -118762,16 +118683,16 @@ var systemRouter = t.router({
|
|
|
118762
118683
|
* an interval to drive the bottom-bar status pill.
|
|
118763
118684
|
*/
|
|
118764
118685
|
health: publicProcedure.query(() => {
|
|
118765
|
-
|
|
118686
|
+
log74.debug("services.health called");
|
|
118766
118687
|
const tunnel = tunnelService.getStatus();
|
|
118767
|
-
|
|
118688
|
+
log74.debug({ tunnel }, "services.health: tunnel status");
|
|
118768
118689
|
const result = {
|
|
118769
118690
|
webserver: true,
|
|
118770
118691
|
version: package_default.version,
|
|
118771
118692
|
tunnel: tunnel.running,
|
|
118772
118693
|
tunnel_url: tunnel.url
|
|
118773
118694
|
};
|
|
118774
|
-
|
|
118695
|
+
log74.debug({ result }, "services.health result");
|
|
118775
118696
|
return result;
|
|
118776
118697
|
}),
|
|
118777
118698
|
// What this client's UI is doing, so the branch-status poller can slow down. A client names
|
|
@@ -118910,7 +118831,7 @@ init_errors6();
|
|
|
118910
118831
|
init_chat_service();
|
|
118911
118832
|
init_state();
|
|
118912
118833
|
init_task_service();
|
|
118913
|
-
var
|
|
118834
|
+
var log75 = createLogger("tasks-router");
|
|
118914
118835
|
var tasksRouter = t.router({
|
|
118915
118836
|
list: publicProcedure.input(
|
|
118916
118837
|
external_exports2.object({
|
|
@@ -118972,7 +118893,7 @@ var tasksRouter = t.router({
|
|
|
118972
118893
|
if (input2.files && input2.files.length > 0) {
|
|
118973
118894
|
const savedFiles = await saveWorktreeUploads(input2.worktreeId, input2.files);
|
|
118974
118895
|
if (savedFiles.length !== input2.files.length) {
|
|
118975
|
-
|
|
118896
|
+
log75.warn(
|
|
118976
118897
|
{ chatId, submitted: input2.files.length, saved: savedFiles.length },
|
|
118977
118898
|
"tasks.submit: some file uploads were dropped (malformed data URL?)"
|
|
118978
118899
|
);
|
|
@@ -119398,25 +119319,25 @@ var tokensRouter = t.router({
|
|
|
119398
119319
|
init_src();
|
|
119399
119320
|
init_zod();
|
|
119400
119321
|
init_tunnel_service();
|
|
119401
|
-
var
|
|
119322
|
+
var log76 = createLogger("trpc.tunnel");
|
|
119402
119323
|
var tunnelRouter = t.router({
|
|
119403
119324
|
status: publicProcedure.query(() => {
|
|
119404
119325
|
return tunnelService.getStatus();
|
|
119405
119326
|
}),
|
|
119406
119327
|
start: publicProcedure.input(external_exports2.object({}).optional()).mutation(async () => {
|
|
119407
|
-
|
|
119328
|
+
log76.debug("tunnel.start called");
|
|
119408
119329
|
try {
|
|
119409
119330
|
await tunnelService.start();
|
|
119410
119331
|
} catch (err) {
|
|
119411
|
-
|
|
119332
|
+
log76.debug({ err }, "tunnel.start: startTunnel failed");
|
|
119412
119333
|
return { ok: true, url: null };
|
|
119413
119334
|
}
|
|
119414
119335
|
const status = tunnelService.getStatus();
|
|
119415
|
-
|
|
119336
|
+
log76.debug({ status }, "tunnel.start: after startTunnel");
|
|
119416
119337
|
if (status.url) {
|
|
119417
119338
|
return { ok: true, url: status.url };
|
|
119418
119339
|
}
|
|
119419
|
-
|
|
119340
|
+
log76.debug("tunnel.start: no URL available");
|
|
119420
119341
|
return { ok: true, url: null };
|
|
119421
119342
|
}),
|
|
119422
119343
|
stop: publicProcedure.mutation(async () => {
|
|
@@ -119806,8 +119727,8 @@ function verifyWorktreePreviewGrant(worktreeId4, grant, filePath, now = Date.now
|
|
|
119806
119727
|
init_src2();
|
|
119807
119728
|
init_src();
|
|
119808
119729
|
init_resolver();
|
|
119809
|
-
import { join as
|
|
119810
|
-
var
|
|
119730
|
+
import { join as join54, resolve as resolve12, sep as sep8 } from "node:path";
|
|
119731
|
+
var log77 = createLogger("diff-service");
|
|
119811
119732
|
var EMPTY_TREE_ARGS = ["hash-object", "-t", "tree", "/dev/null"];
|
|
119812
119733
|
var DEFAULT_BRANCH_LIMIT = 50;
|
|
119813
119734
|
var STAGING_BRANCH_PRIORITY = [
|
|
@@ -119903,7 +119824,7 @@ function parseFileStatuses(nameStatusOutput) {
|
|
|
119903
119824
|
return fileStatuses;
|
|
119904
119825
|
}
|
|
119905
119826
|
function assertWorktreeRelative(cwd, filePath) {
|
|
119906
|
-
const target = resolve12(
|
|
119827
|
+
const target = resolve12(join54(cwd, filePath));
|
|
119907
119828
|
if (target !== cwd && !target.startsWith(cwd + sep8)) {
|
|
119908
119829
|
throw new Error("Invalid path");
|
|
119909
119830
|
}
|
|
@@ -119918,7 +119839,7 @@ function assertWorktreeRelative(cwd, filePath) {
|
|
|
119918
119839
|
}
|
|
119919
119840
|
async function readUntrackedFileLines(host, cwd, file3) {
|
|
119920
119841
|
try {
|
|
119921
|
-
const content = new TextDecoder().decode(await host.fs.readFile(
|
|
119842
|
+
const content = new TextDecoder().decode(await host.fs.readFile(join54(cwd, file3)));
|
|
119922
119843
|
const lines = content.split("\n");
|
|
119923
119844
|
if (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
119924
119845
|
lines.pop();
|
|
@@ -120154,7 +120075,7 @@ var DiffService = class {
|
|
|
120154
120075
|
);
|
|
120155
120076
|
refs = output2.split("\n").map((line2) => parseBranchRef(line2.trim())).filter((ref) => ref !== null);
|
|
120156
120077
|
} catch (err) {
|
|
120157
|
-
|
|
120078
|
+
log77.error(
|
|
120158
120079
|
`listBranches: for-each-ref failed for ${cwd}: ${err instanceof Error ? err.message : err}`
|
|
120159
120080
|
);
|
|
120160
120081
|
}
|
|
@@ -120265,7 +120186,7 @@ var DiffService = class {
|
|
|
120265
120186
|
const compareBranch = options.compareBranch ?? defaultBranch;
|
|
120266
120187
|
const cwd = worktree.worktree.path;
|
|
120267
120188
|
const execGit2 = gitRunner(worktree.host);
|
|
120268
|
-
const hasGit = await worktree.host.fs.stat(
|
|
120189
|
+
const hasGit = await worktree.host.fs.stat(join54(cwd, ".git")).then(
|
|
120269
120190
|
() => true,
|
|
120270
120191
|
(err) => {
|
|
120271
120192
|
if (err instanceof HostOfflineError || err instanceof HostTimeoutError) throw err;
|
|
@@ -120303,7 +120224,7 @@ var DiffService = class {
|
|
|
120303
120224
|
applyLineCounts(status.staged, parseNumstat(stagedNumstat));
|
|
120304
120225
|
await Promise.all(
|
|
120305
120226
|
status.untracked.map(async (entry) => {
|
|
120306
|
-
const lines = await countUntrackedLines(worktree.host,
|
|
120227
|
+
const lines = await countUntrackedLines(worktree.host, join54(cwd, entry.path));
|
|
120307
120228
|
if (lines !== null) {
|
|
120308
120229
|
entry.additions = lines;
|
|
120309
120230
|
entry.deletions = 0;
|
|
@@ -120460,7 +120381,7 @@ init_src();
|
|
|
120460
120381
|
init_errors6();
|
|
120461
120382
|
init_local_host_policy();
|
|
120462
120383
|
init_worktree_service();
|
|
120463
|
-
var
|
|
120384
|
+
var log78 = createLogger("direct-access");
|
|
120464
120385
|
var DEFAULT_TOKEN_TTL_MS2 = 10 * 6e4;
|
|
120465
120386
|
function tokenTtlMs() {
|
|
120466
120387
|
const ms = Number(process.env.BAND_DIRECT_TOKEN_TTL_MS);
|
|
@@ -120495,7 +120416,7 @@ var DirectAccessService = class {
|
|
|
120495
120416
|
);
|
|
120496
120417
|
return { hostId: hostId2, ...grant };
|
|
120497
120418
|
} catch (err) {
|
|
120498
|
-
|
|
120419
|
+
log78.debug(
|
|
120499
120420
|
{ hostId: hostId2, worktreeId: worktreeId4, message: err instanceof Error ? err.message : String(err) },
|
|
120500
120421
|
"no direct path to the worker"
|
|
120501
120422
|
);
|
|
@@ -120507,7 +120428,7 @@ var directAccessService = new DirectAccessService();
|
|
|
120507
120428
|
|
|
120508
120429
|
// ../../packages/worktree-ops/src/files.ts
|
|
120509
120430
|
init_resolver();
|
|
120510
|
-
import { dirname as dirname16, extname as extname3, join as
|
|
120431
|
+
import { dirname as dirname16, extname as extname3, join as join55, resolve as resolve13, sep as sep9 } from "node:path";
|
|
120511
120432
|
var MAX_FILE_SIZE2 = 1024 * 1024;
|
|
120512
120433
|
var LANG_MAP2 = {
|
|
120513
120434
|
".js": "javascript",
|
|
@@ -120574,7 +120495,7 @@ var FilesService = class {
|
|
|
120574
120495
|
throw new WorktreeNotFoundError(worktreeId4);
|
|
120575
120496
|
}
|
|
120576
120497
|
const root = worktree.worktree.path;
|
|
120577
|
-
const target = resolve13(
|
|
120498
|
+
const target = resolve13(join55(root, relative2));
|
|
120578
120499
|
const insideRoot = target === root || target.startsWith(root + sep9);
|
|
120579
120500
|
if (!insideRoot) {
|
|
120580
120501
|
throw new Error("Invalid path");
|
|
@@ -120755,7 +120676,7 @@ var filesService = new FilesService({
|
|
|
120755
120676
|
|
|
120756
120677
|
// src/server/services/git-graph-service.ts
|
|
120757
120678
|
init_src2();
|
|
120758
|
-
import { createHash as
|
|
120679
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
120759
120680
|
init_errors6();
|
|
120760
120681
|
init_worktree_service();
|
|
120761
120682
|
var FS = "";
|
|
@@ -120827,7 +120748,7 @@ var GitGraphService = class {
|
|
|
120827
120748
|
} catch {
|
|
120828
120749
|
return "";
|
|
120829
120750
|
}
|
|
120830
|
-
return
|
|
120751
|
+
return createHash13("sha1").update(out).digest("hex");
|
|
120831
120752
|
}
|
|
120832
120753
|
/**
|
|
120833
120754
|
* One page of HEAD's history, newest first in topological order, so every
|
|
@@ -122871,7 +122792,7 @@ async function readBody2(req, max3) {
|
|
|
122871
122792
|
// src/server/api/mcp-proxy/stdio.ts
|
|
122872
122793
|
init_src();
|
|
122873
122794
|
init_mcp_stdio_service();
|
|
122874
|
-
var
|
|
122795
|
+
var log79 = createLogger("mcp-proxy-stdio");
|
|
122875
122796
|
var MAX_REQUEST_BYTES = 4 * 1024 * 1024;
|
|
122876
122797
|
var sessionHeader = (req) => {
|
|
122877
122798
|
const value = req.headers["mcp-session-id"];
|
|
@@ -123002,7 +122923,7 @@ data: ${JSON.stringify(message)}
|
|
|
123002
122923
|
if (gone) {
|
|
123003
122924
|
return sendJson3(res, 404, { error: "The stdio MCP server's session ended" });
|
|
123004
122925
|
}
|
|
123005
|
-
|
|
122926
|
+
log79.warn(
|
|
123006
122927
|
{ server: server.name, err: err instanceof Error ? err.name : "unknown" },
|
|
123007
122928
|
"no answer"
|
|
123008
122929
|
);
|
|
@@ -123027,7 +122948,7 @@ data: ${JSON.stringify(message)}
|
|
|
123027
122948
|
}
|
|
123028
122949
|
|
|
123029
122950
|
// src/server/api/mcp-proxy/handler.ts
|
|
123030
|
-
var
|
|
122951
|
+
var log80 = createLogger("mcp-proxy");
|
|
123031
122952
|
var MCP_PROXY_PREFIX = "/mcp-proxy/";
|
|
123032
122953
|
var ROUTE = /^\/mcp-proxy\/([^/]+)\/?$/;
|
|
123033
122954
|
var MAX_REQUEST_BYTES2 = 4 * 1024 * 1024;
|
|
@@ -123189,13 +123110,13 @@ async function handleMcpProxy(req, res) {
|
|
|
123189
123110
|
try {
|
|
123190
123111
|
upstream = await sendUpstream(server, { method, headers, body, signal: abort.signal });
|
|
123191
123112
|
} catch (err) {
|
|
123192
|
-
|
|
123113
|
+
log80.warn({ server: name5, err: errorCode2(err) }, "upstream failed");
|
|
123193
123114
|
auditUnanswered(server, auth2.sessionId, plan, "upstream-unreachable");
|
|
123194
123115
|
return sendJson3(res, 502, { error: "The upstream MCP server did not answer" });
|
|
123195
123116
|
}
|
|
123196
123117
|
if (upstream.status === 401 || upstream.status >= 300 && upstream.status < 400) {
|
|
123197
123118
|
await upstream.body?.cancel().catch(() => void 0);
|
|
123198
|
-
|
|
123119
|
+
log80.warn({ server: name5, status: upstream.status }, "upstream refused the stored credential");
|
|
123199
123120
|
auditUnanswered(server, auth2.sessionId, plan, `upstream-${upstream.status}`);
|
|
123200
123121
|
return sendJson3(res, 502, {
|
|
123201
123122
|
error: upstream.status === 401 ? "The upstream MCP server rejected the stored credential" : "The upstream MCP server redirected, which the proxy does not follow"
|
|
@@ -123263,7 +123184,7 @@ async function handleMcpProxy(req, res) {
|
|
|
123263
123184
|
} catch (err) {
|
|
123264
123185
|
auditUnanswered(server, auth2.sessionId, plan, "stream-failed");
|
|
123265
123186
|
if (!abort.signal.aborted) {
|
|
123266
|
-
|
|
123187
|
+
log80.warn(
|
|
123267
123188
|
{ server: name5, err: errorCode2(err) },
|
|
123268
123189
|
err instanceof SseEventTooLargeError ? "event too large to inspect" : "proxy stream failed"
|
|
123269
123190
|
);
|
|
@@ -123298,7 +123219,7 @@ function getScalarHtml(specUrl) {
|
|
|
123298
123219
|
// src/server/api/pairing/handler.ts
|
|
123299
123220
|
init_src();
|
|
123300
123221
|
init_token_service();
|
|
123301
|
-
var
|
|
123222
|
+
var log81 = createLogger("pairing");
|
|
123302
123223
|
var PAIR_EXCHANGE_PATH = "/api/pair/exchange";
|
|
123303
123224
|
var MAX_BODY_BYTES2 = 4096;
|
|
123304
123225
|
var PAIR_REFUSED_MESSAGE = "This link was already used or has expired. Ask for a new one in Settings > Devices.";
|
|
@@ -123390,7 +123311,7 @@ async function handlePairExchange(req, res) {
|
|
|
123390
123311
|
send3(200, out, { "Set-Cookie": buildCookieHeader(out.token, isSecure(req)) });
|
|
123391
123312
|
} catch (err) {
|
|
123392
123313
|
if (!(err instanceof PairingExchangeError)) throw err;
|
|
123393
|
-
|
|
123314
|
+
log81.debug(`pairing exchange refused: ${err.reason}`);
|
|
123394
123315
|
send3(401, { error: PAIR_REFUSED_MESSAGE });
|
|
123395
123316
|
}
|
|
123396
123317
|
}
|
|
@@ -123398,7 +123319,7 @@ async function handlePairExchange(req, res) {
|
|
|
123398
123319
|
// src/server/api/provisioning/handler.ts
|
|
123399
123320
|
init_src();
|
|
123400
123321
|
import { pipeline } from "node:stream";
|
|
123401
|
-
var
|
|
123322
|
+
var log82 = createLogger("provisioning");
|
|
123402
123323
|
var PROVISION_PREFIX = "/api/provision/";
|
|
123403
123324
|
var MAX_EXCHANGE_BODY_BYTES2 = 4096;
|
|
123404
123325
|
var MAX_LOG_BODY_BYTES = 128 * 1024;
|
|
@@ -123455,7 +123376,7 @@ async function handleProvision(req, res) {
|
|
|
123455
123376
|
send3(200, provisioningService.exchange(code2), "text/plain; charset=utf-8");
|
|
123456
123377
|
} catch (err) {
|
|
123457
123378
|
if (!(err instanceof ProvisionExchangeError)) throw err;
|
|
123458
|
-
|
|
123379
|
+
log82.debug(`provisioning exchange refused: ${err.reason}`);
|
|
123459
123380
|
refused();
|
|
123460
123381
|
}
|
|
123461
123382
|
return;
|
|
@@ -123591,7 +123512,7 @@ var OutputFlow = class {
|
|
|
123591
123512
|
};
|
|
123592
123513
|
|
|
123593
123514
|
// ../../packages/worktree-ops/src/terminal-socket.ts
|
|
123594
|
-
var
|
|
123515
|
+
var log83 = createLogger("terminal-ws");
|
|
123595
123516
|
var MAX_CLOSE_REASON_BYTES = 123;
|
|
123596
123517
|
var HEARTBEAT_INTERVAL_MS2 = 3e4;
|
|
123597
123518
|
function clampCloseReason(reason) {
|
|
@@ -123659,7 +123580,7 @@ function createInbox(ws) {
|
|
|
123659
123580
|
};
|
|
123660
123581
|
}
|
|
123661
123582
|
function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendingMessage) {
|
|
123662
|
-
|
|
123583
|
+
log83.debug(
|
|
123663
123584
|
"Terminal %s: %s (worktree %s)",
|
|
123664
123585
|
isNew ? "connected" : "reconnected",
|
|
123665
123586
|
terminalId,
|
|
@@ -123679,7 +123600,7 @@ function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendi
|
|
|
123679
123600
|
});
|
|
123680
123601
|
const unsubscribeExit = backend.onExit(terminalId, (event) => {
|
|
123681
123602
|
unsubscribeTitle();
|
|
123682
|
-
|
|
123603
|
+
log83.debug("PTY exited with code %d for terminal %s", event.exitCode, terminalId);
|
|
123683
123604
|
if (ws.readyState === ws.OPEN) {
|
|
123684
123605
|
ws.close(1e3, "Terminal exited");
|
|
123685
123606
|
}
|
|
@@ -123707,7 +123628,7 @@ function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendi
|
|
|
123707
123628
|
try {
|
|
123708
123629
|
attached = await backend.attach(terminalId, dims);
|
|
123709
123630
|
} catch (err) {
|
|
123710
|
-
|
|
123631
|
+
log83.error("Failed to attach terminal %s: %s", terminalId, err);
|
|
123711
123632
|
safeClose(ws, 1011, "Terminal attach failed");
|
|
123712
123633
|
return;
|
|
123713
123634
|
}
|
|
@@ -123749,7 +123670,7 @@ function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendi
|
|
|
123749
123670
|
const cols = Number.isFinite(parsed.cols) && parsed.cols > 0 ? parsed.cols : void 0;
|
|
123750
123671
|
const rows = Number.isFinite(parsed.rows) && parsed.rows > 0 ? parsed.rows : void 0;
|
|
123751
123672
|
void startReplay(cols, rows, parsed.flow === true).catch((err) => {
|
|
123752
|
-
|
|
123673
|
+
log83.error("Failed to replay terminal %s: %s", terminalId, err);
|
|
123753
123674
|
});
|
|
123754
123675
|
return;
|
|
123755
123676
|
}
|
|
@@ -123769,7 +123690,7 @@ function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendi
|
|
|
123769
123690
|
flow?.dispose();
|
|
123770
123691
|
attachment?.detach();
|
|
123771
123692
|
unsubscribeExit();
|
|
123772
|
-
|
|
123693
|
+
log83.debug("Terminal disconnected: %s (PTY kept alive)", terminalId);
|
|
123773
123694
|
});
|
|
123774
123695
|
if (pendingMessage) {
|
|
123775
123696
|
processMessage(pendingMessage);
|
|
@@ -123792,7 +123713,7 @@ function handleMessage(backend, ws, terminalId, message) {
|
|
|
123792
123713
|
}
|
|
123793
123714
|
if (parsed.type === "close") {
|
|
123794
123715
|
void backend.kill(terminalId).catch((err) => {
|
|
123795
|
-
|
|
123716
|
+
log83.error("Failed to kill terminal %s: %s", terminalId, err);
|
|
123796
123717
|
});
|
|
123797
123718
|
ws.close(1e3, "Terminal closed by client");
|
|
123798
123719
|
return;
|
|
@@ -123808,7 +123729,7 @@ function handleMessage(backend, ws, terminalId, message) {
|
|
|
123808
123729
|
|
|
123809
123730
|
// src/server/api/terminals/ws.ts
|
|
123810
123731
|
init_terminal_service();
|
|
123811
|
-
var
|
|
123732
|
+
var log84 = createLogger("terminal-ws");
|
|
123812
123733
|
async function handleTerminalConnection(ws, req) {
|
|
123813
123734
|
if (!req.url) {
|
|
123814
123735
|
safeClose(ws, 4e3, "Missing request URL");
|
|
@@ -123827,7 +123748,7 @@ async function handleTerminalConnection(ws, req) {
|
|
|
123827
123748
|
existing = await terminalService.info(terminalId) !== null;
|
|
123828
123749
|
} catch (err) {
|
|
123829
123750
|
const msg = err instanceof Error ? err.message : String(err);
|
|
123830
|
-
|
|
123751
|
+
log84.error("Failed to look up terminal %s: %s", terminalId, msg);
|
|
123831
123752
|
safeClose(ws, 1011, msg);
|
|
123832
123753
|
return;
|
|
123833
123754
|
}
|
|
@@ -123875,7 +123796,7 @@ async function handleTerminalConnection(ws, req) {
|
|
|
123875
123796
|
await terminalService.spawn(worktreeId4, terminalId, spawnOpts);
|
|
123876
123797
|
} catch (err) {
|
|
123877
123798
|
const msg = err instanceof Error ? err.message : String(err);
|
|
123878
|
-
|
|
123799
|
+
log84.error("Failed to spawn terminal %s for worktree %s: %s", terminalId, worktreeId4, msg);
|
|
123879
123800
|
safeClose(ws, 4001, msg);
|
|
123880
123801
|
return;
|
|
123881
123802
|
}
|
|
@@ -123975,14 +123896,14 @@ async function handleVoiceTranscribe(req, res) {
|
|
|
123975
123896
|
|
|
123976
123897
|
// src/server/api/web-app-manifest.ts
|
|
123977
123898
|
import { createReadStream as createReadStream5, statSync as statSync15 } from "node:fs";
|
|
123978
|
-
import { join as
|
|
123899
|
+
import { join as join56 } from "node:path";
|
|
123979
123900
|
var WEB_APP_MANIFEST_PATH = "/manifest.webmanifest";
|
|
123980
123901
|
var ICON_FILES = ["band-192.png", "band-512.png", "apple-touch-icon.png"];
|
|
123981
123902
|
function handleWebAppManifest(req, res, publicDir) {
|
|
123982
123903
|
if (req.method !== "GET" && req.method !== "HEAD") return false;
|
|
123983
123904
|
const pathname = req.url?.split("?")[0];
|
|
123984
123905
|
if (pathname === WEB_APP_MANIFEST_PATH) {
|
|
123985
|
-
sendFile(req, res,
|
|
123906
|
+
sendFile(req, res, join56(publicDir, "manifest.webmanifest"), {
|
|
123986
123907
|
"Content-Type": "application/manifest+json",
|
|
123987
123908
|
"Cache-Control": "no-cache"
|
|
123988
123909
|
});
|
|
@@ -123990,7 +123911,7 @@ function handleWebAppManifest(req, res, publicDir) {
|
|
|
123990
123911
|
}
|
|
123991
123912
|
const icon = ICON_FILES.find((name5) => pathname === `/icons/${name5}`);
|
|
123992
123913
|
if (!icon) return false;
|
|
123993
|
-
sendFile(req, res,
|
|
123914
|
+
sendFile(req, res, join56(publicDir, "icons", icon), {
|
|
123994
123915
|
"Content-Type": "image/png",
|
|
123995
123916
|
"Cache-Control": "public, max-age=86400"
|
|
123996
123917
|
});
|
|
@@ -124014,7 +123935,7 @@ init_src();
|
|
|
124014
123935
|
init_wrapper();
|
|
124015
123936
|
init_browser_lookup();
|
|
124016
123937
|
init_remote_cdp();
|
|
124017
|
-
var
|
|
123938
|
+
var log85 = createLogger("cdp-proxy");
|
|
124018
123939
|
async function handleCdpConnection(ws, req) {
|
|
124019
123940
|
const url3 = new URL(req.url ?? "", `http://${req.headers.host}`);
|
|
124020
123941
|
const bandTabId = url3.searchParams.get("bandTabId");
|
|
@@ -124057,17 +123978,17 @@ async function handleCdpConnection(ws, req) {
|
|
|
124057
123978
|
cdpTargetId = await ensureCdpTargetId(bandTabId);
|
|
124058
123979
|
} catch (err) {
|
|
124059
123980
|
const message = err instanceof Error ? err.message : String(err);
|
|
124060
|
-
|
|
123981
|
+
log85.debug("ensureCdpTargetId failed for %s: %s", bandTabId, message);
|
|
124061
123982
|
if (ws.readyState === ws.OPEN) {
|
|
124062
123983
|
ws.close(4001, message.slice(0, 123));
|
|
124063
123984
|
}
|
|
124064
123985
|
return;
|
|
124065
123986
|
}
|
|
124066
123987
|
const upstreamUrl = `ws://${DESKTOP_CDP_HOST}:${DESKTOP_CDP_PORT}/devtools/page/${encodeURIComponent(cdpTargetId)}`;
|
|
124067
|
-
|
|
123988
|
+
log85.info("CDP proxy connecting bandTabId=%s upstream=%s", bandTabId, upstreamUrl);
|
|
124068
123989
|
upstream = new wrapper_default(upstreamUrl);
|
|
124069
123990
|
upstream.on("open", () => {
|
|
124070
|
-
|
|
123991
|
+
log85.info("CDP upstream open bandTabId=%s pending=%d", bandTabId, pending2.length);
|
|
124071
123992
|
for (const msg of pending2) {
|
|
124072
123993
|
upstream?.send(msg);
|
|
124073
123994
|
}
|
|
@@ -124079,20 +124000,20 @@ async function handleCdpConnection(ws, req) {
|
|
|
124079
124000
|
}
|
|
124080
124001
|
});
|
|
124081
124002
|
upstream.on("error", (err) => {
|
|
124082
|
-
|
|
124003
|
+
log85.warn("CDP upstream error bandTabId=%s: %s", bandTabId, err.message);
|
|
124083
124004
|
markTargetDestroyed(bandTabId);
|
|
124084
124005
|
if (ws.readyState === ws.OPEN) {
|
|
124085
124006
|
ws.close(4001, `Desktop CDP error: ${err.message}`.slice(0, 123));
|
|
124086
124007
|
}
|
|
124087
124008
|
});
|
|
124088
124009
|
upstream.on("close", (code) => {
|
|
124089
|
-
|
|
124010
|
+
log85.info("CDP upstream closed bandTabId=%s code=%d", bandTabId, code);
|
|
124090
124011
|
if (ws.readyState === ws.OPEN) {
|
|
124091
124012
|
ws.close(1e3, "Upstream closed");
|
|
124092
124013
|
}
|
|
124093
124014
|
});
|
|
124094
124015
|
ws.on("close", () => {
|
|
124095
|
-
|
|
124016
|
+
log85.debug("CDP client closed bandTabId=%s", bandTabId);
|
|
124096
124017
|
if (upstream && (upstream.readyState === wrapper_default.OPEN || upstream.readyState === wrapper_default.CONNECTING)) {
|
|
124097
124018
|
try {
|
|
124098
124019
|
upstream.close();
|
|
@@ -124101,7 +124022,7 @@ async function handleCdpConnection(ws, req) {
|
|
|
124101
124022
|
}
|
|
124102
124023
|
});
|
|
124103
124024
|
ws.on("error", (err) => {
|
|
124104
|
-
|
|
124025
|
+
log85.debug("CDP client error bandTabId=%s: %s", bandTabId, err.message);
|
|
124105
124026
|
try {
|
|
124106
124027
|
upstream?.close();
|
|
124107
124028
|
} catch {
|
|
@@ -124131,7 +124052,7 @@ async function bridgeRemote(ws, worktreeId4) {
|
|
|
124131
124052
|
cdp = await openRemoteCdp(worktreeId4);
|
|
124132
124053
|
} catch (err) {
|
|
124133
124054
|
const message = err instanceof Error ? err.message : String(err);
|
|
124134
|
-
|
|
124055
|
+
log85.warn("remote CDP failed for worktree %s: %s", worktreeId4, message);
|
|
124135
124056
|
if (ws.readyState === ws.OPEN)
|
|
124136
124057
|
ws.close(4001, closeReason(`Remote browser unavailable: ${message}`));
|
|
124137
124058
|
return true;
|
|
@@ -124155,7 +124076,7 @@ async function bridgeRemote(ws, worktreeId4) {
|
|
|
124155
124076
|
if (ws.readyState === ws.OPEN) ws.send(message);
|
|
124156
124077
|
}
|
|
124157
124078
|
} catch (err) {
|
|
124158
|
-
|
|
124079
|
+
log85.debug("remote CDP stream ended for worktree %s: %s", worktreeId4, String(err));
|
|
124159
124080
|
}
|
|
124160
124081
|
if (ws.readyState === ws.OPEN) ws.close(1e3, "Upstream closed");
|
|
124161
124082
|
})();
|
|
@@ -124165,7 +124086,7 @@ async function bridgeRemote(ws, worktreeId4) {
|
|
|
124165
124086
|
// src/server/infra/browser-host/cdp-targets.ts
|
|
124166
124087
|
init_src();
|
|
124167
124088
|
init_wrapper();
|
|
124168
|
-
var
|
|
124089
|
+
var log86 = createLogger("cdp-targets");
|
|
124169
124090
|
var CdpUnreachableError = class extends Error {
|
|
124170
124091
|
constructor(message) {
|
|
124171
124092
|
super(message);
|
|
@@ -124221,7 +124142,7 @@ async function captureSnapshot(bandTabId) {
|
|
|
124221
124142
|
});
|
|
124222
124143
|
ws.on("error", (err) => {
|
|
124223
124144
|
clearTimeout(timeout);
|
|
124224
|
-
|
|
124145
|
+
log86.debug("captureSnapshot ws error for tab %s: %s", bandTabId, err.message);
|
|
124225
124146
|
markTargetDestroyed(bandTabId);
|
|
124226
124147
|
settle2(new CdpUnreachableError(err.message));
|
|
124227
124148
|
});
|
|
@@ -124348,7 +124269,7 @@ var RfbClientFilter = class {
|
|
|
124348
124269
|
};
|
|
124349
124270
|
|
|
124350
124271
|
// src/server/infra/host/desktop-proxy.ts
|
|
124351
|
-
var
|
|
124272
|
+
var log87 = createLogger("desktop-proxy");
|
|
124352
124273
|
var DESKTOP_PATH = /^\/api\/hosts\/([^/]+)\/desktop$/;
|
|
124353
124274
|
function desktopHostId(pathname) {
|
|
124354
124275
|
const match = DESKTOP_PATH.exec(pathname);
|
|
@@ -124397,7 +124318,7 @@ async function handleDesktopConnection(ws, req, hostId2) {
|
|
|
124397
124318
|
);
|
|
124398
124319
|
if (enabled !== null) {
|
|
124399
124320
|
filter.viewOnly = !enabled;
|
|
124400
|
-
|
|
124321
|
+
log87.debug("desktop of host %s is now %s", hostId2, enabled ? "controlled" : "view-only");
|
|
124401
124322
|
}
|
|
124402
124323
|
return;
|
|
124403
124324
|
}
|
|
@@ -124432,7 +124353,7 @@ async function handleDesktopConnection(ws, req, hostId2) {
|
|
|
124432
124353
|
opened = true;
|
|
124433
124354
|
} catch (err) {
|
|
124434
124355
|
const message = err instanceof Error ? err.message : String(err);
|
|
124435
|
-
|
|
124356
|
+
log87.warn("desktop of host %s is unavailable: %s", hostId2, message);
|
|
124436
124357
|
release();
|
|
124437
124358
|
ws.close(4001, message.slice(0, 120));
|
|
124438
124359
|
return;
|
|
@@ -124442,7 +124363,7 @@ async function handleDesktopConnection(ws, req, hostId2) {
|
|
|
124442
124363
|
release();
|
|
124443
124364
|
return;
|
|
124444
124365
|
}
|
|
124445
|
-
|
|
124366
|
+
log87.debug("desktop viewer connected: %s (%s)", hostId2, req.socket.remoteAddress ?? "unknown");
|
|
124446
124367
|
for (const chunk of pending2.splice(0)) desktop.write(chunk);
|
|
124447
124368
|
try {
|
|
124448
124369
|
for await (const bytes of desktop.output) {
|
|
@@ -124450,7 +124371,7 @@ async function handleDesktopConnection(ws, req, hostId2) {
|
|
|
124450
124371
|
await new Promise((resolve15) => ws.send(bytes, { binary: true }, () => resolve15()));
|
|
124451
124372
|
}
|
|
124452
124373
|
} catch (err) {
|
|
124453
|
-
|
|
124374
|
+
log87.warn("desktop stream of host %s failed: %s", hostId2, err.message);
|
|
124454
124375
|
} finally {
|
|
124455
124376
|
if (opened) {
|
|
124456
124377
|
desktop.close();
|
|
@@ -124468,7 +124389,7 @@ init_src();
|
|
|
124468
124389
|
init_worktrees();
|
|
124469
124390
|
init_registry();
|
|
124470
124391
|
var worktreeQueries2 = new WorktreeQueries();
|
|
124471
|
-
var
|
|
124392
|
+
var log88 = createLogger("lsp-proxy");
|
|
124472
124393
|
function frameMessage(json3) {
|
|
124473
124394
|
const body = Buffer.from(json3, "utf-8");
|
|
124474
124395
|
const header = `Content-Length: ${body.byteLength}\r
|
|
@@ -124486,7 +124407,7 @@ function createFrameParser(onMessage) {
|
|
|
124486
124407
|
const headerStr = buffer.subarray(0, separatorIdx).toString("ascii");
|
|
124487
124408
|
const match = headerStr.match(/Content-Length:\s*(\d+)/i);
|
|
124488
124409
|
if (!match) {
|
|
124489
|
-
|
|
124410
|
+
log88.warn("Malformed LSP header: %s", headerStr);
|
|
124490
124411
|
buffer = buffer.subarray(separatorIdx + 4);
|
|
124491
124412
|
continue;
|
|
124492
124413
|
}
|
|
@@ -124531,7 +124452,7 @@ async function handleLspConnection(ws, req) {
|
|
|
124531
124452
|
connection = await hostRegistry.hostFor(worktreeId4).lsp.connect({ worktreeId: worktreeId4, lang, root: worktree.worktreePath });
|
|
124532
124453
|
} catch (err) {
|
|
124533
124454
|
const message = err instanceof Error ? err.message : String(err);
|
|
124534
|
-
|
|
124455
|
+
log88.error("Failed to spawn %s language server for worktree %s: %s", lang, worktreeId4, message);
|
|
124535
124456
|
ws.close(4001, message);
|
|
124536
124457
|
return;
|
|
124537
124458
|
}
|
|
@@ -124539,7 +124460,7 @@ async function handleLspConnection(ws, req) {
|
|
|
124539
124460
|
connection.close();
|
|
124540
124461
|
return;
|
|
124541
124462
|
}
|
|
124542
|
-
|
|
124463
|
+
log88.debug("LSP client connected: %s/%s", worktreeId4, lang);
|
|
124543
124464
|
const pendingRequests = /* @__PURE__ */ new Map();
|
|
124544
124465
|
const openDocuments = /* @__PURE__ */ new Set();
|
|
124545
124466
|
const serverId = `${worktreeId4}:${lang}`;
|
|
@@ -124575,7 +124496,7 @@ async function handleLspConnection(ws, req) {
|
|
|
124575
124496
|
const retriedIds = /* @__PURE__ */ new Set();
|
|
124576
124497
|
const RETRY_DELAY_MS = 2e3;
|
|
124577
124498
|
const parseFrame = createFrameParser((json3) => {
|
|
124578
|
-
|
|
124499
|
+
log88.debug(
|
|
124579
124500
|
"LSP stdout [%s/%s]: %s",
|
|
124580
124501
|
worktreeId4,
|
|
124581
124502
|
lang,
|
|
@@ -124587,7 +124508,7 @@ async function handleLspConnection(ws, req) {
|
|
|
124587
124508
|
const originalRequest = pendingRequests.get(msg.id);
|
|
124588
124509
|
retriedIds.add(msg.id);
|
|
124589
124510
|
pendingRequests.delete(msg.id);
|
|
124590
|
-
|
|
124511
|
+
log88.debug(
|
|
124591
124512
|
"LSP retrying request %d after 'No Project' error [%s/%s]",
|
|
124592
124513
|
msg.id,
|
|
124593
124514
|
worktreeId4,
|
|
@@ -124618,16 +124539,16 @@ async function handleLspConnection(ws, req) {
|
|
|
124618
124539
|
for await (const chunk of connection.output)
|
|
124619
124540
|
parseFrame(Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength));
|
|
124620
124541
|
} catch (err) {
|
|
124621
|
-
|
|
124542
|
+
log88.warn("LSP output stream failed [%s/%s]: %s", worktreeId4, lang, String(err));
|
|
124622
124543
|
}
|
|
124623
124544
|
release();
|
|
124624
124545
|
if (ws.readyState === ws.OPEN) {
|
|
124625
|
-
|
|
124546
|
+
log88.debug("LSP server exited, closing WebSocket");
|
|
124626
124547
|
ws.close(1e3, "Language server exited");
|
|
124627
124548
|
}
|
|
124628
124549
|
})();
|
|
124629
124550
|
function forwardToStdin(json3) {
|
|
124630
|
-
|
|
124551
|
+
log88.debug(
|
|
124631
124552
|
"LSP stdin [%s/%s]: %s",
|
|
124632
124553
|
worktreeId4,
|
|
124633
124554
|
lang,
|
|
@@ -124659,7 +124580,7 @@ async function handleLspConnection(ws, req) {
|
|
|
124659
124580
|
ws.on("close", () => {
|
|
124660
124581
|
release();
|
|
124661
124582
|
connection.close();
|
|
124662
|
-
|
|
124583
|
+
log88.debug("LSP client disconnected: %s/%s (server kept alive)", worktreeId4, lang);
|
|
124663
124584
|
});
|
|
124664
124585
|
}
|
|
124665
124586
|
|
|
@@ -124668,7 +124589,7 @@ init_webhook();
|
|
|
124668
124589
|
|
|
124669
124590
|
// src/server/services/_utils/hosted-file.ts
|
|
124670
124591
|
init_registry();
|
|
124671
|
-
import { basename as basename6, dirname as dirname17, join as
|
|
124592
|
+
import { basename as basename6, dirname as dirname17, join as join57 } from "node:path";
|
|
124672
124593
|
async function openHostedFile(kind, worktreeId4, rawName, chatId) {
|
|
124673
124594
|
const host = hostRegistry.hostFor(worktreeId4);
|
|
124674
124595
|
if (host.id === hostRegistry.local.id) return null;
|
|
@@ -124682,7 +124603,7 @@ async function openHostedFile(kind, worktreeId4, rawName, chatId) {
|
|
|
124682
124603
|
try {
|
|
124683
124604
|
const dirs = (await host.info()).dirs;
|
|
124684
124605
|
if (!dirs) return null;
|
|
124685
|
-
const path2 = chatId ?
|
|
124606
|
+
const path2 = chatId ? join57(dirs[kind], worktreeId4, chatId, name5) : join57(dirs[kind], worktreeId4, name5);
|
|
124686
124607
|
const dir = await host.fs.realpath(dirname17(path2));
|
|
124687
124608
|
if (!(await host.fs.realpath(path2)).startsWith(`${dir}/`)) return null;
|
|
124688
124609
|
const stat7 = await host.fs.stat(path2, { followSymlinks: true });
|
|
@@ -132824,15 +132745,15 @@ init_src();
|
|
|
132824
132745
|
init_registry();
|
|
132825
132746
|
async function installSkills2(opts = {}) {
|
|
132826
132747
|
const result = await hostRegistry.local.agentEnv.installSkills({ home: opts.home });
|
|
132827
|
-
const
|
|
132828
|
-
if (
|
|
132829
|
-
for (const warning of result.warnings)
|
|
132830
|
-
for (const path2 of result.written)
|
|
132748
|
+
const log90 = opts.log;
|
|
132749
|
+
if (log90) {
|
|
132750
|
+
for (const warning of result.warnings) log90.warn(warning);
|
|
132751
|
+
for (const path2 of result.written) log90.info("Installed skill at %s", path2);
|
|
132831
132752
|
for (const path2 of result.updated) {
|
|
132832
|
-
|
|
132753
|
+
log90.info("Updated skill at %s (content differed \u2014 shipped version reinstalled)", path2);
|
|
132833
132754
|
}
|
|
132834
132755
|
for (const conflict of result.conflicts) {
|
|
132835
|
-
|
|
132756
|
+
log90.warn("Skill symlink conflict \u2014 %s (left as-is; remove it manually to re-link)", conflict);
|
|
132836
132757
|
}
|
|
132837
132758
|
}
|
|
132838
132759
|
return result;
|
|
@@ -132845,7 +132766,7 @@ init_state();
|
|
|
132845
132766
|
init_sync_service();
|
|
132846
132767
|
init_worktree_group_service();
|
|
132847
132768
|
init_worktree_service();
|
|
132848
|
-
var
|
|
132769
|
+
var log89 = createLogger("setup");
|
|
132849
132770
|
async function runFirstTimeSetup() {
|
|
132850
132771
|
forgetLocalWorktrees();
|
|
132851
132772
|
convertLegacyLabels();
|
|
@@ -132858,7 +132779,7 @@ async function runFirstTimeSetup() {
|
|
|
132858
132779
|
]);
|
|
132859
132780
|
for (const r of results) {
|
|
132860
132781
|
if (r.status === "rejected") {
|
|
132861
|
-
|
|
132782
|
+
log89.warn(
|
|
132862
132783
|
"Setup step failed: %s",
|
|
132863
132784
|
r.reason instanceof Error ? r.reason.message : String(r.reason)
|
|
132864
132785
|
);
|
|
@@ -132872,7 +132793,7 @@ async function refreshAgentModelsInBackground() {
|
|
|
132872
132793
|
const ok2 = results.filter((r) => !r.error).length;
|
|
132873
132794
|
const failed = results.length - ok2;
|
|
132874
132795
|
if (results.length > 0) {
|
|
132875
|
-
|
|
132796
|
+
log89.info(
|
|
132876
132797
|
"Background model refresh: %d/%d agents updated (%d failed)",
|
|
132877
132798
|
ok2,
|
|
132878
132799
|
results.length,
|
|
@@ -132880,7 +132801,7 @@ async function refreshAgentModelsInBackground() {
|
|
|
132880
132801
|
);
|
|
132881
132802
|
}
|
|
132882
132803
|
} catch (err) {
|
|
132883
|
-
|
|
132804
|
+
log89.warn(
|
|
132884
132805
|
"Background model refresh failed: %s",
|
|
132885
132806
|
err instanceof Error ? err.message : String(err)
|
|
132886
132807
|
);
|
|
@@ -132895,7 +132816,7 @@ async function ensureRepoRemotes() {
|
|
|
132895
132816
|
try {
|
|
132896
132817
|
await repoService.backfillRemotes();
|
|
132897
132818
|
} catch (err) {
|
|
132898
|
-
|
|
132819
|
+
log89.warn(
|
|
132899
132820
|
"Failed to record repo remotes at boot: %s",
|
|
132900
132821
|
err instanceof Error ? err.message : String(err)
|
|
132901
132822
|
);
|
|
@@ -132905,7 +132826,7 @@ function migrateRepoCronjobs() {
|
|
|
132905
132826
|
try {
|
|
132906
132827
|
cronjobService.migrateRepoJobs();
|
|
132907
132828
|
} catch (err) {
|
|
132908
|
-
|
|
132829
|
+
log89.warn(
|
|
132909
132830
|
"Failed to move repo-scoped cronjobs to worktrees at boot: %s",
|
|
132910
132831
|
err instanceof Error ? err.message : String(err)
|
|
132911
132832
|
);
|
|
@@ -132915,7 +132836,7 @@ function convertLegacyLabels() {
|
|
|
132915
132836
|
try {
|
|
132916
132837
|
worktreeGroupService.convertLegacyLabels();
|
|
132917
132838
|
} catch (err) {
|
|
132918
|
-
|
|
132839
|
+
log89.warn(
|
|
132919
132840
|
"Failed to convert repo labels to groups at boot: %s",
|
|
132920
132841
|
err instanceof Error ? err.message : String(err)
|
|
132921
132842
|
);
|
|
@@ -132925,7 +132846,7 @@ function forgetLocalWorktrees() {
|
|
|
132925
132846
|
try {
|
|
132926
132847
|
worktreeService.forgetLocalWorktrees();
|
|
132927
132848
|
} catch (err) {
|
|
132928
|
-
|
|
132849
|
+
log89.warn(
|
|
132929
132850
|
"Failed to forget local worktrees at boot: %s",
|
|
132930
132851
|
err instanceof Error ? err.message : String(err)
|
|
132931
132852
|
);
|
|
@@ -132935,7 +132856,7 @@ async function ensureRepoStateInSync() {
|
|
|
132935
132856
|
try {
|
|
132936
132857
|
await syncService.syncWorktrees();
|
|
132937
132858
|
} catch (err) {
|
|
132938
|
-
|
|
132859
|
+
log89.warn(
|
|
132939
132860
|
"Failed to sync repo state at boot: %s",
|
|
132940
132861
|
err instanceof Error ? err.message : String(err)
|
|
132941
132862
|
);
|
|
@@ -132946,22 +132867,22 @@ async function ensureCliInstalled() {
|
|
|
132946
132867
|
try {
|
|
132947
132868
|
cliStatus = await checkCli();
|
|
132948
132869
|
} catch (err) {
|
|
132949
|
-
|
|
132870
|
+
log89.warn("Could not check CLI status: %s", err instanceof Error ? err.message : String(err));
|
|
132950
132871
|
return;
|
|
132951
132872
|
}
|
|
132952
132873
|
if (cliStatus === "Installed") {
|
|
132953
132874
|
return;
|
|
132954
132875
|
}
|
|
132955
132876
|
if (cliStatus !== "NotInstalled") {
|
|
132956
|
-
|
|
132877
|
+
log89.warn("CLI not auto-installed (status: %s)", cliStatus);
|
|
132957
132878
|
return;
|
|
132958
132879
|
}
|
|
132959
|
-
|
|
132880
|
+
log89.info("Installing band CLI...");
|
|
132960
132881
|
try {
|
|
132961
132882
|
await installCli();
|
|
132962
|
-
|
|
132883
|
+
log89.info("CLI installed to %s", SYMLINK_PATH);
|
|
132963
132884
|
} catch (err) {
|
|
132964
|
-
|
|
132885
|
+
log89.warn("CLI installation failed: %s", err instanceof Error ? err.message : String(err));
|
|
132965
132886
|
}
|
|
132966
132887
|
}
|
|
132967
132888
|
async function ensureDefaultCodingAgents() {
|
|
@@ -132970,17 +132891,17 @@ async function ensureDefaultCodingAgents() {
|
|
|
132970
132891
|
if (Array.isArray(existing) && existing.length > 0) {
|
|
132971
132892
|
return;
|
|
132972
132893
|
}
|
|
132973
|
-
|
|
132894
|
+
log89.info("Detecting installed coding agents...");
|
|
132974
132895
|
const detected = [];
|
|
132975
132896
|
for (const check3 of AGENT_CHECKS) {
|
|
132976
132897
|
const path2 = await systemService.whichBinary(check3.binary);
|
|
132977
132898
|
if (path2) {
|
|
132978
|
-
|
|
132899
|
+
log89.info("Detected coding agent: %s (%s)", check3.id, path2);
|
|
132979
132900
|
detected.push({ id: check3.id, type: check3.type, label: check3.label });
|
|
132980
132901
|
}
|
|
132981
132902
|
}
|
|
132982
132903
|
if (detected.length === 0) {
|
|
132983
|
-
|
|
132904
|
+
log89.info("No coding agent CLIs detected on PATH");
|
|
132984
132905
|
return;
|
|
132985
132906
|
}
|
|
132986
132907
|
const current3 = loadSettings();
|
|
@@ -132989,7 +132910,7 @@ async function ensureDefaultCodingAgents() {
|
|
|
132989
132910
|
current3.defaultCodingAgent = detected[0].id;
|
|
132990
132911
|
}
|
|
132991
132912
|
saveSettings(current3);
|
|
132992
|
-
|
|
132913
|
+
log89.info("Enabled %d coding agent(s); default = %s", detected.length, current3.defaultCodingAgent);
|
|
132993
132914
|
}
|
|
132994
132915
|
function ensureNotificationDefaults() {
|
|
132995
132916
|
const settings3 = loadSettings();
|
|
@@ -133001,7 +132922,7 @@ function ensureNotificationDefaults() {
|
|
|
133001
132922
|
...settings3,
|
|
133002
132923
|
notifications: { ...notifications, soundOnNeedsAttention: true }
|
|
133003
132924
|
});
|
|
133004
|
-
|
|
132925
|
+
log89.info("Set default notifications.soundOnNeedsAttention = true");
|
|
133005
132926
|
}
|
|
133006
132927
|
function migrateAgentDefaultMode() {
|
|
133007
132928
|
const settings3 = loadSettings();
|
|
@@ -133009,15 +132930,15 @@ function migrateAgentDefaultMode() {
|
|
|
133009
132930
|
const mode = agentModeFromVia(settings3.cli?.defaultVia);
|
|
133010
132931
|
if (!mode) return;
|
|
133011
132932
|
saveSettings({ ...settings3, agents: { ...settings3.agents, defaultMode: mode } });
|
|
133012
|
-
|
|
132933
|
+
log89.info("Migrated cli.defaultVia to agents.defaultMode = %s", mode);
|
|
133013
132934
|
}
|
|
133014
132935
|
async function ensureSkillsInstalled() {
|
|
133015
132936
|
try {
|
|
133016
|
-
const result = await installSkills2({ log:
|
|
132937
|
+
const result = await installSkills2({ log: log89 });
|
|
133017
132938
|
const wrote = result.written.length + result.updated.length;
|
|
133018
132939
|
const linkChange = result.linked.length;
|
|
133019
132940
|
if (wrote > 0 || linkChange > 0 || result.conflicts.length > 0) {
|
|
133020
|
-
|
|
132941
|
+
log89.info(
|
|
133021
132942
|
"Synced CLI skills (shared: %d written, %d updated, %d unchanged; symlinks: %d created, %d already-linked, %d conflicts, %d skipped)",
|
|
133022
132943
|
result.written.length,
|
|
133023
132944
|
result.updated.length,
|
|
@@ -133029,7 +132950,7 @@ async function ensureSkillsInstalled() {
|
|
|
133029
132950
|
);
|
|
133030
132951
|
}
|
|
133031
132952
|
} catch (err) {
|
|
133032
|
-
|
|
132953
|
+
log89.warn("Failed to sync CLI skills: %s", err instanceof Error ? err.message : String(err));
|
|
133033
132954
|
}
|
|
133034
132955
|
}
|
|
133035
132956
|
var SetupService = class {
|
|
@@ -133050,7 +132971,7 @@ init_worktree_service();
|
|
|
133050
132971
|
function logCrash(message) {
|
|
133051
132972
|
try {
|
|
133052
132973
|
mkdirSync11(bandHome(), { recursive: true });
|
|
133053
|
-
appendFileSync2(
|
|
132974
|
+
appendFileSync2(join58(bandHome(), "server.log"), message, "utf-8");
|
|
133054
132975
|
} catch {
|
|
133055
132976
|
}
|
|
133056
132977
|
}
|
|
@@ -133090,9 +133011,9 @@ function resolveUiDir() {
|
|
|
133090
133011
|
if (explicit) return resolve14(explicit);
|
|
133091
133012
|
const candidates = [
|
|
133092
133013
|
resolve14(SERVER_ROOT, "..", "..", "web", "dist", "client"),
|
|
133093
|
-
|
|
133014
|
+
join58(SERVER_ROOT, "client")
|
|
133094
133015
|
];
|
|
133095
|
-
return candidates.find((dir) => existsSync18(
|
|
133016
|
+
return candidates.find((dir) => existsSync18(join58(dir, "_shell.html"))) ?? candidates[1];
|
|
133096
133017
|
}
|
|
133097
133018
|
var clientDir = resolveUiDir();
|
|
133098
133019
|
var uiRoot = process.env.BAND_UI_ROOT ? resolve14(process.env.BAND_UI_ROOT) : resolve14(SERVER_ROOT, "..", "web");
|
|
@@ -133143,7 +133064,7 @@ function getOpenApiSpec() {
|
|
|
133143
133064
|
if (isDev) {
|
|
133144
133065
|
const { generateOpenAPIDocument } = await import("@trpc/openapi");
|
|
133145
133066
|
const doc = await generateOpenAPIDocument(
|
|
133146
|
-
|
|
133067
|
+
join58(SERVER_ROOT, "src", "server", "api", "router.ts"),
|
|
133147
133068
|
{
|
|
133148
133069
|
title: "Band API",
|
|
133149
133070
|
version: "1.0.0"
|
|
@@ -133152,7 +133073,7 @@ function getOpenApiSpec() {
|
|
|
133152
133073
|
doc.servers = [{ url: "/trpc" }];
|
|
133153
133074
|
return JSON.stringify(doc, null, 2);
|
|
133154
133075
|
}
|
|
133155
|
-
const openApiDoc = JSON.parse(readFileSync12(
|
|
133076
|
+
const openApiDoc = JSON.parse(readFileSync12(join58(SERVER_ROOT, "openapi.json"), "utf-8"));
|
|
133156
133077
|
openApiDoc.servers = [{ url: "/trpc" }];
|
|
133157
133078
|
return JSON.stringify(openApiDoc, null, 2);
|
|
133158
133079
|
})().catch((err) => {
|
|
@@ -133182,9 +133103,9 @@ function serveStaticFile(res, root, subdir, rawFilename) {
|
|
|
133182
133103
|
res.end("Bad request");
|
|
133183
133104
|
return;
|
|
133184
133105
|
}
|
|
133185
|
-
const filePath =
|
|
133106
|
+
const filePath = join58(root, subdir, filename);
|
|
133186
133107
|
try {
|
|
133187
|
-
const dir = realpathSync7(
|
|
133108
|
+
const dir = realpathSync7(join58(root, subdir));
|
|
133188
133109
|
if (!realpathSync7(filePath).startsWith(dir + sep10)) {
|
|
133189
133110
|
res.writeHead(404);
|
|
133190
133111
|
res.end("Not found");
|
|
@@ -133235,7 +133156,7 @@ async function serveWorktreeFile(res, worktreeId4, rawPath, extraHeaders = {}, v
|
|
|
133235
133156
|
return;
|
|
133236
133157
|
}
|
|
133237
133158
|
const root = worktree.worktree.path;
|
|
133238
|
-
const target = resolve14(
|
|
133159
|
+
const target = resolve14(join58(root, rawPath));
|
|
133239
133160
|
if (!target.startsWith(root + sep10) && target !== root) {
|
|
133240
133161
|
res.writeHead(400);
|
|
133241
133162
|
res.end("Bad request");
|
|
@@ -133546,7 +133467,7 @@ async function main() {
|
|
|
133546
133467
|
res.end(JSON.stringify({ status: "ok", app: "band-web-server" }));
|
|
133547
133468
|
return;
|
|
133548
133469
|
}
|
|
133549
|
-
if (handleWebAppManifest(req, res, isDev ?
|
|
133470
|
+
if (handleWebAppManifest(req, res, isDev ? join58(uiRoot, "public") : clientDir)) return;
|
|
133550
133471
|
if (req.url?.split("?")[0] === WORKER_EXCHANGE_PATH) {
|
|
133551
133472
|
await workerLinkService.handleExchange(req, res);
|
|
133552
133473
|
return;
|
|
@@ -133654,7 +133575,7 @@ async function main() {
|
|
|
133654
133575
|
const encodedName = encodeURIComponent(parsed.name);
|
|
133655
133576
|
if (await serveHostedFile(res, "shared", parsed.worktreeId, encodedName, parsed.chatId))
|
|
133656
133577
|
return;
|
|
133657
|
-
const subdir = parsed.chatId ?
|
|
133578
|
+
const subdir = parsed.chatId ? join58("shared", parsed.worktreeId, parsed.chatId) : join58("shared", parsed.worktreeId);
|
|
133658
133579
|
serveStaticFile(res, bandHome(), subdir, encodedName);
|
|
133659
133580
|
return;
|
|
133660
133581
|
}
|
|
@@ -133875,7 +133796,7 @@ async function main() {
|
|
|
133875
133796
|
if (pathname.startsWith("/_shell")) res.setHeader("Cache-Control", "no-cache");
|
|
133876
133797
|
}
|
|
133877
133798
|
});
|
|
133878
|
-
const shellPath2 =
|
|
133799
|
+
const shellPath2 = join58(clientDir, "_shell.html");
|
|
133879
133800
|
if (!existsSync18(shellPath2)) {
|
|
133880
133801
|
throw new Error(
|
|
133881
133802
|
`UI build not found at ${clientDir} (no _shell.html). Run \`pnpm build\` or pass --ui-dir <path>.`
|