@band-app/server 0.54.0 → 0.54.2
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-zm8MgtWD.js} +1 -1
- package/dist/client/assets/{_basePickBy-D-5MXYU_.js → _basePickBy-Df9AWPQJ.js} +1 -1
- package/dist/client/assets/{_baseUniq-DYuk2xMI.js → _baseUniq-C8iGnWYN.js} +1 -1
- package/dist/client/assets/{arc-dXtOms1t.js → arc-Dotr_YMW.js} +1 -1
- package/dist/client/assets/{architectureDiagram-VXUJARFQ-CsyRS4YA.js → architectureDiagram-VXUJARFQ-BkG8VmpL.js} +1 -1
- package/dist/client/assets/{blockDiagram-VD42YOAC-DKwcsJ3k.js → blockDiagram-VD42YOAC-DZYGOHoq.js} +1 -1
- package/dist/client/assets/{c4Diagram-YG6GDRKO-B-1bWrTm.js → c4Diagram-YG6GDRKO-Ce9RV_Np.js} +1 -1
- package/dist/client/assets/channel-BQWEKiCC.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-Lx4boQMz.js → chunk-4BX2VUAB-Ck1qaTAA.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-C4WK81Kx.js → chunk-55IACEB6-CeH02gXd.js} +1 -1
- package/dist/client/assets/{chunk-B4BG7PRW-awrixx-i.js → chunk-B4BG7PRW-DqBzx79X.js} +1 -1
- package/dist/client/assets/{chunk-DI55MBZ5-BXvp16cX.js → chunk-DI55MBZ5-p68JZT5Z.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-DyY6khot.js → chunk-FMBD7UC4-DC8dY12t.js} +1 -1
- package/dist/client/assets/{chunk-QN33PNHL-BMvkmzKw.js → chunk-QN33PNHL-D1Af7sn_.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-CWY-fLAo.js → chunk-QZHKN3VN-BHBPr8iM.js} +1 -1
- package/dist/client/assets/{chunk-TZMSLE5B-BE-ngWv6.js → chunk-TZMSLE5B-BP9v1VXR.js} +1 -1
- package/dist/client/assets/classDiagram-2ON5EDUG-Bkz5oJ-y.js +1 -0
- package/dist/client/assets/classDiagram-v2-WZHVMYZB-Bkz5oJ-y.js +1 -0
- package/dist/client/assets/clone-Dr7z_3vQ.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-DJ8h3kKA.js → cose-bilkent-S5V4N54A-C7S-iRjs.js} +1 -1
- package/dist/client/assets/{dagre-6UL2VRFP-Bd1qWRGC.js → dagre-6UL2VRFP-CIdLKDDa.js} +1 -1
- package/dist/client/assets/{diagram-PSM6KHXK-BR64_p5f.js → diagram-PSM6KHXK-_VfU4I5J.js} +1 -1
- package/dist/client/assets/{diagram-QEK2KX5R-DFQt3gYM.js → diagram-QEK2KX5R-ByPoixdO.js} +1 -1
- package/dist/client/assets/{diagram-S2PKOQOG-C8HaYYzZ.js → diagram-S2PKOQOG-CU2nF5Pi.js} +1 -1
- package/dist/client/assets/{erDiagram-Q2GNP2WA-CS64Rcxd.js → erDiagram-Q2GNP2WA-DuReqla0.js} +1 -1
- package/dist/client/assets/{flowDiagram-NV44I4VS-C-lDTK_F.js → flowDiagram-NV44I4VS-BzbJhnQR.js} +1 -1
- package/dist/client/assets/{ganttDiagram-JELNMOA3-mfB20mUi.js → ganttDiagram-JELNMOA3-BeBP4O51.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-DIT7OOcN.js → gitGraphDiagram-V2S2FVAM-7rU4MgM6.js} +1 -1
- package/dist/client/assets/{graph-CuDWaZgk.js → graph-v9lPIGDx.js} +1 -1
- package/dist/client/assets/{highlighted-body-B3W2YXNL-CEukDjjL.js → highlighted-body-B3W2YXNL-Bt5DPhhI.js} +1 -1
- package/dist/client/assets/{index-BAJM6NLC.js → index-Be1D1vwS.js} +1 -1
- package/dist/client/assets/{index-BAlhbw5A.js → index-CJefa5Go.js} +1 -1
- package/dist/client/assets/{index-CQknVNu4.js → index-CsZW3tVv.js} +1 -1
- package/dist/client/assets/{index-DFdFKost.js → index-D2wFO-D3.js} +1 -1
- package/dist/client/assets/{index-DV3p0C-w.js → index-DGN6wKkW.js} +1 -1
- package/dist/client/assets/{index-CiKJmP62.js → index-DjGPjARU.js} +1 -1
- package/dist/client/assets/{index-BMcFlUOo.js → index-DoGYlvHl.js} +1 -1
- package/dist/client/assets/{index-B7yHTHBd.js → index-DrM0qB0a.js} +1 -1
- package/dist/client/assets/{index-CwJX9TIf.js → index-Dy40JkoS.js} +1 -1
- package/dist/client/assets/{index-CQfVS8uj.js → index-Q6D-8JjG.js} +1 -1
- package/dist/client/assets/{index-BAFH952I.js → index-Qk1h8PGS.js} +1 -1
- package/dist/client/assets/{index-CzkjYgaV.js → index-XAyPsPHs.js} +1 -1
- package/dist/client/assets/{index-B7DmSLZ5.js → index-jC0z3Kaq.js} +1 -1
- package/dist/client/assets/{infoDiagram-HS3SLOUP-BJFhYv2N.js → infoDiagram-HS3SLOUP-BOjyAfYW.js} +1 -1
- package/dist/client/assets/{journeyDiagram-XKPGCS4Q-CtemPXmL.js → journeyDiagram-XKPGCS4Q-daUwYLfO.js} +1 -1
- package/dist/client/assets/{kanban-definition-3W4ZIXB7-C9Xu3EkY.js → kanban-definition-3W4ZIXB7-Dkcl1vfA.js} +1 -1
- package/dist/client/assets/{layout-DtMsQ09j.js → layout-CSSEtaEF.js} +1 -1
- package/dist/client/assets/main-BYKQWpTo.css +1 -0
- package/dist/client/assets/{main-DashEqVP.js → main-BzXVe5ia.js} +253 -253
- package/dist/client/assets/{mindmap-definition-VGOIOE7T-C_FSSv6y.js → mindmap-definition-VGOIOE7T-D17_XGFA.js} +1 -1
- package/dist/client/assets/{pieDiagram-ADFJNKIX-BdDAYUXV.js → pieDiagram-ADFJNKIX-D07iYAxA.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-AYHSOK5B-B5g2nuTP.js → quadrantDiagram-AYHSOK5B-B9imU2k-.js} +1 -1
- package/dist/client/assets/{requirementDiagram-UZGBJVZJ-BYa9pNRf.js → requirementDiagram-UZGBJVZJ-CMH8dVSi.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-TZEHDZUN-Co2c_zNW.js → sankeyDiagram-TZEHDZUN-CWS08bde.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-WL72ISMW-eShduLQR.js → sequenceDiagram-WL72ISMW-BcDiQ1t6.js} +1 -1
- package/dist/client/assets/{stateDiagram-FKZM4ZOC-53kPEZua.js → stateDiagram-FKZM4ZOC-Be7DSpGK.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-4FDKWEC3-CSGrJZGI.js +1 -0
- package/dist/client/assets/{timeline-definition-IT6M3QCI-CZjtXE9X.js → timeline-definition-IT6M3QCI-BwTGYKzr.js} +1 -1
- package/dist/client/assets/{treemap-GDKQZRPO-DOvJYPBs.js → treemap-GDKQZRPO-DDASk1M2.js} +1 -1
- package/dist/client/assets/{worktree._worktreeId-BUGQ0lrG.js → worktree._worktreeId-C3DGXQD8.js} +1 -1
- package/dist/client/assets/{worktree._worktreeId-CvNxzyR7.js → worktree._worktreeId-DsTjUoT9.js} +1 -1
- package/dist/client/assets/{xychartDiagram-PRI3JC2R-BwZe0MO_.js → xychartDiagram-PRI3JC2R-CShK1tn5.js} +1 -1
- package/dist/openapi.json +16 -0
- package/dist/start-server.mjs +343 -367
- package/package.json +8 -7
- 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({
|
|
@@ -68350,6 +68350,9 @@ function validateHello(h) {
|
|
|
68350
68350
|
if (h.serviceManager !== void 0 && h.serviceManager !== "launchd" && h.serviceManager !== "systemd") {
|
|
68351
68351
|
return "serviceManager must be launchd or systemd";
|
|
68352
68352
|
}
|
|
68353
|
+
if (h.updateBlocked !== void 0 && (typeof h.updateBlocked !== "string" || h.updateBlocked.length > 300)) {
|
|
68354
|
+
return "updateBlocked must be a short string";
|
|
68355
|
+
}
|
|
68353
68356
|
if (h.tools !== void 0) {
|
|
68354
68357
|
const tools = h.tools;
|
|
68355
68358
|
if (typeof tools !== "object" || tools === null || Array.isArray(tools) || !Object.values(tools).every((v2) => typeof v2 === "string")) {
|
|
@@ -68472,6 +68475,8 @@ var init_channel = __esm({
|
|
|
68472
68475
|
reportedBytes = 0;
|
|
68473
68476
|
remoteEnded = false;
|
|
68474
68477
|
readWaiter = null;
|
|
68478
|
+
/** The reader left its loop early. Later data is consumed on arrival, so the channel can finish. */
|
|
68479
|
+
discarding = false;
|
|
68475
68480
|
failure = null;
|
|
68476
68481
|
host;
|
|
68477
68482
|
window;
|
|
@@ -68546,6 +68551,16 @@ var init_channel = __esm({
|
|
|
68546
68551
|
this.fail(new Error(`channel ${this.id} reset: ${reason}`));
|
|
68547
68552
|
}
|
|
68548
68553
|
// ---- session hooks -----------------------------------------------------
|
|
68554
|
+
/**
|
|
68555
|
+
* For a channel nobody on this side reads any more: one this side only writes to, or a reader
|
|
68556
|
+
* that left its loop for good. The peer's frames, including its end marker, are consumed on
|
|
68557
|
+
* arrival. Without that the end is never acknowledged and the channel stays in both
|
|
68558
|
+
* sessions' maps. Do not call it while a reader may still come back to the channel.
|
|
68559
|
+
*/
|
|
68560
|
+
discardIncoming() {
|
|
68561
|
+
this.discarding = true;
|
|
68562
|
+
this.discardInbox();
|
|
68563
|
+
}
|
|
68549
68564
|
/** After a (re)attach: restart transmission from the first frame the peer lacks. */
|
|
68550
68565
|
resumeSend(peerLastSeq) {
|
|
68551
68566
|
this.retained = this.retained.filter((f2) => f2.frame.seq > peerLastSeq);
|
|
@@ -68583,6 +68598,7 @@ var init_channel = __esm({
|
|
|
68583
68598
|
} else {
|
|
68584
68599
|
this.inbox.push({ seq: frame.seq, data: frame.payload });
|
|
68585
68600
|
}
|
|
68601
|
+
if (this.discarding) this.discardInbox();
|
|
68586
68602
|
this.wakeReader();
|
|
68587
68603
|
return;
|
|
68588
68604
|
}
|
|
@@ -68637,6 +68653,7 @@ var init_channel = __esm({
|
|
|
68637
68653
|
return { value: item.data, done: false };
|
|
68638
68654
|
}
|
|
68639
68655
|
if (this.failure) throw this.failure;
|
|
68656
|
+
if (this.discarding && this.remoteEnded) return { value: void 0, done: true };
|
|
68640
68657
|
await new Promise((resolve15) => {
|
|
68641
68658
|
this.readWaiter = resolve15;
|
|
68642
68659
|
});
|
|
@@ -68684,6 +68701,19 @@ var init_channel = __esm({
|
|
|
68684
68701
|
this.readWaiter = null;
|
|
68685
68702
|
w2?.();
|
|
68686
68703
|
}
|
|
68704
|
+
/** Consumes everything queued without delivering it, and reports the credit. */
|
|
68705
|
+
discardInbox() {
|
|
68706
|
+
while (this.inbox.length > 0) {
|
|
68707
|
+
const item = this.inbox.shift();
|
|
68708
|
+
this.consumedSeq = item.seq;
|
|
68709
|
+
if (item.data) {
|
|
68710
|
+
this.inboxBytes -= item.data.length;
|
|
68711
|
+
this.consumedBytes += item.data.length;
|
|
68712
|
+
}
|
|
68713
|
+
}
|
|
68714
|
+
this.sendCredit(true);
|
|
68715
|
+
this.maybeDone();
|
|
68716
|
+
}
|
|
68687
68717
|
maybeDone() {
|
|
68688
68718
|
if (this.localEndAcked && this.remoteEnded && this.inbox.length === 0)
|
|
68689
68719
|
this.host.channelDone(this.id);
|
|
@@ -68817,6 +68847,15 @@ var init_session3 = __esm({
|
|
|
68817
68847
|
getChannel(id) {
|
|
68818
68848
|
return this.channels.get(id);
|
|
68819
68849
|
}
|
|
68850
|
+
/** How many channels are open, by name. Largest first. */
|
|
68851
|
+
channelCounts() {
|
|
68852
|
+
const counts = /* @__PURE__ */ new Map();
|
|
68853
|
+
for (const ch of this.channels.values()) counts.set(ch.name, (counts.get(ch.name) ?? 0) + 1);
|
|
68854
|
+
return [...counts].map(([name5, count3]) => ({ name: name5, count: count3 })).sort((a, b2) => b2.count - a.count);
|
|
68855
|
+
}
|
|
68856
|
+
get openChannelCount() {
|
|
68857
|
+
return this.channels.size;
|
|
68858
|
+
}
|
|
68820
68859
|
/** Highest received sequence per channel, for `hello.resume` and `ready.resume`. */
|
|
68821
68860
|
resumeMap() {
|
|
68822
68861
|
const out = {};
|
|
@@ -68995,7 +69034,8 @@ var init_session3 = __esm({
|
|
|
68995
69034
|
}
|
|
68996
69035
|
if (this.channels.has(p2.chan) || this.tombstones.has(p2.chan)) return;
|
|
68997
69036
|
if (this.channels.size >= MAX_CHANNELS) {
|
|
68998
|
-
this.
|
|
69037
|
+
const held = this.channelCounts().slice(0, 5).map((c) => `${c.name}=${c.count}`).join(", ");
|
|
69038
|
+
this.emit("fault", `refused channel ${p2.chan}: too many channels (open: ${held})`);
|
|
68999
69039
|
this.writeBinary(
|
|
69000
69040
|
encodeFrame({
|
|
69001
69041
|
chan: p2.chan,
|
|
@@ -69134,6 +69174,7 @@ function sendPayload(session, value) {
|
|
|
69134
69174
|
const text4 = JSON.stringify(value ?? null);
|
|
69135
69175
|
if (Buffer.byteLength(text4) <= PAYLOAD_INLINE_LIMIT) return { json: value ?? null };
|
|
69136
69176
|
const ch = session.openChannel("payload");
|
|
69177
|
+
ch.discardIncoming();
|
|
69137
69178
|
ch.send(Buffer.from(text4)).then(
|
|
69138
69179
|
() => ch.end(),
|
|
69139
69180
|
() => void 0
|
|
@@ -69157,7 +69198,7 @@ var init_payload = __esm({
|
|
|
69157
69198
|
});
|
|
69158
69199
|
|
|
69159
69200
|
// ../../packages/link/src/relay.ts
|
|
69160
|
-
var METHOD_RELAY_REGISTER, METHOD_RELAY_REVOKE, METHOD_RELAY_HTTP, RELAY_MAX_BODY_BYTES,
|
|
69201
|
+
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
69202
|
var init_relay = __esm({
|
|
69162
69203
|
"../../packages/link/src/relay.ts"() {
|
|
69163
69204
|
"use strict";
|
|
@@ -69165,7 +69206,6 @@ var init_relay = __esm({
|
|
|
69165
69206
|
METHOD_RELAY_REVOKE = "relay.revoke";
|
|
69166
69207
|
METHOD_RELAY_HTTP = "relay.http";
|
|
69167
69208
|
RELAY_MAX_BODY_BYTES = 512 * 1024;
|
|
69168
|
-
METHOD_CLI_FETCH = "cli.fetch";
|
|
69169
69209
|
METHOD_LIFECYCLE_IDLE = "lifecycle.idle";
|
|
69170
69210
|
METHOD_LIFECYCLE_POLICY = "lifecycle.policy";
|
|
69171
69211
|
METHOD_LIFECYCLE_SLEEP = "lifecycle.sleep";
|
|
@@ -70994,6 +71034,7 @@ var init_pty2 = __esm({
|
|
|
70994
71034
|
this.done = true;
|
|
70995
71035
|
this.release();
|
|
70996
71036
|
this.channel.end();
|
|
71037
|
+
this.channel.discardIncoming();
|
|
70997
71038
|
}
|
|
70998
71039
|
release() {
|
|
70999
71040
|
const resume = this.resume;
|
|
@@ -71154,6 +71195,7 @@ function duplexOf(ch) {
|
|
|
71154
71195
|
close: () => {
|
|
71155
71196
|
closed = true;
|
|
71156
71197
|
ch.end();
|
|
71198
|
+
ch.discardIncoming();
|
|
71157
71199
|
}
|
|
71158
71200
|
};
|
|
71159
71201
|
}
|
|
@@ -71277,6 +71319,7 @@ var init_remote_host = __esm({
|
|
|
71277
71319
|
});
|
|
71278
71320
|
}
|
|
71279
71321
|
const ch = this.rpc.session().openChannel("speech.audio", {});
|
|
71322
|
+
ch.discardIncoming();
|
|
71280
71323
|
const done = this.rpc.call("speech.transcribe", {
|
|
71281
71324
|
...rest,
|
|
71282
71325
|
audio: { chan: ch.id }
|
|
@@ -71408,6 +71451,7 @@ var init_remote_host = __esm({
|
|
|
71408
71451
|
return;
|
|
71409
71452
|
}
|
|
71410
71453
|
const ch = this.rpc.session().openChannel("fs.write", { path: path2 });
|
|
71454
|
+
ch.discardIncoming();
|
|
71411
71455
|
const done = this.rpc.call("fs.writeFile", { ...base, data: { chan: ch.id } });
|
|
71412
71456
|
done.catch(() => void 0);
|
|
71413
71457
|
try {
|
|
@@ -71450,8 +71494,14 @@ var init_remote_host = __esm({
|
|
|
71450
71494
|
const reply = await this.rpc.request("acp.spawn", { ...launch, cwd });
|
|
71451
71495
|
const stdio = this.rpc.channel(reply.stdio);
|
|
71452
71496
|
const stderr = this.rpc.channel(reply.stderr);
|
|
71453
|
-
const exit = new Promise((resolve15) => this.agents.set(reply.agentId, resolve15));
|
|
71454
71497
|
let closed = false;
|
|
71498
|
+
const exit = new Promise(
|
|
71499
|
+
(resolve15) => this.agents.set(reply.agentId, (result) => {
|
|
71500
|
+
resolve15(result);
|
|
71501
|
+
closed = true;
|
|
71502
|
+
stdio.end();
|
|
71503
|
+
})
|
|
71504
|
+
);
|
|
71455
71505
|
return {
|
|
71456
71506
|
pid: reply.pid ?? void 0,
|
|
71457
71507
|
stdin: {
|
|
@@ -72246,8 +72296,8 @@ var init_environment_builds = __esm({
|
|
|
72246
72296
|
get(id) {
|
|
72247
72297
|
return getDb().select().from(environmentBuilds).where(eq2(environmentBuilds.id, id)).get();
|
|
72248
72298
|
}
|
|
72249
|
-
setLog(id,
|
|
72250
|
-
getDb().update(environmentBuilds).set({ log:
|
|
72299
|
+
setLog(id, log90) {
|
|
72300
|
+
getDb().update(environmentBuilds).set({ log: log90 }).where(eq2(environmentBuilds.id, id)).run();
|
|
72251
72301
|
}
|
|
72252
72302
|
finish(id, result) {
|
|
72253
72303
|
getDb().update(environmentBuilds).set({
|
|
@@ -72615,32 +72665,32 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72615
72665
|
}
|
|
72616
72666
|
// ---- running ---------------------------------------------------------------
|
|
72617
72667
|
async run(row, plan) {
|
|
72618
|
-
const
|
|
72668
|
+
const log90 = new BuildLog(row.id, (id, text4) => this.queries.setLog(id, text4));
|
|
72619
72669
|
let tmp = null;
|
|
72620
72670
|
const container = `band-env-${row.id.slice(0, 12)}`;
|
|
72621
72671
|
let failure4 = null;
|
|
72622
72672
|
try {
|
|
72623
|
-
|
|
72624
|
-
|
|
72673
|
+
log90.add(`Building ${plan.tag} for ${plan.repo} at ${plan.ref} (${plan.commit.slice(0, 12)})`);
|
|
72674
|
+
log90.flush();
|
|
72625
72675
|
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
|
-
|
|
72676
|
+
await this.exportCheckout(plan, tmp, log90);
|
|
72677
|
+
const toolchain = await this.buildToolchain(plan, tmp, log90);
|
|
72678
|
+
const layered = await this.addWorkerLayer(plan, tmp, toolchain, log90);
|
|
72679
|
+
await this.install(plan, tmp, layered, container, log90);
|
|
72680
|
+
if (plan.registry) await this.push(plan, log90);
|
|
72681
|
+
log90.add(`Done: ${plan.tag}`);
|
|
72632
72682
|
} catch (err) {
|
|
72633
72683
|
failure4 = err.message;
|
|
72634
|
-
|
|
72684
|
+
log90.add(`FAILED: ${failure4}`);
|
|
72635
72685
|
}
|
|
72636
|
-
await this.exec(plan.host, "docker", ["rm", "--force", container],
|
|
72686
|
+
await this.exec(plan.host, "docker", ["rm", "--force", container], log90, { quiet: true }).catch(
|
|
72637
72687
|
() => void 0
|
|
72638
72688
|
);
|
|
72639
72689
|
await this.exec(
|
|
72640
72690
|
plan.host,
|
|
72641
72691
|
"docker",
|
|
72642
72692
|
["rmi", toolchainTag(plan.repo, plan.key), layeredTag(plan.repo, plan.key)],
|
|
72643
|
-
|
|
72693
|
+
log90,
|
|
72644
72694
|
{ quiet: true }
|
|
72645
72695
|
).catch(() => void 0);
|
|
72646
72696
|
if (tmp) await plan.host.fs.rm(tmp, { recursive: true, force: true }).catch(() => void 0);
|
|
@@ -72649,14 +72699,14 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72649
72699
|
this.queries.finish(row.id, {
|
|
72650
72700
|
status: "ready",
|
|
72651
72701
|
image: plan.tag,
|
|
72652
|
-
log:
|
|
72702
|
+
log: log90.toString(),
|
|
72653
72703
|
at: Date.now()
|
|
72654
72704
|
});
|
|
72655
72705
|
} else {
|
|
72656
72706
|
this.queries.finish(row.id, {
|
|
72657
72707
|
status: "failed",
|
|
72658
72708
|
error: failure4.slice(0, 2e3),
|
|
72659
|
-
log:
|
|
72709
|
+
log: log90.toString(),
|
|
72660
72710
|
at: Date.now()
|
|
72661
72711
|
});
|
|
72662
72712
|
}
|
|
@@ -72665,9 +72715,9 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72665
72715
|
}
|
|
72666
72716
|
}
|
|
72667
72717
|
/** Runs a command on the builder host, adding it and its output to the log. */
|
|
72668
|
-
async exec(host, tool, args,
|
|
72718
|
+
async exec(host, tool, args, log90, options = {}) {
|
|
72669
72719
|
const bin = tool === "docker" ? this.dockerBin(host) : tool === "devcontainer" ? this.devcontainerBin(host) : "git";
|
|
72670
|
-
if (!options.quiet)
|
|
72720
|
+
if (!options.quiet) log90.add(`$ ${tool} ${args.join(" ")}`);
|
|
72671
72721
|
try {
|
|
72672
72722
|
const out = await host.exec(bin, args, {
|
|
72673
72723
|
cwd: options.cwd,
|
|
@@ -72675,35 +72725,35 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72675
72725
|
timeoutMs: envNumber("BAND_ENVIRONMENT_BUILD_TIMEOUT_MS", DEFAULT_STEP_TIMEOUT_MS)
|
|
72676
72726
|
});
|
|
72677
72727
|
if (!options.quiet) {
|
|
72678
|
-
if (out.stdout.trim())
|
|
72679
|
-
if (out.stderr.trim())
|
|
72680
|
-
|
|
72728
|
+
if (out.stdout.trim()) log90.add(out.stdout.trimEnd());
|
|
72729
|
+
if (out.stderr.trim()) log90.add(out.stderr.trimEnd());
|
|
72730
|
+
log90.flush();
|
|
72681
72731
|
}
|
|
72682
72732
|
return out.stdout;
|
|
72683
72733
|
} catch (err) {
|
|
72684
72734
|
if (!options.quiet) {
|
|
72685
|
-
|
|
72686
|
-
|
|
72735
|
+
log90.add(err.message);
|
|
72736
|
+
log90.flush();
|
|
72687
72737
|
}
|
|
72688
72738
|
throw new Error(`${tool} ${args[0] ?? ""} failed: ${firstLine(err.message)}`);
|
|
72689
72739
|
}
|
|
72690
72740
|
}
|
|
72691
72741
|
/** Writes the default branch's files, with no `.git`, to `<tmp>/src`. */
|
|
72692
|
-
async exportCheckout(plan, tmp,
|
|
72742
|
+
async exportCheckout(plan, tmp, log90) {
|
|
72693
72743
|
const src = posix4.join(tmp, "src");
|
|
72694
72744
|
await plan.host.fs.mkdir(src);
|
|
72695
72745
|
const index3 = posix4.join(tmp, "index");
|
|
72696
|
-
await this.exec(plan.host, "git", ["read-tree", plan.ref],
|
|
72746
|
+
await this.exec(plan.host, "git", ["read-tree", plan.ref], log90, {
|
|
72697
72747
|
cwd: plan.repoPath,
|
|
72698
72748
|
env: { GIT_INDEX_FILE: index3 }
|
|
72699
72749
|
});
|
|
72700
|
-
await this.exec(plan.host, "git", ["checkout-index", "--all", `--prefix=${src}/`],
|
|
72750
|
+
await this.exec(plan.host, "git", ["checkout-index", "--all", `--prefix=${src}/`], log90, {
|
|
72701
72751
|
cwd: plan.repoPath,
|
|
72702
72752
|
env: { GIT_INDEX_FILE: index3 }
|
|
72703
72753
|
});
|
|
72704
72754
|
}
|
|
72705
72755
|
/** Layer 2: returns the tag of an image holding the repo's toolchain. */
|
|
72706
|
-
async buildToolchain(plan, tmp,
|
|
72756
|
+
async buildToolchain(plan, tmp, log90) {
|
|
72707
72757
|
const build = plan.environment.build;
|
|
72708
72758
|
const src = posix4.join(tmp, "src");
|
|
72709
72759
|
const tag = toolchainTag(plan.repo, plan.key);
|
|
@@ -72712,7 +72762,7 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72712
72762
|
plan.host,
|
|
72713
72763
|
"docker",
|
|
72714
72764
|
dockerBuildArgs({ checkout: src, dockerfile: build.dockerfile, tag }),
|
|
72715
|
-
|
|
72765
|
+
log90
|
|
72716
72766
|
);
|
|
72717
72767
|
return tag;
|
|
72718
72768
|
}
|
|
@@ -72722,7 +72772,7 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72722
72772
|
plan.host,
|
|
72723
72773
|
"devcontainer",
|
|
72724
72774
|
devcontainerBuildArgs({ checkout: src, config: build.devcontainer, tag }),
|
|
72725
|
-
|
|
72775
|
+
log90
|
|
72726
72776
|
);
|
|
72727
72777
|
} catch (err) {
|
|
72728
72778
|
throw new Error(
|
|
@@ -72732,11 +72782,11 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72732
72782
|
return tag;
|
|
72733
72783
|
}
|
|
72734
72784
|
const image = build?.image;
|
|
72735
|
-
await this.exec(plan.host, "docker", ["pull", image],
|
|
72785
|
+
await this.exec(plan.host, "docker", ["pull", image], log90);
|
|
72736
72786
|
return image;
|
|
72737
72787
|
}
|
|
72738
72788
|
/** Layer 1 on top of layer 2: copies the worker from the worker base image. */
|
|
72739
|
-
async addWorkerLayer(plan, tmp, toolchain,
|
|
72789
|
+
async addWorkerLayer(plan, tmp, toolchain, log90) {
|
|
72740
72790
|
const dir = posix4.join(tmp, "layer");
|
|
72741
72791
|
await plan.host.fs.mkdir(dir);
|
|
72742
72792
|
await plan.host.fs.writeFile(
|
|
@@ -72748,38 +72798,38 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
|
|
|
72748
72798
|
});
|
|
72749
72799
|
await plan.host.fs.mkdir(posix4.join(dir, "root", "work"), { recursive: true });
|
|
72750
72800
|
const tag = layeredTag(plan.repo, plan.key);
|
|
72751
|
-
await this.exec(plan.host, "docker", ["build", "--tag", tag, dir],
|
|
72801
|
+
await this.exec(plan.host, "docker", ["build", "--tag", tag, dir], log90);
|
|
72752
72802
|
return tag;
|
|
72753
72803
|
}
|
|
72754
72804
|
/** Runs `install` at the default branch inside the image and commits the result as the final tag. */
|
|
72755
|
-
async install(plan, tmp, layered, container,
|
|
72805
|
+
async install(plan, tmp, layered, container, log90) {
|
|
72756
72806
|
const install = plan.environment.install;
|
|
72757
72807
|
if (install === void 0) {
|
|
72758
|
-
await this.exec(plan.host, "docker", ["tag", layered, plan.tag],
|
|
72808
|
+
await this.exec(plan.host, "docker", ["tag", layered, plan.tag], log90);
|
|
72759
72809
|
return;
|
|
72760
72810
|
}
|
|
72761
72811
|
await this.exec(
|
|
72762
72812
|
plan.host,
|
|
72763
72813
|
"docker",
|
|
72764
72814
|
installCreateArgs({ name: container, image: layered, install }),
|
|
72765
|
-
|
|
72815
|
+
log90
|
|
72766
72816
|
);
|
|
72767
72817
|
await this.exec(
|
|
72768
72818
|
plan.host,
|
|
72769
72819
|
"docker",
|
|
72770
72820
|
["cp", `${posix4.join(tmp, "src")}/.`, `${container}:${IMAGE_WORKDIR}`],
|
|
72771
|
-
|
|
72821
|
+
log90
|
|
72772
72822
|
);
|
|
72773
|
-
await this.exec(plan.host, "docker", ["start", "--attach", container],
|
|
72823
|
+
await this.exec(plan.host, "docker", ["start", "--attach", container], log90);
|
|
72774
72824
|
await this.exec(
|
|
72775
72825
|
plan.host,
|
|
72776
72826
|
"docker",
|
|
72777
72827
|
commitArgs({ container, tag: plan.tag, key: plan.key, commit: plan.commit }),
|
|
72778
|
-
|
|
72828
|
+
log90
|
|
72779
72829
|
);
|
|
72780
72830
|
}
|
|
72781
|
-
async push(plan,
|
|
72782
|
-
await this.exec(plan.host, "docker", ["push", plan.tag],
|
|
72831
|
+
async push(plan, log90) {
|
|
72832
|
+
await this.exec(plan.host, "docker", ["push", plan.tag], log90);
|
|
72783
72833
|
}
|
|
72784
72834
|
// ---- auto trigger ----------------------------------------------------------
|
|
72785
72835
|
/**
|
|
@@ -88196,11 +88246,11 @@ var require_core = __commonJS({
|
|
|
88196
88246
|
Ajv2.ValidationError = validation_error_1.default;
|
|
88197
88247
|
Ajv2.MissingRefError = ref_error_1.default;
|
|
88198
88248
|
exports.default = Ajv2;
|
|
88199
|
-
function checkOptions(checkOpts, options, msg,
|
|
88249
|
+
function checkOptions(checkOpts, options, msg, log90 = "error") {
|
|
88200
88250
|
for (const key2 in checkOpts) {
|
|
88201
88251
|
const opt = key2;
|
|
88202
88252
|
if (opt in options)
|
|
88203
|
-
this.logger[
|
|
88253
|
+
this.logger[log90](`${msg}: option ${key2}. ${checkOpts[opt]}`);
|
|
88204
88254
|
}
|
|
88205
88255
|
}
|
|
88206
88256
|
function getSchEnv(keyRef) {
|
|
@@ -90693,7 +90743,7 @@ import {
|
|
|
90693
90743
|
statSync as statSync16
|
|
90694
90744
|
} from "node:fs";
|
|
90695
90745
|
import { createServer as createServer3 } from "node:http";
|
|
90696
|
-
import { basename as basename7, join as
|
|
90746
|
+
import { basename as basename7, join as join58, resolve as resolve14, sep as sep10 } from "node:path";
|
|
90697
90747
|
import { pipeline as pipeline2, Readable as Readable2 } from "node:stream";
|
|
90698
90748
|
import { parseArgs } from "node:util";
|
|
90699
90749
|
|
|
@@ -111704,7 +111754,7 @@ init_registry();
|
|
|
111704
111754
|
// package.json
|
|
111705
111755
|
var package_default = {
|
|
111706
111756
|
name: "@band-app/server",
|
|
111707
|
-
version: "0.54.
|
|
111757
|
+
version: "0.54.2",
|
|
111708
111758
|
type: "module",
|
|
111709
111759
|
types: "src/index.ts",
|
|
111710
111760
|
exports: {
|
|
@@ -111744,6 +111794,7 @@ var package_default = {
|
|
|
111744
111794
|
"@agentclientprotocol/claude-agent-acp": "0.81.2",
|
|
111745
111795
|
"@agentclientprotocol/codex-acp": "1.13.1",
|
|
111746
111796
|
"@agentclientprotocol/sdk": "1.5.0",
|
|
111797
|
+
"@anthropic-ai/sdk": "1.1.0",
|
|
111747
111798
|
"@vscode/ripgrep": "^1.18.0",
|
|
111748
111799
|
"node-pty": "^1.1.0",
|
|
111749
111800
|
prettier: "^3.8.3",
|
|
@@ -111819,6 +111870,7 @@ function describeHostVersion(host, hubVersion, latest) {
|
|
|
111819
111870
|
serviceManager: null,
|
|
111820
111871
|
updateTarget: null,
|
|
111821
111872
|
canUpdate: false,
|
|
111873
|
+
updateBlockedReason: null,
|
|
111822
111874
|
manualCommand: null
|
|
111823
111875
|
};
|
|
111824
111876
|
}
|
|
@@ -111837,6 +111889,7 @@ function describeHostVersion(host, hubVersion, latest) {
|
|
|
111837
111889
|
serviceManager,
|
|
111838
111890
|
updateTarget,
|
|
111839
111891
|
canUpdate: host.status === "online" && serviceManager !== null && updateTarget !== null,
|
|
111892
|
+
updateBlockedReason: typeof host.info?.updateBlocked === "string" ? host.info.updateBlocked : null,
|
|
111840
111893
|
manualCommand: updateTarget ? workerUpdateCommand(updateTarget) : null
|
|
111841
111894
|
};
|
|
111842
111895
|
}
|
|
@@ -112721,84 +112774,6 @@ init_git_credential_service();
|
|
|
112721
112774
|
init_placement_service();
|
|
112722
112775
|
init_token_service();
|
|
112723
112776
|
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
112777
|
init_worker_lease_service();
|
|
112803
112778
|
|
|
112804
112779
|
// src/server/services/worker-relay-service.ts
|
|
@@ -112858,7 +112833,7 @@ function repoHostRefusal(repo, callerHostId) {
|
|
|
112858
112833
|
init_state();
|
|
112859
112834
|
init_subscription_service();
|
|
112860
112835
|
init_terminal_service();
|
|
112861
|
-
var
|
|
112836
|
+
var log65 = createLogger("worker-relay");
|
|
112862
112837
|
var REPLY_HEADERS = ["content-type", "cache-control", "mcp-session-id"];
|
|
112863
112838
|
var FORWARDED_HEADERS = [
|
|
112864
112839
|
"content-type",
|
|
@@ -112867,7 +112842,7 @@ var FORWARDED_HEADERS = [
|
|
|
112867
112842
|
"mcp-session-id",
|
|
112868
112843
|
"last-event-id"
|
|
112869
112844
|
];
|
|
112870
|
-
var
|
|
112845
|
+
var RPC_INVALID_PARAMS2 = -32602;
|
|
112871
112846
|
var defaultLookups = {
|
|
112872
112847
|
hostOfWorktree: (id) => hostRegistry.hostIdOfScope(id),
|
|
112873
112848
|
worktreeOfChat: (id) => {
|
|
@@ -112899,7 +112874,7 @@ var WorkerRelayService = class {
|
|
|
112899
112874
|
let request = parseRequest(params);
|
|
112900
112875
|
const verdict = checkRelayRequest(request, session.workerId, this.lookups);
|
|
112901
112876
|
if (!verdict.ok) {
|
|
112902
|
-
|
|
112877
|
+
log65.warn(
|
|
112903
112878
|
`refused ${request.method} ${request.path.split("?")[0]} from ${session.workerId}: ${verdict.reason}`
|
|
112904
112879
|
);
|
|
112905
112880
|
return this.answer(session, verdict.status, refusalBody(request, verdict));
|
|
@@ -112912,7 +112887,7 @@ var WorkerRelayService = class {
|
|
|
112912
112887
|
chatId: request.scope.chatId,
|
|
112913
112888
|
...entry
|
|
112914
112889
|
});
|
|
112915
|
-
|
|
112890
|
+
log65.info(
|
|
112916
112891
|
`admin host ${session.workerId} called ${entry.procedure}${entry.targetHostId ? ` on ${entry.targetHostId}` : ""}`
|
|
112917
112892
|
);
|
|
112918
112893
|
}
|
|
@@ -112945,7 +112920,7 @@ var WorkerRelayService = class {
|
|
|
112945
112920
|
redirect: "manual"
|
|
112946
112921
|
});
|
|
112947
112922
|
} catch (err) {
|
|
112948
|
-
|
|
112923
|
+
log65.warn(`relay call failed: ${err instanceof Error ? err.message : err}`);
|
|
112949
112924
|
return this.answer(session, 502, { error: "The hub could not answer" });
|
|
112950
112925
|
}
|
|
112951
112926
|
const replyHeaders = {};
|
|
@@ -112962,7 +112937,7 @@ var WorkerRelayService = class {
|
|
|
112962
112937
|
try {
|
|
112963
112938
|
return this.answer(session, upstream.status, redactSettingsReply(await upstream.json()));
|
|
112964
112939
|
} catch (err) {
|
|
112965
|
-
|
|
112940
|
+
log65.warn(`relay call failed: ${err instanceof Error ? err.message : err}`);
|
|
112966
112941
|
return this.answer(session, 502, { error: "The hub could not answer" });
|
|
112967
112942
|
}
|
|
112968
112943
|
}
|
|
@@ -112971,7 +112946,7 @@ var WorkerRelayService = class {
|
|
|
112971
112946
|
const filtered = filterReposReply(await upstream.json(), session.workerId);
|
|
112972
112947
|
return this.answer(session, upstream.status, filtered);
|
|
112973
112948
|
} catch (err) {
|
|
112974
|
-
|
|
112949
|
+
log65.warn(`relay call failed: ${err instanceof Error ? err.message : err}`);
|
|
112975
112950
|
return this.answer(session, 502, { error: "The hub could not answer" });
|
|
112976
112951
|
}
|
|
112977
112952
|
}
|
|
@@ -112979,7 +112954,7 @@ var WorkerRelayService = class {
|
|
|
112979
112954
|
try {
|
|
112980
112955
|
return this.answer(session, upstream.status, redactHostsReply(await upstream.json()));
|
|
112981
112956
|
} catch (err) {
|
|
112982
|
-
|
|
112957
|
+
log65.warn(`relay call failed: ${err instanceof Error ? err.message : err}`);
|
|
112983
112958
|
return this.answer(session, 502, { error: "The hub could not answer" });
|
|
112984
112959
|
}
|
|
112985
112960
|
}
|
|
@@ -113010,6 +112985,7 @@ var WorkerRelayService = class {
|
|
|
113010
112985
|
/** A short JSON answer, sent the same way as any other. */
|
|
113011
112986
|
answer(session, status, body) {
|
|
113012
112987
|
const ch = session.openChannel("relay.body");
|
|
112988
|
+
ch.discardIncoming();
|
|
113013
112989
|
ch.send(Buffer.from(JSON.stringify(body))).then(() => ch.end()).catch(() => void 0);
|
|
113014
112990
|
return { status, headers: { "content-type": "application/json" }, chan: ch.id };
|
|
113015
112991
|
}
|
|
@@ -113024,7 +113000,7 @@ function parseRequest(params) {
|
|
|
113024
113000
|
const p2 = params;
|
|
113025
113001
|
const scope3 = p2?.scope;
|
|
113026
113002
|
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(
|
|
113003
|
+
throw new RpcError(RPC_INVALID_PARAMS2, "bad relay.http params");
|
|
113028
113004
|
}
|
|
113029
113005
|
return p2;
|
|
113030
113006
|
}
|
|
@@ -113032,7 +113008,7 @@ var workerRelayService = new WorkerRelayService();
|
|
|
113032
113008
|
|
|
113033
113009
|
// src/server/services/worker-link-service.ts
|
|
113034
113010
|
init_worktree_service();
|
|
113035
|
-
var
|
|
113011
|
+
var log66 = createLogger("worker-link");
|
|
113036
113012
|
var repoQueries5 = new RepoQueries();
|
|
113037
113013
|
var LOCAL_HOST_ID12 = "local";
|
|
113038
113014
|
var CAPABILITY_REFRESH_MS = 3 * 6e4;
|
|
@@ -113063,7 +113039,7 @@ var WorkerLinkService = class {
|
|
|
113063
113039
|
this.server.on("disconnected", (session) => {
|
|
113064
113040
|
const close = session.lastClose;
|
|
113065
113041
|
if (close) {
|
|
113066
|
-
|
|
113042
|
+
log66.info(
|
|
113067
113043
|
`link of ${session.workerId} closed (code ${close.code}${close.reason ? `, ${close.reason}` : ""})`
|
|
113068
113044
|
);
|
|
113069
113045
|
}
|
|
@@ -113071,7 +113047,7 @@ var WorkerLinkService = class {
|
|
|
113071
113047
|
});
|
|
113072
113048
|
this.server.on(
|
|
113073
113049
|
"fault",
|
|
113074
|
-
(session, reason) =>
|
|
113050
|
+
(session, reason) => log66.warn(`link of ${session.workerId}: ${reason}`)
|
|
113075
113051
|
);
|
|
113076
113052
|
this.server.on(
|
|
113077
113053
|
"lost",
|
|
@@ -113096,12 +113072,12 @@ var WorkerLinkService = class {
|
|
|
113096
113072
|
const problem2 = compatibilityProblem(version3, HUB_VERSION);
|
|
113097
113073
|
if (!problem2) return auth2;
|
|
113098
113074
|
if (HUB_VERSION_UNRELEASED) {
|
|
113099
|
-
|
|
113075
|
+
log66.info(
|
|
113100
113076
|
`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
113077
|
);
|
|
113102
113078
|
return auth2;
|
|
113103
113079
|
}
|
|
113104
|
-
|
|
113080
|
+
log66.warn(`worker ${hello.workerId} refused: ${problem2}`);
|
|
113105
113081
|
if (this.server.getSession(hello.workerId)?.attached) {
|
|
113106
113082
|
return { ok: false, reason: problem2, code: VERSION_REFUSED_CODE };
|
|
113107
113083
|
}
|
|
@@ -113112,7 +113088,7 @@ var WorkerLinkService = class {
|
|
|
113112
113088
|
try {
|
|
113113
113089
|
this.queries.setHostRefusal(hello.workerId, { version: version3, reason: problem2 });
|
|
113114
113090
|
} catch (err) {
|
|
113115
|
-
|
|
113091
|
+
log66.warn(`could not record the refusal: ${err instanceof Error ? err.message : err}`);
|
|
113116
113092
|
}
|
|
113117
113093
|
this.publish(hello.workerId, "offline");
|
|
113118
113094
|
return { ok: false, reason: problem2, code: VERSION_REFUSED_CODE };
|
|
@@ -113135,7 +113111,7 @@ var WorkerLinkService = class {
|
|
|
113135
113111
|
this.refreshTimer.unref();
|
|
113136
113112
|
this.unsubscribeRevoke = this.tokens.onRevoked((row) => {
|
|
113137
113113
|
if (row.kind === "worker_session" && row.hostId) {
|
|
113138
|
-
if (this.server.drop(row.hostId, "token revoked"))
|
|
113114
|
+
if (this.server.drop(row.hostId, "token revoked")) log66.info(`cut link of ${row.hostId}`);
|
|
113139
113115
|
}
|
|
113140
113116
|
});
|
|
113141
113117
|
}
|
|
@@ -113165,7 +113141,7 @@ var WorkerLinkService = class {
|
|
|
113165
113141
|
this.queries.setHostInfo(row.id, stored);
|
|
113166
113142
|
if (changed) this.publish(row.id, "online");
|
|
113167
113143
|
} catch (err) {
|
|
113168
|
-
|
|
113144
|
+
log66.debug(
|
|
113169
113145
|
`could not refresh the report of ${row.id}: ${err instanceof Error ? err.message : err}`
|
|
113170
113146
|
);
|
|
113171
113147
|
}
|
|
@@ -113195,7 +113171,6 @@ var WorkerLinkService = class {
|
|
|
113195
113171
|
onSession(session) {
|
|
113196
113172
|
this.remoteHost(session.workerId).attachSession(session);
|
|
113197
113173
|
workerRelayService.attach(session);
|
|
113198
|
-
workerCliService.attach(session);
|
|
113199
113174
|
gitCredentialService.attach(session);
|
|
113200
113175
|
ephemeralLifecycleService.attach(session);
|
|
113201
113176
|
checkpointService.attach(session);
|
|
@@ -113209,7 +113184,7 @@ var WorkerLinkService = class {
|
|
|
113209
113184
|
try {
|
|
113210
113185
|
info = await this.remoteHost(workerId).info();
|
|
113211
113186
|
} catch (err) {
|
|
113212
|
-
|
|
113187
|
+
log66.warn(
|
|
113213
113188
|
`could not read host info from ${workerId}: ${err instanceof Error ? err.message : err}`
|
|
113214
113189
|
);
|
|
113215
113190
|
}
|
|
@@ -113224,42 +113199,43 @@ var WorkerLinkService = class {
|
|
|
113224
113199
|
agents: hello.agents,
|
|
113225
113200
|
tools: info?.tools ?? hello.tools ?? {},
|
|
113226
113201
|
mode: hello.mode,
|
|
113227
|
-
...hello.serviceManager ? { serviceManager: hello.serviceManager } : {}
|
|
113202
|
+
...hello.serviceManager ? { serviceManager: hello.serviceManager } : {},
|
|
113203
|
+
...hello.updateBlocked ? { updateBlocked: hello.updateBlocked } : {}
|
|
113228
113204
|
};
|
|
113229
113205
|
const version3 = workerVersionOf(hello);
|
|
113230
113206
|
this.queries.markHostOnline(workerId, at, { info: stored, version: version3 ?? hello.buildId });
|
|
113231
113207
|
workerUpdateService.onConnected(workerId, version3);
|
|
113232
|
-
|
|
113208
|
+
log66.info(`worker ${workerId} is online`);
|
|
113233
113209
|
workerLeaseService.onConnected(session);
|
|
113234
113210
|
try {
|
|
113235
113211
|
seedCodingAgentsFromTypes(hello.agents);
|
|
113236
113212
|
} catch (err) {
|
|
113237
|
-
|
|
113213
|
+
log66.warn(`could not seed coding agents: ${err instanceof Error ? err.message : err}`);
|
|
113238
113214
|
}
|
|
113239
113215
|
this.publish(workerId, "online");
|
|
113240
113216
|
void repoService.backfillRemotesFromWorker(workerId).catch((err) => {
|
|
113241
|
-
|
|
113217
|
+
log66.warn(`remote backfill on ${workerId}: ${err instanceof Error ? err.message : err}`);
|
|
113242
113218
|
});
|
|
113243
113219
|
chatOwnershipService.onConnected(session);
|
|
113244
113220
|
void ephemeralLifecycleService.onConnected(session);
|
|
113245
113221
|
void followService.onHostReturned(workerId).catch((err) => {
|
|
113246
|
-
|
|
113222
|
+
log66.warn(`follow check on ${workerId}: ${err instanceof Error ? err.message : err}`);
|
|
113247
113223
|
});
|
|
113248
113224
|
placementService.onHostOnline(workerId);
|
|
113249
113225
|
void worktreeService.finishPendingRemovals(workerId).catch((err) => {
|
|
113250
|
-
|
|
113226
|
+
log66.warn(`pending removals on ${workerId}: ${err instanceof Error ? err.message : err}`);
|
|
113251
113227
|
});
|
|
113252
113228
|
}
|
|
113253
113229
|
setStatus(workerId, status, lastSeenAt) {
|
|
113254
113230
|
try {
|
|
113255
113231
|
this.queries.setHostStatus(workerId, status, lastSeenAt);
|
|
113256
113232
|
} catch (err) {
|
|
113257
|
-
|
|
113233
|
+
log66.warn(
|
|
113258
113234
|
`could not record ${workerId} as ${status}: ${err instanceof Error ? err.message : err}`
|
|
113259
113235
|
);
|
|
113260
113236
|
return;
|
|
113261
113237
|
}
|
|
113262
|
-
|
|
113238
|
+
log66.info(`worker ${workerId} is ${status}`);
|
|
113263
113239
|
this.publish(workerId, status);
|
|
113264
113240
|
}
|
|
113265
113241
|
publish(hostId2, hostStatus) {
|
|
@@ -113304,7 +113280,7 @@ var WorkerLinkService = class {
|
|
|
113304
113280
|
send3(200, out);
|
|
113305
113281
|
} catch (err) {
|
|
113306
113282
|
if (!(err instanceof TokenExchangeError)) throw err;
|
|
113307
|
-
|
|
113283
|
+
log66.warn(`bootstrap exchange refused: ${err.reason}`);
|
|
113308
113284
|
send3(401, { error: "invalid or expired token" });
|
|
113309
113285
|
}
|
|
113310
113286
|
}
|
|
@@ -113321,7 +113297,7 @@ function reportKey(report2) {
|
|
|
113321
113297
|
|
|
113322
113298
|
// src/server/services/worker-update-service.ts
|
|
113323
113299
|
init_worktree_service();
|
|
113324
|
-
var
|
|
113300
|
+
var log67 = createLogger("worker-update");
|
|
113325
113301
|
var INSTALL_TIMEOUT_MS = 11 * 6e4;
|
|
113326
113302
|
var RESTART_TIMEOUT_MS = 3 * 6e4;
|
|
113327
113303
|
var WorkerUpdateError = class extends Error {
|
|
@@ -113367,7 +113343,7 @@ var WorkerUpdateService = class {
|
|
|
113367
113343
|
throw new WorkerUpdateError("not-updatable", "The worker is not connected");
|
|
113368
113344
|
const target = view4.updateTarget;
|
|
113369
113345
|
this.set(hostId2, { target, state: "installing", error: null }, row.status);
|
|
113370
|
-
|
|
113346
|
+
log67.info(`updating worker ${hostId2} to ${target}`);
|
|
113371
113347
|
void this.run(hostId2, target, session, row.status);
|
|
113372
113348
|
return { target };
|
|
113373
113349
|
}
|
|
@@ -113381,7 +113357,7 @@ var WorkerUpdateService = class {
|
|
|
113381
113357
|
} catch (err) {
|
|
113382
113358
|
const message = this.describe(err, target);
|
|
113383
113359
|
this.set(hostId2, { target, state: "failed", error: message }, hostStatus);
|
|
113384
|
-
|
|
113360
|
+
log67.warn(`update of worker ${hostId2} failed: ${message}`);
|
|
113385
113361
|
return;
|
|
113386
113362
|
}
|
|
113387
113363
|
if (this.updates.get(hostId2)?.state !== "installing") return;
|
|
@@ -113418,7 +113394,7 @@ var WorkerUpdateService = class {
|
|
|
113418
113394
|
this.timers.delete(hostId2);
|
|
113419
113395
|
if (version3 === current3.target) {
|
|
113420
113396
|
this.updates.delete(hostId2);
|
|
113421
|
-
|
|
113397
|
+
log67.info(`worker ${hostId2} now runs ${version3}`);
|
|
113422
113398
|
} else {
|
|
113423
113399
|
this.set(
|
|
113424
113400
|
hostId2,
|
|
@@ -116243,9 +116219,9 @@ init_zod();
|
|
|
116243
116219
|
// src/server/services/provisioning-service.ts
|
|
116244
116220
|
init_src();
|
|
116245
116221
|
init_dist();
|
|
116246
|
-
import { createHash as
|
|
116222
|
+
import { createHash as createHash12, randomBytes as randomBytes16, randomUUID as randomUUID18 } from "node:crypto";
|
|
116247
116223
|
import { createReadStream as createReadStream4, existsSync as existsSync17, mkdirSync as mkdirSync10, rmSync as rmSync7, statSync as statSync14 } from "node:fs";
|
|
116248
|
-
import { join as
|
|
116224
|
+
import { join as join52 } from "node:path";
|
|
116249
116225
|
|
|
116250
116226
|
// src/server/infra/db/queries/provisions.ts
|
|
116251
116227
|
init_drizzle_orm2();
|
|
@@ -116272,11 +116248,11 @@ var ProvisionQueries = class {
|
|
|
116272
116248
|
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
116249
|
return Number(result.changes ?? 0) > 0;
|
|
116274
116250
|
}
|
|
116275
|
-
setLog(id,
|
|
116276
|
-
this.db().update(hostProvisions).set({ log:
|
|
116251
|
+
setLog(id, log90, at) {
|
|
116252
|
+
this.db().update(hostProvisions).set({ log: log90, updatedAt: at }).where(eq2(hostProvisions.id, id)).run();
|
|
116277
116253
|
}
|
|
116278
|
-
finish(id, state2, exitCode,
|
|
116279
|
-
this.db().update(hostProvisions).set({ state: state2, exitCode, log:
|
|
116254
|
+
finish(id, state2, exitCode, log90, at) {
|
|
116255
|
+
this.db().update(hostProvisions).set({ state: state2, exitCode, log: log90, updatedAt: at }).where(eq2(hostProvisions.id, id)).run();
|
|
116280
116256
|
}
|
|
116281
116257
|
/** Ids of rows created before `at`, so their bundle files can be deleted. */
|
|
116282
116258
|
idsCreatedBefore(at) {
|
|
@@ -116528,7 +116504,7 @@ function renderProvisionScript(opts) {
|
|
|
116528
116504
|
init_settings_service();
|
|
116529
116505
|
init_token_service();
|
|
116530
116506
|
init_vault_service();
|
|
116531
|
-
var
|
|
116507
|
+
var log68 = createLogger("provisioning");
|
|
116532
116508
|
var DEFAULT_PROVISION_TTL_MS = 60 * 60 * 1e3;
|
|
116533
116509
|
var DEFAULT_START_COMMAND = "band/provision.sh";
|
|
116534
116510
|
var MAX_LOG_BYTES2 = 256 * 1024;
|
|
@@ -116560,7 +116536,7 @@ var ProvisionAuthError = class extends Error {
|
|
|
116560
116536
|
}
|
|
116561
116537
|
};
|
|
116562
116538
|
function sha2562(text4) {
|
|
116563
|
-
return
|
|
116539
|
+
return createHash12("sha256").update(text4).digest("hex");
|
|
116564
116540
|
}
|
|
116565
116541
|
function newSecret(prefix) {
|
|
116566
116542
|
return `${prefix}${randomBytes16(32).toString("base64url")}`;
|
|
@@ -116603,7 +116579,7 @@ var ProvisioningService = class {
|
|
|
116603
116579
|
return Date.now();
|
|
116604
116580
|
}
|
|
116605
116581
|
dir(id) {
|
|
116606
|
-
return
|
|
116582
|
+
return join52(bandHome(), "provisioning", id);
|
|
116607
116583
|
}
|
|
116608
116584
|
settings() {
|
|
116609
116585
|
const s2 = settingsService.get().provisioning ?? {};
|
|
@@ -116658,7 +116634,7 @@ var ProvisioningService = class {
|
|
|
116658
116634
|
spentAt: null,
|
|
116659
116635
|
updatedAt: at
|
|
116660
116636
|
});
|
|
116661
|
-
|
|
116637
|
+
log68.info(
|
|
116662
116638
|
`created provisioning command ${id}${commitSha ? ` at ${commitSha.slice(0, 12)}` : ""}`
|
|
116663
116639
|
);
|
|
116664
116640
|
const command2 = `curl -fsSL ${hubUrl}/api/provision/${code}/script | sh`;
|
|
@@ -116698,7 +116674,7 @@ var ProvisioningService = class {
|
|
|
116698
116674
|
tokenService.removeHost(boot.hostId);
|
|
116699
116675
|
throw new ProvisionExchangeError("used");
|
|
116700
116676
|
}
|
|
116701
|
-
|
|
116677
|
+
log68.info(`exchanged provisioning code ${row.id} for host ${boot.hostId}`);
|
|
116702
116678
|
const lines = [
|
|
116703
116679
|
`token=${boot.token}`,
|
|
116704
116680
|
`workerId=${boot.hostId}`,
|
|
@@ -116723,7 +116699,7 @@ var ProvisioningService = class {
|
|
|
116723
116699
|
/** The bundle file and size for a code, once its run token is shown. */
|
|
116724
116700
|
bundle(code, runToken) {
|
|
116725
116701
|
const row = this.authorize(code, runToken);
|
|
116726
|
-
const file3 =
|
|
116702
|
+
const file3 = join52(this.dir(row.id), "bundle.tgz");
|
|
116727
116703
|
if (!row.repoUrl || !existsSync17(file3)) throw new ProvisionAuthError();
|
|
116728
116704
|
return { stream: createReadStream4(file3), size: statSync14(file3).size };
|
|
116729
116705
|
}
|
|
@@ -116740,7 +116716,7 @@ var ProvisioningService = class {
|
|
|
116740
116716
|
return;
|
|
116741
116717
|
}
|
|
116742
116718
|
this.queries.finish(row.id, exit === 0 ? "done" : "failed", exit, next, at);
|
|
116743
|
-
if (exit !== 0)
|
|
116719
|
+
if (exit !== 0) log68.info(`provisioning ${row.id} failed with exit code ${exit}`);
|
|
116744
116720
|
}
|
|
116745
116721
|
status(id) {
|
|
116746
116722
|
const row = this.queries.findById(id);
|
|
@@ -116765,7 +116741,7 @@ band provision: the worker did not say hello within ${minutes} min. Marked faile
|
|
|
116765
116741
|
`;
|
|
116766
116742
|
const exitCode = row.exitCode ?? TIMEOUT_EXIT_CODE;
|
|
116767
116743
|
this.queries.finish(row.id, "failed", exitCode, row.log + note, at);
|
|
116768
|
-
|
|
116744
|
+
log68.info(`provisioning ${row.id} timed out waiting for host ${row.hostId}`);
|
|
116769
116745
|
return { ...row, state: "failed", exitCode, log: row.log + note };
|
|
116770
116746
|
}
|
|
116771
116747
|
view(spent) {
|
|
@@ -116802,7 +116778,7 @@ band provision: the worker did not say hello within ${minutes} min. Marked faile
|
|
|
116802
116778
|
async buildBundle(id, settings3) {
|
|
116803
116779
|
const dir = this.dir(id);
|
|
116804
116780
|
mkdirSync10(dir, { recursive: true });
|
|
116805
|
-
const src =
|
|
116781
|
+
const src = join52(dir, "src");
|
|
116806
116782
|
const host = hostRegistry.local;
|
|
116807
116783
|
const env = { GIT_TERMINAL_PROMPT: "0" };
|
|
116808
116784
|
const key2 = parseRemoteUrl2(settings3.repoUrl);
|
|
@@ -116824,10 +116800,10 @@ band provision: the worker did not say hello within ${minutes} min. Marked faile
|
|
|
116824
116800
|
await host.exec("git", args, { env, timeoutMs: 12e4 });
|
|
116825
116801
|
const sha = (await host.exec("git", ["-C", src, "rev-parse", "HEAD"], { env })).stdout.trim();
|
|
116826
116802
|
const command2 = settings3.command || DEFAULT_START_COMMAND;
|
|
116827
|
-
if (!existsSync17(
|
|
116803
|
+
if (!existsSync17(join52(src, command2))) {
|
|
116828
116804
|
throw new Error(`the repo at ${sha.slice(0, 12)} has no ${command2}`);
|
|
116829
116805
|
}
|
|
116830
|
-
await host.exec("tar", ["-czf",
|
|
116806
|
+
await host.exec("tar", ["-czf", join52(dir, "bundle.tgz"), "--exclude=.git", "-C", src, "."], {
|
|
116831
116807
|
timeoutMs: 12e4
|
|
116832
116808
|
});
|
|
116833
116809
|
rmSync7(src, { recursive: true, force: true });
|
|
@@ -116920,12 +116896,12 @@ init_zod();
|
|
|
116920
116896
|
init_registry();
|
|
116921
116897
|
init_queued_message_store();
|
|
116922
116898
|
import { realpathSync as realpathSync6 } from "node:fs";
|
|
116923
|
-
import { join as
|
|
116899
|
+
import { join as join53, resolve as resolve11, sep as sep7 } from "node:path";
|
|
116924
116900
|
init_chat_ownership_service();
|
|
116925
116901
|
init_chat_service();
|
|
116926
116902
|
init_state();
|
|
116927
116903
|
init_task_service();
|
|
116928
|
-
var
|
|
116904
|
+
var log69 = createLogger("trpc.queue");
|
|
116929
116905
|
var queuedFileSchema = external_exports2.object({
|
|
116930
116906
|
mediaType: external_exports2.string(),
|
|
116931
116907
|
url: external_exports2.string(),
|
|
@@ -116933,7 +116909,7 @@ var queuedFileSchema = external_exports2.object({
|
|
|
116933
116909
|
filename: external_exports2.string().optional()
|
|
116934
116910
|
});
|
|
116935
116911
|
function isPathWithinUploadDir(p2) {
|
|
116936
|
-
const uploadDir =
|
|
116912
|
+
const uploadDir = join53(bandHome(), "uploads");
|
|
116937
116913
|
const normalized2 = resolve11(p2);
|
|
116938
116914
|
if (normalized2 !== uploadDir && !normalized2.startsWith(uploadDir + sep7)) {
|
|
116939
116915
|
return false;
|
|
@@ -116958,7 +116934,7 @@ async function resolveQueuedFiles(chatId, worktreeId4, files) {
|
|
|
116958
116934
|
if (derivedPath) {
|
|
116959
116935
|
const inside = remote ? await isWithinUploads(worktreeId4, derivedPath) : isPathWithinUploadDir(derivedPath);
|
|
116960
116936
|
if (!inside) {
|
|
116961
|
-
|
|
116937
|
+
log69.warn(
|
|
116962
116938
|
{ chatId, path: derivedPath, filename: file3.filename },
|
|
116963
116939
|
"queue: dropping file with path outside uploads directory"
|
|
116964
116940
|
);
|
|
@@ -116983,7 +116959,7 @@ async function resolveQueuedFiles(chatId, worktreeId4, files) {
|
|
|
116983
116959
|
});
|
|
116984
116960
|
continue;
|
|
116985
116961
|
}
|
|
116986
|
-
|
|
116962
|
+
log69.warn(
|
|
116987
116963
|
{ chatId, url: file3.url, filename: file3.filename },
|
|
116988
116964
|
"queue: dropping file with no path and non-data URL \u2014 cannot recover disk path"
|
|
116989
116965
|
);
|
|
@@ -116991,7 +116967,7 @@ async function resolveQueuedFiles(chatId, worktreeId4, files) {
|
|
|
116991
116967
|
if (needsSave.length > 0) {
|
|
116992
116968
|
const saved = await saveWorktreeUploads(worktreeId4, needsSave);
|
|
116993
116969
|
if (saved.length !== needsSave.length) {
|
|
116994
|
-
|
|
116970
|
+
log69.error(
|
|
116995
116971
|
{ chatId, expected: needsSave.length, got: saved.length },
|
|
116996
116972
|
"queue: saveUploadedFilesDetailed returned unexpected count \u2014 dropping data-URL files (cannot map 1:1)"
|
|
116997
116973
|
);
|
|
@@ -117024,7 +117000,7 @@ var queueRouter = t.router({
|
|
|
117024
117000
|
try {
|
|
117025
117001
|
files = await resolveQueuedFiles(chatId, input2.worktreeId, input2.files);
|
|
117026
117002
|
} catch (err) {
|
|
117027
|
-
|
|
117003
|
+
log69.error(
|
|
117028
117004
|
{ chatId, err: err instanceof Error ? err.message : err },
|
|
117029
117005
|
"queue.push: failed to persist file uploads; enqueuing text only"
|
|
117030
117006
|
);
|
|
@@ -117074,7 +117050,7 @@ var queueRouter = t.router({
|
|
|
117074
117050
|
files: await resolveQueuedFiles(chatId, input2.worktreeId, m2.files)
|
|
117075
117051
|
};
|
|
117076
117052
|
} catch (err) {
|
|
117077
|
-
|
|
117053
|
+
log69.error(
|
|
117078
117054
|
{ chatId, messageId: m2.id, err: err instanceof Error ? err.message : err },
|
|
117079
117055
|
"queue: failed to resolve files for queued message; dropping its files"
|
|
117080
117056
|
);
|
|
@@ -117231,7 +117207,7 @@ function aggregateTurnsByHourAndModel(snap, provider) {
|
|
|
117231
117207
|
}
|
|
117232
117208
|
return Array.from(buckets.values());
|
|
117233
117209
|
}
|
|
117234
|
-
var
|
|
117210
|
+
var log70 = createLogger("usage-scanner");
|
|
117235
117211
|
var SCHEDULER_KEY2 = Symbol.for("band.usage-scanner");
|
|
117236
117212
|
var g7 = globalThis;
|
|
117237
117213
|
if (!g7[SCHEDULER_KEY2]) {
|
|
@@ -117293,14 +117269,14 @@ var UsageScannerService = class {
|
|
|
117293
117269
|
try {
|
|
117294
117270
|
totalRows += await this.scanPair(ws, a);
|
|
117295
117271
|
} catch (err) {
|
|
117296
|
-
|
|
117272
|
+
log70.warn(
|
|
117297
117273
|
{ err, worktreeId: ws.worktreeId, agentType: a.agentType },
|
|
117298
117274
|
"usage scanner pair failed"
|
|
117299
117275
|
);
|
|
117300
117276
|
}
|
|
117301
117277
|
}
|
|
117302
117278
|
}
|
|
117303
|
-
|
|
117279
|
+
log70.debug(
|
|
117304
117280
|
{ durationMs: this.now() - started, worktrees: worktrees2.length, rowsWritten: totalRows },
|
|
117305
117281
|
"usage scanner tick complete"
|
|
117306
117282
|
);
|
|
@@ -117345,7 +117321,7 @@ var UsageScannerService = class {
|
|
|
117345
117321
|
try {
|
|
117346
117322
|
reader = await this.getUsageReader(a, ws.hostId);
|
|
117347
117323
|
} catch (err) {
|
|
117348
|
-
|
|
117324
|
+
log70.debug({ err, agentId: a.agentId }, "failed to resolve usage reader for scan");
|
|
117349
117325
|
return 0;
|
|
117350
117326
|
}
|
|
117351
117327
|
if (!reader) return 0;
|
|
@@ -117354,7 +117330,7 @@ var UsageScannerService = class {
|
|
|
117354
117330
|
try {
|
|
117355
117331
|
sessions = await reader.listSessions(ws.worktreePath);
|
|
117356
117332
|
} catch (err) {
|
|
117357
|
-
|
|
117333
|
+
log70.debug(
|
|
117358
117334
|
{ err, agentId: a.agentId, worktreePath: ws.worktreePath },
|
|
117359
117335
|
"listSessions failed during usage scan"
|
|
117360
117336
|
);
|
|
@@ -117370,7 +117346,7 @@ var UsageScannerService = class {
|
|
|
117370
117346
|
try {
|
|
117371
117347
|
snap = await reader.getSessionUsage(s2.sessionId, ws.worktreePath);
|
|
117372
117348
|
} catch (err) {
|
|
117373
|
-
|
|
117349
|
+
log70.debug(
|
|
117374
117350
|
{ err, sessionId: s2.sessionId, agentType: a.agentType },
|
|
117375
117351
|
"getSessionUsage failed"
|
|
117376
117352
|
);
|
|
@@ -117409,7 +117385,7 @@ var UsageScannerService = class {
|
|
|
117409
117385
|
this.scanState.set(ws.worktreeId, a.agentType, maxObserved);
|
|
117410
117386
|
}
|
|
117411
117387
|
if (changed.length > slice.length) {
|
|
117412
|
-
|
|
117388
|
+
log70.debug(
|
|
117413
117389
|
{
|
|
117414
117390
|
worktreeId: ws.worktreeId,
|
|
117415
117391
|
agentType: a.agentType,
|
|
@@ -117476,11 +117452,11 @@ function startUsageScanner(options = {}) {
|
|
|
117476
117452
|
const intervalMs = options.intervalMs ?? USAGE_SCAN_INTERVAL_MS;
|
|
117477
117453
|
const svc = getUsageScannerService();
|
|
117478
117454
|
svc.tick().catch((err) => {
|
|
117479
|
-
|
|
117455
|
+
log70.warn({ err }, "initial usage scanner tick failed");
|
|
117480
117456
|
});
|
|
117481
117457
|
const timer = setInterval(() => {
|
|
117482
117458
|
svc.tick().catch((err) => {
|
|
117483
|
-
|
|
117459
|
+
log70.warn({ err }, "scheduled usage scanner tick failed");
|
|
117484
117460
|
});
|
|
117485
117461
|
}, intervalMs);
|
|
117486
117462
|
timer.unref();
|
|
@@ -117851,7 +117827,7 @@ function worktreeGh(host, localHostId, cwd) {
|
|
|
117851
117827
|
init_branch_status_poller();
|
|
117852
117828
|
init_plugin_host_service();
|
|
117853
117829
|
init_worktree_service();
|
|
117854
|
-
var
|
|
117830
|
+
var log71 = createLogger("review-service");
|
|
117855
117831
|
var NoOpenReviewError = class extends Error {
|
|
117856
117832
|
constructor(worktreeId4) {
|
|
117857
117833
|
super(`No open review to merge for worktree ${worktreeId4}`);
|
|
@@ -117892,7 +117868,7 @@ var ReviewService = class {
|
|
|
117892
117868
|
};
|
|
117893
117869
|
} catch (err) {
|
|
117894
117870
|
const message = err instanceof Error ? err.message : String(err);
|
|
117895
|
-
|
|
117871
|
+
log71.warn("Review lookup failed for %s (%s): %s", worktreeId4, provider.id, message);
|
|
117896
117872
|
return { status: "error", message };
|
|
117897
117873
|
}
|
|
117898
117874
|
}
|
|
@@ -118057,7 +118033,7 @@ init_ephemeral_lifecycle_service();
|
|
|
118057
118033
|
init_runner_service();
|
|
118058
118034
|
init_state();
|
|
118059
118035
|
init_token_service();
|
|
118060
|
-
var
|
|
118036
|
+
var log72 = createLogger("reaper");
|
|
118061
118037
|
var DEFAULT_INTERVAL_MS = 3e4;
|
|
118062
118038
|
var DEFAULT_HELLO_GRACE_MS = 6e4;
|
|
118063
118039
|
var DEFAULT_OFFLINE_MS = 12e4;
|
|
@@ -118154,12 +118130,12 @@ var RunnerReaperService = class {
|
|
|
118154
118130
|
try {
|
|
118155
118131
|
await this.reap(machine, Date.now());
|
|
118156
118132
|
} catch (err) {
|
|
118157
|
-
|
|
118133
|
+
log72.warn(`could not check machine ${machine.id}: ${errorText5(err)}`);
|
|
118158
118134
|
}
|
|
118159
118135
|
}
|
|
118160
118136
|
await this.reapOrphans();
|
|
118161
118137
|
} catch (err) {
|
|
118162
|
-
|
|
118138
|
+
log72.warn(`sweep failed: ${errorText5(err)}`);
|
|
118163
118139
|
} finally {
|
|
118164
118140
|
this.ticking = false;
|
|
118165
118141
|
}
|
|
@@ -118221,7 +118197,7 @@ var RunnerReaperService = class {
|
|
|
118221
118197
|
const deadline = machine.spawnedAt + lifetimeMs + runner.lifetimeGraceSec * 1e3;
|
|
118222
118198
|
if (machine.state === "running") {
|
|
118223
118199
|
this.machines.update(machine.id, { state: "stopping", stoppingSince: now });
|
|
118224
|
-
|
|
118200
|
+
log72.info(`machine ${machine.id} reached its maximum lifetime of ${runner.maxLifetimeSec}s`);
|
|
118225
118201
|
}
|
|
118226
118202
|
const reason = `maximum lifetime of ${runner.maxLifetimeSec}s reached`;
|
|
118227
118203
|
if (!online) {
|
|
@@ -118267,7 +118243,7 @@ var RunnerReaperService = class {
|
|
|
118267
118243
|
return;
|
|
118268
118244
|
}
|
|
118269
118245
|
const lost = this.unstored(machine.workerId);
|
|
118270
|
-
|
|
118246
|
+
log72.error(
|
|
118271
118247
|
`HARD DEADLINE: destroying machine ${machine.id} (${reason}) although worktree(s) ${lost.join(", ") || "of its worker"} were not stored`
|
|
118272
118248
|
);
|
|
118273
118249
|
await this.destroyNow(
|
|
@@ -118294,11 +118270,11 @@ var RunnerReaperService = class {
|
|
|
118294
118270
|
const key2 = `${machine.id}:${text4}`;
|
|
118295
118271
|
if (!this.warned.has(key2)) {
|
|
118296
118272
|
this.warned.add(key2);
|
|
118297
|
-
|
|
118273
|
+
log72.info(`machine ${machine.id}: ${text4}`);
|
|
118298
118274
|
}
|
|
118299
118275
|
}
|
|
118300
118276
|
async destroyNow(machine, reason, opts = {}) {
|
|
118301
|
-
|
|
118277
|
+
log72.info(`destroying machine ${machine.id} of runner ${machine.runnerId}: ${reason}`);
|
|
118302
118278
|
const task = this.runners.destroyMachine(machine.id, reason);
|
|
118303
118279
|
this.pending.add(task);
|
|
118304
118280
|
try {
|
|
@@ -118314,7 +118290,7 @@ var RunnerReaperService = class {
|
|
|
118314
118290
|
tokenService.removeHost(hostId2);
|
|
118315
118291
|
hostRegistry.unregister(hostId2);
|
|
118316
118292
|
} catch (err) {
|
|
118317
|
-
|
|
118293
|
+
log72.warn(`could not remove host ${hostId2}: ${errorText5(err)}`);
|
|
118318
118294
|
}
|
|
118319
118295
|
}
|
|
118320
118296
|
// ---- orphans ---------------------------------------------------------------
|
|
@@ -118333,7 +118309,7 @@ var RunnerReaperService = class {
|
|
|
118333
118309
|
try {
|
|
118334
118310
|
handles = await this.runners.listHandles(runner);
|
|
118335
118311
|
} catch (err) {
|
|
118336
|
-
|
|
118312
|
+
log72.warn(`status of runner ${runner.id} failed: ${errorText5(err)}`);
|
|
118337
118313
|
continue;
|
|
118338
118314
|
}
|
|
118339
118315
|
if (this.runners.hasAttemptInFlight(runner.id)) continue;
|
|
@@ -118345,10 +118321,10 @@ var RunnerReaperService = class {
|
|
|
118345
118321
|
if (nowKnown.has(handle)) continue;
|
|
118346
118322
|
const ok2 = await this.runners.destroyHandle(runner, handle, "no record of this machine");
|
|
118347
118323
|
if (ok2) {
|
|
118348
|
-
|
|
118324
|
+
log72.info(`destroyed orphan ${handle} of runner ${runner.id}`);
|
|
118349
118325
|
this.machines.settleHandle(runner.id, handle, "destroyed by the reaper as an orphan");
|
|
118350
118326
|
} else {
|
|
118351
|
-
|
|
118327
|
+
log72.warn(`could not destroy orphan ${handle} of runner ${runner.id}`);
|
|
118352
118328
|
}
|
|
118353
118329
|
}
|
|
118354
118330
|
}
|
|
@@ -118414,7 +118390,7 @@ init_errors6();
|
|
|
118414
118390
|
init_agent_session_service();
|
|
118415
118391
|
init_chat_service();
|
|
118416
118392
|
init_worktree_service();
|
|
118417
|
-
var
|
|
118393
|
+
var log73 = createLogger("session-service");
|
|
118418
118394
|
var SessionService = class {
|
|
118419
118395
|
/** Lists past sessions for a worktree's chat pane (default chat when
|
|
118420
118396
|
* `chatId` is undefined). */
|
|
@@ -118427,7 +118403,7 @@ var SessionService = class {
|
|
|
118427
118403
|
if (!chatService.get(chatId)) {
|
|
118428
118404
|
chatService.create(input2.worktreeId, { id: chatId, name: "Chat" });
|
|
118429
118405
|
}
|
|
118430
|
-
|
|
118406
|
+
log73.debug({ chatId, worktreeId: input2.worktreeId }, "listing past sessions for chat");
|
|
118431
118407
|
return agentSessionService.listSessions(chatId);
|
|
118432
118408
|
}
|
|
118433
118409
|
};
|
|
@@ -118754,7 +118730,7 @@ init_branch_status_poller();
|
|
|
118754
118730
|
init_client_activity_service();
|
|
118755
118731
|
init_state();
|
|
118756
118732
|
init_tunnel_service();
|
|
118757
|
-
var
|
|
118733
|
+
var log74 = createLogger("trpc.system");
|
|
118758
118734
|
var systemRouter = t.router({
|
|
118759
118735
|
/**
|
|
118760
118736
|
* Combined liveness probe — webserver is always true if this query
|
|
@@ -118762,16 +118738,16 @@ var systemRouter = t.router({
|
|
|
118762
118738
|
* an interval to drive the bottom-bar status pill.
|
|
118763
118739
|
*/
|
|
118764
118740
|
health: publicProcedure.query(() => {
|
|
118765
|
-
|
|
118741
|
+
log74.debug("services.health called");
|
|
118766
118742
|
const tunnel = tunnelService.getStatus();
|
|
118767
|
-
|
|
118743
|
+
log74.debug({ tunnel }, "services.health: tunnel status");
|
|
118768
118744
|
const result = {
|
|
118769
118745
|
webserver: true,
|
|
118770
118746
|
version: package_default.version,
|
|
118771
118747
|
tunnel: tunnel.running,
|
|
118772
118748
|
tunnel_url: tunnel.url
|
|
118773
118749
|
};
|
|
118774
|
-
|
|
118750
|
+
log74.debug({ result }, "services.health result");
|
|
118775
118751
|
return result;
|
|
118776
118752
|
}),
|
|
118777
118753
|
// What this client's UI is doing, so the branch-status poller can slow down. A client names
|
|
@@ -118910,7 +118886,7 @@ init_errors6();
|
|
|
118910
118886
|
init_chat_service();
|
|
118911
118887
|
init_state();
|
|
118912
118888
|
init_task_service();
|
|
118913
|
-
var
|
|
118889
|
+
var log75 = createLogger("tasks-router");
|
|
118914
118890
|
var tasksRouter = t.router({
|
|
118915
118891
|
list: publicProcedure.input(
|
|
118916
118892
|
external_exports2.object({
|
|
@@ -118972,7 +118948,7 @@ var tasksRouter = t.router({
|
|
|
118972
118948
|
if (input2.files && input2.files.length > 0) {
|
|
118973
118949
|
const savedFiles = await saveWorktreeUploads(input2.worktreeId, input2.files);
|
|
118974
118950
|
if (savedFiles.length !== input2.files.length) {
|
|
118975
|
-
|
|
118951
|
+
log75.warn(
|
|
118976
118952
|
{ chatId, submitted: input2.files.length, saved: savedFiles.length },
|
|
118977
118953
|
"tasks.submit: some file uploads were dropped (malformed data URL?)"
|
|
118978
118954
|
);
|
|
@@ -119398,25 +119374,25 @@ var tokensRouter = t.router({
|
|
|
119398
119374
|
init_src();
|
|
119399
119375
|
init_zod();
|
|
119400
119376
|
init_tunnel_service();
|
|
119401
|
-
var
|
|
119377
|
+
var log76 = createLogger("trpc.tunnel");
|
|
119402
119378
|
var tunnelRouter = t.router({
|
|
119403
119379
|
status: publicProcedure.query(() => {
|
|
119404
119380
|
return tunnelService.getStatus();
|
|
119405
119381
|
}),
|
|
119406
119382
|
start: publicProcedure.input(external_exports2.object({}).optional()).mutation(async () => {
|
|
119407
|
-
|
|
119383
|
+
log76.debug("tunnel.start called");
|
|
119408
119384
|
try {
|
|
119409
119385
|
await tunnelService.start();
|
|
119410
119386
|
} catch (err) {
|
|
119411
|
-
|
|
119387
|
+
log76.debug({ err }, "tunnel.start: startTunnel failed");
|
|
119412
119388
|
return { ok: true, url: null };
|
|
119413
119389
|
}
|
|
119414
119390
|
const status = tunnelService.getStatus();
|
|
119415
|
-
|
|
119391
|
+
log76.debug({ status }, "tunnel.start: after startTunnel");
|
|
119416
119392
|
if (status.url) {
|
|
119417
119393
|
return { ok: true, url: status.url };
|
|
119418
119394
|
}
|
|
119419
|
-
|
|
119395
|
+
log76.debug("tunnel.start: no URL available");
|
|
119420
119396
|
return { ok: true, url: null };
|
|
119421
119397
|
}),
|
|
119422
119398
|
stop: publicProcedure.mutation(async () => {
|
|
@@ -119806,8 +119782,8 @@ function verifyWorktreePreviewGrant(worktreeId4, grant, filePath, now = Date.now
|
|
|
119806
119782
|
init_src2();
|
|
119807
119783
|
init_src();
|
|
119808
119784
|
init_resolver();
|
|
119809
|
-
import { join as
|
|
119810
|
-
var
|
|
119785
|
+
import { join as join54, resolve as resolve12, sep as sep8 } from "node:path";
|
|
119786
|
+
var log77 = createLogger("diff-service");
|
|
119811
119787
|
var EMPTY_TREE_ARGS = ["hash-object", "-t", "tree", "/dev/null"];
|
|
119812
119788
|
var DEFAULT_BRANCH_LIMIT = 50;
|
|
119813
119789
|
var STAGING_BRANCH_PRIORITY = [
|
|
@@ -119903,7 +119879,7 @@ function parseFileStatuses(nameStatusOutput) {
|
|
|
119903
119879
|
return fileStatuses;
|
|
119904
119880
|
}
|
|
119905
119881
|
function assertWorktreeRelative(cwd, filePath) {
|
|
119906
|
-
const target = resolve12(
|
|
119882
|
+
const target = resolve12(join54(cwd, filePath));
|
|
119907
119883
|
if (target !== cwd && !target.startsWith(cwd + sep8)) {
|
|
119908
119884
|
throw new Error("Invalid path");
|
|
119909
119885
|
}
|
|
@@ -119918,7 +119894,7 @@ function assertWorktreeRelative(cwd, filePath) {
|
|
|
119918
119894
|
}
|
|
119919
119895
|
async function readUntrackedFileLines(host, cwd, file3) {
|
|
119920
119896
|
try {
|
|
119921
|
-
const content = new TextDecoder().decode(await host.fs.readFile(
|
|
119897
|
+
const content = new TextDecoder().decode(await host.fs.readFile(join54(cwd, file3)));
|
|
119922
119898
|
const lines = content.split("\n");
|
|
119923
119899
|
if (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
119924
119900
|
lines.pop();
|
|
@@ -120154,7 +120130,7 @@ var DiffService = class {
|
|
|
120154
120130
|
);
|
|
120155
120131
|
refs = output2.split("\n").map((line2) => parseBranchRef(line2.trim())).filter((ref) => ref !== null);
|
|
120156
120132
|
} catch (err) {
|
|
120157
|
-
|
|
120133
|
+
log77.error(
|
|
120158
120134
|
`listBranches: for-each-ref failed for ${cwd}: ${err instanceof Error ? err.message : err}`
|
|
120159
120135
|
);
|
|
120160
120136
|
}
|
|
@@ -120265,7 +120241,7 @@ var DiffService = class {
|
|
|
120265
120241
|
const compareBranch = options.compareBranch ?? defaultBranch;
|
|
120266
120242
|
const cwd = worktree.worktree.path;
|
|
120267
120243
|
const execGit2 = gitRunner(worktree.host);
|
|
120268
|
-
const hasGit = await worktree.host.fs.stat(
|
|
120244
|
+
const hasGit = await worktree.host.fs.stat(join54(cwd, ".git")).then(
|
|
120269
120245
|
() => true,
|
|
120270
120246
|
(err) => {
|
|
120271
120247
|
if (err instanceof HostOfflineError || err instanceof HostTimeoutError) throw err;
|
|
@@ -120303,7 +120279,7 @@ var DiffService = class {
|
|
|
120303
120279
|
applyLineCounts(status.staged, parseNumstat(stagedNumstat));
|
|
120304
120280
|
await Promise.all(
|
|
120305
120281
|
status.untracked.map(async (entry) => {
|
|
120306
|
-
const lines = await countUntrackedLines(worktree.host,
|
|
120282
|
+
const lines = await countUntrackedLines(worktree.host, join54(cwd, entry.path));
|
|
120307
120283
|
if (lines !== null) {
|
|
120308
120284
|
entry.additions = lines;
|
|
120309
120285
|
entry.deletions = 0;
|
|
@@ -120460,7 +120436,7 @@ init_src();
|
|
|
120460
120436
|
init_errors6();
|
|
120461
120437
|
init_local_host_policy();
|
|
120462
120438
|
init_worktree_service();
|
|
120463
|
-
var
|
|
120439
|
+
var log78 = createLogger("direct-access");
|
|
120464
120440
|
var DEFAULT_TOKEN_TTL_MS2 = 10 * 6e4;
|
|
120465
120441
|
function tokenTtlMs() {
|
|
120466
120442
|
const ms = Number(process.env.BAND_DIRECT_TOKEN_TTL_MS);
|
|
@@ -120495,7 +120471,7 @@ var DirectAccessService = class {
|
|
|
120495
120471
|
);
|
|
120496
120472
|
return { hostId: hostId2, ...grant };
|
|
120497
120473
|
} catch (err) {
|
|
120498
|
-
|
|
120474
|
+
log78.debug(
|
|
120499
120475
|
{ hostId: hostId2, worktreeId: worktreeId4, message: err instanceof Error ? err.message : String(err) },
|
|
120500
120476
|
"no direct path to the worker"
|
|
120501
120477
|
);
|
|
@@ -120507,7 +120483,7 @@ var directAccessService = new DirectAccessService();
|
|
|
120507
120483
|
|
|
120508
120484
|
// ../../packages/worktree-ops/src/files.ts
|
|
120509
120485
|
init_resolver();
|
|
120510
|
-
import { dirname as dirname16, extname as extname3, join as
|
|
120486
|
+
import { dirname as dirname16, extname as extname3, join as join55, resolve as resolve13, sep as sep9 } from "node:path";
|
|
120511
120487
|
var MAX_FILE_SIZE2 = 1024 * 1024;
|
|
120512
120488
|
var LANG_MAP2 = {
|
|
120513
120489
|
".js": "javascript",
|
|
@@ -120574,7 +120550,7 @@ var FilesService = class {
|
|
|
120574
120550
|
throw new WorktreeNotFoundError(worktreeId4);
|
|
120575
120551
|
}
|
|
120576
120552
|
const root = worktree.worktree.path;
|
|
120577
|
-
const target = resolve13(
|
|
120553
|
+
const target = resolve13(join55(root, relative2));
|
|
120578
120554
|
const insideRoot = target === root || target.startsWith(root + sep9);
|
|
120579
120555
|
if (!insideRoot) {
|
|
120580
120556
|
throw new Error("Invalid path");
|
|
@@ -120755,7 +120731,7 @@ var filesService = new FilesService({
|
|
|
120755
120731
|
|
|
120756
120732
|
// src/server/services/git-graph-service.ts
|
|
120757
120733
|
init_src2();
|
|
120758
|
-
import { createHash as
|
|
120734
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
120759
120735
|
init_errors6();
|
|
120760
120736
|
init_worktree_service();
|
|
120761
120737
|
var FS = "";
|
|
@@ -120827,7 +120803,7 @@ var GitGraphService = class {
|
|
|
120827
120803
|
} catch {
|
|
120828
120804
|
return "";
|
|
120829
120805
|
}
|
|
120830
|
-
return
|
|
120806
|
+
return createHash13("sha1").update(out).digest("hex");
|
|
120831
120807
|
}
|
|
120832
120808
|
/**
|
|
120833
120809
|
* One page of HEAD's history, newest first in topological order, so every
|
|
@@ -122871,7 +122847,7 @@ async function readBody2(req, max3) {
|
|
|
122871
122847
|
// src/server/api/mcp-proxy/stdio.ts
|
|
122872
122848
|
init_src();
|
|
122873
122849
|
init_mcp_stdio_service();
|
|
122874
|
-
var
|
|
122850
|
+
var log79 = createLogger("mcp-proxy-stdio");
|
|
122875
122851
|
var MAX_REQUEST_BYTES = 4 * 1024 * 1024;
|
|
122876
122852
|
var sessionHeader = (req) => {
|
|
122877
122853
|
const value = req.headers["mcp-session-id"];
|
|
@@ -123002,7 +122978,7 @@ data: ${JSON.stringify(message)}
|
|
|
123002
122978
|
if (gone) {
|
|
123003
122979
|
return sendJson3(res, 404, { error: "The stdio MCP server's session ended" });
|
|
123004
122980
|
}
|
|
123005
|
-
|
|
122981
|
+
log79.warn(
|
|
123006
122982
|
{ server: server.name, err: err instanceof Error ? err.name : "unknown" },
|
|
123007
122983
|
"no answer"
|
|
123008
122984
|
);
|
|
@@ -123027,7 +123003,7 @@ data: ${JSON.stringify(message)}
|
|
|
123027
123003
|
}
|
|
123028
123004
|
|
|
123029
123005
|
// src/server/api/mcp-proxy/handler.ts
|
|
123030
|
-
var
|
|
123006
|
+
var log80 = createLogger("mcp-proxy");
|
|
123031
123007
|
var MCP_PROXY_PREFIX = "/mcp-proxy/";
|
|
123032
123008
|
var ROUTE = /^\/mcp-proxy\/([^/]+)\/?$/;
|
|
123033
123009
|
var MAX_REQUEST_BYTES2 = 4 * 1024 * 1024;
|
|
@@ -123189,13 +123165,13 @@ async function handleMcpProxy(req, res) {
|
|
|
123189
123165
|
try {
|
|
123190
123166
|
upstream = await sendUpstream(server, { method, headers, body, signal: abort.signal });
|
|
123191
123167
|
} catch (err) {
|
|
123192
|
-
|
|
123168
|
+
log80.warn({ server: name5, err: errorCode2(err) }, "upstream failed");
|
|
123193
123169
|
auditUnanswered(server, auth2.sessionId, plan, "upstream-unreachable");
|
|
123194
123170
|
return sendJson3(res, 502, { error: "The upstream MCP server did not answer" });
|
|
123195
123171
|
}
|
|
123196
123172
|
if (upstream.status === 401 || upstream.status >= 300 && upstream.status < 400) {
|
|
123197
123173
|
await upstream.body?.cancel().catch(() => void 0);
|
|
123198
|
-
|
|
123174
|
+
log80.warn({ server: name5, status: upstream.status }, "upstream refused the stored credential");
|
|
123199
123175
|
auditUnanswered(server, auth2.sessionId, plan, `upstream-${upstream.status}`);
|
|
123200
123176
|
return sendJson3(res, 502, {
|
|
123201
123177
|
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 +123239,7 @@ async function handleMcpProxy(req, res) {
|
|
|
123263
123239
|
} catch (err) {
|
|
123264
123240
|
auditUnanswered(server, auth2.sessionId, plan, "stream-failed");
|
|
123265
123241
|
if (!abort.signal.aborted) {
|
|
123266
|
-
|
|
123242
|
+
log80.warn(
|
|
123267
123243
|
{ server: name5, err: errorCode2(err) },
|
|
123268
123244
|
err instanceof SseEventTooLargeError ? "event too large to inspect" : "proxy stream failed"
|
|
123269
123245
|
);
|
|
@@ -123298,7 +123274,7 @@ function getScalarHtml(specUrl) {
|
|
|
123298
123274
|
// src/server/api/pairing/handler.ts
|
|
123299
123275
|
init_src();
|
|
123300
123276
|
init_token_service();
|
|
123301
|
-
var
|
|
123277
|
+
var log81 = createLogger("pairing");
|
|
123302
123278
|
var PAIR_EXCHANGE_PATH = "/api/pair/exchange";
|
|
123303
123279
|
var MAX_BODY_BYTES2 = 4096;
|
|
123304
123280
|
var PAIR_REFUSED_MESSAGE = "This link was already used or has expired. Ask for a new one in Settings > Devices.";
|
|
@@ -123390,7 +123366,7 @@ async function handlePairExchange(req, res) {
|
|
|
123390
123366
|
send3(200, out, { "Set-Cookie": buildCookieHeader(out.token, isSecure(req)) });
|
|
123391
123367
|
} catch (err) {
|
|
123392
123368
|
if (!(err instanceof PairingExchangeError)) throw err;
|
|
123393
|
-
|
|
123369
|
+
log81.debug(`pairing exchange refused: ${err.reason}`);
|
|
123394
123370
|
send3(401, { error: PAIR_REFUSED_MESSAGE });
|
|
123395
123371
|
}
|
|
123396
123372
|
}
|
|
@@ -123398,7 +123374,7 @@ async function handlePairExchange(req, res) {
|
|
|
123398
123374
|
// src/server/api/provisioning/handler.ts
|
|
123399
123375
|
init_src();
|
|
123400
123376
|
import { pipeline } from "node:stream";
|
|
123401
|
-
var
|
|
123377
|
+
var log82 = createLogger("provisioning");
|
|
123402
123378
|
var PROVISION_PREFIX = "/api/provision/";
|
|
123403
123379
|
var MAX_EXCHANGE_BODY_BYTES2 = 4096;
|
|
123404
123380
|
var MAX_LOG_BODY_BYTES = 128 * 1024;
|
|
@@ -123455,7 +123431,7 @@ async function handleProvision(req, res) {
|
|
|
123455
123431
|
send3(200, provisioningService.exchange(code2), "text/plain; charset=utf-8");
|
|
123456
123432
|
} catch (err) {
|
|
123457
123433
|
if (!(err instanceof ProvisionExchangeError)) throw err;
|
|
123458
|
-
|
|
123434
|
+
log82.debug(`provisioning exchange refused: ${err.reason}`);
|
|
123459
123435
|
refused();
|
|
123460
123436
|
}
|
|
123461
123437
|
return;
|
|
@@ -123591,7 +123567,7 @@ var OutputFlow = class {
|
|
|
123591
123567
|
};
|
|
123592
123568
|
|
|
123593
123569
|
// ../../packages/worktree-ops/src/terminal-socket.ts
|
|
123594
|
-
var
|
|
123570
|
+
var log83 = createLogger("terminal-ws");
|
|
123595
123571
|
var MAX_CLOSE_REASON_BYTES = 123;
|
|
123596
123572
|
var HEARTBEAT_INTERVAL_MS2 = 3e4;
|
|
123597
123573
|
function clampCloseReason(reason) {
|
|
@@ -123659,7 +123635,7 @@ function createInbox(ws) {
|
|
|
123659
123635
|
};
|
|
123660
123636
|
}
|
|
123661
123637
|
function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendingMessage) {
|
|
123662
|
-
|
|
123638
|
+
log83.debug(
|
|
123663
123639
|
"Terminal %s: %s (worktree %s)",
|
|
123664
123640
|
isNew ? "connected" : "reconnected",
|
|
123665
123641
|
terminalId,
|
|
@@ -123679,7 +123655,7 @@ function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendi
|
|
|
123679
123655
|
});
|
|
123680
123656
|
const unsubscribeExit = backend.onExit(terminalId, (event) => {
|
|
123681
123657
|
unsubscribeTitle();
|
|
123682
|
-
|
|
123658
|
+
log83.debug("PTY exited with code %d for terminal %s", event.exitCode, terminalId);
|
|
123683
123659
|
if (ws.readyState === ws.OPEN) {
|
|
123684
123660
|
ws.close(1e3, "Terminal exited");
|
|
123685
123661
|
}
|
|
@@ -123707,7 +123683,7 @@ function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendi
|
|
|
123707
123683
|
try {
|
|
123708
123684
|
attached = await backend.attach(terminalId, dims);
|
|
123709
123685
|
} catch (err) {
|
|
123710
|
-
|
|
123686
|
+
log83.error("Failed to attach terminal %s: %s", terminalId, err);
|
|
123711
123687
|
safeClose(ws, 1011, "Terminal attach failed");
|
|
123712
123688
|
return;
|
|
123713
123689
|
}
|
|
@@ -123749,7 +123725,7 @@ function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendi
|
|
|
123749
123725
|
const cols = Number.isFinite(parsed.cols) && parsed.cols > 0 ? parsed.cols : void 0;
|
|
123750
123726
|
const rows = Number.isFinite(parsed.rows) && parsed.rows > 0 ? parsed.rows : void 0;
|
|
123751
123727
|
void startReplay(cols, rows, parsed.flow === true).catch((err) => {
|
|
123752
|
-
|
|
123728
|
+
log83.error("Failed to replay terminal %s: %s", terminalId, err);
|
|
123753
123729
|
});
|
|
123754
123730
|
return;
|
|
123755
123731
|
}
|
|
@@ -123769,7 +123745,7 @@ function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendi
|
|
|
123769
123745
|
flow?.dispose();
|
|
123770
123746
|
attachment?.detach();
|
|
123771
123747
|
unsubscribeExit();
|
|
123772
|
-
|
|
123748
|
+
log83.debug("Terminal disconnected: %s (PTY kept alive)", terminalId);
|
|
123773
123749
|
});
|
|
123774
123750
|
if (pendingMessage) {
|
|
123775
123751
|
processMessage(pendingMessage);
|
|
@@ -123792,7 +123768,7 @@ function handleMessage(backend, ws, terminalId, message) {
|
|
|
123792
123768
|
}
|
|
123793
123769
|
if (parsed.type === "close") {
|
|
123794
123770
|
void backend.kill(terminalId).catch((err) => {
|
|
123795
|
-
|
|
123771
|
+
log83.error("Failed to kill terminal %s: %s", terminalId, err);
|
|
123796
123772
|
});
|
|
123797
123773
|
ws.close(1e3, "Terminal closed by client");
|
|
123798
123774
|
return;
|
|
@@ -123808,7 +123784,7 @@ function handleMessage(backend, ws, terminalId, message) {
|
|
|
123808
123784
|
|
|
123809
123785
|
// src/server/api/terminals/ws.ts
|
|
123810
123786
|
init_terminal_service();
|
|
123811
|
-
var
|
|
123787
|
+
var log84 = createLogger("terminal-ws");
|
|
123812
123788
|
async function handleTerminalConnection(ws, req) {
|
|
123813
123789
|
if (!req.url) {
|
|
123814
123790
|
safeClose(ws, 4e3, "Missing request URL");
|
|
@@ -123827,7 +123803,7 @@ async function handleTerminalConnection(ws, req) {
|
|
|
123827
123803
|
existing = await terminalService.info(terminalId) !== null;
|
|
123828
123804
|
} catch (err) {
|
|
123829
123805
|
const msg = err instanceof Error ? err.message : String(err);
|
|
123830
|
-
|
|
123806
|
+
log84.error("Failed to look up terminal %s: %s", terminalId, msg);
|
|
123831
123807
|
safeClose(ws, 1011, msg);
|
|
123832
123808
|
return;
|
|
123833
123809
|
}
|
|
@@ -123875,7 +123851,7 @@ async function handleTerminalConnection(ws, req) {
|
|
|
123875
123851
|
await terminalService.spawn(worktreeId4, terminalId, spawnOpts);
|
|
123876
123852
|
} catch (err) {
|
|
123877
123853
|
const msg = err instanceof Error ? err.message : String(err);
|
|
123878
|
-
|
|
123854
|
+
log84.error("Failed to spawn terminal %s for worktree %s: %s", terminalId, worktreeId4, msg);
|
|
123879
123855
|
safeClose(ws, 4001, msg);
|
|
123880
123856
|
return;
|
|
123881
123857
|
}
|
|
@@ -123975,14 +123951,14 @@ async function handleVoiceTranscribe(req, res) {
|
|
|
123975
123951
|
|
|
123976
123952
|
// src/server/api/web-app-manifest.ts
|
|
123977
123953
|
import { createReadStream as createReadStream5, statSync as statSync15 } from "node:fs";
|
|
123978
|
-
import { join as
|
|
123954
|
+
import { join as join56 } from "node:path";
|
|
123979
123955
|
var WEB_APP_MANIFEST_PATH = "/manifest.webmanifest";
|
|
123980
123956
|
var ICON_FILES = ["band-192.png", "band-512.png", "apple-touch-icon.png"];
|
|
123981
123957
|
function handleWebAppManifest(req, res, publicDir) {
|
|
123982
123958
|
if (req.method !== "GET" && req.method !== "HEAD") return false;
|
|
123983
123959
|
const pathname = req.url?.split("?")[0];
|
|
123984
123960
|
if (pathname === WEB_APP_MANIFEST_PATH) {
|
|
123985
|
-
sendFile(req, res,
|
|
123961
|
+
sendFile(req, res, join56(publicDir, "manifest.webmanifest"), {
|
|
123986
123962
|
"Content-Type": "application/manifest+json",
|
|
123987
123963
|
"Cache-Control": "no-cache"
|
|
123988
123964
|
});
|
|
@@ -123990,7 +123966,7 @@ function handleWebAppManifest(req, res, publicDir) {
|
|
|
123990
123966
|
}
|
|
123991
123967
|
const icon = ICON_FILES.find((name5) => pathname === `/icons/${name5}`);
|
|
123992
123968
|
if (!icon) return false;
|
|
123993
|
-
sendFile(req, res,
|
|
123969
|
+
sendFile(req, res, join56(publicDir, "icons", icon), {
|
|
123994
123970
|
"Content-Type": "image/png",
|
|
123995
123971
|
"Cache-Control": "public, max-age=86400"
|
|
123996
123972
|
});
|
|
@@ -124014,7 +123990,7 @@ init_src();
|
|
|
124014
123990
|
init_wrapper();
|
|
124015
123991
|
init_browser_lookup();
|
|
124016
123992
|
init_remote_cdp();
|
|
124017
|
-
var
|
|
123993
|
+
var log85 = createLogger("cdp-proxy");
|
|
124018
123994
|
async function handleCdpConnection(ws, req) {
|
|
124019
123995
|
const url3 = new URL(req.url ?? "", `http://${req.headers.host}`);
|
|
124020
123996
|
const bandTabId = url3.searchParams.get("bandTabId");
|
|
@@ -124057,17 +124033,17 @@ async function handleCdpConnection(ws, req) {
|
|
|
124057
124033
|
cdpTargetId = await ensureCdpTargetId(bandTabId);
|
|
124058
124034
|
} catch (err) {
|
|
124059
124035
|
const message = err instanceof Error ? err.message : String(err);
|
|
124060
|
-
|
|
124036
|
+
log85.debug("ensureCdpTargetId failed for %s: %s", bandTabId, message);
|
|
124061
124037
|
if (ws.readyState === ws.OPEN) {
|
|
124062
124038
|
ws.close(4001, message.slice(0, 123));
|
|
124063
124039
|
}
|
|
124064
124040
|
return;
|
|
124065
124041
|
}
|
|
124066
124042
|
const upstreamUrl = `ws://${DESKTOP_CDP_HOST}:${DESKTOP_CDP_PORT}/devtools/page/${encodeURIComponent(cdpTargetId)}`;
|
|
124067
|
-
|
|
124043
|
+
log85.info("CDP proxy connecting bandTabId=%s upstream=%s", bandTabId, upstreamUrl);
|
|
124068
124044
|
upstream = new wrapper_default(upstreamUrl);
|
|
124069
124045
|
upstream.on("open", () => {
|
|
124070
|
-
|
|
124046
|
+
log85.info("CDP upstream open bandTabId=%s pending=%d", bandTabId, pending2.length);
|
|
124071
124047
|
for (const msg of pending2) {
|
|
124072
124048
|
upstream?.send(msg);
|
|
124073
124049
|
}
|
|
@@ -124079,20 +124055,20 @@ async function handleCdpConnection(ws, req) {
|
|
|
124079
124055
|
}
|
|
124080
124056
|
});
|
|
124081
124057
|
upstream.on("error", (err) => {
|
|
124082
|
-
|
|
124058
|
+
log85.warn("CDP upstream error bandTabId=%s: %s", bandTabId, err.message);
|
|
124083
124059
|
markTargetDestroyed(bandTabId);
|
|
124084
124060
|
if (ws.readyState === ws.OPEN) {
|
|
124085
124061
|
ws.close(4001, `Desktop CDP error: ${err.message}`.slice(0, 123));
|
|
124086
124062
|
}
|
|
124087
124063
|
});
|
|
124088
124064
|
upstream.on("close", (code) => {
|
|
124089
|
-
|
|
124065
|
+
log85.info("CDP upstream closed bandTabId=%s code=%d", bandTabId, code);
|
|
124090
124066
|
if (ws.readyState === ws.OPEN) {
|
|
124091
124067
|
ws.close(1e3, "Upstream closed");
|
|
124092
124068
|
}
|
|
124093
124069
|
});
|
|
124094
124070
|
ws.on("close", () => {
|
|
124095
|
-
|
|
124071
|
+
log85.debug("CDP client closed bandTabId=%s", bandTabId);
|
|
124096
124072
|
if (upstream && (upstream.readyState === wrapper_default.OPEN || upstream.readyState === wrapper_default.CONNECTING)) {
|
|
124097
124073
|
try {
|
|
124098
124074
|
upstream.close();
|
|
@@ -124101,7 +124077,7 @@ async function handleCdpConnection(ws, req) {
|
|
|
124101
124077
|
}
|
|
124102
124078
|
});
|
|
124103
124079
|
ws.on("error", (err) => {
|
|
124104
|
-
|
|
124080
|
+
log85.debug("CDP client error bandTabId=%s: %s", bandTabId, err.message);
|
|
124105
124081
|
try {
|
|
124106
124082
|
upstream?.close();
|
|
124107
124083
|
} catch {
|
|
@@ -124131,7 +124107,7 @@ async function bridgeRemote(ws, worktreeId4) {
|
|
|
124131
124107
|
cdp = await openRemoteCdp(worktreeId4);
|
|
124132
124108
|
} catch (err) {
|
|
124133
124109
|
const message = err instanceof Error ? err.message : String(err);
|
|
124134
|
-
|
|
124110
|
+
log85.warn("remote CDP failed for worktree %s: %s", worktreeId4, message);
|
|
124135
124111
|
if (ws.readyState === ws.OPEN)
|
|
124136
124112
|
ws.close(4001, closeReason(`Remote browser unavailable: ${message}`));
|
|
124137
124113
|
return true;
|
|
@@ -124155,7 +124131,7 @@ async function bridgeRemote(ws, worktreeId4) {
|
|
|
124155
124131
|
if (ws.readyState === ws.OPEN) ws.send(message);
|
|
124156
124132
|
}
|
|
124157
124133
|
} catch (err) {
|
|
124158
|
-
|
|
124134
|
+
log85.debug("remote CDP stream ended for worktree %s: %s", worktreeId4, String(err));
|
|
124159
124135
|
}
|
|
124160
124136
|
if (ws.readyState === ws.OPEN) ws.close(1e3, "Upstream closed");
|
|
124161
124137
|
})();
|
|
@@ -124165,7 +124141,7 @@ async function bridgeRemote(ws, worktreeId4) {
|
|
|
124165
124141
|
// src/server/infra/browser-host/cdp-targets.ts
|
|
124166
124142
|
init_src();
|
|
124167
124143
|
init_wrapper();
|
|
124168
|
-
var
|
|
124144
|
+
var log86 = createLogger("cdp-targets");
|
|
124169
124145
|
var CdpUnreachableError = class extends Error {
|
|
124170
124146
|
constructor(message) {
|
|
124171
124147
|
super(message);
|
|
@@ -124221,7 +124197,7 @@ async function captureSnapshot(bandTabId) {
|
|
|
124221
124197
|
});
|
|
124222
124198
|
ws.on("error", (err) => {
|
|
124223
124199
|
clearTimeout(timeout);
|
|
124224
|
-
|
|
124200
|
+
log86.debug("captureSnapshot ws error for tab %s: %s", bandTabId, err.message);
|
|
124225
124201
|
markTargetDestroyed(bandTabId);
|
|
124226
124202
|
settle2(new CdpUnreachableError(err.message));
|
|
124227
124203
|
});
|
|
@@ -124348,7 +124324,7 @@ var RfbClientFilter = class {
|
|
|
124348
124324
|
};
|
|
124349
124325
|
|
|
124350
124326
|
// src/server/infra/host/desktop-proxy.ts
|
|
124351
|
-
var
|
|
124327
|
+
var log87 = createLogger("desktop-proxy");
|
|
124352
124328
|
var DESKTOP_PATH = /^\/api\/hosts\/([^/]+)\/desktop$/;
|
|
124353
124329
|
function desktopHostId(pathname) {
|
|
124354
124330
|
const match = DESKTOP_PATH.exec(pathname);
|
|
@@ -124397,7 +124373,7 @@ async function handleDesktopConnection(ws, req, hostId2) {
|
|
|
124397
124373
|
);
|
|
124398
124374
|
if (enabled !== null) {
|
|
124399
124375
|
filter.viewOnly = !enabled;
|
|
124400
|
-
|
|
124376
|
+
log87.debug("desktop of host %s is now %s", hostId2, enabled ? "controlled" : "view-only");
|
|
124401
124377
|
}
|
|
124402
124378
|
return;
|
|
124403
124379
|
}
|
|
@@ -124432,7 +124408,7 @@ async function handleDesktopConnection(ws, req, hostId2) {
|
|
|
124432
124408
|
opened = true;
|
|
124433
124409
|
} catch (err) {
|
|
124434
124410
|
const message = err instanceof Error ? err.message : String(err);
|
|
124435
|
-
|
|
124411
|
+
log87.warn("desktop of host %s is unavailable: %s", hostId2, message);
|
|
124436
124412
|
release();
|
|
124437
124413
|
ws.close(4001, message.slice(0, 120));
|
|
124438
124414
|
return;
|
|
@@ -124442,7 +124418,7 @@ async function handleDesktopConnection(ws, req, hostId2) {
|
|
|
124442
124418
|
release();
|
|
124443
124419
|
return;
|
|
124444
124420
|
}
|
|
124445
|
-
|
|
124421
|
+
log87.debug("desktop viewer connected: %s (%s)", hostId2, req.socket.remoteAddress ?? "unknown");
|
|
124446
124422
|
for (const chunk of pending2.splice(0)) desktop.write(chunk);
|
|
124447
124423
|
try {
|
|
124448
124424
|
for await (const bytes of desktop.output) {
|
|
@@ -124450,7 +124426,7 @@ async function handleDesktopConnection(ws, req, hostId2) {
|
|
|
124450
124426
|
await new Promise((resolve15) => ws.send(bytes, { binary: true }, () => resolve15()));
|
|
124451
124427
|
}
|
|
124452
124428
|
} catch (err) {
|
|
124453
|
-
|
|
124429
|
+
log87.warn("desktop stream of host %s failed: %s", hostId2, err.message);
|
|
124454
124430
|
} finally {
|
|
124455
124431
|
if (opened) {
|
|
124456
124432
|
desktop.close();
|
|
@@ -124468,7 +124444,7 @@ init_src();
|
|
|
124468
124444
|
init_worktrees();
|
|
124469
124445
|
init_registry();
|
|
124470
124446
|
var worktreeQueries2 = new WorktreeQueries();
|
|
124471
|
-
var
|
|
124447
|
+
var log88 = createLogger("lsp-proxy");
|
|
124472
124448
|
function frameMessage(json3) {
|
|
124473
124449
|
const body = Buffer.from(json3, "utf-8");
|
|
124474
124450
|
const header = `Content-Length: ${body.byteLength}\r
|
|
@@ -124486,7 +124462,7 @@ function createFrameParser(onMessage) {
|
|
|
124486
124462
|
const headerStr = buffer.subarray(0, separatorIdx).toString("ascii");
|
|
124487
124463
|
const match = headerStr.match(/Content-Length:\s*(\d+)/i);
|
|
124488
124464
|
if (!match) {
|
|
124489
|
-
|
|
124465
|
+
log88.warn("Malformed LSP header: %s", headerStr);
|
|
124490
124466
|
buffer = buffer.subarray(separatorIdx + 4);
|
|
124491
124467
|
continue;
|
|
124492
124468
|
}
|
|
@@ -124531,7 +124507,7 @@ async function handleLspConnection(ws, req) {
|
|
|
124531
124507
|
connection = await hostRegistry.hostFor(worktreeId4).lsp.connect({ worktreeId: worktreeId4, lang, root: worktree.worktreePath });
|
|
124532
124508
|
} catch (err) {
|
|
124533
124509
|
const message = err instanceof Error ? err.message : String(err);
|
|
124534
|
-
|
|
124510
|
+
log88.error("Failed to spawn %s language server for worktree %s: %s", lang, worktreeId4, message);
|
|
124535
124511
|
ws.close(4001, message);
|
|
124536
124512
|
return;
|
|
124537
124513
|
}
|
|
@@ -124539,7 +124515,7 @@ async function handleLspConnection(ws, req) {
|
|
|
124539
124515
|
connection.close();
|
|
124540
124516
|
return;
|
|
124541
124517
|
}
|
|
124542
|
-
|
|
124518
|
+
log88.debug("LSP client connected: %s/%s", worktreeId4, lang);
|
|
124543
124519
|
const pendingRequests = /* @__PURE__ */ new Map();
|
|
124544
124520
|
const openDocuments = /* @__PURE__ */ new Set();
|
|
124545
124521
|
const serverId = `${worktreeId4}:${lang}`;
|
|
@@ -124575,7 +124551,7 @@ async function handleLspConnection(ws, req) {
|
|
|
124575
124551
|
const retriedIds = /* @__PURE__ */ new Set();
|
|
124576
124552
|
const RETRY_DELAY_MS = 2e3;
|
|
124577
124553
|
const parseFrame = createFrameParser((json3) => {
|
|
124578
|
-
|
|
124554
|
+
log88.debug(
|
|
124579
124555
|
"LSP stdout [%s/%s]: %s",
|
|
124580
124556
|
worktreeId4,
|
|
124581
124557
|
lang,
|
|
@@ -124587,7 +124563,7 @@ async function handleLspConnection(ws, req) {
|
|
|
124587
124563
|
const originalRequest = pendingRequests.get(msg.id);
|
|
124588
124564
|
retriedIds.add(msg.id);
|
|
124589
124565
|
pendingRequests.delete(msg.id);
|
|
124590
|
-
|
|
124566
|
+
log88.debug(
|
|
124591
124567
|
"LSP retrying request %d after 'No Project' error [%s/%s]",
|
|
124592
124568
|
msg.id,
|
|
124593
124569
|
worktreeId4,
|
|
@@ -124618,16 +124594,16 @@ async function handleLspConnection(ws, req) {
|
|
|
124618
124594
|
for await (const chunk of connection.output)
|
|
124619
124595
|
parseFrame(Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength));
|
|
124620
124596
|
} catch (err) {
|
|
124621
|
-
|
|
124597
|
+
log88.warn("LSP output stream failed [%s/%s]: %s", worktreeId4, lang, String(err));
|
|
124622
124598
|
}
|
|
124623
124599
|
release();
|
|
124624
124600
|
if (ws.readyState === ws.OPEN) {
|
|
124625
|
-
|
|
124601
|
+
log88.debug("LSP server exited, closing WebSocket");
|
|
124626
124602
|
ws.close(1e3, "Language server exited");
|
|
124627
124603
|
}
|
|
124628
124604
|
})();
|
|
124629
124605
|
function forwardToStdin(json3) {
|
|
124630
|
-
|
|
124606
|
+
log88.debug(
|
|
124631
124607
|
"LSP stdin [%s/%s]: %s",
|
|
124632
124608
|
worktreeId4,
|
|
124633
124609
|
lang,
|
|
@@ -124659,7 +124635,7 @@ async function handleLspConnection(ws, req) {
|
|
|
124659
124635
|
ws.on("close", () => {
|
|
124660
124636
|
release();
|
|
124661
124637
|
connection.close();
|
|
124662
|
-
|
|
124638
|
+
log88.debug("LSP client disconnected: %s/%s (server kept alive)", worktreeId4, lang);
|
|
124663
124639
|
});
|
|
124664
124640
|
}
|
|
124665
124641
|
|
|
@@ -124668,7 +124644,7 @@ init_webhook();
|
|
|
124668
124644
|
|
|
124669
124645
|
// src/server/services/_utils/hosted-file.ts
|
|
124670
124646
|
init_registry();
|
|
124671
|
-
import { basename as basename6, dirname as dirname17, join as
|
|
124647
|
+
import { basename as basename6, dirname as dirname17, join as join57 } from "node:path";
|
|
124672
124648
|
async function openHostedFile(kind, worktreeId4, rawName, chatId) {
|
|
124673
124649
|
const host = hostRegistry.hostFor(worktreeId4);
|
|
124674
124650
|
if (host.id === hostRegistry.local.id) return null;
|
|
@@ -124682,7 +124658,7 @@ async function openHostedFile(kind, worktreeId4, rawName, chatId) {
|
|
|
124682
124658
|
try {
|
|
124683
124659
|
const dirs = (await host.info()).dirs;
|
|
124684
124660
|
if (!dirs) return null;
|
|
124685
|
-
const path2 = chatId ?
|
|
124661
|
+
const path2 = chatId ? join57(dirs[kind], worktreeId4, chatId, name5) : join57(dirs[kind], worktreeId4, name5);
|
|
124686
124662
|
const dir = await host.fs.realpath(dirname17(path2));
|
|
124687
124663
|
if (!(await host.fs.realpath(path2)).startsWith(`${dir}/`)) return null;
|
|
124688
124664
|
const stat7 = await host.fs.stat(path2, { followSymlinks: true });
|
|
@@ -132824,15 +132800,15 @@ init_src();
|
|
|
132824
132800
|
init_registry();
|
|
132825
132801
|
async function installSkills2(opts = {}) {
|
|
132826
132802
|
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)
|
|
132803
|
+
const log90 = opts.log;
|
|
132804
|
+
if (log90) {
|
|
132805
|
+
for (const warning of result.warnings) log90.warn(warning);
|
|
132806
|
+
for (const path2 of result.written) log90.info("Installed skill at %s", path2);
|
|
132831
132807
|
for (const path2 of result.updated) {
|
|
132832
|
-
|
|
132808
|
+
log90.info("Updated skill at %s (content differed \u2014 shipped version reinstalled)", path2);
|
|
132833
132809
|
}
|
|
132834
132810
|
for (const conflict of result.conflicts) {
|
|
132835
|
-
|
|
132811
|
+
log90.warn("Skill symlink conflict \u2014 %s (left as-is; remove it manually to re-link)", conflict);
|
|
132836
132812
|
}
|
|
132837
132813
|
}
|
|
132838
132814
|
return result;
|
|
@@ -132845,7 +132821,7 @@ init_state();
|
|
|
132845
132821
|
init_sync_service();
|
|
132846
132822
|
init_worktree_group_service();
|
|
132847
132823
|
init_worktree_service();
|
|
132848
|
-
var
|
|
132824
|
+
var log89 = createLogger("setup");
|
|
132849
132825
|
async function runFirstTimeSetup() {
|
|
132850
132826
|
forgetLocalWorktrees();
|
|
132851
132827
|
convertLegacyLabels();
|
|
@@ -132858,7 +132834,7 @@ async function runFirstTimeSetup() {
|
|
|
132858
132834
|
]);
|
|
132859
132835
|
for (const r of results) {
|
|
132860
132836
|
if (r.status === "rejected") {
|
|
132861
|
-
|
|
132837
|
+
log89.warn(
|
|
132862
132838
|
"Setup step failed: %s",
|
|
132863
132839
|
r.reason instanceof Error ? r.reason.message : String(r.reason)
|
|
132864
132840
|
);
|
|
@@ -132872,7 +132848,7 @@ async function refreshAgentModelsInBackground() {
|
|
|
132872
132848
|
const ok2 = results.filter((r) => !r.error).length;
|
|
132873
132849
|
const failed = results.length - ok2;
|
|
132874
132850
|
if (results.length > 0) {
|
|
132875
|
-
|
|
132851
|
+
log89.info(
|
|
132876
132852
|
"Background model refresh: %d/%d agents updated (%d failed)",
|
|
132877
132853
|
ok2,
|
|
132878
132854
|
results.length,
|
|
@@ -132880,7 +132856,7 @@ async function refreshAgentModelsInBackground() {
|
|
|
132880
132856
|
);
|
|
132881
132857
|
}
|
|
132882
132858
|
} catch (err) {
|
|
132883
|
-
|
|
132859
|
+
log89.warn(
|
|
132884
132860
|
"Background model refresh failed: %s",
|
|
132885
132861
|
err instanceof Error ? err.message : String(err)
|
|
132886
132862
|
);
|
|
@@ -132895,7 +132871,7 @@ async function ensureRepoRemotes() {
|
|
|
132895
132871
|
try {
|
|
132896
132872
|
await repoService.backfillRemotes();
|
|
132897
132873
|
} catch (err) {
|
|
132898
|
-
|
|
132874
|
+
log89.warn(
|
|
132899
132875
|
"Failed to record repo remotes at boot: %s",
|
|
132900
132876
|
err instanceof Error ? err.message : String(err)
|
|
132901
132877
|
);
|
|
@@ -132905,7 +132881,7 @@ function migrateRepoCronjobs() {
|
|
|
132905
132881
|
try {
|
|
132906
132882
|
cronjobService.migrateRepoJobs();
|
|
132907
132883
|
} catch (err) {
|
|
132908
|
-
|
|
132884
|
+
log89.warn(
|
|
132909
132885
|
"Failed to move repo-scoped cronjobs to worktrees at boot: %s",
|
|
132910
132886
|
err instanceof Error ? err.message : String(err)
|
|
132911
132887
|
);
|
|
@@ -132915,7 +132891,7 @@ function convertLegacyLabels() {
|
|
|
132915
132891
|
try {
|
|
132916
132892
|
worktreeGroupService.convertLegacyLabels();
|
|
132917
132893
|
} catch (err) {
|
|
132918
|
-
|
|
132894
|
+
log89.warn(
|
|
132919
132895
|
"Failed to convert repo labels to groups at boot: %s",
|
|
132920
132896
|
err instanceof Error ? err.message : String(err)
|
|
132921
132897
|
);
|
|
@@ -132925,7 +132901,7 @@ function forgetLocalWorktrees() {
|
|
|
132925
132901
|
try {
|
|
132926
132902
|
worktreeService.forgetLocalWorktrees();
|
|
132927
132903
|
} catch (err) {
|
|
132928
|
-
|
|
132904
|
+
log89.warn(
|
|
132929
132905
|
"Failed to forget local worktrees at boot: %s",
|
|
132930
132906
|
err instanceof Error ? err.message : String(err)
|
|
132931
132907
|
);
|
|
@@ -132935,7 +132911,7 @@ async function ensureRepoStateInSync() {
|
|
|
132935
132911
|
try {
|
|
132936
132912
|
await syncService.syncWorktrees();
|
|
132937
132913
|
} catch (err) {
|
|
132938
|
-
|
|
132914
|
+
log89.warn(
|
|
132939
132915
|
"Failed to sync repo state at boot: %s",
|
|
132940
132916
|
err instanceof Error ? err.message : String(err)
|
|
132941
132917
|
);
|
|
@@ -132946,22 +132922,22 @@ async function ensureCliInstalled() {
|
|
|
132946
132922
|
try {
|
|
132947
132923
|
cliStatus = await checkCli();
|
|
132948
132924
|
} catch (err) {
|
|
132949
|
-
|
|
132925
|
+
log89.warn("Could not check CLI status: %s", err instanceof Error ? err.message : String(err));
|
|
132950
132926
|
return;
|
|
132951
132927
|
}
|
|
132952
132928
|
if (cliStatus === "Installed") {
|
|
132953
132929
|
return;
|
|
132954
132930
|
}
|
|
132955
132931
|
if (cliStatus !== "NotInstalled") {
|
|
132956
|
-
|
|
132932
|
+
log89.warn("CLI not auto-installed (status: %s)", cliStatus);
|
|
132957
132933
|
return;
|
|
132958
132934
|
}
|
|
132959
|
-
|
|
132935
|
+
log89.info("Installing band CLI...");
|
|
132960
132936
|
try {
|
|
132961
132937
|
await installCli();
|
|
132962
|
-
|
|
132938
|
+
log89.info("CLI installed to %s", SYMLINK_PATH);
|
|
132963
132939
|
} catch (err) {
|
|
132964
|
-
|
|
132940
|
+
log89.warn("CLI installation failed: %s", err instanceof Error ? err.message : String(err));
|
|
132965
132941
|
}
|
|
132966
132942
|
}
|
|
132967
132943
|
async function ensureDefaultCodingAgents() {
|
|
@@ -132970,17 +132946,17 @@ async function ensureDefaultCodingAgents() {
|
|
|
132970
132946
|
if (Array.isArray(existing) && existing.length > 0) {
|
|
132971
132947
|
return;
|
|
132972
132948
|
}
|
|
132973
|
-
|
|
132949
|
+
log89.info("Detecting installed coding agents...");
|
|
132974
132950
|
const detected = [];
|
|
132975
132951
|
for (const check3 of AGENT_CHECKS) {
|
|
132976
132952
|
const path2 = await systemService.whichBinary(check3.binary);
|
|
132977
132953
|
if (path2) {
|
|
132978
|
-
|
|
132954
|
+
log89.info("Detected coding agent: %s (%s)", check3.id, path2);
|
|
132979
132955
|
detected.push({ id: check3.id, type: check3.type, label: check3.label });
|
|
132980
132956
|
}
|
|
132981
132957
|
}
|
|
132982
132958
|
if (detected.length === 0) {
|
|
132983
|
-
|
|
132959
|
+
log89.info("No coding agent CLIs detected on PATH");
|
|
132984
132960
|
return;
|
|
132985
132961
|
}
|
|
132986
132962
|
const current3 = loadSettings();
|
|
@@ -132989,7 +132965,7 @@ async function ensureDefaultCodingAgents() {
|
|
|
132989
132965
|
current3.defaultCodingAgent = detected[0].id;
|
|
132990
132966
|
}
|
|
132991
132967
|
saveSettings(current3);
|
|
132992
|
-
|
|
132968
|
+
log89.info("Enabled %d coding agent(s); default = %s", detected.length, current3.defaultCodingAgent);
|
|
132993
132969
|
}
|
|
132994
132970
|
function ensureNotificationDefaults() {
|
|
132995
132971
|
const settings3 = loadSettings();
|
|
@@ -133001,7 +132977,7 @@ function ensureNotificationDefaults() {
|
|
|
133001
132977
|
...settings3,
|
|
133002
132978
|
notifications: { ...notifications, soundOnNeedsAttention: true }
|
|
133003
132979
|
});
|
|
133004
|
-
|
|
132980
|
+
log89.info("Set default notifications.soundOnNeedsAttention = true");
|
|
133005
132981
|
}
|
|
133006
132982
|
function migrateAgentDefaultMode() {
|
|
133007
132983
|
const settings3 = loadSettings();
|
|
@@ -133009,15 +132985,15 @@ function migrateAgentDefaultMode() {
|
|
|
133009
132985
|
const mode = agentModeFromVia(settings3.cli?.defaultVia);
|
|
133010
132986
|
if (!mode) return;
|
|
133011
132987
|
saveSettings({ ...settings3, agents: { ...settings3.agents, defaultMode: mode } });
|
|
133012
|
-
|
|
132988
|
+
log89.info("Migrated cli.defaultVia to agents.defaultMode = %s", mode);
|
|
133013
132989
|
}
|
|
133014
132990
|
async function ensureSkillsInstalled() {
|
|
133015
132991
|
try {
|
|
133016
|
-
const result = await installSkills2({ log:
|
|
132992
|
+
const result = await installSkills2({ log: log89 });
|
|
133017
132993
|
const wrote = result.written.length + result.updated.length;
|
|
133018
132994
|
const linkChange = result.linked.length;
|
|
133019
132995
|
if (wrote > 0 || linkChange > 0 || result.conflicts.length > 0) {
|
|
133020
|
-
|
|
132996
|
+
log89.info(
|
|
133021
132997
|
"Synced CLI skills (shared: %d written, %d updated, %d unchanged; symlinks: %d created, %d already-linked, %d conflicts, %d skipped)",
|
|
133022
132998
|
result.written.length,
|
|
133023
132999
|
result.updated.length,
|
|
@@ -133029,7 +133005,7 @@ async function ensureSkillsInstalled() {
|
|
|
133029
133005
|
);
|
|
133030
133006
|
}
|
|
133031
133007
|
} catch (err) {
|
|
133032
|
-
|
|
133008
|
+
log89.warn("Failed to sync CLI skills: %s", err instanceof Error ? err.message : String(err));
|
|
133033
133009
|
}
|
|
133034
133010
|
}
|
|
133035
133011
|
var SetupService = class {
|
|
@@ -133050,7 +133026,7 @@ init_worktree_service();
|
|
|
133050
133026
|
function logCrash(message) {
|
|
133051
133027
|
try {
|
|
133052
133028
|
mkdirSync11(bandHome(), { recursive: true });
|
|
133053
|
-
appendFileSync2(
|
|
133029
|
+
appendFileSync2(join58(bandHome(), "server.log"), message, "utf-8");
|
|
133054
133030
|
} catch {
|
|
133055
133031
|
}
|
|
133056
133032
|
}
|
|
@@ -133090,9 +133066,9 @@ function resolveUiDir() {
|
|
|
133090
133066
|
if (explicit) return resolve14(explicit);
|
|
133091
133067
|
const candidates = [
|
|
133092
133068
|
resolve14(SERVER_ROOT, "..", "..", "web", "dist", "client"),
|
|
133093
|
-
|
|
133069
|
+
join58(SERVER_ROOT, "client")
|
|
133094
133070
|
];
|
|
133095
|
-
return candidates.find((dir) => existsSync18(
|
|
133071
|
+
return candidates.find((dir) => existsSync18(join58(dir, "_shell.html"))) ?? candidates[1];
|
|
133096
133072
|
}
|
|
133097
133073
|
var clientDir = resolveUiDir();
|
|
133098
133074
|
var uiRoot = process.env.BAND_UI_ROOT ? resolve14(process.env.BAND_UI_ROOT) : resolve14(SERVER_ROOT, "..", "web");
|
|
@@ -133143,7 +133119,7 @@ function getOpenApiSpec() {
|
|
|
133143
133119
|
if (isDev) {
|
|
133144
133120
|
const { generateOpenAPIDocument } = await import("@trpc/openapi");
|
|
133145
133121
|
const doc = await generateOpenAPIDocument(
|
|
133146
|
-
|
|
133122
|
+
join58(SERVER_ROOT, "src", "server", "api", "router.ts"),
|
|
133147
133123
|
{
|
|
133148
133124
|
title: "Band API",
|
|
133149
133125
|
version: "1.0.0"
|
|
@@ -133152,7 +133128,7 @@ function getOpenApiSpec() {
|
|
|
133152
133128
|
doc.servers = [{ url: "/trpc" }];
|
|
133153
133129
|
return JSON.stringify(doc, null, 2);
|
|
133154
133130
|
}
|
|
133155
|
-
const openApiDoc = JSON.parse(readFileSync12(
|
|
133131
|
+
const openApiDoc = JSON.parse(readFileSync12(join58(SERVER_ROOT, "openapi.json"), "utf-8"));
|
|
133156
133132
|
openApiDoc.servers = [{ url: "/trpc" }];
|
|
133157
133133
|
return JSON.stringify(openApiDoc, null, 2);
|
|
133158
133134
|
})().catch((err) => {
|
|
@@ -133182,9 +133158,9 @@ function serveStaticFile(res, root, subdir, rawFilename) {
|
|
|
133182
133158
|
res.end("Bad request");
|
|
133183
133159
|
return;
|
|
133184
133160
|
}
|
|
133185
|
-
const filePath =
|
|
133161
|
+
const filePath = join58(root, subdir, filename);
|
|
133186
133162
|
try {
|
|
133187
|
-
const dir = realpathSync7(
|
|
133163
|
+
const dir = realpathSync7(join58(root, subdir));
|
|
133188
133164
|
if (!realpathSync7(filePath).startsWith(dir + sep10)) {
|
|
133189
133165
|
res.writeHead(404);
|
|
133190
133166
|
res.end("Not found");
|
|
@@ -133235,7 +133211,7 @@ async function serveWorktreeFile(res, worktreeId4, rawPath, extraHeaders = {}, v
|
|
|
133235
133211
|
return;
|
|
133236
133212
|
}
|
|
133237
133213
|
const root = worktree.worktree.path;
|
|
133238
|
-
const target = resolve14(
|
|
133214
|
+
const target = resolve14(join58(root, rawPath));
|
|
133239
133215
|
if (!target.startsWith(root + sep10) && target !== root) {
|
|
133240
133216
|
res.writeHead(400);
|
|
133241
133217
|
res.end("Bad request");
|
|
@@ -133546,7 +133522,7 @@ async function main() {
|
|
|
133546
133522
|
res.end(JSON.stringify({ status: "ok", app: "band-web-server" }));
|
|
133547
133523
|
return;
|
|
133548
133524
|
}
|
|
133549
|
-
if (handleWebAppManifest(req, res, isDev ?
|
|
133525
|
+
if (handleWebAppManifest(req, res, isDev ? join58(uiRoot, "public") : clientDir)) return;
|
|
133550
133526
|
if (req.url?.split("?")[0] === WORKER_EXCHANGE_PATH) {
|
|
133551
133527
|
await workerLinkService.handleExchange(req, res);
|
|
133552
133528
|
return;
|
|
@@ -133654,7 +133630,7 @@ async function main() {
|
|
|
133654
133630
|
const encodedName = encodeURIComponent(parsed.name);
|
|
133655
133631
|
if (await serveHostedFile(res, "shared", parsed.worktreeId, encodedName, parsed.chatId))
|
|
133656
133632
|
return;
|
|
133657
|
-
const subdir = parsed.chatId ?
|
|
133633
|
+
const subdir = parsed.chatId ? join58("shared", parsed.worktreeId, parsed.chatId) : join58("shared", parsed.worktreeId);
|
|
133658
133634
|
serveStaticFile(res, bandHome(), subdir, encodedName);
|
|
133659
133635
|
return;
|
|
133660
133636
|
}
|
|
@@ -133875,7 +133851,7 @@ async function main() {
|
|
|
133875
133851
|
if (pathname.startsWith("/_shell")) res.setHeader("Cache-Control", "no-cache");
|
|
133876
133852
|
}
|
|
133877
133853
|
});
|
|
133878
|
-
const shellPath2 =
|
|
133854
|
+
const shellPath2 = join58(clientDir, "_shell.html");
|
|
133879
133855
|
if (!existsSync18(shellPath2)) {
|
|
133880
133856
|
throw new Error(
|
|
133881
133857
|
`UI build not found at ${clientDir} (no _shell.html). Run \`pnpm build\` or pass --ui-dir <path>.`
|