@band-app/server 0.53.0 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/_shell.html +0 -0
- package/dist/client/assets/{TerminalPanel-CUrp7Wxk.js → TerminalPanel-RYLpWa8Q.js} +1 -1
- package/dist/client/assets/{_basePickBy-DzTpqc54.js → _basePickBy-D-5MXYU_.js} +1 -1
- package/dist/client/assets/{_baseUniq-BH8BhmRB.js → _baseUniq-DYuk2xMI.js} +1 -1
- package/dist/client/assets/{arc-C3KloRZC.js → arc-dXtOms1t.js} +1 -1
- package/dist/client/assets/{architectureDiagram-VXUJARFQ-C0v4c_1F.js → architectureDiagram-VXUJARFQ-CsyRS4YA.js} +1 -1
- package/dist/client/assets/{blockDiagram-VD42YOAC-JA1asAF3.js → blockDiagram-VD42YOAC-DKwcsJ3k.js} +1 -1
- package/dist/client/assets/{c4Diagram-YG6GDRKO-eDAKz1MH.js → c4Diagram-YG6GDRKO-B-1bWrTm.js} +1 -1
- package/dist/client/assets/channel-B8VkZiqn.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-GiBdk6wd.js → chunk-4BX2VUAB-Lx4boQMz.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-CZirdcYj.js → chunk-55IACEB6-C4WK81Kx.js} +1 -1
- package/dist/client/assets/{chunk-B4BG7PRW-CRx24wmo.js → chunk-B4BG7PRW-awrixx-i.js} +1 -1
- package/dist/client/assets/{chunk-DI55MBZ5-BDlvmWyE.js → chunk-DI55MBZ5-BXvp16cX.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-CFQ4Ns-B.js → chunk-FMBD7UC4-DyY6khot.js} +1 -1
- package/dist/client/assets/{chunk-QN33PNHL-O1rjaqXm.js → chunk-QN33PNHL-BMvkmzKw.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-BUex41N2.js → chunk-QZHKN3VN-CWY-fLAo.js} +1 -1
- package/dist/client/assets/{chunk-TZMSLE5B-DJjv_do_.js → chunk-TZMSLE5B-BE-ngWv6.js} +1 -1
- package/dist/client/assets/classDiagram-2ON5EDUG-CePVU31o.js +1 -0
- package/dist/client/assets/classDiagram-v2-WZHVMYZB-CePVU31o.js +1 -0
- package/dist/client/assets/clone-BGTwLCsr.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-DFpXjakt.js → cose-bilkent-S5V4N54A-DJ8h3kKA.js} +1 -1
- package/dist/client/assets/{dagre-6UL2VRFP-CduI6jnM.js → dagre-6UL2VRFP-Bd1qWRGC.js} +1 -1
- package/dist/client/assets/{diagram-PSM6KHXK-CzWJmLPu.js → diagram-PSM6KHXK-BR64_p5f.js} +1 -1
- package/dist/client/assets/{diagram-QEK2KX5R-CyCNI4-k.js → diagram-QEK2KX5R-DFQt3gYM.js} +1 -1
- package/dist/client/assets/{diagram-S2PKOQOG-C5wLA6ra.js → diagram-S2PKOQOG-C8HaYYzZ.js} +1 -1
- package/dist/client/assets/{erDiagram-Q2GNP2WA-BNMyokGR.js → erDiagram-Q2GNP2WA-CS64Rcxd.js} +1 -1
- package/dist/client/assets/{flowDiagram-NV44I4VS-CDMiz1jN.js → flowDiagram-NV44I4VS-C-lDTK_F.js} +1 -1
- package/dist/client/assets/{ganttDiagram-JELNMOA3-BjKbhCuq.js → ganttDiagram-JELNMOA3-mfB20mUi.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-DcKCNdhS.js → gitGraphDiagram-V2S2FVAM-DIT7OOcN.js} +1 -1
- package/dist/client/assets/{graph-BCkWMEPy.js → graph-CuDWaZgk.js} +1 -1
- package/dist/client/assets/{highlighted-body-B3W2YXNL-ESHG-c2t.js → highlighted-body-B3W2YXNL-CEukDjjL.js} +1 -1
- package/dist/client/assets/{index-D1w6ILcm.js → index-B7DmSLZ5.js} +1 -1
- package/dist/client/assets/{index-CJAA69-B.js → index-B7yHTHBd.js} +1 -1
- package/dist/client/assets/{index-nnOiMGMS.js → index-BAFH952I.js} +1 -1
- package/dist/client/assets/{index-C4YFmo8L.js → index-BAJM6NLC.js} +1 -1
- package/dist/client/assets/{index-biU1uw37.js → index-BAlhbw5A.js} +1 -1
- package/dist/client/assets/{index-MWMi8v82.js → index-BMcFlUOo.js} +1 -1
- package/dist/client/assets/{index-ChF20gAc.js → index-CQfVS8uj.js} +1 -1
- package/dist/client/assets/{index-CutOvwS7.js → index-CQknVNu4.js} +1 -1
- package/dist/client/assets/{index-CklvaSBA.js → index-CiKJmP62.js} +1 -1
- package/dist/client/assets/{index-Ong_o86j.js → index-CwJX9TIf.js} +1 -1
- package/dist/client/assets/{index-kl_BbR04.js → index-CzkjYgaV.js} +1 -1
- package/dist/client/assets/{index-Bp2vWP2Y.js → index-DFdFKost.js} +1 -1
- package/dist/client/assets/{index-C3m3P5mw.js → index-DV3p0C-w.js} +1 -1
- package/dist/client/assets/{infoDiagram-HS3SLOUP-CoptTTxB.js → infoDiagram-HS3SLOUP-BJFhYv2N.js} +1 -1
- package/dist/client/assets/{journeyDiagram-XKPGCS4Q-CMN-HV9u.js → journeyDiagram-XKPGCS4Q-CtemPXmL.js} +1 -1
- package/dist/client/assets/{kanban-definition-3W4ZIXB7-DC3laXMu.js → kanban-definition-3W4ZIXB7-C9Xu3EkY.js} +1 -1
- package/dist/client/assets/{layout-BNpvAk6E.js → layout-DtMsQ09j.js} +1 -1
- package/dist/client/assets/{main-Bgor0kVJ.js → main-DashEqVP.js} +241 -241
- package/dist/client/assets/main-sOkcigfk.css +1 -0
- package/dist/client/assets/{mindmap-definition-VGOIOE7T-CFfDEH47.js → mindmap-definition-VGOIOE7T-C_FSSv6y.js} +1 -1
- package/dist/client/assets/{pieDiagram-ADFJNKIX-CZP5lrkz.js → pieDiagram-ADFJNKIX-BdDAYUXV.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-AYHSOK5B-Bc1rWWnR.js → quadrantDiagram-AYHSOK5B-B5g2nuTP.js} +1 -1
- package/dist/client/assets/{requirementDiagram-UZGBJVZJ-BtfVzz9o.js → requirementDiagram-UZGBJVZJ-BYa9pNRf.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-TZEHDZUN-CTFUjzzh.js → sankeyDiagram-TZEHDZUN-Co2c_zNW.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-WL72ISMW-Ceovvbrm.js → sequenceDiagram-WL72ISMW-eShduLQR.js} +1 -1
- package/dist/client/assets/{stateDiagram-FKZM4ZOC-BboZL1pg.js → stateDiagram-FKZM4ZOC-53kPEZua.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-4FDKWEC3-BOfSj2dL.js +1 -0
- package/dist/client/assets/{timeline-definition-IT6M3QCI-7vfajGp6.js → timeline-definition-IT6M3QCI-CZjtXE9X.js} +1 -1
- package/dist/client/assets/{treemap-GDKQZRPO-C1ZwadxG.js → treemap-GDKQZRPO-DOvJYPBs.js} +1 -1
- package/dist/client/assets/{worktree._worktreeId-BmMetrj_.js → worktree._worktreeId-BUGQ0lrG.js} +1 -1
- package/dist/client/assets/{worktree._worktreeId-C4_UcKsk.js → worktree._worktreeId-CvNxzyR7.js} +1 -1
- package/dist/client/assets/{xychartDiagram-PRI3JC2R-pTpN8cts.js → xychartDiagram-PRI3JC2R-BwZe0MO_.js} +1 -1
- package/dist/start-server.mjs +132 -50
- package/package.json +7 -7
- package/dist/client/assets/channel-DO7Rw5s3.js +0 -1
- package/dist/client/assets/classDiagram-2ON5EDUG-Dydmjn5K.js +0 -1
- package/dist/client/assets/classDiagram-v2-WZHVMYZB-Dydmjn5K.js +0 -1
- package/dist/client/assets/clone-BBqOdmdW.js +0 -1
- package/dist/client/assets/main-oF1qBPU-.css +0 -1
- package/dist/client/assets/stateDiagram-v2-4FDKWEC3-BsPSpOyb.js +0 -1
package/dist/start-server.mjs
CHANGED
|
@@ -54081,7 +54081,7 @@ import { lstatSync as lstatSync3, realpathSync as realpathSync4 } from "node:fs"
|
|
|
54081
54081
|
import { platform } from "node:os";
|
|
54082
54082
|
import { delimiter as delimiter3, join as join19, resolve as resolve4 } from "node:path";
|
|
54083
54083
|
function findCliBinaryAt(opts) {
|
|
54084
|
-
const { cwd, dirname:
|
|
54084
|
+
const { cwd, dirname: dirname18 } = opts;
|
|
54085
54085
|
const exe = platform() === "win32" ? "band.exe" : "band";
|
|
54086
54086
|
const explicit = process.env.BAND_CLI_PATH;
|
|
54087
54087
|
if (explicit) {
|
|
@@ -54097,7 +54097,7 @@ function findCliBinaryAt(opts) {
|
|
|
54097
54097
|
// cwd = repo root (fallback)
|
|
54098
54098
|
resolve4(cwd, "apps"),
|
|
54099
54099
|
// From this source file in dev (packages/host-local/src/process/ → apps/)
|
|
54100
|
-
resolve4(
|
|
54100
|
+
resolve4(dirname18, "..", "..", "..", "..", "apps"),
|
|
54101
54101
|
// From bundled `dist/` file (<Resources>/web/dist/ → <Resources>/) only
|
|
54102
54102
|
// — in dev mode this resolves to `packages/`, which has no
|
|
54103
54103
|
// `cli/target/<profile>/band` and is harmless; the walk above is the
|
|
@@ -54105,7 +54105,7 @@ function findCliBinaryAt(opts) {
|
|
|
54105
54105
|
// layout under <Resources>/cli/ would still resolve. Today's Electron
|
|
54106
54106
|
// bundle ships the binary under `binaries/` (handled by Strategy B),
|
|
54107
54107
|
// so this strategy never hits in production either.
|
|
54108
|
-
resolve4(
|
|
54108
|
+
resolve4(dirname18, "..", "..", "..")
|
|
54109
54109
|
];
|
|
54110
54110
|
for (const appsDir of appsStrategies) {
|
|
54111
54111
|
for (const profile of ["release", "debug"]) {
|
|
@@ -54122,7 +54122,7 @@ function findCliBinaryAt(opts) {
|
|
|
54122
54122
|
resolve4(cwd, "..", "binaries", exe),
|
|
54123
54123
|
// From the bundled dist file (<Resources>/web/dist/start-server.mjs)
|
|
54124
54124
|
// → <Resources>/binaries/band
|
|
54125
|
-
resolve4(
|
|
54125
|
+
resolve4(dirname18, "..", "..", "binaries", exe)
|
|
54126
54126
|
];
|
|
54127
54127
|
for (const p2 of electronCandidates) {
|
|
54128
54128
|
try {
|
|
@@ -63153,10 +63153,10 @@ var init_agent_command = __esm({
|
|
|
63153
63153
|
import { readdirSync as readdirSync8 } from "node:fs";
|
|
63154
63154
|
import { mkdir as mkdir5 } from "node:fs/promises";
|
|
63155
63155
|
import { join as join38 } from "node:path";
|
|
63156
|
-
async function openSharedDir(worktreeId4) {
|
|
63156
|
+
async function openSharedDir(worktreeId4, chatId) {
|
|
63157
63157
|
const host = hostRegistry.hostFor(worktreeId4);
|
|
63158
63158
|
if (host.id === hostRegistry.local.id) {
|
|
63159
|
-
const path3 = join38(bandHome(), "shared", worktreeId4);
|
|
63159
|
+
const path3 = join38(bandHome(), "shared", worktreeId4, chatId);
|
|
63160
63160
|
await mkdir5(path3, { recursive: true });
|
|
63161
63161
|
return {
|
|
63162
63162
|
path: path3,
|
|
@@ -63171,7 +63171,7 @@ async function openSharedDir(worktreeId4) {
|
|
|
63171
63171
|
}
|
|
63172
63172
|
const dirs = (await host.info()).dirs;
|
|
63173
63173
|
if (!dirs) throw new Error(`Worker ${host.id} has no directory for shared files`);
|
|
63174
|
-
const path2 = join38(dirs.shared, worktreeId4);
|
|
63174
|
+
const path2 = join38(dirs.shared, worktreeId4, chatId);
|
|
63175
63175
|
await host.fs.mkdir(path2, { recursive: true });
|
|
63176
63176
|
return {
|
|
63177
63177
|
path: path2,
|
|
@@ -63192,6 +63192,25 @@ async function agentExtraDirs(worktreeId4) {
|
|
|
63192
63192
|
const dirs = (await host.info()).dirs;
|
|
63193
63193
|
return dirs ? [dirs.uploads, dirs.shared] : [];
|
|
63194
63194
|
}
|
|
63195
|
+
function sharedFileUrl(worktreeId4, chatId, filename) {
|
|
63196
|
+
return `/api/shared/${encodeURIComponent(worktreeId4)}/${encodeURIComponent(chatId)}/${encodeURIComponent(filename)}`;
|
|
63197
|
+
}
|
|
63198
|
+
function parseSharedPath(rest) {
|
|
63199
|
+
const raw = rest.split("?")[0].split("/");
|
|
63200
|
+
if (raw.length !== 2 && raw.length !== 3) return null;
|
|
63201
|
+
const parts = [];
|
|
63202
|
+
for (const segment of raw) {
|
|
63203
|
+
let decoded;
|
|
63204
|
+
try {
|
|
63205
|
+
decoded = decodeURIComponent(segment);
|
|
63206
|
+
} catch {
|
|
63207
|
+
return null;
|
|
63208
|
+
}
|
|
63209
|
+
if (!decoded || decoded === "." || decoded === ".." || /[/\\\0]/.test(decoded)) return null;
|
|
63210
|
+
parts.push(decoded);
|
|
63211
|
+
}
|
|
63212
|
+
return parts.length === 3 ? { worktreeId: parts[0], chatId: parts[1], name: parts[2] } : { worktreeId: parts[0], name: parts[1] };
|
|
63213
|
+
}
|
|
63195
63214
|
var init_shared_dir = __esm({
|
|
63196
63215
|
"src/server/services/_utils/shared-dir.ts"() {
|
|
63197
63216
|
"use strict";
|
|
@@ -68229,7 +68248,7 @@ function turnUsage(res, ctx) {
|
|
|
68229
68248
|
return { ...usage, model, costUsd: (previousCost ?? 0) + cost };
|
|
68230
68249
|
}
|
|
68231
68250
|
function sharedDirNote(sharedDir) {
|
|
68232
|
-
return `[File sharing: to send a file to the user, write or copy it to ${sharedDir}/ and it will appear as a
|
|
68251
|
+
return `[File sharing: to send a file to the user, write or copy it to ${sharedDir}/ and it will appear as a file card in this chat.]`;
|
|
68233
68252
|
}
|
|
68234
68253
|
function fileUri(path2) {
|
|
68235
68254
|
return `file://${path2.split("/").map(encodeURIComponent).join("/")}`;
|
|
@@ -68729,6 +68748,8 @@ var init_session3 = __esm({
|
|
|
68729
68748
|
this.misses = opts.heartbeatMisses ?? HEARTBEAT_MISSES;
|
|
68730
68749
|
this.nextChan = opts.role === "client" ? 1 : 2;
|
|
68731
68750
|
}
|
|
68751
|
+
/** Close code and reason of the last socket that ended. Code 1006 means no close frame arrived. */
|
|
68752
|
+
lastClose = null;
|
|
68732
68753
|
get attached() {
|
|
68733
68754
|
return this.ws !== null && this.ws.readyState === 1;
|
|
68734
68755
|
}
|
|
@@ -68823,8 +68844,10 @@ var init_session3 = __esm({
|
|
|
68823
68844
|
ws.on("message", (data, isBinary) => {
|
|
68824
68845
|
if (this.ws === ws) this.onMessage(data, isBinary);
|
|
68825
68846
|
});
|
|
68826
|
-
ws.on("close", () => {
|
|
68827
|
-
if (this.ws
|
|
68847
|
+
ws.on("close", (code, reason) => {
|
|
68848
|
+
if (this.ws !== ws) return;
|
|
68849
|
+
this.lastClose = { code, reason: reason.toString().slice(0, 200) };
|
|
68850
|
+
this.detach();
|
|
68828
68851
|
});
|
|
68829
68852
|
ws.on("error", () => {
|
|
68830
68853
|
});
|
|
@@ -68913,34 +68936,40 @@ var init_session3 = __esm({
|
|
|
68913
68936
|
let frame;
|
|
68914
68937
|
try {
|
|
68915
68938
|
frame = decodeFrame(Buffer.isBuffer(data) ? data : Buffer.from(data));
|
|
68916
|
-
} catch {
|
|
68917
|
-
this.
|
|
68939
|
+
} catch (err) {
|
|
68940
|
+
this.cut("undecodable frame", err);
|
|
68918
68941
|
return;
|
|
68919
68942
|
}
|
|
68920
68943
|
try {
|
|
68921
68944
|
this.channels.get(frame.chan)?.handleFrame(frame);
|
|
68922
|
-
} catch {
|
|
68923
|
-
this.
|
|
68945
|
+
} catch (err) {
|
|
68946
|
+
this.cut(`channel ${frame.chan} failed to handle a frame`, err);
|
|
68924
68947
|
}
|
|
68925
68948
|
return;
|
|
68926
68949
|
}
|
|
68927
68950
|
let msg;
|
|
68928
68951
|
try {
|
|
68929
68952
|
msg = JSON.parse(data.toString());
|
|
68930
|
-
} catch {
|
|
68931
|
-
this.
|
|
68953
|
+
} catch (err) {
|
|
68954
|
+
this.cut("unparsable message", err);
|
|
68932
68955
|
return;
|
|
68933
68956
|
}
|
|
68934
68957
|
if (msg === null || typeof msg !== "object") {
|
|
68935
|
-
this.
|
|
68958
|
+
this.cut("message is not an object");
|
|
68936
68959
|
return;
|
|
68937
68960
|
}
|
|
68938
68961
|
try {
|
|
68939
68962
|
this.dispatchText(msg);
|
|
68940
|
-
} catch {
|
|
68941
|
-
this.
|
|
68963
|
+
} catch (err) {
|
|
68964
|
+
this.cut("invalid message", err);
|
|
68942
68965
|
}
|
|
68943
68966
|
}
|
|
68967
|
+
/** Drops the socket after a protocol violation, and says why, so the drop is not silent. */
|
|
68968
|
+
cut(reason, err) {
|
|
68969
|
+
const detail = err instanceof Error ? `: ${err.message}` : "";
|
|
68970
|
+
this.emit("fault", `${reason}${detail}`);
|
|
68971
|
+
this.ws?.terminate();
|
|
68972
|
+
}
|
|
68944
68973
|
dispatchText(msg) {
|
|
68945
68974
|
if (typeof msg.method === "string") {
|
|
68946
68975
|
if ("id" in msg && msg.id !== void 0 && msg.id !== null)
|
|
@@ -68965,14 +68994,32 @@ var init_session3 = __esm({
|
|
|
68965
68994
|
throw new Error("malformed link.open");
|
|
68966
68995
|
}
|
|
68967
68996
|
if (this.channels.has(p2.chan) || this.tombstones.has(p2.chan)) return;
|
|
68968
|
-
if (this.channels.size >= MAX_CHANNELS)
|
|
68997
|
+
if (this.channels.size >= MAX_CHANNELS) {
|
|
68998
|
+
this.emit("fault", `refused channel ${p2.chan}: too many channels`);
|
|
68999
|
+
this.writeBinary(
|
|
69000
|
+
encodeFrame({
|
|
69001
|
+
chan: p2.chan,
|
|
69002
|
+
seq: 0,
|
|
69003
|
+
kind: "reset",
|
|
69004
|
+
payload: Buffer.from("too many channels")
|
|
69005
|
+
})
|
|
69006
|
+
);
|
|
69007
|
+
return;
|
|
69008
|
+
}
|
|
68969
69009
|
const ch = new Channel(this, p2.chan, p2.name, p2.meta, this.window);
|
|
68970
69010
|
this.channels.set(p2.chan, ch);
|
|
68971
69011
|
this.emit("channel", ch);
|
|
68972
69012
|
return;
|
|
68973
69013
|
}
|
|
68974
69014
|
}
|
|
68975
|
-
|
|
69015
|
+
try {
|
|
69016
|
+
this.notifyHandlers.get(msg.method)?.(msg.params);
|
|
69017
|
+
} catch (err) {
|
|
69018
|
+
this.emit(
|
|
69019
|
+
"fault",
|
|
69020
|
+
`notification ${msg.method} handler threw: ${err instanceof Error ? err.message : String(err)}`
|
|
69021
|
+
);
|
|
69022
|
+
}
|
|
68976
69023
|
}
|
|
68977
69024
|
async onRequest(msg) {
|
|
68978
69025
|
const handler = this.handlers.get(msg.method);
|
|
@@ -69324,7 +69371,8 @@ var init_server3 = __esm({
|
|
|
69324
69371
|
resumed,
|
|
69325
69372
|
wsPing: true
|
|
69326
69373
|
});
|
|
69327
|
-
} catch {
|
|
69374
|
+
} catch (err) {
|
|
69375
|
+
this.emit("fault", session, `attach failed: ${err instanceof Error ? err.message : err}`);
|
|
69328
69376
|
ws.terminate();
|
|
69329
69377
|
return;
|
|
69330
69378
|
}
|
|
@@ -69341,6 +69389,7 @@ var init_server3 = __esm({
|
|
|
69341
69389
|
this.expiry.set(session.workerId, t2);
|
|
69342
69390
|
});
|
|
69343
69391
|
session.on("lost", () => this.emit("lost", session));
|
|
69392
|
+
session.on("fault", (reason) => this.emit("fault", session, reason));
|
|
69344
69393
|
}
|
|
69345
69394
|
dropSession(session, reason) {
|
|
69346
69395
|
clearTimeout(this.expiry.get(session.workerId));
|
|
@@ -70413,7 +70462,7 @@ async function runTask(task) {
|
|
|
70413
70462
|
}
|
|
70414
70463
|
if (task.model) await applyTurnChoice(chatId, "model", task.model);
|
|
70415
70464
|
if (task.mode) await applyTurnChoice(chatId, "mode", task.mode);
|
|
70416
|
-
const shared2 = await openSharedDir(task.worktreeId);
|
|
70465
|
+
const shared2 = await openSharedDir(task.worktreeId, chatId);
|
|
70417
70466
|
const seenShared = new Set(await shared2.list());
|
|
70418
70467
|
const announce = (names) => {
|
|
70419
70468
|
for (const filename of names) {
|
|
@@ -70422,7 +70471,7 @@ async function runTask(task) {
|
|
|
70422
70471
|
agentSessionService.record(chatId, {
|
|
70423
70472
|
type: "file",
|
|
70424
70473
|
mediaType: mimeTypeFromFilename(filename),
|
|
70425
|
-
url:
|
|
70474
|
+
url: sharedFileUrl(task.worktreeId, chatId, filename),
|
|
70426
70475
|
filename
|
|
70427
70476
|
});
|
|
70428
70477
|
}
|
|
@@ -75665,10 +75714,8 @@ var init_client_state_keys = __esm({
|
|
|
75665
75714
|
perWorktree("band:dockview-layout-v9:", [jsonPart("device")]),
|
|
75666
75715
|
// The `at` of the continuation the user has seen, which hides the sidebar clock icon.
|
|
75667
75716
|
perWorktree("band:continued-seen:", [rawPart("device")]),
|
|
75668
|
-
// The repo names the mobile app's worktree list has collapsed.
|
|
75717
|
+
// The repo and group names the mobile app's worktree list has collapsed.
|
|
75669
75718
|
exact("band.mobile.collapsed-repos", [jsonPart("device")]),
|
|
75670
|
-
// How the mobile worktree list is grouped: repo, origin or host.
|
|
75671
|
-
exact("band.mobile.group-by", [rawPart("device")]),
|
|
75672
75719
|
// The group the mobile worktree list is filtered to (a group id; unset means All).
|
|
75673
75720
|
exact("band.mobile.group-filter", [rawPart("device")])
|
|
75674
75721
|
];
|
|
@@ -75803,7 +75850,7 @@ var init_client_state_service = __esm({
|
|
|
75803
75850
|
}
|
|
75804
75851
|
const updatedAt = Date.now();
|
|
75805
75852
|
const version3 = input2.baseVersion + 1;
|
|
75806
|
-
|
|
75853
|
+
let written = input2.baseVersion === 0 ? this.queries.insertIfAbsent({
|
|
75807
75854
|
key: input2.key,
|
|
75808
75855
|
scope: input2.scope,
|
|
75809
75856
|
worktreeId: worktreeId4,
|
|
@@ -75815,6 +75862,16 @@ var init_client_state_service = __esm({
|
|
|
75815
75862
|
version: version3,
|
|
75816
75863
|
updatedAt
|
|
75817
75864
|
});
|
|
75865
|
+
if (!written && input2.baseVersion === 0) {
|
|
75866
|
+
const current3 = this.queries.find(input2.key, input2.scope);
|
|
75867
|
+
if (current3 && current3.value === null) {
|
|
75868
|
+
written = this.queries.updateIfVersion(input2.key, input2.scope, current3.version, {
|
|
75869
|
+
value,
|
|
75870
|
+
version: current3.version + 1,
|
|
75871
|
+
updatedAt
|
|
75872
|
+
});
|
|
75873
|
+
}
|
|
75874
|
+
}
|
|
75818
75875
|
const entry = this.queries.find(input2.key, input2.scope) ?? {
|
|
75819
75876
|
key: input2.key,
|
|
75820
75877
|
scope: input2.scope,
|
|
@@ -83233,7 +83290,7 @@ var init_agent_session_service = __esm({
|
|
|
83233
83290
|
ownerGrants.delete(chatId);
|
|
83234
83291
|
const grant = await worktree.host.relay?.issue({ worktreeId: chat.worktreeId, chatId });
|
|
83235
83292
|
if (grant) ownerGrants.set(chatId, grant);
|
|
83236
|
-
const shared2 = await openSharedDir(chat.worktreeId).catch(() => null);
|
|
83293
|
+
const shared2 = await openSharedDir(chat.worktreeId, chatId).catch(() => null);
|
|
83237
83294
|
const login = await agentLoginService.resolve({
|
|
83238
83295
|
agentType: def.type,
|
|
83239
83296
|
repo: worktree.repo.name,
|
|
@@ -90632,6 +90689,7 @@ import {
|
|
|
90632
90689
|
existsSync as existsSync18,
|
|
90633
90690
|
mkdirSync as mkdirSync11,
|
|
90634
90691
|
readFileSync as readFileSync12,
|
|
90692
|
+
realpathSync as realpathSync7,
|
|
90635
90693
|
statSync as statSync16
|
|
90636
90694
|
} from "node:fs";
|
|
90637
90695
|
import { createServer as createServer3 } from "node:http";
|
|
@@ -111646,7 +111704,7 @@ init_registry();
|
|
|
111646
111704
|
// package.json
|
|
111647
111705
|
var package_default = {
|
|
111648
111706
|
name: "@band-app/server",
|
|
111649
|
-
version: "0.
|
|
111707
|
+
version: "0.54.0",
|
|
111650
111708
|
type: "module",
|
|
111651
111709
|
types: "src/index.ts",
|
|
111652
111710
|
exports: {
|
|
@@ -113002,9 +113060,18 @@ var WorkerLinkService = class {
|
|
|
113002
113060
|
this.server = new LinkServer({ authenticate: (hello) => this.authenticate(hello) });
|
|
113003
113061
|
this.server.on("session", (session) => this.onSession(session));
|
|
113004
113062
|
this.server.on("connected", (session) => void this.onConnected(session));
|
|
113063
|
+
this.server.on("disconnected", (session) => {
|
|
113064
|
+
const close = session.lastClose;
|
|
113065
|
+
if (close) {
|
|
113066
|
+
log67.info(
|
|
113067
|
+
`link of ${session.workerId} closed (code ${close.code}${close.reason ? `, ${close.reason}` : ""})`
|
|
113068
|
+
);
|
|
113069
|
+
}
|
|
113070
|
+
this.setStatus(session.workerId, "offline", this.now());
|
|
113071
|
+
});
|
|
113005
113072
|
this.server.on(
|
|
113006
|
-
"
|
|
113007
|
-
(session) =>
|
|
113073
|
+
"fault",
|
|
113074
|
+
(session, reason) => log67.warn(`link of ${session.workerId}: ${reason}`)
|
|
113008
113075
|
);
|
|
113009
113076
|
this.server.on(
|
|
113010
113077
|
"lost",
|
|
@@ -124601,8 +124668,8 @@ init_webhook();
|
|
|
124601
124668
|
|
|
124602
124669
|
// src/server/services/_utils/hosted-file.ts
|
|
124603
124670
|
init_registry();
|
|
124604
|
-
import { basename as basename6, join as join58 } from "node:path";
|
|
124605
|
-
async function openHostedFile(kind, worktreeId4, rawName) {
|
|
124671
|
+
import { basename as basename6, dirname as dirname17, join as join58 } from "node:path";
|
|
124672
|
+
async function openHostedFile(kind, worktreeId4, rawName, chatId) {
|
|
124606
124673
|
const host = hostRegistry.hostFor(worktreeId4);
|
|
124607
124674
|
if (host.id === hostRegistry.local.id) return null;
|
|
124608
124675
|
let name5;
|
|
@@ -124615,7 +124682,9 @@ async function openHostedFile(kind, worktreeId4, rawName) {
|
|
|
124615
124682
|
try {
|
|
124616
124683
|
const dirs = (await host.info()).dirs;
|
|
124617
124684
|
if (!dirs) return null;
|
|
124618
|
-
const path2 = join58(dirs[kind], worktreeId4, name5);
|
|
124685
|
+
const path2 = chatId ? join58(dirs[kind], worktreeId4, chatId, name5) : join58(dirs[kind], worktreeId4, name5);
|
|
124686
|
+
const dir = await host.fs.realpath(dirname17(path2));
|
|
124687
|
+
if (!(await host.fs.realpath(path2)).startsWith(`${dir}/`)) return null;
|
|
124619
124688
|
const stat7 = await host.fs.stat(path2, { followSymlinks: true });
|
|
124620
124689
|
if (stat7.kind !== "file") return null;
|
|
124621
124690
|
return { size: stat7.size, stream: host.fs.readStream(path2) };
|
|
@@ -132736,6 +132805,7 @@ async function listenWithFallback(server, startPort, attempts = 20) {
|
|
|
132736
132805
|
}
|
|
132737
132806
|
|
|
132738
132807
|
// start-server.ts
|
|
132808
|
+
init_shared_dir();
|
|
132739
132809
|
init_agent_session_registry_service();
|
|
132740
132810
|
init_branch_status_poller();
|
|
132741
132811
|
init_browser_service();
|
|
@@ -133098,6 +133168,13 @@ function getCachedScalarHtml() {
|
|
|
133098
133168
|
_scalarHtml = getScalarHtml("/api/openapi.json");
|
|
133099
133169
|
return _scalarHtml;
|
|
133100
133170
|
}
|
|
133171
|
+
function hostedFileHeaders(contentType) {
|
|
133172
|
+
const headers = { "X-Content-Type-Options": "nosniff" };
|
|
133173
|
+
if (/^(text\/html|image\/svg\+xml)\b/.test(contentType)) {
|
|
133174
|
+
headers["Content-Security-Policy"] = "sandbox allow-scripts";
|
|
133175
|
+
}
|
|
133176
|
+
return headers;
|
|
133177
|
+
}
|
|
133101
133178
|
function serveStaticFile(res, root, subdir, rawFilename) {
|
|
133102
133179
|
const filename = basename7(decodeURIComponent(rawFilename));
|
|
133103
133180
|
if (!filename || filename.includes("..")) {
|
|
@@ -133107,12 +133184,19 @@ function serveStaticFile(res, root, subdir, rawFilename) {
|
|
|
133107
133184
|
}
|
|
133108
133185
|
const filePath = join59(root, subdir, filename);
|
|
133109
133186
|
try {
|
|
133187
|
+
const dir = realpathSync7(join59(root, subdir));
|
|
133188
|
+
if (!realpathSync7(filePath).startsWith(dir + sep10)) {
|
|
133189
|
+
res.writeHead(404);
|
|
133190
|
+
res.end("Not found");
|
|
133191
|
+
return;
|
|
133192
|
+
}
|
|
133110
133193
|
const fileStat = statSync16(filePath);
|
|
133111
133194
|
const contentType = mimeTypeFromFilename(filename);
|
|
133112
133195
|
res.writeHead(200, {
|
|
133113
133196
|
"Content-Type": contentType,
|
|
133114
133197
|
"Content-Length": fileStat.size.toString(),
|
|
133115
|
-
"Cache-Control": "private, max-age=86400"
|
|
133198
|
+
"Cache-Control": "private, max-age=86400",
|
|
133199
|
+
...hostedFileHeaders(contentType)
|
|
133116
133200
|
});
|
|
133117
133201
|
createReadStream6(filePath).pipe(res);
|
|
133118
133202
|
} catch {
|
|
@@ -133120,18 +133204,20 @@ function serveStaticFile(res, root, subdir, rawFilename) {
|
|
|
133120
133204
|
res.end("Not found");
|
|
133121
133205
|
}
|
|
133122
133206
|
}
|
|
133123
|
-
async function serveHostedFile(res, kind, worktreeId4, rawName) {
|
|
133207
|
+
async function serveHostedFile(res, kind, worktreeId4, rawName, chatId) {
|
|
133124
133208
|
if (hostRegistry.hostFor(worktreeId4).id === hostRegistry.local.id) return false;
|
|
133125
|
-
const file3 = await openHostedFile(kind, worktreeId4, rawName);
|
|
133209
|
+
const file3 = await openHostedFile(kind, worktreeId4, rawName, chatId);
|
|
133126
133210
|
if (!file3) {
|
|
133127
133211
|
res.writeHead(404);
|
|
133128
133212
|
res.end("Not found");
|
|
133129
133213
|
return true;
|
|
133130
133214
|
}
|
|
133215
|
+
const contentType = mimeTypeFromFilename(basename7(decodeURIComponent(rawName)));
|
|
133131
133216
|
res.writeHead(200, {
|
|
133132
|
-
"Content-Type":
|
|
133217
|
+
"Content-Type": contentType,
|
|
133133
133218
|
"Content-Length": file3.size.toString(),
|
|
133134
|
-
"Cache-Control": "private, max-age=86400"
|
|
133219
|
+
"Cache-Control": "private, max-age=86400",
|
|
133220
|
+
...hostedFileHeaders(contentType)
|
|
133135
133221
|
});
|
|
133136
133222
|
pipeline2(
|
|
133137
133223
|
Readable2.from(file3.stream, { objectMode: false, highWaterMark: 64 * 1024 }),
|
|
@@ -133559,21 +133645,17 @@ async function main() {
|
|
|
133559
133645
|
return;
|
|
133560
133646
|
}
|
|
133561
133647
|
if (req.url?.startsWith("/api/shared/")) {
|
|
133562
|
-
const
|
|
133563
|
-
|
|
133564
|
-
if (slashIdx === -1) {
|
|
133648
|
+
const parsed = parseSharedPath(req.url.slice("/api/shared/".length));
|
|
133649
|
+
if (!parsed) {
|
|
133565
133650
|
res.writeHead(400);
|
|
133566
133651
|
res.end("Bad request");
|
|
133567
133652
|
return;
|
|
133568
133653
|
}
|
|
133569
|
-
const
|
|
133570
|
-
if (
|
|
133571
|
-
res.writeHead(400);
|
|
133572
|
-
res.end("Bad request");
|
|
133654
|
+
const encodedName = encodeURIComponent(parsed.name);
|
|
133655
|
+
if (await serveHostedFile(res, "shared", parsed.worktreeId, encodedName, parsed.chatId))
|
|
133573
133656
|
return;
|
|
133574
|
-
|
|
133575
|
-
|
|
133576
|
-
serveStaticFile(res, bandHome(), join59("shared", partition), rest.slice(slashIdx + 1));
|
|
133657
|
+
const subdir = parsed.chatId ? join59("shared", parsed.worktreeId, parsed.chatId) : join59("shared", parsed.worktreeId);
|
|
133658
|
+
serveStaticFile(res, bandHome(), subdir, encodedName);
|
|
133577
133659
|
return;
|
|
133578
133660
|
}
|
|
133579
133661
|
if (req.url?.startsWith("/api/worktree-file/")) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@band-app/server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.54.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "src/index.ts",
|
|
6
6
|
"exports": {
|
|
@@ -57,18 +57,18 @@
|
|
|
57
57
|
"vitest": "^4.0.18",
|
|
58
58
|
"ws": "^8.18.0",
|
|
59
59
|
"zod": "^3.25.67",
|
|
60
|
-
"@band-app/coding-agent": "^0.
|
|
60
|
+
"@band-app/coding-agent": "^0.54.0",
|
|
61
|
+
"@band-app/host-api": "^0.1.0",
|
|
62
|
+
"@band-app/chat-runtime": "^0.1.0",
|
|
61
63
|
"@band-app/environment": "^0.1.0",
|
|
62
64
|
"@band-app/host-local": "^0.1.0",
|
|
63
65
|
"@band-app/host-remote": "^0.1.0",
|
|
64
|
-
"@band-app/
|
|
65
|
-
"@band-app/host-api": "^0.1.0",
|
|
66
|
-
"@band-app/logger": "^0.53.0",
|
|
67
|
-
"@band-app/plugin-api": "^0.1.0",
|
|
66
|
+
"@band-app/link": "^0.1.0",
|
|
68
67
|
"@band-app/plugin-github": "^0.1.0",
|
|
68
|
+
"@band-app/plugin-api": "^0.1.0",
|
|
69
69
|
"@band-app/shared": "^0.1.0",
|
|
70
70
|
"@band-app/worktree-ops": "^0.1.0",
|
|
71
|
-
"@band-app/
|
|
71
|
+
"@band-app/logger": "^0.54.0"
|
|
72
72
|
},
|
|
73
73
|
"scripts": {
|
|
74
74
|
"dev": "NODE_ENV=development tsx watch --exclude '../web/**' start-server.ts",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Y as a,Z as n}from"./main-Bgor0kVJ.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-B4BG7PRW-CRx24wmo.js";import{_ as i}from"./main-Bgor0kVJ.js";import"./chunk-FMBD7UC4-CFQ4Ns-B.js";import"./chunk-55IACEB6-CZirdcYj.js";import"./chunk-QN33PNHL-O1rjaqXm.js";var p={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{p as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-B4BG7PRW-CRx24wmo.js";import{_ as i}from"./main-Bgor0kVJ.js";import"./chunk-FMBD7UC4-CFQ4Ns-B.js";import"./chunk-55IACEB6-CZirdcYj.js";import"./chunk-QN33PNHL-O1rjaqXm.js";var p={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{p as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as r}from"./_baseUniq-BH8BhmRB.js";var e=4;function a(o){return r(o,e)}export{a as c};
|