@band-app/server 0.55.0 → 0.56.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.
Files changed (70) hide show
  1. package/dist/client/_shell.html +0 -0
  2. package/dist/client/assets/{TerminalPanel-DyFsMnFK.js → TerminalPanel-Wv-LbAcs.js} +1 -1
  3. package/dist/client/assets/{_basePickBy-C1Ui1wUI.js → _basePickBy-CgvoOFSS.js} +1 -1
  4. package/dist/client/assets/{_baseUniq-TZ0JUUYF.js → _baseUniq-DF-p-6fY.js} +1 -1
  5. package/dist/client/assets/{arc-BKZRD7Jr.js → arc-ukMuAfYV.js} +1 -1
  6. package/dist/client/assets/{architectureDiagram-VXUJARFQ-C6U3vX0O.js → architectureDiagram-VXUJARFQ-BHOsjgJ7.js} +1 -1
  7. package/dist/client/assets/{blockDiagram-VD42YOAC-CMKfJSCq.js → blockDiagram-VD42YOAC-V0Q-tFQE.js} +1 -1
  8. package/dist/client/assets/{c4Diagram-YG6GDRKO-BxBYCPCn.js → c4Diagram-YG6GDRKO-BK1nC-Zr.js} +1 -1
  9. package/dist/client/assets/channel-C1UOZUKN.js +1 -0
  10. package/dist/client/assets/{chunk-4BX2VUAB-bw9X6kAI.js → chunk-4BX2VUAB-Cc2lXQih.js} +1 -1
  11. package/dist/client/assets/{chunk-55IACEB6-ClHgx4bC.js → chunk-55IACEB6-ByQepK2K.js} +1 -1
  12. package/dist/client/assets/{chunk-B4BG7PRW-Db1XzP6B.js → chunk-B4BG7PRW-BQQywZlE.js} +1 -1
  13. package/dist/client/assets/{chunk-DI55MBZ5-C8HzWkcQ.js → chunk-DI55MBZ5-C0Q1yI7a.js} +1 -1
  14. package/dist/client/assets/{chunk-FMBD7UC4-54B6Y5YM.js → chunk-FMBD7UC4-G_Ta25S5.js} +1 -1
  15. package/dist/client/assets/{chunk-QN33PNHL-BttimAfW.js → chunk-QN33PNHL-vrj5lpjf.js} +1 -1
  16. package/dist/client/assets/{chunk-QZHKN3VN-BoejelHz.js → chunk-QZHKN3VN-DIoJiZ6Q.js} +1 -1
  17. package/dist/client/assets/{chunk-TZMSLE5B-CDFjN9wj.js → chunk-TZMSLE5B-DbF2At2q.js} +1 -1
  18. package/dist/client/assets/classDiagram-2ON5EDUG-CBwXamAz.js +1 -0
  19. package/dist/client/assets/classDiagram-v2-WZHVMYZB-CBwXamAz.js +1 -0
  20. package/dist/client/assets/clone-CnowCdRV.js +1 -0
  21. package/dist/client/assets/{cose-bilkent-S5V4N54A-VQAtNwQc.js → cose-bilkent-S5V4N54A-DmniYlnr.js} +1 -1
  22. package/dist/client/assets/{dagre-6UL2VRFP-BbY85-fg.js → dagre-6UL2VRFP-xNi8WScD.js} +1 -1
  23. package/dist/client/assets/{diagram-PSM6KHXK-ILb8cZAw.js → diagram-PSM6KHXK-CL4dq7uj.js} +1 -1
  24. package/dist/client/assets/{diagram-QEK2KX5R-BGiFNVyl.js → diagram-QEK2KX5R-C7WQ7eoU.js} +1 -1
  25. package/dist/client/assets/{diagram-S2PKOQOG-CccJTBEx.js → diagram-S2PKOQOG-Cl6jL5JB.js} +1 -1
  26. package/dist/client/assets/{erDiagram-Q2GNP2WA-CkfZ33hi.js → erDiagram-Q2GNP2WA-DOCd-FW1.js} +1 -1
  27. package/dist/client/assets/{flowDiagram-NV44I4VS-Mh9EcV52.js → flowDiagram-NV44I4VS-BcjVCXzs.js} +1 -1
  28. package/dist/client/assets/{ganttDiagram-JELNMOA3-Cyw35fle.js → ganttDiagram-JELNMOA3-Cp5IVV1X.js} +1 -1
  29. package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-B_pqKxKc.js → gitGraphDiagram-V2S2FVAM-D81a2lqP.js} +1 -1
  30. package/dist/client/assets/{graph-9t0DxPCF.js → graph-DAQsyN1O.js} +1 -1
  31. package/dist/client/assets/{highlighted-body-B3W2YXNL-BoRk8xol.js → highlighted-body-B3W2YXNL-BHdTpazT.js} +1 -1
  32. package/dist/client/assets/{index-q1D5zrY_.js → index-4wTCyGVZ.js} +1 -1
  33. package/dist/client/assets/{index-BwCTnd17.js → index-BIBgEJc_.js} +1 -1
  34. package/dist/client/assets/{index-D8L39ca2.js → index-BbUBghw-.js} +1 -1
  35. package/dist/client/assets/{index-Ddtx5YHI.js → index-C69wUmqS.js} +1 -1
  36. package/dist/client/assets/{index-Bq4KlIgZ.js → index-CKC2JTdn.js} +1 -1
  37. package/dist/client/assets/{index-BHbtQqNn.js → index-CYW-8-2k.js} +1 -1
  38. package/dist/client/assets/{index-DyQAzRmj.js → index-CzW0lrV1.js} +1 -1
  39. package/dist/client/assets/{index-B4gaIFLM.js → index-D6mUuQso.js} +1 -1
  40. package/dist/client/assets/{index-B9OAdTCy.js → index-DCOA8K1E.js} +1 -1
  41. package/dist/client/assets/{index-0OIfn_16.js → index-DFnmEpf1.js} +1 -1
  42. package/dist/client/assets/{index-EhAKhw5f.js → index-DcgU8Py3.js} +1 -1
  43. package/dist/client/assets/{index-DicOq_Sf.js → index-DdbCWPks.js} +1 -1
  44. package/dist/client/assets/{index-CtGnlQ-q.js → index-U7nQzvUZ.js} +1 -1
  45. package/dist/client/assets/{infoDiagram-HS3SLOUP-BpXpceBS.js → infoDiagram-HS3SLOUP-Cm5s9O89.js} +1 -1
  46. package/dist/client/assets/{journeyDiagram-XKPGCS4Q-CUzBsDC2.js → journeyDiagram-XKPGCS4Q-BEmfY1L5.js} +1 -1
  47. package/dist/client/assets/{kanban-definition-3W4ZIXB7-d7CaBEND.js → kanban-definition-3W4ZIXB7-BR4wUQUP.js} +1 -1
  48. package/dist/client/assets/{layout-D8LvZDRj.js → layout-eg8UUTsn.js} +1 -1
  49. package/dist/client/assets/{main-BIldwfya.js → main-lic-ksql.js} +247 -247
  50. package/dist/client/assets/{mindmap-definition-VGOIOE7T-CkyVVJ9w.js → mindmap-definition-VGOIOE7T-aO87fIIJ.js} +1 -1
  51. package/dist/client/assets/{pieDiagram-ADFJNKIX-UGEIX01f.js → pieDiagram-ADFJNKIX-D1-R_4cR.js} +1 -1
  52. package/dist/client/assets/{quadrantDiagram-AYHSOK5B-C9PM1qGp.js → quadrantDiagram-AYHSOK5B-DG_jZYS7.js} +1 -1
  53. package/dist/client/assets/{requirementDiagram-UZGBJVZJ-BmJorjE0.js → requirementDiagram-UZGBJVZJ-BtxpIvi0.js} +1 -1
  54. package/dist/client/assets/{sankeyDiagram-TZEHDZUN-DK1YkHOf.js → sankeyDiagram-TZEHDZUN-CEZw5ngO.js} +1 -1
  55. package/dist/client/assets/{sequenceDiagram-WL72ISMW-CMalVkVp.js → sequenceDiagram-WL72ISMW-Da7IJD8T.js} +1 -1
  56. package/dist/client/assets/{stateDiagram-FKZM4ZOC-CtDoLljP.js → stateDiagram-FKZM4ZOC-D9MZaz-Z.js} +1 -1
  57. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-BZauII8k.js +1 -0
  58. package/dist/client/assets/{timeline-definition-IT6M3QCI-Vy5fVSzE.js → timeline-definition-IT6M3QCI-Dpy1CJBt.js} +1 -1
  59. package/dist/client/assets/{treemap-GDKQZRPO-DN8hAqbn.js → treemap-GDKQZRPO-CwxFs7qg.js} +1 -1
  60. package/dist/client/assets/{worktree._worktreeId-BjqfB2FM.js → worktree._worktreeId-BrMMD4KZ.js} +1 -1
  61. package/dist/client/assets/{worktree._worktreeId-enSNl8Hs.js → worktree._worktreeId-D8tRL5dj.js} +1 -1
  62. package/dist/client/assets/{xychartDiagram-PRI3JC2R-Dl5pLjgP.js → xychartDiagram-PRI3JC2R-C42Fu89p.js} +1 -1
  63. package/dist/openapi.json +30 -27
  64. package/dist/start-server.mjs +456 -415
  65. package/package.json +10 -10
  66. package/dist/client/assets/channel-BJXLlcqp.js +0 -1
  67. package/dist/client/assets/classDiagram-2ON5EDUG-27E8Epaa.js +0 -1
  68. package/dist/client/assets/classDiagram-v2-WZHVMYZB-27E8Epaa.js +0 -1
  69. package/dist/client/assets/clone-DTRMs_1C.js +0 -1
  70. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-Bu9w4Lt2.js +0 -1
@@ -2989,11 +2989,11 @@ var require_tools = __commonJS({
2989
2989
  }
2990
2990
  }
2991
2991
  }
2992
- function buildFormatters(level, bindings, log94) {
2992
+ function buildFormatters(level, bindings, log95) {
2993
2993
  return {
2994
2994
  level,
2995
2995
  bindings,
2996
- log: log94
2996
+ log: log95
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: log94 } = options.formatters;
3379
+ const { level, bindings: chindings, log: log95 } = options.formatters;
3380
3380
  instance[formattersSym] = buildFormatters(
3381
3381
  level || formatters.level,
3382
3382
  chindings || resetChildingsFormatter,
3383
- log94 || formatters.log
3383
+ log95 || formatters.log
3384
3384
  );
3385
3385
  } else {
3386
3386
  instance[formattersSym] = buildFormatters(
@@ -17542,6 +17542,104 @@ var init_speech_transcription = __esm({
17542
17542
  }
17543
17543
  });
17544
17544
 
17545
+ // ../../packages/worktree-ops/src/http-files.ts
17546
+ import { extname } from "node:path";
17547
+ function parseByteRange(header, size) {
17548
+ const match = /^bytes=(\d*)-(\d*)$/.exec(header?.trim() ?? "");
17549
+ if (!match || match[1] === "" && match[2] === "") return null;
17550
+ if (match[1] !== "" && match[2] !== "" && Number(match[2]) < Number(match[1])) return null;
17551
+ let start;
17552
+ let end;
17553
+ if (match[1] === "") {
17554
+ const length = Number(match[2]);
17555
+ if (length === 0) return "unsatisfiable";
17556
+ start = Math.max(0, size - length);
17557
+ end = size - 1;
17558
+ } else {
17559
+ start = Number(match[1]);
17560
+ end = match[2] === "" ? size - 1 : Math.min(Number(match[2]), size - 1);
17561
+ }
17562
+ if (start >= size || start > end) return "unsatisfiable";
17563
+ return { start, end };
17564
+ }
17565
+ function attachmentDisposition(filename) {
17566
+ const clean = filename.replace(/[/\\]/g, "_") || "download";
17567
+ const ascii = clean.replace(/[^\x20-\x7e]/g, "_").replace(/["%;]/g, "_");
17568
+ const encoded = encodeURIComponent(clean).replace(
17569
+ /['()*]/g,
17570
+ (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
17571
+ );
17572
+ return `attachment; filename="${ascii}"; filename*=UTF-8''${encoded}`;
17573
+ }
17574
+ function mimeTypeFromFilename(filename) {
17575
+ const ext = extname(filename).toLowerCase();
17576
+ return MIME_TYPES[ext] || "application/octet-stream";
17577
+ }
17578
+ function hostedFileHeaders(contentType) {
17579
+ const headers = { "X-Content-Type-Options": "nosniff" };
17580
+ if (/^(text\/html|image\/svg\+xml)\b/.test(contentType)) {
17581
+ headers["Content-Security-Policy"] = "sandbox allow-scripts";
17582
+ }
17583
+ return headers;
17584
+ }
17585
+ function parseSharedPath(rest) {
17586
+ const raw = rest.split("?")[0].split("/");
17587
+ if (raw.length !== 2 && raw.length !== 3) return null;
17588
+ const parts = [];
17589
+ for (const segment of raw) {
17590
+ let decoded;
17591
+ try {
17592
+ decoded = decodeURIComponent(segment);
17593
+ } catch {
17594
+ return null;
17595
+ }
17596
+ if (!decoded || decoded === "." || decoded === ".." || /[/\\\0]/.test(decoded)) return null;
17597
+ parts.push(decoded);
17598
+ }
17599
+ return parts.length === 3 ? { worktreeId: parts[0], chatId: parts[1], name: parts[2] } : { worktreeId: parts[0], name: parts[1] };
17600
+ }
17601
+ var MIME_TYPES;
17602
+ var init_http_files = __esm({
17603
+ "../../packages/worktree-ops/src/http-files.ts"() {
17604
+ "use strict";
17605
+ MIME_TYPES = {
17606
+ ".png": "image/png",
17607
+ ".jpg": "image/jpeg",
17608
+ ".jpeg": "image/jpeg",
17609
+ ".gif": "image/gif",
17610
+ ".webp": "image/webp",
17611
+ ".svg": "image/svg+xml",
17612
+ ".ico": "image/x-icon",
17613
+ ".bmp": "image/bmp",
17614
+ ".avif": "image/avif",
17615
+ ".mp4": "video/mp4",
17616
+ ".m4v": "video/mp4",
17617
+ ".mov": "video/quicktime",
17618
+ ".webm": "video/webm",
17619
+ ".ogv": "video/ogg",
17620
+ ".pdf": "application/pdf",
17621
+ ".json": "application/json",
17622
+ ".txt": "text/plain",
17623
+ ".md": "text/markdown",
17624
+ ".csv": "text/csv",
17625
+ ".html": "text/html; charset=utf-8",
17626
+ ".htm": "text/html; charset=utf-8",
17627
+ ".css": "text/css; charset=utf-8",
17628
+ ".js": "text/javascript; charset=utf-8",
17629
+ ".mjs": "text/javascript; charset=utf-8",
17630
+ ".woff": "font/woff",
17631
+ ".woff2": "font/woff2",
17632
+ ".ttf": "font/ttf",
17633
+ ".otf": "font/otf",
17634
+ ".ts": "application/typescript",
17635
+ ".xml": "application/xml",
17636
+ ".yaml": "application/x-yaml",
17637
+ ".yml": "application/x-yaml",
17638
+ ".zip": "application/zip"
17639
+ };
17640
+ }
17641
+ });
17642
+
17545
17643
  // ../../node_modules/.pnpm/@trpc+server@11.12.0_typescript@5.9.3/node_modules/@trpc/server/dist/codes-DagpWZLc.mjs
17546
17644
  function mergeWithoutOverrides(obj1, ...objs) {
17547
17645
  const newObj = Object.assign(emptyObject(), obj1);
@@ -65815,27 +65913,12 @@ async function agentExtraDirs(worktreeId4) {
65815
65913
  function sharedFileUrl(worktreeId4, chatId, filename) {
65816
65914
  return `/api/shared/${encodeURIComponent(worktreeId4)}/${encodeURIComponent(chatId)}/${encodeURIComponent(filename)}`;
65817
65915
  }
65818
- function parseSharedPath(rest) {
65819
- const raw = rest.split("?")[0].split("/");
65820
- if (raw.length !== 2 && raw.length !== 3) return null;
65821
- const parts = [];
65822
- for (const segment of raw) {
65823
- let decoded;
65824
- try {
65825
- decoded = decodeURIComponent(segment);
65826
- } catch {
65827
- return null;
65828
- }
65829
- if (!decoded || decoded === "." || decoded === ".." || /[/\\\0]/.test(decoded)) return null;
65830
- parts.push(decoded);
65831
- }
65832
- return parts.length === 3 ? { worktreeId: parts[0], chatId: parts[1], name: parts[2] } : { worktreeId: parts[0], name: parts[1] };
65833
- }
65834
65916
  var init_shared_dir = __esm({
65835
65917
  "src/server/services/_utils/shared-dir.ts"() {
65836
65918
  "use strict";
65837
65919
  init_registry();
65838
65920
  init_state();
65921
+ init_http_files();
65839
65922
  }
65840
65923
  });
65841
65924
 
@@ -71332,50 +71415,10 @@ var init_chat_status_service = __esm({
71332
71415
  });
71333
71416
 
71334
71417
  // src/server/services/_utils/mime-types.ts
71335
- import { extname } from "node:path";
71336
- function mimeTypeFromFilename(filename) {
71337
- const ext = extname(filename).toLowerCase();
71338
- return MIME_TYPES[ext] || "application/octet-stream";
71339
- }
71340
- var MIME_TYPES;
71341
71418
  var init_mime_types = __esm({
71342
71419
  "src/server/services/_utils/mime-types.ts"() {
71343
71420
  "use strict";
71344
- MIME_TYPES = {
71345
- ".png": "image/png",
71346
- ".jpg": "image/jpeg",
71347
- ".jpeg": "image/jpeg",
71348
- ".gif": "image/gif",
71349
- ".webp": "image/webp",
71350
- ".svg": "image/svg+xml",
71351
- ".ico": "image/x-icon",
71352
- ".bmp": "image/bmp",
71353
- ".avif": "image/avif",
71354
- ".mp4": "video/mp4",
71355
- ".m4v": "video/mp4",
71356
- ".mov": "video/quicktime",
71357
- ".webm": "video/webm",
71358
- ".ogv": "video/ogg",
71359
- ".pdf": "application/pdf",
71360
- ".json": "application/json",
71361
- ".txt": "text/plain",
71362
- ".md": "text/markdown",
71363
- ".csv": "text/csv",
71364
- ".html": "text/html; charset=utf-8",
71365
- ".htm": "text/html; charset=utf-8",
71366
- ".css": "text/css; charset=utf-8",
71367
- ".js": "text/javascript; charset=utf-8",
71368
- ".mjs": "text/javascript; charset=utf-8",
71369
- ".woff": "font/woff",
71370
- ".woff2": "font/woff2",
71371
- ".ttf": "font/ttf",
71372
- ".otf": "font/otf",
71373
- ".ts": "application/typescript",
71374
- ".xml": "application/xml",
71375
- ".yaml": "application/x-yaml",
71376
- ".yml": "application/x-yaml",
71377
- ".zip": "application/zip"
71378
- };
71421
+ init_http_files();
71379
71422
  }
71380
71423
  });
71381
71424
 
@@ -75358,8 +75401,8 @@ var init_environment_builds = __esm({
75358
75401
  get(id) {
75359
75402
  return getDb().select().from(environmentBuilds).where(eq2(environmentBuilds.id, id)).get();
75360
75403
  }
75361
- setLog(id, log94) {
75362
- getDb().update(environmentBuilds).set({ log: log94 }).where(eq2(environmentBuilds.id, id)).run();
75404
+ setLog(id, log95) {
75405
+ getDb().update(environmentBuilds).set({ log: log95 }).where(eq2(environmentBuilds.id, id)).run();
75363
75406
  }
75364
75407
  finish(id, result) {
75365
75408
  getDb().update(environmentBuilds).set({
@@ -75727,32 +75770,32 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
75727
75770
  }
75728
75771
  // ---- running ---------------------------------------------------------------
75729
75772
  async run(row, plan) {
75730
- const log94 = new BuildLog(row.id, (id, text4) => this.queries.setLog(id, text4));
75773
+ const log95 = new BuildLog(row.id, (id, text4) => this.queries.setLog(id, text4));
75731
75774
  let tmp = null;
75732
75775
  const container = `band-env-${row.id.slice(0, 12)}`;
75733
75776
  let failure4 = null;
75734
75777
  try {
75735
- log94.add(`Building ${plan.tag} for ${plan.repo} at ${plan.ref} (${plan.commit.slice(0, 12)})`);
75736
- log94.flush();
75778
+ log95.add(`Building ${plan.tag} for ${plan.repo} at ${plan.ref} (${plan.commit.slice(0, 12)})`);
75779
+ log95.flush();
75737
75780
  tmp = await plan.host.fs.mkdtemp("band-env-");
75738
- await this.exportCheckout(plan, tmp, log94);
75739
- const toolchain = await this.buildToolchain(plan, tmp, log94);
75740
- const layered = await this.addWorkerLayer(plan, tmp, toolchain, log94);
75741
- await this.install(plan, tmp, layered, container, log94);
75742
- if (plan.registry) await this.push(plan, log94);
75743
- log94.add(`Done: ${plan.tag}`);
75781
+ await this.exportCheckout(plan, tmp, log95);
75782
+ const toolchain = await this.buildToolchain(plan, tmp, log95);
75783
+ const layered = await this.addWorkerLayer(plan, tmp, toolchain, log95);
75784
+ await this.install(plan, tmp, layered, container, log95);
75785
+ if (plan.registry) await this.push(plan, log95);
75786
+ log95.add(`Done: ${plan.tag}`);
75744
75787
  } catch (err) {
75745
75788
  failure4 = err.message;
75746
- log94.add(`FAILED: ${failure4}`);
75789
+ log95.add(`FAILED: ${failure4}`);
75747
75790
  }
75748
- await this.exec(plan.host, "docker", ["rm", "--force", container], log94, { quiet: true }).catch(
75791
+ await this.exec(plan.host, "docker", ["rm", "--force", container], log95, { quiet: true }).catch(
75749
75792
  () => void 0
75750
75793
  );
75751
75794
  await this.exec(
75752
75795
  plan.host,
75753
75796
  "docker",
75754
75797
  ["rmi", toolchainTag(plan.repo, plan.key), layeredTag(plan.repo, plan.key)],
75755
- log94,
75798
+ log95,
75756
75799
  { quiet: true }
75757
75800
  ).catch(() => void 0);
75758
75801
  if (tmp) await plan.host.fs.rm(tmp, { recursive: true, force: true }).catch(() => void 0);
@@ -75761,14 +75804,14 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
75761
75804
  this.queries.finish(row.id, {
75762
75805
  status: "ready",
75763
75806
  image: plan.tag,
75764
- log: log94.toString(),
75807
+ log: log95.toString(),
75765
75808
  at: Date.now()
75766
75809
  });
75767
75810
  } else {
75768
75811
  this.queries.finish(row.id, {
75769
75812
  status: "failed",
75770
75813
  error: failure4.slice(0, 2e3),
75771
- log: log94.toString(),
75814
+ log: log95.toString(),
75772
75815
  at: Date.now()
75773
75816
  });
75774
75817
  }
@@ -75777,9 +75820,9 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
75777
75820
  }
75778
75821
  }
75779
75822
  /** Runs a command on the builder host, adding it and its output to the log. */
75780
- async exec(host, tool2, args, log94, options = {}) {
75823
+ async exec(host, tool2, args, log95, options = {}) {
75781
75824
  const bin = tool2 === "docker" ? this.dockerBin(host) : tool2 === "devcontainer" ? this.devcontainerBin(host) : "git";
75782
- if (!options.quiet) log94.add(`$ ${tool2} ${args.join(" ")}`);
75825
+ if (!options.quiet) log95.add(`$ ${tool2} ${args.join(" ")}`);
75783
75826
  try {
75784
75827
  const out = await host.exec(bin, args, {
75785
75828
  cwd: options.cwd,
@@ -75787,35 +75830,35 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
75787
75830
  timeoutMs: envNumber("BAND_ENVIRONMENT_BUILD_TIMEOUT_MS", DEFAULT_STEP_TIMEOUT_MS)
75788
75831
  });
75789
75832
  if (!options.quiet) {
75790
- if (out.stdout.trim()) log94.add(out.stdout.trimEnd());
75791
- if (out.stderr.trim()) log94.add(out.stderr.trimEnd());
75792
- log94.flush();
75833
+ if (out.stdout.trim()) log95.add(out.stdout.trimEnd());
75834
+ if (out.stderr.trim()) log95.add(out.stderr.trimEnd());
75835
+ log95.flush();
75793
75836
  }
75794
75837
  return out.stdout;
75795
75838
  } catch (err) {
75796
75839
  if (!options.quiet) {
75797
- log94.add(err.message);
75798
- log94.flush();
75840
+ log95.add(err.message);
75841
+ log95.flush();
75799
75842
  }
75800
75843
  throw new Error(`${tool2} ${args[0] ?? ""} failed: ${firstLine(err.message)}`);
75801
75844
  }
75802
75845
  }
75803
75846
  /** Writes the default branch's files, with no `.git`, to `<tmp>/src`. */
75804
- async exportCheckout(plan, tmp, log94) {
75847
+ async exportCheckout(plan, tmp, log95) {
75805
75848
  const src = posix4.join(tmp, "src");
75806
75849
  await plan.host.fs.mkdir(src);
75807
75850
  const index3 = posix4.join(tmp, "index");
75808
- await this.exec(plan.host, "git", ["read-tree", plan.ref], log94, {
75851
+ await this.exec(plan.host, "git", ["read-tree", plan.ref], log95, {
75809
75852
  cwd: plan.repoPath,
75810
75853
  env: { GIT_INDEX_FILE: index3 }
75811
75854
  });
75812
- await this.exec(plan.host, "git", ["checkout-index", "--all", `--prefix=${src}/`], log94, {
75855
+ await this.exec(plan.host, "git", ["checkout-index", "--all", `--prefix=${src}/`], log95, {
75813
75856
  cwd: plan.repoPath,
75814
75857
  env: { GIT_INDEX_FILE: index3 }
75815
75858
  });
75816
75859
  }
75817
75860
  /** Layer 2: returns the tag of an image holding the repo's toolchain. */
75818
- async buildToolchain(plan, tmp, log94) {
75861
+ async buildToolchain(plan, tmp, log95) {
75819
75862
  const build = plan.environment.build;
75820
75863
  const src = posix4.join(tmp, "src");
75821
75864
  const tag = toolchainTag(plan.repo, plan.key);
@@ -75824,7 +75867,7 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
75824
75867
  plan.host,
75825
75868
  "docker",
75826
75869
  dockerBuildArgs({ checkout: src, dockerfile: build.dockerfile, tag }),
75827
- log94
75870
+ log95
75828
75871
  );
75829
75872
  return tag;
75830
75873
  }
@@ -75834,7 +75877,7 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
75834
75877
  plan.host,
75835
75878
  "devcontainer",
75836
75879
  devcontainerBuildArgs({ checkout: src, config: build.devcontainer, tag }),
75837
- log94
75880
+ log95
75838
75881
  );
75839
75882
  } catch (err) {
75840
75883
  throw new Error(
@@ -75844,11 +75887,11 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
75844
75887
  return tag;
75845
75888
  }
75846
75889
  const image = build?.image;
75847
- await this.exec(plan.host, "docker", ["pull", image], log94);
75890
+ await this.exec(plan.host, "docker", ["pull", image], log95);
75848
75891
  return image;
75849
75892
  }
75850
75893
  /** Layer 1 on top of layer 2: copies the worker from the worker base image. */
75851
- async addWorkerLayer(plan, tmp, toolchain, log94) {
75894
+ async addWorkerLayer(plan, tmp, toolchain, log95) {
75852
75895
  const dir = posix4.join(tmp, "layer");
75853
75896
  await plan.host.fs.mkdir(dir);
75854
75897
  await plan.host.fs.writeFile(
@@ -75860,38 +75903,38 @@ ${this.text.slice(-MAX_LOG_BYTES)}`;
75860
75903
  });
75861
75904
  await plan.host.fs.mkdir(posix4.join(dir, "root", "work"), { recursive: true });
75862
75905
  const tag = layeredTag(plan.repo, plan.key);
75863
- await this.exec(plan.host, "docker", ["build", "--tag", tag, dir], log94);
75906
+ await this.exec(plan.host, "docker", ["build", "--tag", tag, dir], log95);
75864
75907
  return tag;
75865
75908
  }
75866
75909
  /** Runs `install` at the default branch inside the image and commits the result as the final tag. */
75867
- async install(plan, tmp, layered, container, log94) {
75910
+ async install(plan, tmp, layered, container, log95) {
75868
75911
  const install = plan.environment.install;
75869
75912
  if (install === void 0) {
75870
- await this.exec(plan.host, "docker", ["tag", layered, plan.tag], log94);
75913
+ await this.exec(plan.host, "docker", ["tag", layered, plan.tag], log95);
75871
75914
  return;
75872
75915
  }
75873
75916
  await this.exec(
75874
75917
  plan.host,
75875
75918
  "docker",
75876
75919
  installCreateArgs({ name: container, image: layered, install }),
75877
- log94
75920
+ log95
75878
75921
  );
75879
75922
  await this.exec(
75880
75923
  plan.host,
75881
75924
  "docker",
75882
75925
  ["cp", `${posix4.join(tmp, "src")}/.`, `${container}:${IMAGE_WORKDIR}`],
75883
- log94
75926
+ log95
75884
75927
  );
75885
- await this.exec(plan.host, "docker", ["start", "--attach", container], log94);
75928
+ await this.exec(plan.host, "docker", ["start", "--attach", container], log95);
75886
75929
  await this.exec(
75887
75930
  plan.host,
75888
75931
  "docker",
75889
75932
  commitArgs({ container, tag: plan.tag, key: plan.key, commit: plan.commit }),
75890
- log94
75933
+ log95
75891
75934
  );
75892
75935
  }
75893
- async push(plan, log94) {
75894
- await this.exec(plan.host, "docker", ["push", plan.tag], log94);
75936
+ async push(plan, log95) {
75937
+ await this.exec(plan.host, "docker", ["push", plan.tag], log95);
75895
75938
  }
75896
75939
  // ---- auto trigger ----------------------------------------------------------
75897
75940
  /**
@@ -90129,11 +90172,11 @@ var require_core = __commonJS({
90129
90172
  Ajv2.ValidationError = validation_error_1.default;
90130
90173
  Ajv2.MissingRefError = ref_error_1.default;
90131
90174
  exports.default = Ajv2;
90132
- function checkOptions(checkOpts, options, msg, log94 = "error") {
90175
+ function checkOptions(checkOpts, options, msg, log95 = "error") {
90133
90176
  for (const key2 in checkOpts) {
90134
90177
  const opt = key2;
90135
90178
  if (opt in options)
90136
- this.logger[log94](`${msg}: option ${key2}. ${checkOpts[opt]}`);
90179
+ this.logger[log95](`${msg}: option ${key2}. ${checkOpts[opt]}`);
90137
90180
  }
90138
90181
  }
90139
90182
  function getSchEnv(keyRef) {
@@ -92663,6 +92706,7 @@ function createTerminalBackend(serverRoot, bandHome2) {
92663
92706
  // start-server.ts
92664
92707
  init_src4();
92665
92708
  init_speech_transcription();
92709
+ init_http_files();
92666
92710
 
92667
92711
  // ../../node_modules/.pnpm/@trpc+server@11.12.0_typescript@5.9.3/node_modules/@trpc/server/dist/adapters/fetch/index.mjs
92668
92712
  init_getErrorShape_vC8mUXJD();
@@ -112513,9 +112557,6 @@ function throwAsTRPCError(err) {
112513
112557
  init_dist();
112514
112558
  init_zod();
112515
112559
 
112516
- // src/server/services/editor-service.ts
112517
- import { isAbsolute as isAbsolute5, join as join52, resolve as resolve10, sep as sep6 } from "node:path";
112518
-
112519
112560
  // ../../packages/shared/src/file-location.ts
112520
112561
  function formatFileLocation(filePath, line2, options) {
112521
112562
  if (line2 != null && options?.lineEnd != null) return `${filePath}:${line2}-${options.lineEnd}`;
@@ -112524,12 +112565,71 @@ function formatFileLocation(filePath, line2, options) {
112524
112565
  return filePath;
112525
112566
  }
112526
112567
 
112568
+ // ../../packages/worktree-ops/src/resolve-path.ts
112569
+ init_resolver();
112570
+ import { isAbsolute as isAbsolute4, join as join51, resolve as resolve10, sep as sep6 } from "node:path";
112571
+ var PathsService = class {
112572
+ constructor(worktrees2) {
112573
+ this.worktrees = worktrees2;
112574
+ }
112575
+ async resolvePath(input3) {
112576
+ const worktree = this.worktrees.resolve(input3.worktreeId);
112577
+ if (!worktree) throw new WorktreeNotFoundError(input3.worktreeId);
112578
+ const resolved = await resolveTarget(worktree.host.fs, worktree.worktree.path, input3.filePath);
112579
+ return {
112580
+ exists: resolved.exists,
112581
+ isFile: resolved.isFile,
112582
+ external: !resolved.inside,
112583
+ worktreeRelativePath: resolved.inside ? resolved.relativePath : null
112584
+ };
112585
+ }
112586
+ };
112587
+ async function resolveTarget(fs3, root, filePath) {
112588
+ const absoluteTarget = isAbsolute4(filePath) ? resolve10(filePath) : resolve10(root, filePath);
112589
+ let canonicalRoot = root;
112590
+ try {
112591
+ canonicalRoot = await fs3.realpath(root);
112592
+ } catch {
112593
+ }
112594
+ const canonicalTarget = await canonicalizeMaybeMissing(fs3, absoluteTarget);
112595
+ let targetStat = null;
112596
+ try {
112597
+ targetStat = await fs3.stat(canonicalTarget, { followSymlinks: true });
112598
+ } catch {
112599
+ }
112600
+ const normalizedRoot = canonicalRoot.replace(/\/+$/, "");
112601
+ const inside = canonicalTarget === normalizedRoot || canonicalTarget.startsWith(`${normalizedRoot}${sep6}`);
112602
+ const relativePath = inside ? (canonicalTarget === normalizedRoot ? "" : canonicalTarget.slice(normalizedRoot.length + 1)).split(sep6).join("/") : null;
112603
+ return {
112604
+ canonicalTarget,
112605
+ exists: !!targetStat,
112606
+ isFile: targetStat?.kind === "file",
112607
+ inside,
112608
+ relativePath
112609
+ };
112610
+ }
112611
+ async function canonicalizeMaybeMissing(fs3, p2) {
112612
+ try {
112613
+ return await fs3.realpath(p2);
112614
+ } catch {
112615
+ }
112616
+ const parts = p2.split(sep6);
112617
+ for (let i = parts.length - 1; i > 0; i--) {
112618
+ const prefix = parts.slice(0, i).join(sep6) || sep6;
112619
+ try {
112620
+ const canonicalPrefix = await fs3.realpath(prefix);
112621
+ return join51(canonicalPrefix, ...parts.slice(i));
112622
+ } catch {
112623
+ }
112624
+ }
112625
+ return p2;
112626
+ }
112627
+
112527
112628
  // src/server/services/editor-service.ts
112528
112629
  init_errors6();
112529
112630
  init_registry();
112530
112631
 
112531
- // src/server/services/file-watcher.ts
112532
- init_worktree_service();
112632
+ // ../../packages/worktree-ops/src/file-watch.ts
112533
112633
  var IGNORED_SEGMENTS = /* @__PURE__ */ new Set([
112534
112634
  ".git",
112535
112635
  "node_modules",
@@ -112600,16 +112700,15 @@ async function pumpChanges(worktreeId4, entry, host, root) {
112600
112700
  for (const listener of entry.listeners) listener(null);
112601
112701
  stopWatcher(worktreeId4, entry);
112602
112702
  }
112603
- function subscribeToFileChanges(worktreeId4, listener) {
112703
+ function subscribeToFileChanges(worktreeId4, open4, listener) {
112604
112704
  let entry = watchers.get(worktreeId4);
112605
112705
  if (!entry) {
112606
- const ws = worktreeService.resolve(worktreeId4);
112607
- if (!ws) return () => {
112706
+ const target = open4();
112707
+ if (!target) return () => {
112608
112708
  };
112609
- const root = ws.worktree.path;
112610
112709
  entry = { controller: new AbortController(), listeners: /* @__PURE__ */ new Set(), pendingTimers: /* @__PURE__ */ new Map() };
112611
112710
  watchers.set(worktreeId4, entry);
112612
- void pumpChanges(worktreeId4, entry, ws.host, root);
112711
+ void pumpChanges(worktreeId4, entry, target.host, target.root);
112613
112712
  }
112614
112713
  entry.listeners.add(listener);
112615
112714
  const subscribed = entry;
@@ -112619,10 +112718,23 @@ function subscribeToFileChanges(worktreeId4, listener) {
112619
112718
  };
112620
112719
  }
112621
112720
 
112721
+ // src/server/services/file-watcher.ts
112722
+ init_worktree_service();
112723
+ function subscribeToFileChanges2(worktreeId4, listener) {
112724
+ return subscribeToFileChanges(
112725
+ worktreeId4,
112726
+ () => {
112727
+ const ws = worktreeService.resolve(worktreeId4);
112728
+ return ws ? { host: ws.host, root: ws.worktree.path } : null;
112729
+ },
112730
+ listener
112731
+ );
112732
+ }
112733
+
112622
112734
  // src/server/services/formatter.ts
112623
112735
  init_src();
112624
112736
  init_registry();
112625
- import { basename as basename4, dirname as dirname15, isAbsolute as isAbsolute4, join as join51, resolve as resolvePath3 } from "node:path";
112737
+ import { basename as basename4, dirname as dirname15, isAbsolute as isAbsolute5, join as join52, resolve as resolvePath3 } from "node:path";
112626
112738
  import prettier from "prettier";
112627
112739
  var log64 = createLogger("formatter");
112628
112740
  var FormatterError = class extends Error {
@@ -112638,7 +112750,7 @@ var FormatterError = class extends Error {
112638
112750
  async function formatFile(worktreePath, filePath, content, options = {}) {
112639
112751
  const fs3 = options.fs ?? hostRegistry.local.fs;
112640
112752
  const onHub = fs3 === hostRegistry.local.fs;
112641
- const absFile = isAbsolute4(filePath) ? filePath : resolvePath3(worktreePath, filePath);
112753
+ const absFile = isAbsolute5(filePath) ? filePath : resolvePath3(worktreePath, filePath);
112642
112754
  if (!await isInsideWorktree(fs3, absFile, worktreePath)) {
112643
112755
  throw new FormatterError(
112644
112756
  "FILE_NOT_IN_WORKTREE",
@@ -112704,10 +112816,10 @@ async function resolveConfigOnHost(fs3, absFile, worktreePath) {
112704
112816
  let dir = dirname15(absFile);
112705
112817
  for (; ; ) {
112706
112818
  for (const name5 of JSON_CONFIGS) {
112707
- const parsed = await readJson2(fs3, join51(dir, name5));
112819
+ const parsed = await readJson2(fs3, join52(dir, name5));
112708
112820
  if (parsed && typeof parsed === "object") return withoutPlugins(parsed);
112709
112821
  }
112710
- const pkg = await readJson2(fs3, join51(dir, "package.json"));
112822
+ const pkg = await readJson2(fs3, join52(dir, "package.json"));
112711
112823
  if (pkg && typeof pkg.prettier === "object" && pkg.prettier !== null) {
112712
112824
  return withoutPlugins(pkg.prettier);
112713
112825
  }
@@ -112745,7 +112857,7 @@ async function isInsideWorktree(fs3, absFile, worktreePath) {
112745
112857
  realFile = await fs3.realpath(absFile);
112746
112858
  } catch {
112747
112859
  try {
112748
- realFile = join51(await fs3.realpath(dirname15(absFile)), basename4(absFile));
112860
+ realFile = join52(await fs3.realpath(dirname15(absFile)), basename4(absFile));
112749
112861
  } catch {
112750
112862
  realFile = absFile;
112751
112863
  }
@@ -112796,7 +112908,7 @@ var EditorService = class {
112796
112908
  // File-change subscriptions (per-worktree fs.watch)
112797
112909
  // -------------------------------------------------------------------------
112798
112910
  subscribeToFileChanges(worktreeId4, listener) {
112799
- return subscribeToFileChanges(worktreeId4, listener);
112911
+ return subscribeToFileChanges2(worktreeId4, listener);
112800
112912
  }
112801
112913
  // -------------------------------------------------------------------------
112802
112914
  // LSP lifecycle pass-throughs
@@ -112823,11 +112935,7 @@ var EditorService = class {
112823
112935
  if (!worktree) {
112824
112936
  throw new EditorOpenError("NOT_FOUND", `Worktree '${targetWorktreeId}' not found`);
112825
112937
  }
112826
- const resolved = await this.resolveTarget(
112827
- worktree.host.fs,
112828
- worktree.worktree.path,
112829
- input3.filePath
112830
- );
112938
+ const resolved = await resolveTarget(worktree.host.fs, worktree.worktree.path, input3.filePath);
112831
112939
  if (!resolved.exists) {
112832
112940
  throw new EditorOpenError("NOT_FOUND", `File not found: ${input3.filePath}`);
112833
112941
  }
@@ -112853,66 +112961,6 @@ var EditorService = class {
112853
112961
  external: !resolved.inside
112854
112962
  };
112855
112963
  }
112856
- /**
112857
- * Resolve a path (absolute or worktree-relative) against a worktree and
112858
- * report where it lands. Used by the dashboard's Quick Open to decide, for
112859
- * an absolute-path query, whether to open the file as a normal
112860
- * worktree-relative tab (when it lives *inside* the worktree) or as an
112861
- * external tab (outside) — and, either way, whether it exists at all.
112862
- *
112863
- * Shares the exact canonicalize + segment-aware containment logic that
112864
- * `openFile` uses, so an absolute path typed into Quick Open and the same
112865
- * path passed to `band open` resolve identically. Unlike `openFile` this
112866
- * neither emits an SSE event nor throws for a missing file — the caller
112867
- * only offers to open when `exists && isFile`.
112868
- */
112869
- async resolvePath(input3) {
112870
- const worktree = worktreeService.resolve(input3.worktreeId);
112871
- if (!worktree) {
112872
- throw new WorktreeNotFoundError(input3.worktreeId);
112873
- }
112874
- const resolved = await this.resolveTarget(
112875
- worktree.host.fs,
112876
- worktree.worktree.path,
112877
- input3.filePath
112878
- );
112879
- return {
112880
- exists: resolved.exists,
112881
- isFile: resolved.isFile,
112882
- external: !resolved.inside,
112883
- worktreeRelativePath: resolved.inside ? resolved.relativePath : null
112884
- };
112885
- }
112886
- /**
112887
- * Shared resolution core for {@link openFile} and {@link resolvePath}:
112888
- * canonicalize the target (following the deepest existing ancestor so
112889
- * not-yet-created paths still classify), stat it, and run the
112890
- * segment-aware containment check against the canonicalized worktree root.
112891
- */
112892
- async resolveTarget(fs3, root, filePath) {
112893
- const absoluteTarget = isAbsolute5(filePath) ? resolve10(filePath) : resolve10(root, filePath);
112894
- let canonicalRoot = root;
112895
- try {
112896
- canonicalRoot = await fs3.realpath(root);
112897
- } catch {
112898
- }
112899
- const canonicalTarget = await canonicalizeMaybeMissing(fs3, absoluteTarget);
112900
- let targetStat = null;
112901
- try {
112902
- targetStat = await fs3.stat(canonicalTarget, { followSymlinks: true });
112903
- } catch {
112904
- }
112905
- const normalizedRoot = canonicalRoot.replace(/\/+$/, "");
112906
- const inside = canonicalTarget === normalizedRoot || canonicalTarget.startsWith(`${normalizedRoot}${sep6}`);
112907
- const relativePath = inside ? (canonicalTarget === normalizedRoot ? "" : canonicalTarget.slice(normalizedRoot.length + 1)).split(sep6).join("/") : null;
112908
- return {
112909
- canonicalTarget,
112910
- exists: !!targetStat,
112911
- isFile: targetStat?.kind === "file",
112912
- inside,
112913
- relativePath
112914
- };
112915
- }
112916
112964
  };
112917
112965
  var EditorOpenError = class extends Error {
112918
112966
  code;
@@ -112922,22 +112970,6 @@ var EditorOpenError = class extends Error {
112922
112970
  this.code = code;
112923
112971
  }
112924
112972
  };
112925
- async function canonicalizeMaybeMissing(fs3, p2) {
112926
- try {
112927
- return await fs3.realpath(p2);
112928
- } catch {
112929
- }
112930
- const parts = p2.split(sep6);
112931
- for (let i = parts.length - 1; i > 0; i--) {
112932
- const prefix = parts.slice(0, i).join(sep6) || sep6;
112933
- try {
112934
- const canonicalPrefix = await fs3.realpath(prefix);
112935
- return join52(canonicalPrefix, ...parts.slice(i));
112936
- } catch {
112937
- }
112938
- }
112939
- return p2;
112940
- }
112941
112973
  var editorService = new EditorService();
112942
112974
 
112943
112975
  // src/server/api/editor/router.ts
@@ -113700,7 +113732,7 @@ init_registry();
113700
113732
  // package.json
113701
113733
  var package_default = {
113702
113734
  name: "@band-app/server",
113703
- version: "0.55.0",
113735
+ version: "0.56.0",
113704
113736
  type: "module",
113705
113737
  types: "src/index.ts",
113706
113738
  exports: {
@@ -118504,11 +118536,11 @@ var ProvisionQueries = class {
118504
118536
  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();
118505
118537
  return Number(result.changes ?? 0) > 0;
118506
118538
  }
118507
- setLog(id, log94, at) {
118508
- this.db().update(hostProvisions).set({ log: log94, updatedAt: at }).where(eq2(hostProvisions.id, id)).run();
118539
+ setLog(id, log95, at) {
118540
+ this.db().update(hostProvisions).set({ log: log95, updatedAt: at }).where(eq2(hostProvisions.id, id)).run();
118509
118541
  }
118510
- finish(id, state2, exitCode, log94, at) {
118511
- this.db().update(hostProvisions).set({ state: state2, exitCode, log: log94, updatedAt: at }).where(eq2(hostProvisions.id, id)).run();
118542
+ finish(id, state2, exitCode, log95, at) {
118543
+ this.db().update(hostProvisions).set({ state: state2, exitCode, log: log95, updatedAt: at }).where(eq2(hostProvisions.id, id)).run();
118512
118544
  }
118513
118545
  /** Ids of rows created before `at`, so their bundle files can be deleted. */
118514
118546
  idsCreatedBefore(at) {
@@ -122098,6 +122130,32 @@ var searchContentInput = external_exports2.object({
122098
122130
  regex: external_exports2.boolean().default(false),
122099
122131
  limit: external_exports2.number().default(100)
122100
122132
  });
122133
+ var commitShaSchema = external_exports2.string().regex(/^[0-9a-f]{7,40}$/i, "sha must be a 7\u201340 character hex commit id");
122134
+ var listBranchesInput = external_exports2.object({
122135
+ worktreeId: external_exports2.string(),
122136
+ query: external_exports2.string().max(200).optional(),
122137
+ limit: external_exports2.number().int().min(1).max(500).optional()
122138
+ });
122139
+ var getCommitHistoryInput = external_exports2.object({
122140
+ worktreeId: external_exports2.string(),
122141
+ skip: external_exports2.number().int().min(0).optional(),
122142
+ limit: external_exports2.number().int().min(1).max(500).optional()
122143
+ });
122144
+ var getCommitHistorySignatureInput = external_exports2.object({ worktreeId: external_exports2.string() });
122145
+ var getCommitDetailsInput = external_exports2.object({ worktreeId: external_exports2.string(), sha: commitShaSchema });
122146
+ var createFileInput = external_exports2.object({
122147
+ worktreeId: external_exports2.string(),
122148
+ path: external_exports2.string().min(1),
122149
+ content: external_exports2.string().default("")
122150
+ });
122151
+ var createDirectoryInput = external_exports2.object({ worktreeId: external_exports2.string(), path: external_exports2.string().min(1) });
122152
+ var deletePathInput = external_exports2.object({ worktreeId: external_exports2.string(), path: external_exports2.string().min(1) });
122153
+ var renamePathInput = external_exports2.object({
122154
+ worktreeId: external_exports2.string(),
122155
+ fromPath: external_exports2.string().min(1),
122156
+ toPath: external_exports2.string().min(1)
122157
+ });
122158
+ var resolvePathInput = external_exports2.object({ worktreeId: external_exports2.string(), path: external_exports2.string().min(1) });
122101
122159
 
122102
122160
  // ../../packages/worktree-ops/src/direct.ts
122103
122161
  var op = (o) => o;
@@ -122149,6 +122207,42 @@ var directOps = {
122149
122207
  regex: i.regex,
122150
122208
  limit: i.limit
122151
122209
  })
122210
+ }),
122211
+ "worktree.listBranches": op({
122212
+ input: listBranchesInput,
122213
+ run: (ops, i) => ops.diff.listBranches(i.worktreeId, { query: i.query, limit: i.limit })
122214
+ }),
122215
+ "worktree.getCommitHistory": op({
122216
+ input: getCommitHistoryInput,
122217
+ run: (ops, i) => ops.gitGraph.getCommitHistory(i.worktreeId, { skip: i.skip, limit: i.limit })
122218
+ }),
122219
+ "worktree.getCommitHistorySignature": op({
122220
+ input: getCommitHistorySignatureInput,
122221
+ run: (ops, i) => ops.gitGraph.getCommitHistorySignature(i.worktreeId)
122222
+ }),
122223
+ "worktree.getCommitDetails": op({
122224
+ input: getCommitDetailsInput,
122225
+ run: (ops, i) => ops.gitGraph.getCommitDetails(i.worktreeId, i.sha)
122226
+ }),
122227
+ "worktree.createFile": op({
122228
+ input: createFileInput,
122229
+ run: (ops, i) => ops.files.createFile(i.worktreeId, i.path, i.content)
122230
+ }),
122231
+ "worktree.createDirectory": op({
122232
+ input: createDirectoryInput,
122233
+ run: (ops, i) => ops.files.createDirectory(i.worktreeId, i.path)
122234
+ }),
122235
+ "worktree.deletePath": op({
122236
+ input: deletePathInput,
122237
+ run: (ops, i) => ops.files.deletePath(i.worktreeId, i.path)
122238
+ }),
122239
+ "worktree.renamePath": op({
122240
+ input: renamePathInput,
122241
+ run: (ops, i) => ops.files.renamePath(i.worktreeId, i.fromPath, i.toPath)
122242
+ }),
122243
+ "worktree.copyPath": op({
122244
+ input: renamePathInput,
122245
+ run: (ops, i) => ops.files.copyPath(i.worktreeId, i.fromPath, i.toPath)
122152
122246
  })
122153
122247
  };
122154
122248
 
@@ -123146,11 +123240,10 @@ var filesService = new FilesService({
123146
123240
  ensureAwake: (worktreeId4) => ephemeralLifecycleService.ensureAwake(worktreeId4)
123147
123241
  });
123148
123242
 
123149
- // src/server/services/git-graph-service.ts
123243
+ // ../../packages/worktree-ops/src/git-graph.ts
123150
123244
  init_src3();
123151
123245
  import { createHash as createHash14 } from "node:crypto";
123152
- init_errors6();
123153
- init_worktree_service();
123246
+ init_resolver();
123154
123247
  var FS = "";
123155
123248
  var RS = "";
123156
123249
  var COMMIT_HISTORY_DEFAULT_LIMIT = 50;
@@ -123196,7 +123289,7 @@ function parseNameStatus2(output2) {
123196
123289
  return files;
123197
123290
  }
123198
123291
  var GitGraphService = class {
123199
- constructor(worktrees2 = worktreeService) {
123292
+ constructor(worktrees2) {
123200
123293
  this.worktrees = worktrees2;
123201
123294
  }
123202
123295
  target(worktreeId4) {
@@ -123325,7 +123418,10 @@ var GitGraphService = class {
123325
123418
  return { diff };
123326
123419
  }
123327
123420
  };
123328
- var gitGraphService = new GitGraphService();
123421
+
123422
+ // src/server/services/git-graph-service.ts
123423
+ init_worktree_service();
123424
+ var gitGraphService = new GitGraphService(worktreeService);
123329
123425
 
123330
123426
  // ../../node_modules/.pnpm/fzf@0.5.2/node_modules/fzf/dist/fzf.es.js
123331
123427
  var normalized = {
@@ -124383,9 +124479,14 @@ var searchService = new SearchService({
124383
124479
  // src/server/api/worktree/router.ts
124384
124480
  init_terminal_service();
124385
124481
  init_worktree_service();
124386
- var worktreeOps = { files: filesService, diff: diffService, search: searchService };
124482
+ var pathsService = new PathsService(worktreeService);
124483
+ var worktreeOps = {
124484
+ files: filesService,
124485
+ diff: diffService,
124486
+ search: searchService,
124487
+ gitGraph: gitGraphService
124488
+ };
124387
124489
  var pathListSchema = external_exports2.array(filePathSchema).min(1).max(5e4);
124388
- var commitShaSchema = external_exports2.string().regex(/^[0-9a-f]{7,40}$/i, "sha must be a 7\u201340 character hex commit id");
124389
124490
  var worktreeRouter = t.router({
124390
124491
  /**
124391
124492
  * A short-lived token for the worker that holds `worktreeId`, when that
@@ -124493,29 +124594,10 @@ var worktreeRouter = t.router({
124493
124594
  unsubscribe();
124494
124595
  }
124495
124596
  }),
124496
- listBranches: publicProcedure.input(
124497
- external_exports2.object({
124498
- worktreeId: external_exports2.string(),
124499
- query: external_exports2.string().max(200).optional(),
124500
- limit: external_exports2.number().int().min(1).max(500).optional()
124501
- })
124502
- ).query(
124503
- ({ input: input3 }) => diffService.listBranches(input3.worktreeId, { query: input3.query, limit: input3.limit })
124504
- ),
124505
- getCommitHistory: publicProcedure.input(
124506
- external_exports2.object({
124507
- worktreeId: external_exports2.string(),
124508
- skip: external_exports2.number().int().min(0).optional(),
124509
- limit: external_exports2.number().int().min(1).max(500).optional()
124510
- })
124511
- ).query(
124512
- ({ input: input3 }) => gitGraphService.getCommitHistory(input3.worktreeId, {
124513
- skip: input3.skip,
124514
- limit: input3.limit
124515
- })
124516
- ),
124517
- getCommitHistorySignature: publicProcedure.input(external_exports2.object({ worktreeId: external_exports2.string() })).query(({ input: input3 }) => gitGraphService.getCommitHistorySignature(input3.worktreeId)),
124518
- getCommitDetails: publicProcedure.input(external_exports2.object({ worktreeId: external_exports2.string(), sha: commitShaSchema })).query(({ input: input3 }) => gitGraphService.getCommitDetails(input3.worktreeId, input3.sha)),
124597
+ listBranches: publicProcedure.input(directOps["worktree.listBranches"].input).query(({ input: input3 }) => directOps["worktree.listBranches"].run(worktreeOps, input3)),
124598
+ getCommitHistory: publicProcedure.input(directOps["worktree.getCommitHistory"].input).query(({ input: input3 }) => directOps["worktree.getCommitHistory"].run(worktreeOps, input3)),
124599
+ getCommitHistorySignature: publicProcedure.input(directOps["worktree.getCommitHistorySignature"].input).query(({ input: input3 }) => directOps["worktree.getCommitHistorySignature"].run(worktreeOps, input3)),
124600
+ getCommitDetails: publicProcedure.input(directOps["worktree.getCommitDetails"].input).query(({ input: input3 }) => directOps["worktree.getCommitDetails"].run(worktreeOps, input3)),
124519
124601
  getCommitFileDiff: publicProcedure.input(
124520
124602
  external_exports2.object({
124521
124603
  worktreeId: external_exports2.string(),
@@ -124563,31 +124645,11 @@ var worktreeRouter = t.router({
124563
124645
  listFiles: publicProcedure.input(directOps["worktree.listFiles"].input).query(({ input: input3 }) => directOps["worktree.listFiles"].run(worktreeOps, input3)),
124564
124646
  getFile: publicProcedure.input(directOps["worktree.getFile"].input).query(({ input: input3 }) => directOps["worktree.getFile"].run(worktreeOps, input3)),
124565
124647
  saveFile: publicProcedure.input(directOps["worktree.saveFile"].input).mutation(({ input: input3 }) => directOps["worktree.saveFile"].run(worktreeOps, input3)),
124566
- createFile: publicProcedure.input(
124567
- external_exports2.object({
124568
- worktreeId: external_exports2.string(),
124569
- path: external_exports2.string().min(1),
124570
- content: external_exports2.string().default("")
124571
- })
124572
- ).mutation(({ input: input3 }) => filesService.createFile(input3.worktreeId, input3.path, input3.content)),
124573
- createDirectory: publicProcedure.input(external_exports2.object({ worktreeId: external_exports2.string(), path: external_exports2.string().min(1) })).mutation(({ input: input3 }) => filesService.createDirectory(input3.worktreeId, input3.path)),
124574
- deletePath: publicProcedure.input(external_exports2.object({ worktreeId: external_exports2.string(), path: external_exports2.string().min(1) })).mutation(({ input: input3 }) => filesService.deletePath(input3.worktreeId, input3.path)),
124575
- renamePath: publicProcedure.input(
124576
- external_exports2.object({
124577
- worktreeId: external_exports2.string(),
124578
- fromPath: external_exports2.string().min(1),
124579
- toPath: external_exports2.string().min(1)
124580
- })
124581
- ).mutation(
124582
- ({ input: input3 }) => filesService.renamePath(input3.worktreeId, input3.fromPath, input3.toPath)
124583
- ),
124584
- copyPath: publicProcedure.input(
124585
- external_exports2.object({
124586
- worktreeId: external_exports2.string(),
124587
- fromPath: external_exports2.string().min(1),
124588
- toPath: external_exports2.string().min(1)
124589
- })
124590
- ).mutation(({ input: input3 }) => filesService.copyPath(input3.worktreeId, input3.fromPath, input3.toPath)),
124648
+ createFile: publicProcedure.input(directOps["worktree.createFile"].input).mutation(({ input: input3 }) => directOps["worktree.createFile"].run(worktreeOps, input3)),
124649
+ createDirectory: publicProcedure.input(directOps["worktree.createDirectory"].input).mutation(({ input: input3 }) => directOps["worktree.createDirectory"].run(worktreeOps, input3)),
124650
+ deletePath: publicProcedure.input(directOps["worktree.deletePath"].input).mutation(({ input: input3 }) => directOps["worktree.deletePath"].run(worktreeOps, input3)),
124651
+ renamePath: publicProcedure.input(directOps["worktree.renamePath"].input).mutation(({ input: input3 }) => directOps["worktree.renamePath"].run(worktreeOps, input3)),
124652
+ copyPath: publicProcedure.input(directOps["worktree.copyPath"].input).mutation(({ input: input3 }) => directOps["worktree.copyPath"].run(worktreeOps, input3)),
124591
124653
  /** A signed, expiring URL for one worktree file, for a browser tab that cannot send the auth header. */
124592
124654
  previewUrl: publicProcedure.input(external_exports2.object({ worktreeId: external_exports2.string(), path: external_exports2.string().min(1) })).query(({ input: input3 }) => {
124593
124655
  if (!worktreeService.resolve(input3.worktreeId)) {
@@ -124610,8 +124672,8 @@ var worktreeRouter = t.router({
124610
124672
  // `host.readFile` — and the `external` flag is load-bearing, not dead code:
124611
124673
  // it's how the client decides between a worktree-relative and an external
124612
124674
  // tab. Do not "harden" this by dropping the out-of-worktree classification.
124613
- resolvePath: publicProcedure.input(external_exports2.object({ worktreeId: external_exports2.string(), path: external_exports2.string().min(1) })).query(
124614
- ({ input: input3 }) => editorService.resolvePath({ worktreeId: input3.worktreeId, filePath: input3.path })
124675
+ resolvePath: publicProcedure.input(resolvePathInput).query(
124676
+ ({ input: input3 }) => pathsService.resolvePath({ worktreeId: input3.worktreeId, filePath: input3.path })
124615
124677
  ),
124616
124678
  searchContent: publicProcedure.input(directOps["worktree.searchContent"].input).query(({ input: input3 }) => directOps["worktree.searchContent"].run(worktreeOps, input3))
124617
124679
  });
@@ -125847,18 +125909,11 @@ async function handlePairExchange(req, res) {
125847
125909
 
125848
125910
  // src/server/api/plugins/stream-handler.ts
125849
125911
  init_src();
125850
- init_plugin_host_service();
125912
+
125913
+ // ../../packages/worktree-ops/src/plugin-stream-socket.ts
125914
+ init_src();
125851
125915
  var log85 = createLogger("plugin-stream");
125852
- var STREAM_PATH = /^\/api\/plugins\/([a-z0-9][a-z0-9-]*)\/worktrees\/([^/]+)\/stream$/;
125853
- function pluginStreamTarget(pathname) {
125854
- const match = STREAM_PATH.exec(pathname);
125855
- if (!match?.[1] || !match[2]) return null;
125856
- try {
125857
- return { pluginId: match[1], worktreeId: decodeURIComponent(match[2]) };
125858
- } catch {
125859
- return null;
125860
- }
125861
- }
125916
+ var MAX_INPUT_BYTES = 64 * 1024;
125862
125917
  function parseModeRequest(text4) {
125863
125918
  try {
125864
125919
  const msg = JSON.parse(text4);
@@ -125867,8 +125922,7 @@ function parseModeRequest(text4) {
125867
125922
  }
125868
125923
  return null;
125869
125924
  }
125870
- var MAX_INPUT_BYTES = 64 * 1024;
125871
- async function handlePluginStream(ws, req, target) {
125925
+ async function bridgePluginStream(ws, label2, open4, onOpenFailed) {
125872
125926
  let controlling = false;
125873
125927
  let stream = null;
125874
125928
  ws.on("message", (data, isBinary) => {
@@ -125879,35 +125933,24 @@ async function handlePluginStream(ws, req, target) {
125879
125933
  const enabled = parseModeRequest(text4);
125880
125934
  if (enabled !== null) {
125881
125935
  controlling = enabled;
125882
- log85.debug(
125883
- "%s stream of %s is now %s",
125884
- target.pluginId,
125885
- target.worktreeId,
125886
- enabled ? "controlled" : "view-only"
125887
- );
125936
+ log85.debug("%s is now %s", label2, enabled ? "controlled" : "view-only");
125888
125937
  return;
125889
125938
  }
125890
125939
  if (controlling && stream && text4.length <= MAX_INPUT_BYTES) stream.send(text4);
125891
125940
  });
125892
125941
  ws.once("close", () => stream?.close());
125893
125942
  try {
125894
- stream = await pluginHost.openStream(target.pluginId, target.worktreeId, "screen");
125943
+ stream = await open4();
125895
125944
  } catch (err) {
125896
125945
  const message = err instanceof Error ? err.message : String(err);
125897
- log85.warn("%s stream of %s is unavailable: %s", target.pluginId, target.worktreeId, message);
125898
- ws.close(4001, message.slice(0, 120));
125946
+ log85.warn("%s is unavailable: %s", label2, message);
125947
+ onOpenFailed(message);
125899
125948
  return;
125900
125949
  }
125901
125950
  if (ws.readyState !== ws.OPEN) {
125902
125951
  stream.close();
125903
125952
  return;
125904
125953
  }
125905
- log85.debug(
125906
- "%s viewer connected: %s (%s)",
125907
- target.pluginId,
125908
- target.worktreeId,
125909
- req.socket.remoteAddress ?? "unknown"
125910
- );
125911
125954
  try {
125912
125955
  for await (const message of stream.messages) {
125913
125956
  if (ws.readyState !== ws.OPEN) break;
@@ -125916,22 +125959,45 @@ async function handlePluginStream(ws, req, target) {
125916
125959
  );
125917
125960
  }
125918
125961
  } catch (err) {
125919
- log85.warn(
125920
- "%s stream of %s failed: %s",
125921
- target.pluginId,
125922
- target.worktreeId,
125923
- err.message
125924
- );
125962
+ log85.warn("%s failed: %s", label2, err.message);
125925
125963
  } finally {
125926
125964
  stream.close();
125927
125965
  if (ws.readyState === ws.OPEN) ws.close(1e3, "The stream ended");
125928
125966
  }
125929
125967
  }
125930
125968
 
125969
+ // src/server/api/plugins/stream-handler.ts
125970
+ init_plugin_host_service();
125971
+ var log86 = createLogger("plugin-stream");
125972
+ var STREAM_PATH = /^\/api\/plugins\/([a-z0-9][a-z0-9-]*)\/worktrees\/([^/]+)\/stream$/;
125973
+ function pluginStreamTarget(pathname) {
125974
+ const match = STREAM_PATH.exec(pathname);
125975
+ if (!match?.[1] || !match[2]) return null;
125976
+ try {
125977
+ return { pluginId: match[1], worktreeId: decodeURIComponent(match[2]) };
125978
+ } catch {
125979
+ return null;
125980
+ }
125981
+ }
125982
+ async function handlePluginStream(ws, req, target) {
125983
+ log86.debug(
125984
+ "%s viewer connected: %s (%s)",
125985
+ target.pluginId,
125986
+ target.worktreeId,
125987
+ req.socket.remoteAddress ?? "unknown"
125988
+ );
125989
+ await bridgePluginStream(
125990
+ ws,
125991
+ `${target.pluginId} stream of ${target.worktreeId}`,
125992
+ () => pluginHost.openStream(target.pluginId, target.worktreeId, "screen", { profile: "hub" }),
125993
+ (message) => ws.close(4001, message.slice(0, 120))
125994
+ );
125995
+ }
125996
+
125931
125997
  // src/server/api/provisioning/handler.ts
125932
125998
  init_src();
125933
125999
  import { pipeline } from "node:stream";
125934
- var log86 = createLogger("provisioning");
126000
+ var log87 = createLogger("provisioning");
125935
126001
  var PROVISION_PREFIX = "/api/provision/";
125936
126002
  var MAX_EXCHANGE_BODY_BYTES2 = 4096;
125937
126003
  var MAX_LOG_BODY_BYTES = 128 * 1024;
@@ -125988,7 +126054,7 @@ async function handleProvision(req, res) {
125988
126054
  send3(200, provisioningService.exchange(code2), "text/plain; charset=utf-8");
125989
126055
  } catch (err) {
125990
126056
  if (!(err instanceof ProvisionExchangeError)) throw err;
125991
- log86.debug(`provisioning exchange refused: ${err.reason}`);
126057
+ log87.debug(`provisioning exchange refused: ${err.reason}`);
125992
126058
  refused();
125993
126059
  }
125994
126060
  return;
@@ -126124,7 +126190,7 @@ var OutputFlow = class {
126124
126190
  };
126125
126191
 
126126
126192
  // ../../packages/worktree-ops/src/terminal-socket.ts
126127
- var log87 = createLogger("terminal-ws");
126193
+ var log88 = createLogger("terminal-ws");
126128
126194
  var MAX_CLOSE_REASON_BYTES = 123;
126129
126195
  var HEARTBEAT_INTERVAL_MS2 = 3e4;
126130
126196
  function clampCloseReason(reason) {
@@ -126192,7 +126258,7 @@ function createInbox(ws) {
126192
126258
  };
126193
126259
  }
126194
126260
  function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendingMessage) {
126195
- log87.debug(
126261
+ log88.debug(
126196
126262
  "Terminal %s: %s (worktree %s)",
126197
126263
  isNew ? "connected" : "reconnected",
126198
126264
  terminalId,
@@ -126212,7 +126278,7 @@ function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendi
126212
126278
  });
126213
126279
  const unsubscribeExit = backend.onExit(terminalId, (event) => {
126214
126280
  unsubscribeTitle();
126215
- log87.debug("PTY exited with code %d for terminal %s", event.exitCode, terminalId);
126281
+ log88.debug("PTY exited with code %d for terminal %s", event.exitCode, terminalId);
126216
126282
  if (ws.readyState === ws.OPEN) {
126217
126283
  ws.close(1e3, "Terminal exited");
126218
126284
  }
@@ -126240,7 +126306,7 @@ function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendi
126240
126306
  try {
126241
126307
  attached = await backend.attach(terminalId, dims);
126242
126308
  } catch (err) {
126243
- log87.error("Failed to attach terminal %s: %s", terminalId, err);
126309
+ log88.error("Failed to attach terminal %s: %s", terminalId, err);
126244
126310
  safeClose(ws, 1011, "Terminal attach failed");
126245
126311
  return;
126246
126312
  }
@@ -126282,7 +126348,7 @@ function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendi
126282
126348
  const cols = Number.isFinite(parsed.cols) && parsed.cols > 0 ? parsed.cols : void 0;
126283
126349
  const rows = Number.isFinite(parsed.rows) && parsed.rows > 0 ? parsed.rows : void 0;
126284
126350
  void startReplay(cols, rows, parsed.flow === true).catch((err) => {
126285
- log87.error("Failed to replay terminal %s: %s", terminalId, err);
126351
+ log88.error("Failed to replay terminal %s: %s", terminalId, err);
126286
126352
  });
126287
126353
  return;
126288
126354
  }
@@ -126302,7 +126368,7 @@ function attachSession(backend, ws, inbox, terminalId, worktreeId4, isNew, pendi
126302
126368
  flow?.dispose();
126303
126369
  attachment?.detach();
126304
126370
  unsubscribeExit();
126305
- log87.debug("Terminal disconnected: %s (PTY kept alive)", terminalId);
126371
+ log88.debug("Terminal disconnected: %s (PTY kept alive)", terminalId);
126306
126372
  });
126307
126373
  if (pendingMessage) {
126308
126374
  processMessage(pendingMessage);
@@ -126325,7 +126391,7 @@ function handleMessage(backend, ws, terminalId, message) {
126325
126391
  }
126326
126392
  if (parsed.type === "close") {
126327
126393
  void backend.kill(terminalId).catch((err) => {
126328
- log87.error("Failed to kill terminal %s: %s", terminalId, err);
126394
+ log88.error("Failed to kill terminal %s: %s", terminalId, err);
126329
126395
  });
126330
126396
  ws.close(1e3, "Terminal closed by client");
126331
126397
  return;
@@ -126341,7 +126407,7 @@ function handleMessage(backend, ws, terminalId, message) {
126341
126407
 
126342
126408
  // src/server/api/terminals/ws.ts
126343
126409
  init_terminal_service();
126344
- var log88 = createLogger("terminal-ws");
126410
+ var log89 = createLogger("terminal-ws");
126345
126411
  async function handleTerminalConnection(ws, req) {
126346
126412
  if (!req.url) {
126347
126413
  safeClose(ws, 4e3, "Missing request URL");
@@ -126360,7 +126426,7 @@ async function handleTerminalConnection(ws, req) {
126360
126426
  existing = await terminalService.info(terminalId) !== null;
126361
126427
  } catch (err) {
126362
126428
  const msg = err instanceof Error ? err.message : String(err);
126363
- log88.error("Failed to look up terminal %s: %s", terminalId, msg);
126429
+ log89.error("Failed to look up terminal %s: %s", terminalId, msg);
126364
126430
  safeClose(ws, 1011, msg);
126365
126431
  return;
126366
126432
  }
@@ -126408,7 +126474,7 @@ async function handleTerminalConnection(ws, req) {
126408
126474
  await terminalService.spawn(worktreeId4, terminalId, spawnOpts);
126409
126475
  } catch (err) {
126410
126476
  const msg = err instanceof Error ? err.message : String(err);
126411
- log88.error("Failed to spawn terminal %s for worktree %s: %s", terminalId, worktreeId4, msg);
126477
+ log89.error("Failed to spawn terminal %s for worktree %s: %s", terminalId, worktreeId4, msg);
126412
126478
  safeClose(ws, 4001, msg);
126413
126479
  return;
126414
126480
  }
@@ -126547,7 +126613,7 @@ init_src();
126547
126613
  init_wrapper();
126548
126614
  init_browser_lookup();
126549
126615
  init_remote_cdp();
126550
- var log89 = createLogger("cdp-proxy");
126616
+ var log90 = createLogger("cdp-proxy");
126551
126617
  async function handleCdpConnection(ws, req) {
126552
126618
  const url3 = new URL(req.url ?? "", `http://${req.headers.host}`);
126553
126619
  const bandTabId = url3.searchParams.get("bandTabId");
@@ -126590,17 +126656,17 @@ async function handleCdpConnection(ws, req) {
126590
126656
  cdpTargetId = await ensureCdpTargetId(bandTabId);
126591
126657
  } catch (err) {
126592
126658
  const message = err instanceof Error ? err.message : String(err);
126593
- log89.debug("ensureCdpTargetId failed for %s: %s", bandTabId, message);
126659
+ log90.debug("ensureCdpTargetId failed for %s: %s", bandTabId, message);
126594
126660
  if (ws.readyState === ws.OPEN) {
126595
126661
  ws.close(4001, message.slice(0, 123));
126596
126662
  }
126597
126663
  return;
126598
126664
  }
126599
126665
  const upstreamUrl = `ws://${DESKTOP_CDP_HOST}:${DESKTOP_CDP_PORT}/devtools/page/${encodeURIComponent(cdpTargetId)}`;
126600
- log89.info("CDP proxy connecting bandTabId=%s upstream=%s", bandTabId, upstreamUrl);
126666
+ log90.info("CDP proxy connecting bandTabId=%s upstream=%s", bandTabId, upstreamUrl);
126601
126667
  upstream = new wrapper_default(upstreamUrl);
126602
126668
  upstream.on("open", () => {
126603
- log89.info("CDP upstream open bandTabId=%s pending=%d", bandTabId, pending2.length);
126669
+ log90.info("CDP upstream open bandTabId=%s pending=%d", bandTabId, pending2.length);
126604
126670
  for (const msg of pending2) {
126605
126671
  upstream?.send(msg);
126606
126672
  }
@@ -126612,20 +126678,20 @@ async function handleCdpConnection(ws, req) {
126612
126678
  }
126613
126679
  });
126614
126680
  upstream.on("error", (err) => {
126615
- log89.warn("CDP upstream error bandTabId=%s: %s", bandTabId, err.message);
126681
+ log90.warn("CDP upstream error bandTabId=%s: %s", bandTabId, err.message);
126616
126682
  markTargetDestroyed(bandTabId);
126617
126683
  if (ws.readyState === ws.OPEN) {
126618
126684
  ws.close(4001, `Desktop CDP error: ${err.message}`.slice(0, 123));
126619
126685
  }
126620
126686
  });
126621
126687
  upstream.on("close", (code) => {
126622
- log89.info("CDP upstream closed bandTabId=%s code=%d", bandTabId, code);
126688
+ log90.info("CDP upstream closed bandTabId=%s code=%d", bandTabId, code);
126623
126689
  if (ws.readyState === ws.OPEN) {
126624
126690
  ws.close(1e3, "Upstream closed");
126625
126691
  }
126626
126692
  });
126627
126693
  ws.on("close", () => {
126628
- log89.debug("CDP client closed bandTabId=%s", bandTabId);
126694
+ log90.debug("CDP client closed bandTabId=%s", bandTabId);
126629
126695
  if (upstream && (upstream.readyState === wrapper_default.OPEN || upstream.readyState === wrapper_default.CONNECTING)) {
126630
126696
  try {
126631
126697
  upstream.close();
@@ -126634,7 +126700,7 @@ async function handleCdpConnection(ws, req) {
126634
126700
  }
126635
126701
  });
126636
126702
  ws.on("error", (err) => {
126637
- log89.debug("CDP client error bandTabId=%s: %s", bandTabId, err.message);
126703
+ log90.debug("CDP client error bandTabId=%s: %s", bandTabId, err.message);
126638
126704
  try {
126639
126705
  upstream?.close();
126640
126706
  } catch {
@@ -126664,7 +126730,7 @@ async function bridgeRemote(ws, worktreeId4) {
126664
126730
  cdp = await openRemoteCdp(worktreeId4);
126665
126731
  } catch (err) {
126666
126732
  const message = err instanceof Error ? err.message : String(err);
126667
- log89.warn("remote CDP failed for worktree %s: %s", worktreeId4, message);
126733
+ log90.warn("remote CDP failed for worktree %s: %s", worktreeId4, message);
126668
126734
  if (ws.readyState === ws.OPEN)
126669
126735
  ws.close(4001, closeReason(`Remote browser unavailable: ${message}`));
126670
126736
  return true;
@@ -126688,7 +126754,7 @@ async function bridgeRemote(ws, worktreeId4) {
126688
126754
  if (ws.readyState === ws.OPEN) ws.send(message);
126689
126755
  }
126690
126756
  } catch (err) {
126691
- log89.debug("remote CDP stream ended for worktree %s: %s", worktreeId4, String(err));
126757
+ log90.debug("remote CDP stream ended for worktree %s: %s", worktreeId4, String(err));
126692
126758
  }
126693
126759
  if (ws.readyState === ws.OPEN) ws.close(1e3, "Upstream closed");
126694
126760
  })();
@@ -126698,7 +126764,7 @@ async function bridgeRemote(ws, worktreeId4) {
126698
126764
  // src/server/infra/browser-host/cdp-targets.ts
126699
126765
  init_src();
126700
126766
  init_wrapper();
126701
- var log90 = createLogger("cdp-targets");
126767
+ var log91 = createLogger("cdp-targets");
126702
126768
  var CdpUnreachableError = class extends Error {
126703
126769
  constructor(message) {
126704
126770
  super(message);
@@ -126754,7 +126820,7 @@ async function captureSnapshot(bandTabId) {
126754
126820
  });
126755
126821
  ws.on("error", (err) => {
126756
126822
  clearTimeout(timeout);
126757
- log90.debug("captureSnapshot ws error for tab %s: %s", bandTabId, err.message);
126823
+ log91.debug("captureSnapshot ws error for tab %s: %s", bandTabId, err.message);
126758
126824
  markTargetDestroyed(bandTabId);
126759
126825
  settle2(new CdpUnreachableError(err.message));
126760
126826
  });
@@ -126881,7 +126947,7 @@ var RfbClientFilter = class {
126881
126947
  };
126882
126948
 
126883
126949
  // src/server/infra/host/desktop-proxy.ts
126884
- var log91 = createLogger("desktop-proxy");
126950
+ var log92 = createLogger("desktop-proxy");
126885
126951
  var DESKTOP_PATH = /^\/api\/hosts\/([^/]+)\/desktop$/;
126886
126952
  function desktopHostId(pathname) {
126887
126953
  const match = DESKTOP_PATH.exec(pathname);
@@ -126930,7 +126996,7 @@ async function handleDesktopConnection(ws, req, hostId2) {
126930
126996
  );
126931
126997
  if (enabled !== null) {
126932
126998
  filter.viewOnly = !enabled;
126933
- log91.debug("desktop of host %s is now %s", hostId2, enabled ? "controlled" : "view-only");
126999
+ log92.debug("desktop of host %s is now %s", hostId2, enabled ? "controlled" : "view-only");
126934
127000
  }
126935
127001
  return;
126936
127002
  }
@@ -126965,7 +127031,7 @@ async function handleDesktopConnection(ws, req, hostId2) {
126965
127031
  opened = true;
126966
127032
  } catch (err) {
126967
127033
  const message = err instanceof Error ? err.message : String(err);
126968
- log91.warn("desktop of host %s is unavailable: %s", hostId2, message);
127034
+ log92.warn("desktop of host %s is unavailable: %s", hostId2, message);
126969
127035
  release();
126970
127036
  ws.close(4001, message.slice(0, 120));
126971
127037
  return;
@@ -126975,7 +127041,7 @@ async function handleDesktopConnection(ws, req, hostId2) {
126975
127041
  release();
126976
127042
  return;
126977
127043
  }
126978
- log91.debug("desktop viewer connected: %s (%s)", hostId2, req.socket.remoteAddress ?? "unknown");
127044
+ log92.debug("desktop viewer connected: %s (%s)", hostId2, req.socket.remoteAddress ?? "unknown");
126979
127045
  for (const chunk of pending2.splice(0)) desktop.write(chunk);
126980
127046
  try {
126981
127047
  for await (const bytes of desktop.output) {
@@ -126983,7 +127049,7 @@ async function handleDesktopConnection(ws, req, hostId2) {
126983
127049
  await new Promise((resolve15) => ws.send(bytes, { binary: true }, () => resolve15()));
126984
127050
  }
126985
127051
  } catch (err) {
126986
- log91.warn("desktop stream of host %s failed: %s", hostId2, err.message);
127052
+ log92.warn("desktop stream of host %s failed: %s", hostId2, err.message);
126987
127053
  } finally {
126988
127054
  if (opened) {
126989
127055
  desktop.close();
@@ -126996,12 +127062,9 @@ async function handleDesktopConnection(ws, req, hostId2) {
126996
127062
  // start-server.ts
126997
127063
  init_registry();
126998
127064
 
126999
- // src/server/infra/lsp/lsp-proxy.ts
127065
+ // ../../packages/worktree-ops/src/lsp-socket.ts
127000
127066
  init_src();
127001
- init_worktrees();
127002
- init_registry();
127003
- var worktreeQueries2 = new WorktreeQueries();
127004
- var log92 = createLogger("lsp-proxy");
127067
+ var log93 = createLogger("lsp-proxy");
127005
127068
  function frameMessage(json4) {
127006
127069
  const body = Buffer.from(json4, "utf-8");
127007
127070
  const header = `Content-Length: ${body.byteLength}\r
@@ -127019,7 +127082,7 @@ function createFrameParser(onMessage) {
127019
127082
  const headerStr = buffer.subarray(0, separatorIdx).toString("ascii");
127020
127083
  const match = headerStr.match(/Content-Length:\s*(\d+)/i);
127021
127084
  if (!match) {
127022
- log92.warn("Malformed LSP header: %s", headerStr);
127085
+ log93.warn("Malformed LSP header: %s", headerStr);
127023
127086
  buffer = buffer.subarray(separatorIdx + 4);
127024
127087
  continue;
127025
127088
  }
@@ -127043,28 +127106,17 @@ function didCloseMessage(uri) {
127043
127106
  });
127044
127107
  }
127045
127108
  var serverDocuments = /* @__PURE__ */ new Map();
127046
- async function handleLspConnection(ws, req) {
127047
- const url3 = new URL(req.url, `http://${req.headers.host}`);
127048
- const worktreeId4 = url3.searchParams.get("worktreeId");
127049
- const lang = url3.searchParams.get("lang");
127050
- if (!worktreeId4 || !lang) {
127051
- ws.close(4e3, "Missing worktreeId or lang");
127052
- return;
127053
- }
127109
+ async function serveLspSocket(ws, worktreeId4, lang, connect3) {
127054
127110
  const pendingMessages = [];
127055
127111
  ws.on("message", (data) => {
127056
127112
  pendingMessages.push(data.toString());
127057
127113
  });
127058
127114
  let connection;
127059
127115
  try {
127060
- const worktree = worktreeQueries2.findIdentity(worktreeId4);
127061
- if (!worktree) {
127062
- throw new Error(`Worktree not found: ${worktreeId4}`);
127063
- }
127064
- connection = await hostRegistry.hostFor(worktreeId4).lsp.connect({ worktreeId: worktreeId4, lang, root: worktree.worktreePath });
127116
+ connection = await connect3();
127065
127117
  } catch (err) {
127066
127118
  const message = err instanceof Error ? err.message : String(err);
127067
- log92.error("Failed to spawn %s language server for worktree %s: %s", lang, worktreeId4, message);
127119
+ log93.error("Failed to spawn %s language server for worktree %s: %s", lang, worktreeId4, message);
127068
127120
  ws.close(4001, message);
127069
127121
  return;
127070
127122
  }
@@ -127072,7 +127124,7 @@ async function handleLspConnection(ws, req) {
127072
127124
  connection.close();
127073
127125
  return;
127074
127126
  }
127075
- log92.debug("LSP client connected: %s/%s", worktreeId4, lang);
127127
+ log93.debug("LSP client connected: %s/%s", worktreeId4, lang);
127076
127128
  const pendingRequests = /* @__PURE__ */ new Map();
127077
127129
  const openDocuments = /* @__PURE__ */ new Set();
127078
127130
  const serverId = `${worktreeId4}:${lang}`;
@@ -127108,7 +127160,7 @@ async function handleLspConnection(ws, req) {
127108
127160
  const retriedIds = /* @__PURE__ */ new Set();
127109
127161
  const RETRY_DELAY_MS = 2e3;
127110
127162
  const parseFrame = createFrameParser((json4) => {
127111
- log92.debug(
127163
+ log93.debug(
127112
127164
  "LSP stdout [%s/%s]: %s",
127113
127165
  worktreeId4,
127114
127166
  lang,
@@ -127120,7 +127172,7 @@ async function handleLspConnection(ws, req) {
127120
127172
  const originalRequest = pendingRequests.get(msg.id);
127121
127173
  retriedIds.add(msg.id);
127122
127174
  pendingRequests.delete(msg.id);
127123
- log92.debug(
127175
+ log93.debug(
127124
127176
  "LSP retrying request %d after 'No Project' error [%s/%s]",
127125
127177
  msg.id,
127126
127178
  worktreeId4,
@@ -127151,16 +127203,16 @@ async function handleLspConnection(ws, req) {
127151
127203
  for await (const chunk of connection.output)
127152
127204
  parseFrame(Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength));
127153
127205
  } catch (err) {
127154
- log92.warn("LSP output stream failed [%s/%s]: %s", worktreeId4, lang, String(err));
127206
+ log93.warn("LSP output stream failed [%s/%s]: %s", worktreeId4, lang, String(err));
127155
127207
  }
127156
127208
  release();
127157
127209
  if (ws.readyState === ws.OPEN) {
127158
- log92.debug("LSP server exited, closing WebSocket");
127210
+ log93.debug("LSP server exited, closing WebSocket");
127159
127211
  ws.close(1e3, "Language server exited");
127160
127212
  }
127161
127213
  })();
127162
127214
  function forwardToStdin(json4) {
127163
- log92.debug(
127215
+ log93.debug(
127164
127216
  "LSP stdin [%s/%s]: %s",
127165
127217
  worktreeId4,
127166
127218
  lang,
@@ -127192,7 +127244,28 @@ async function handleLspConnection(ws, req) {
127192
127244
  ws.on("close", () => {
127193
127245
  release();
127194
127246
  connection.close();
127195
- log92.debug("LSP client disconnected: %s/%s (server kept alive)", worktreeId4, lang);
127247
+ log93.debug("LSP client disconnected: %s/%s (server kept alive)", worktreeId4, lang);
127248
+ });
127249
+ }
127250
+
127251
+ // src/server/infra/lsp/lsp-proxy.ts
127252
+ init_worktrees();
127253
+ init_registry();
127254
+ var worktreeQueries2 = new WorktreeQueries();
127255
+ async function handleLspConnection(ws, req) {
127256
+ const url3 = new URL(req.url, `http://${req.headers.host}`);
127257
+ const worktreeId4 = url3.searchParams.get("worktreeId");
127258
+ const lang = url3.searchParams.get("lang");
127259
+ if (!worktreeId4 || !lang) {
127260
+ ws.close(4e3, "Missing worktreeId or lang");
127261
+ return;
127262
+ }
127263
+ await serveLspSocket(ws, worktreeId4, lang, async () => {
127264
+ const worktree = worktreeQueries2.findIdentity(worktreeId4);
127265
+ if (!worktree) {
127266
+ throw new Error(`Worktree not found: ${worktreeId4}`);
127267
+ }
127268
+ return hostRegistry.hostFor(worktreeId4).lsp.connect({ worktreeId: worktreeId4, lang, root: worktree.worktreePath });
127196
127269
  });
127197
127270
  }
127198
127271
 
@@ -127200,35 +127273,10 @@ async function handleLspConnection(ws, req) {
127200
127273
  init_webhook2();
127201
127274
 
127202
127275
  // src/server/services/_utils/byte-range.ts
127203
- function parseByteRange(header, size) {
127204
- const match = /^bytes=(\d*)-(\d*)$/.exec(header?.trim() ?? "");
127205
- if (!match || match[1] === "" && match[2] === "") return null;
127206
- if (match[1] !== "" && match[2] !== "" && Number(match[2]) < Number(match[1])) return null;
127207
- let start;
127208
- let end;
127209
- if (match[1] === "") {
127210
- const length = Number(match[2]);
127211
- if (length === 0) return "unsatisfiable";
127212
- start = Math.max(0, size - length);
127213
- end = size - 1;
127214
- } else {
127215
- start = Number(match[1]);
127216
- end = match[2] === "" ? size - 1 : Math.min(Number(match[2]), size - 1);
127217
- }
127218
- if (start >= size || start > end) return "unsatisfiable";
127219
- return { start, end };
127220
- }
127276
+ init_http_files();
127221
127277
 
127222
127278
  // src/server/services/_utils/content-disposition.ts
127223
- function attachmentDisposition(filename) {
127224
- const clean = filename.replace(/[/\\]/g, "_") || "download";
127225
- const ascii = clean.replace(/[^\x20-\x7e]/g, "_").replace(/["%;]/g, "_");
127226
- const encoded = encodeURIComponent(clean).replace(
127227
- /['()*]/g,
127228
- (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
127229
- );
127230
- return `attachment; filename="${ascii}"; filename*=UTF-8''${encoded}`;
127231
- }
127279
+ init_http_files();
127232
127280
 
127233
127281
  // src/server/services/_utils/hosted-file.ts
127234
127282
  init_registry();
@@ -135387,15 +135435,15 @@ init_src();
135387
135435
  init_registry();
135388
135436
  async function installSkills2(opts = {}) {
135389
135437
  const result = await hostRegistry.local.agentEnv.installSkills({ home: opts.home });
135390
- const log94 = opts.log;
135391
- if (log94) {
135392
- for (const warning of result.warnings) log94.warn(warning);
135393
- for (const path2 of result.written) log94.info("Installed skill at %s", path2);
135438
+ const log95 = opts.log;
135439
+ if (log95) {
135440
+ for (const warning of result.warnings) log95.warn(warning);
135441
+ for (const path2 of result.written) log95.info("Installed skill at %s", path2);
135394
135442
  for (const path2 of result.updated) {
135395
- log94.info("Updated skill at %s (content differed \u2014 shipped version reinstalled)", path2);
135443
+ log95.info("Updated skill at %s (content differed \u2014 shipped version reinstalled)", path2);
135396
135444
  }
135397
135445
  for (const conflict of result.conflicts) {
135398
- log94.warn("Skill symlink conflict \u2014 %s (left as-is; remove it manually to re-link)", conflict);
135446
+ log95.warn("Skill symlink conflict \u2014 %s (left as-is; remove it manually to re-link)", conflict);
135399
135447
  }
135400
135448
  }
135401
135449
  return result;
@@ -135408,7 +135456,7 @@ init_state();
135408
135456
  init_sync_service();
135409
135457
  init_worktree_group_service();
135410
135458
  init_worktree_service();
135411
- var log93 = createLogger("setup");
135459
+ var log94 = createLogger("setup");
135412
135460
  async function runFirstTimeSetup() {
135413
135461
  forgetLocalWorktrees();
135414
135462
  convertLegacyLabels();
@@ -135421,7 +135469,7 @@ async function runFirstTimeSetup() {
135421
135469
  ]);
135422
135470
  for (const r of results) {
135423
135471
  if (r.status === "rejected") {
135424
- log93.warn(
135472
+ log94.warn(
135425
135473
  "Setup step failed: %s",
135426
135474
  r.reason instanceof Error ? r.reason.message : String(r.reason)
135427
135475
  );
@@ -135435,7 +135483,7 @@ async function refreshAgentModelsInBackground() {
135435
135483
  const ok2 = results.filter((r) => !r.error).length;
135436
135484
  const failed = results.length - ok2;
135437
135485
  if (results.length > 0) {
135438
- log93.info(
135486
+ log94.info(
135439
135487
  "Background model refresh: %d/%d agents updated (%d failed)",
135440
135488
  ok2,
135441
135489
  results.length,
@@ -135443,7 +135491,7 @@ async function refreshAgentModelsInBackground() {
135443
135491
  );
135444
135492
  }
135445
135493
  } catch (err) {
135446
- log93.warn(
135494
+ log94.warn(
135447
135495
  "Background model refresh failed: %s",
135448
135496
  err instanceof Error ? err.message : String(err)
135449
135497
  );
@@ -135458,7 +135506,7 @@ async function ensureRepoRemotes() {
135458
135506
  try {
135459
135507
  await repoService.backfillRemotes();
135460
135508
  } catch (err) {
135461
- log93.warn(
135509
+ log94.warn(
135462
135510
  "Failed to record repo remotes at boot: %s",
135463
135511
  err instanceof Error ? err.message : String(err)
135464
135512
  );
@@ -135468,7 +135516,7 @@ function migrateRepoCronjobs() {
135468
135516
  try {
135469
135517
  cronjobService.migrateRepoJobs();
135470
135518
  } catch (err) {
135471
- log93.warn(
135519
+ log94.warn(
135472
135520
  "Failed to move repo-scoped cronjobs to worktrees at boot: %s",
135473
135521
  err instanceof Error ? err.message : String(err)
135474
135522
  );
@@ -135478,7 +135526,7 @@ function convertLegacyLabels() {
135478
135526
  try {
135479
135527
  worktreeGroupService.convertLegacyLabels();
135480
135528
  } catch (err) {
135481
- log93.warn(
135529
+ log94.warn(
135482
135530
  "Failed to convert repo labels to groups at boot: %s",
135483
135531
  err instanceof Error ? err.message : String(err)
135484
135532
  );
@@ -135488,7 +135536,7 @@ function forgetLocalWorktrees() {
135488
135536
  try {
135489
135537
  worktreeService.forgetLocalWorktrees();
135490
135538
  } catch (err) {
135491
- log93.warn(
135539
+ log94.warn(
135492
135540
  "Failed to forget local worktrees at boot: %s",
135493
135541
  err instanceof Error ? err.message : String(err)
135494
135542
  );
@@ -135498,7 +135546,7 @@ async function ensureRepoStateInSync() {
135498
135546
  try {
135499
135547
  await syncService.syncWorktrees();
135500
135548
  } catch (err) {
135501
- log93.warn(
135549
+ log94.warn(
135502
135550
  "Failed to sync repo state at boot: %s",
135503
135551
  err instanceof Error ? err.message : String(err)
135504
135552
  );
@@ -135509,22 +135557,22 @@ async function ensureCliInstalled() {
135509
135557
  try {
135510
135558
  cliStatus = await checkCli();
135511
135559
  } catch (err) {
135512
- log93.warn("Could not check CLI status: %s", err instanceof Error ? err.message : String(err));
135560
+ log94.warn("Could not check CLI status: %s", err instanceof Error ? err.message : String(err));
135513
135561
  return;
135514
135562
  }
135515
135563
  if (cliStatus === "Installed") {
135516
135564
  return;
135517
135565
  }
135518
135566
  if (cliStatus !== "NotInstalled") {
135519
- log93.warn("CLI not auto-installed (status: %s)", cliStatus);
135567
+ log94.warn("CLI not auto-installed (status: %s)", cliStatus);
135520
135568
  return;
135521
135569
  }
135522
- log93.info("Installing band CLI...");
135570
+ log94.info("Installing band CLI...");
135523
135571
  try {
135524
135572
  await installCli();
135525
- log93.info("CLI installed to %s", SYMLINK_PATH);
135573
+ log94.info("CLI installed to %s", SYMLINK_PATH);
135526
135574
  } catch (err) {
135527
- log93.warn("CLI installation failed: %s", err instanceof Error ? err.message : String(err));
135575
+ log94.warn("CLI installation failed: %s", err instanceof Error ? err.message : String(err));
135528
135576
  }
135529
135577
  }
135530
135578
  async function ensureDefaultCodingAgents() {
@@ -135533,17 +135581,17 @@ async function ensureDefaultCodingAgents() {
135533
135581
  if (Array.isArray(existing) && existing.length > 0) {
135534
135582
  return;
135535
135583
  }
135536
- log93.info("Detecting installed coding agents...");
135584
+ log94.info("Detecting installed coding agents...");
135537
135585
  const detected = [];
135538
135586
  for (const check3 of AGENT_CHECKS) {
135539
135587
  const path2 = await systemService.whichBinary(check3.binary);
135540
135588
  if (path2) {
135541
- log93.info("Detected coding agent: %s (%s)", check3.id, path2);
135589
+ log94.info("Detected coding agent: %s (%s)", check3.id, path2);
135542
135590
  detected.push({ id: check3.id, type: check3.type, label: check3.label });
135543
135591
  }
135544
135592
  }
135545
135593
  if (detected.length === 0) {
135546
- log93.info("No coding agent CLIs detected on PATH");
135594
+ log94.info("No coding agent CLIs detected on PATH");
135547
135595
  return;
135548
135596
  }
135549
135597
  const current3 = loadSettings();
@@ -135552,7 +135600,7 @@ async function ensureDefaultCodingAgents() {
135552
135600
  current3.defaultCodingAgent = detected[0].id;
135553
135601
  }
135554
135602
  saveSettings(current3);
135555
- log93.info("Enabled %d coding agent(s); default = %s", detected.length, current3.defaultCodingAgent);
135603
+ log94.info("Enabled %d coding agent(s); default = %s", detected.length, current3.defaultCodingAgent);
135556
135604
  }
135557
135605
  function ensureNotificationDefaults() {
135558
135606
  const settings3 = loadSettings();
@@ -135564,7 +135612,7 @@ function ensureNotificationDefaults() {
135564
135612
  ...settings3,
135565
135613
  notifications: { ...notifications, soundOnNeedsAttention: true }
135566
135614
  });
135567
- log93.info("Set default notifications.soundOnNeedsAttention = true");
135615
+ log94.info("Set default notifications.soundOnNeedsAttention = true");
135568
135616
  }
135569
135617
  function migrateAgentDefaultMode() {
135570
135618
  const settings3 = loadSettings();
@@ -135572,15 +135620,15 @@ function migrateAgentDefaultMode() {
135572
135620
  const mode = agentModeFromVia(settings3.cli?.defaultVia);
135573
135621
  if (!mode) return;
135574
135622
  saveSettings({ ...settings3, agents: { ...settings3.agents, defaultMode: mode } });
135575
- log93.info("Migrated cli.defaultVia to agents.defaultMode = %s", mode);
135623
+ log94.info("Migrated cli.defaultVia to agents.defaultMode = %s", mode);
135576
135624
  }
135577
135625
  async function ensureSkillsInstalled() {
135578
135626
  try {
135579
- const result = await installSkills2({ log: log93 });
135627
+ const result = await installSkills2({ log: log94 });
135580
135628
  const wrote = result.written.length + result.updated.length;
135581
135629
  const linkChange = result.linked.length;
135582
135630
  if (wrote > 0 || linkChange > 0 || result.conflicts.length > 0) {
135583
- log93.info(
135631
+ log94.info(
135584
135632
  "Synced CLI skills (shared: %d written, %d updated, %d unchanged; symlinks: %d created, %d already-linked, %d conflicts, %d skipped)",
135585
135633
  result.written.length,
135586
135634
  result.updated.length,
@@ -135592,7 +135640,7 @@ async function ensureSkillsInstalled() {
135592
135640
  );
135593
135641
  }
135594
135642
  } catch (err) {
135595
- log93.warn("Failed to sync CLI skills: %s", err instanceof Error ? err.message : String(err));
135643
+ log94.warn("Failed to sync CLI skills: %s", err instanceof Error ? err.message : String(err));
135596
135644
  }
135597
135645
  }
135598
135646
  var SetupService = class {
@@ -135732,13 +135780,6 @@ function getCachedScalarHtml() {
135732
135780
  _scalarHtml = getScalarHtml("/api/openapi.json");
135733
135781
  return _scalarHtml;
135734
135782
  }
135735
- function hostedFileHeaders(contentType) {
135736
- const headers = { "X-Content-Type-Options": "nosniff" };
135737
- if (/^(text\/html|image\/svg\+xml)\b/.test(contentType)) {
135738
- headers["Content-Security-Policy"] = "sandbox allow-scripts";
135739
- }
135740
- return headers;
135741
- }
135742
135783
  function serveStaticFile(res, root, subdir, rawFilename) {
135743
135784
  const filename = basename7(decodeURIComponent(rawFilename));
135744
135785
  if (!filename || filename.includes("..")) {