@band-app/server 0.57.0 → 0.59.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 (131) hide show
  1. package/dist/client/_shell.html +0 -0
  2. package/dist/client/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  3. package/dist/client/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  4. package/dist/client/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  5. package/dist/client/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  6. package/dist/client/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  7. package/dist/client/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  8. package/dist/client/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  9. package/dist/client/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  10. package/dist/client/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  11. package/dist/client/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  12. package/dist/client/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  13. package/dist/client/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  14. package/dist/client/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  15. package/dist/client/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  16. package/dist/client/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  17. package/dist/client/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  18. package/dist/client/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  19. package/dist/client/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  20. package/dist/client/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  21. package/dist/client/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  22. package/dist/client/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  23. package/dist/client/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  24. package/dist/client/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  25. package/dist/client/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  26. package/dist/client/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  27. package/dist/client/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  28. package/dist/client/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  29. package/dist/client/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  30. package/dist/client/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  31. package/dist/client/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  32. package/dist/client/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  33. package/dist/client/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  34. package/dist/client/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  35. package/dist/client/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  36. package/dist/client/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  37. package/dist/client/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  38. package/dist/client/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  39. package/dist/client/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  40. package/dist/client/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  41. package/dist/client/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  42. package/dist/client/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  43. package/dist/client/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  44. package/dist/client/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  45. package/dist/client/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  46. package/dist/client/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  47. package/dist/client/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  48. package/dist/client/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  49. package/dist/client/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  50. package/dist/client/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  51. package/dist/client/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  52. package/dist/client/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  53. package/dist/client/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  54. package/dist/client/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  55. package/dist/client/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  56. package/dist/client/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  57. package/dist/client/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  58. package/dist/client/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  59. package/dist/client/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  60. package/dist/client/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  61. package/dist/client/assets/{TerminalPanel-BQ7jJvVY.js → TerminalPanel-Dls8_vGY.js} +1 -1
  62. package/dist/client/assets/{_basePickBy-CWJhZ7PD.js → _basePickBy-B5gHumRZ.js} +1 -1
  63. package/dist/client/assets/{_baseUniq-CT0jJrWu.js → _baseUniq-Bk4j3bVH.js} +1 -1
  64. package/dist/client/assets/{arc-CWIqvrD4.js → arc-BE7I7FD7.js} +1 -1
  65. package/dist/client/assets/{architectureDiagram-VXUJARFQ-DU_1irNi.js → architectureDiagram-VXUJARFQ-BBWBwpgm.js} +1 -1
  66. package/dist/client/assets/{blockDiagram-VD42YOAC-CZ6uMShZ.js → blockDiagram-VD42YOAC-CfFgUppR.js} +1 -1
  67. package/dist/client/assets/{c4Diagram-YG6GDRKO-DII3gdbS.js → c4Diagram-YG6GDRKO-ClgEIcXl.js} +1 -1
  68. package/dist/client/assets/channel-CLuseuD8.js +1 -0
  69. package/dist/client/assets/{chunk-4BX2VUAB-CW4TSJub.js → chunk-4BX2VUAB-BTsFCzlB.js} +1 -1
  70. package/dist/client/assets/{chunk-55IACEB6-Cdu6EJZT.js → chunk-55IACEB6-HURI4nLM.js} +1 -1
  71. package/dist/client/assets/{chunk-B4BG7PRW-B1x_SAjR.js → chunk-B4BG7PRW-rC-ot-Mn.js} +1 -1
  72. package/dist/client/assets/{chunk-DI55MBZ5-D4Ap-nF_.js → chunk-DI55MBZ5-C2_9NN7e.js} +1 -1
  73. package/dist/client/assets/{chunk-FMBD7UC4-DNgzxeD7.js → chunk-FMBD7UC4-CyCfpT3p.js} +1 -1
  74. package/dist/client/assets/{chunk-QN33PNHL-DE9GCyLi.js → chunk-QN33PNHL-BbkJTAOV.js} +1 -1
  75. package/dist/client/assets/{chunk-QZHKN3VN-BS7uTEeT.js → chunk-QZHKN3VN-BSdemm5A.js} +1 -1
  76. package/dist/client/assets/{chunk-TZMSLE5B-DNZIw0Ke.js → chunk-TZMSLE5B-D4wvd9Yu.js} +1 -1
  77. package/dist/client/assets/classDiagram-2ON5EDUG-PhOyZKeC.js +1 -0
  78. package/dist/client/assets/classDiagram-v2-WZHVMYZB-PhOyZKeC.js +1 -0
  79. package/dist/client/assets/clone-CMv9qsOc.js +1 -0
  80. package/dist/client/assets/{cose-bilkent-S5V4N54A-CCgQ5TY-.js → cose-bilkent-S5V4N54A-J0yf-ZRd.js} +1 -1
  81. package/dist/client/assets/{dagre-6UL2VRFP-DrhLtS4C.js → dagre-6UL2VRFP-D2ktTA5V.js} +1 -1
  82. package/dist/client/assets/{diagram-PSM6KHXK-DQSaKLXK.js → diagram-PSM6KHXK-DlQLNiTP.js} +1 -1
  83. package/dist/client/assets/{diagram-QEK2KX5R-DbUXqE8i.js → diagram-QEK2KX5R-oY37vdEd.js} +1 -1
  84. package/dist/client/assets/{diagram-S2PKOQOG-DJejbOW1.js → diagram-S2PKOQOG-DaOX0asw.js} +1 -1
  85. package/dist/client/assets/{erDiagram-Q2GNP2WA-DEeEW3Kd.js → erDiagram-Q2GNP2WA-BeewDnEp.js} +1 -1
  86. package/dist/client/assets/{flowDiagram-NV44I4VS-BrKPt2KY.js → flowDiagram-NV44I4VS-CgEQ2bXi.js} +1 -1
  87. package/dist/client/assets/{ganttDiagram-JELNMOA3-NxtYANPR.js → ganttDiagram-JELNMOA3-DLIhunms.js} +1 -1
  88. package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-0qQVaZpT.js → gitGraphDiagram-V2S2FVAM-BbcljkLL.js} +1 -1
  89. package/dist/client/assets/{graph-D-vRi72k.js → graph-C1SThxwq.js} +1 -1
  90. package/dist/client/assets/{highlighted-body-B3W2YXNL-vjxbNAd7.js → highlighted-body-B3W2YXNL-6fAWPSpW.js} +1 -1
  91. package/dist/client/assets/{index-C1z37ULd.js → index-5YEiuPMI.js} +1 -1
  92. package/dist/client/assets/{index-6vsAmyuh.js → index-B1SUzFra.js} +1 -1
  93. package/dist/client/assets/{index-BZ43NplR.js → index-BAfOs6Gy.js} +1 -1
  94. package/dist/client/assets/{index-DCFHhI43.js → index-Bh3TSdKT.js} +1 -1
  95. package/dist/client/assets/{index-CUWHOWHZ.js → index-Bk8JlBY0.js} +1 -1
  96. package/dist/client/assets/{index-Kn6ZarbI.js → index-Bxgl3ZHO.js} +1 -1
  97. package/dist/client/assets/{index-BHMWFIFp.js → index-CLieczz3.js} +1 -1
  98. package/dist/client/assets/{index-DxA2gLxH.js → index-CiOhy6I5.js} +1 -1
  99. package/dist/client/assets/{index-CU3l0cqI.js → index-D13XFok4.js} +1 -1
  100. package/dist/client/assets/{index-C93xaF2D.js → index-D7f6vSSM.js} +1 -1
  101. package/dist/client/assets/{index-59DRJg8o.js → index-DMWW3BkM.js} +1 -1
  102. package/dist/client/assets/{index-D7ZIaN5W.js → index-DNW-icyC.js} +1 -1
  103. package/dist/client/assets/{index-BZoUdjXh.js → index-DWbGgUyQ.js} +1 -1
  104. package/dist/client/assets/{infoDiagram-HS3SLOUP-DVvA2Rdm.js → infoDiagram-HS3SLOUP-vyRt2Bsk.js} +1 -1
  105. package/dist/client/assets/{journeyDiagram-XKPGCS4Q-CozouUkd.js → journeyDiagram-XKPGCS4Q-DBXVmGpv.js} +1 -1
  106. package/dist/client/assets/{kanban-definition-3W4ZIXB7-DdqQIj8J.js → kanban-definition-3W4ZIXB7-CEpw89r7.js} +1 -1
  107. package/dist/client/assets/{layout-Si_SwcDU.js → layout-Q53PNtzV.js} +1 -1
  108. package/dist/client/assets/main-BVyM6Kwo.css +1 -0
  109. package/dist/client/assets/{main-DOFdCOPt.js → main-doYM8mtx.js} +269 -265
  110. package/dist/client/assets/{mindmap-definition-VGOIOE7T-C5aQiwY1.js → mindmap-definition-VGOIOE7T-jFXUryZ1.js} +1 -1
  111. package/dist/client/assets/{pieDiagram-ADFJNKIX-C_OndLWU.js → pieDiagram-ADFJNKIX-24FHt1PP.js} +1 -1
  112. package/dist/client/assets/{quadrantDiagram-AYHSOK5B-2j7ury0K.js → quadrantDiagram-AYHSOK5B-BznmAQTy.js} +1 -1
  113. package/dist/client/assets/{requirementDiagram-UZGBJVZJ-BUPmH6ij.js → requirementDiagram-UZGBJVZJ-auw6LsZk.js} +1 -1
  114. package/dist/client/assets/{sankeyDiagram-TZEHDZUN-CVrjDWIQ.js → sankeyDiagram-TZEHDZUN-CX_06gNQ.js} +1 -1
  115. package/dist/client/assets/{sequenceDiagram-WL72ISMW-Dz_Etmjx.js → sequenceDiagram-WL72ISMW-tQMk7iIO.js} +1 -1
  116. package/dist/client/assets/{stateDiagram-FKZM4ZOC-DKxAJWnz.js → stateDiagram-FKZM4ZOC-DCZeLtBb.js} +1 -1
  117. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-9Yihsv84.js +1 -0
  118. package/dist/client/assets/{timeline-definition-IT6M3QCI-DDqd2wFA.js → timeline-definition-IT6M3QCI-CqegSAwa.js} +1 -1
  119. package/dist/client/assets/{treemap-GDKQZRPO-B-4nXAG1.js → treemap-GDKQZRPO-C1eLC_yq.js} +1 -1
  120. package/dist/client/assets/{worktree._worktreeId-GQhsr6UA.js → worktree._worktreeId-BfJo-vJP.js} +1 -1
  121. package/dist/client/assets/{worktree._worktreeId-1wxOo9iN.js → worktree._worktreeId-CNBIqdCa.js} +1 -1
  122. package/dist/client/assets/{xychartDiagram-PRI3JC2R-BIeX7Ci-.js → xychartDiagram-PRI3JC2R-CDiV-aAA.js} +1 -1
  123. package/dist/openapi.json +533 -36
  124. package/dist/start-server.mjs +1097 -399
  125. package/package.json +11 -11
  126. package/dist/client/assets/channel-26GHUpO9.js +0 -1
  127. package/dist/client/assets/classDiagram-2ON5EDUG-CXw_6Q71.js +0 -1
  128. package/dist/client/assets/classDiagram-v2-WZHVMYZB-CXw_6Q71.js +0 -1
  129. package/dist/client/assets/clone-X9pt_2az.js +0 -1
  130. package/dist/client/assets/main-B3ss88Hs.css +0 -1
  131. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-8yPLqakb.js +0 -1
@@ -2136,7 +2136,7 @@ var require_thread_stream = __commonJS({
2136
2136
  var { version: version3 } = require_package();
2137
2137
  var { EventEmitter: EventEmitter4 } = __require("events");
2138
2138
  var { Worker: Worker2 } = __require("worker_threads");
2139
- var { join: join62 } = __require("path");
2139
+ var { join: join63 } = __require("path");
2140
2140
  var { pathToFileURL } = __require("url");
2141
2141
  var { wait } = require_wait();
2142
2142
  var {
@@ -2172,7 +2172,7 @@ var require_thread_stream = __commonJS({
2172
2172
  function createWorker(stream, opts) {
2173
2173
  const { filename, workerData } = opts;
2174
2174
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
2175
- const toExecute = bundlerOverrides["thread-stream-worker"] || join62(__dirname, "lib", "worker.js");
2175
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join63(__dirname, "lib", "worker.js");
2176
2176
  const worker2 = new Worker2(toExecute, {
2177
2177
  ...opts.workerOpts,
2178
2178
  trackUnmanagedFds: false,
@@ -2558,7 +2558,7 @@ var require_transport = __commonJS({
2558
2558
  "use strict";
2559
2559
  var { createRequire: createRequire3 } = __require("module");
2560
2560
  var getCallers = require_caller();
2561
- var { join: join62, isAbsolute: isAbsolute7, sep: sep13 } = __require("node:path");
2561
+ var { join: join63, isAbsolute: isAbsolute7, sep: sep13 } = __require("node:path");
2562
2562
  var sleep3 = require_atomic_sleep();
2563
2563
  var onExit = require_on_exit_leak_free();
2564
2564
  var ThreadStream = require_thread_stream();
@@ -2621,7 +2621,7 @@ var require_transport = __commonJS({
2621
2621
  throw new Error("only one of target or targets can be specified");
2622
2622
  }
2623
2623
  if (targets) {
2624
- target = bundlerOverrides["pino-worker"] || join62(__dirname, "worker.js");
2624
+ target = bundlerOverrides["pino-worker"] || join63(__dirname, "worker.js");
2625
2625
  options.targets = targets.filter((dest) => dest.target).map((dest) => {
2626
2626
  return {
2627
2627
  ...dest,
@@ -2639,7 +2639,7 @@ var require_transport = __commonJS({
2639
2639
  });
2640
2640
  });
2641
2641
  } else if (pipeline4) {
2642
- target = bundlerOverrides["pino-worker"] || join62(__dirname, "worker.js");
2642
+ target = bundlerOverrides["pino-worker"] || join63(__dirname, "worker.js");
2643
2643
  options.pipelines = [pipeline4.map((dest) => {
2644
2644
  return {
2645
2645
  ...dest,
@@ -2661,7 +2661,7 @@ var require_transport = __commonJS({
2661
2661
  return origin;
2662
2662
  }
2663
2663
  if (origin === "pino/file") {
2664
- return join62(__dirname, "..", "file.js");
2664
+ return join63(__dirname, "..", "file.js");
2665
2665
  }
2666
2666
  let fixTarget2;
2667
2667
  for (const filePath of callers) {
@@ -3650,7 +3650,7 @@ var require_safe_stable_stringify = __commonJS({
3650
3650
  return circularValue;
3651
3651
  }
3652
3652
  let res = "";
3653
- let join62 = ",";
3653
+ let join63 = ",";
3654
3654
  const originalIndentation = indentation;
3655
3655
  if (Array.isArray(value)) {
3656
3656
  if (value.length === 0) {
@@ -3664,7 +3664,7 @@ var require_safe_stable_stringify = __commonJS({
3664
3664
  indentation += spacer;
3665
3665
  res += `
3666
3666
  ${indentation}`;
3667
- join62 = `,
3667
+ join63 = `,
3668
3668
  ${indentation}`;
3669
3669
  }
3670
3670
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -3672,13 +3672,13 @@ ${indentation}`;
3672
3672
  for (; i < maximumValuesToStringify - 1; i++) {
3673
3673
  const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
3674
3674
  res += tmp2 !== void 0 ? tmp2 : "null";
3675
- res += join62;
3675
+ res += join63;
3676
3676
  }
3677
3677
  const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
3678
3678
  res += tmp !== void 0 ? tmp : "null";
3679
3679
  if (value.length - 1 > maximumBreadth) {
3680
3680
  const removedKeys = value.length - maximumBreadth - 1;
3681
- res += `${join62}"... ${getItemCount(removedKeys)} not stringified"`;
3681
+ res += `${join63}"... ${getItemCount(removedKeys)} not stringified"`;
3682
3682
  }
3683
3683
  if (spacer !== "") {
3684
3684
  res += `
@@ -3699,7 +3699,7 @@ ${originalIndentation}`;
3699
3699
  let separator = "";
3700
3700
  if (spacer !== "") {
3701
3701
  indentation += spacer;
3702
- join62 = `,
3702
+ join63 = `,
3703
3703
  ${indentation}`;
3704
3704
  whitespace = " ";
3705
3705
  }
@@ -3713,13 +3713,13 @@ ${indentation}`;
3713
3713
  const tmp = stringifyFnReplacer(key3, value, stack, replacer, spacer, indentation);
3714
3714
  if (tmp !== void 0) {
3715
3715
  res += `${separator}${strEscape(key3)}:${whitespace}${tmp}`;
3716
- separator = join62;
3716
+ separator = join63;
3717
3717
  }
3718
3718
  }
3719
3719
  if (keyLength > maximumBreadth) {
3720
3720
  const removedKeys = keyLength - maximumBreadth;
3721
3721
  res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
3722
- separator = join62;
3722
+ separator = join63;
3723
3723
  }
3724
3724
  if (spacer !== "" && separator.length > 1) {
3725
3725
  res = `
@@ -3760,7 +3760,7 @@ ${originalIndentation}`;
3760
3760
  }
3761
3761
  const originalIndentation = indentation;
3762
3762
  let res = "";
3763
- let join62 = ",";
3763
+ let join63 = ",";
3764
3764
  if (Array.isArray(value)) {
3765
3765
  if (value.length === 0) {
3766
3766
  return "[]";
@@ -3773,7 +3773,7 @@ ${originalIndentation}`;
3773
3773
  indentation += spacer;
3774
3774
  res += `
3775
3775
  ${indentation}`;
3776
- join62 = `,
3776
+ join63 = `,
3777
3777
  ${indentation}`;
3778
3778
  }
3779
3779
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -3781,13 +3781,13 @@ ${indentation}`;
3781
3781
  for (; i < maximumValuesToStringify - 1; i++) {
3782
3782
  const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
3783
3783
  res += tmp2 !== void 0 ? tmp2 : "null";
3784
- res += join62;
3784
+ res += join63;
3785
3785
  }
3786
3786
  const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
3787
3787
  res += tmp !== void 0 ? tmp : "null";
3788
3788
  if (value.length - 1 > maximumBreadth) {
3789
3789
  const removedKeys = value.length - maximumBreadth - 1;
3790
- res += `${join62}"... ${getItemCount(removedKeys)} not stringified"`;
3790
+ res += `${join63}"... ${getItemCount(removedKeys)} not stringified"`;
3791
3791
  }
3792
3792
  if (spacer !== "") {
3793
3793
  res += `
@@ -3800,7 +3800,7 @@ ${originalIndentation}`;
3800
3800
  let whitespace = "";
3801
3801
  if (spacer !== "") {
3802
3802
  indentation += spacer;
3803
- join62 = `,
3803
+ join63 = `,
3804
3804
  ${indentation}`;
3805
3805
  whitespace = " ";
3806
3806
  }
@@ -3809,7 +3809,7 @@ ${indentation}`;
3809
3809
  const tmp = stringifyArrayReplacer(key3, value[key3], stack, replacer, spacer, indentation);
3810
3810
  if (tmp !== void 0) {
3811
3811
  res += `${separator}${strEscape(key3)}:${whitespace}${tmp}`;
3812
- separator = join62;
3812
+ separator = join63;
3813
3813
  }
3814
3814
  }
3815
3815
  if (spacer !== "" && separator.length > 1) {
@@ -3867,20 +3867,20 @@ ${originalIndentation}`;
3867
3867
  indentation += spacer;
3868
3868
  let res2 = `
3869
3869
  ${indentation}`;
3870
- const join63 = `,
3870
+ const join64 = `,
3871
3871
  ${indentation}`;
3872
3872
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
3873
3873
  let i = 0;
3874
3874
  for (; i < maximumValuesToStringify - 1; i++) {
3875
3875
  const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
3876
3876
  res2 += tmp2 !== void 0 ? tmp2 : "null";
3877
- res2 += join63;
3877
+ res2 += join64;
3878
3878
  }
3879
3879
  const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
3880
3880
  res2 += tmp !== void 0 ? tmp : "null";
3881
3881
  if (value.length - 1 > maximumBreadth) {
3882
3882
  const removedKeys = value.length - maximumBreadth - 1;
3883
- res2 += `${join63}"... ${getItemCount(removedKeys)} not stringified"`;
3883
+ res2 += `${join64}"... ${getItemCount(removedKeys)} not stringified"`;
3884
3884
  }
3885
3885
  res2 += `
3886
3886
  ${originalIndentation}`;
@@ -3896,16 +3896,16 @@ ${originalIndentation}`;
3896
3896
  return '"[Object]"';
3897
3897
  }
3898
3898
  indentation += spacer;
3899
- const join62 = `,
3899
+ const join63 = `,
3900
3900
  ${indentation}`;
3901
3901
  let res = "";
3902
3902
  let separator = "";
3903
3903
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
3904
3904
  if (isTypedArrayWithEntries(value)) {
3905
- res += stringifyTypedArray(value, join62, maximumBreadth);
3905
+ res += stringifyTypedArray(value, join63, maximumBreadth);
3906
3906
  keys = keys.slice(value.length);
3907
3907
  maximumPropertiesToStringify -= value.length;
3908
- separator = join62;
3908
+ separator = join63;
3909
3909
  }
3910
3910
  if (deterministic) {
3911
3911
  keys = sort(keys, comparator2);
@@ -3916,13 +3916,13 @@ ${indentation}`;
3916
3916
  const tmp = stringifyIndent(key3, value[key3], stack, spacer, indentation);
3917
3917
  if (tmp !== void 0) {
3918
3918
  res += `${separator}${strEscape(key3)}: ${tmp}`;
3919
- separator = join62;
3919
+ separator = join63;
3920
3920
  }
3921
3921
  }
3922
3922
  if (keyLength > maximumBreadth) {
3923
3923
  const removedKeys = keyLength - maximumBreadth;
3924
3924
  res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
3925
- separator = join62;
3925
+ separator = join63;
3926
3926
  }
3927
3927
  if (separator !== "") {
3928
3928
  res = `
@@ -4289,7 +4289,7 @@ var require_pino = __commonJS({
4289
4289
  } = symbols;
4290
4290
  var { epochTime, nullTime } = time6;
4291
4291
  var { pid } = process;
4292
- var hostname6 = os.hostname();
4292
+ var hostname7 = os.hostname();
4293
4293
  var defaultErrorSerializer = stdSerializers.err;
4294
4294
  var defaultOptions2 = {
4295
4295
  level: "info",
@@ -4299,7 +4299,7 @@ var require_pino = __commonJS({
4299
4299
  errorKey: "err",
4300
4300
  nestedKey: null,
4301
4301
  enabled: true,
4302
- base: { pid, hostname: hostname6 },
4302
+ base: { pid, hostname: hostname7 },
4303
4303
  serializers: Object.assign(/* @__PURE__ */ Object.create(null), {
4304
4304
  err: defaultErrorSerializer
4305
4305
  }),
@@ -4604,9 +4604,9 @@ function checkEndpointOwner(socketPath) {
4604
4604
  }
4605
4605
  return "ok";
4606
4606
  }
4607
- function entryIdentity(path2, stat8) {
4607
+ function entryIdentity(path2, stat9) {
4608
4608
  try {
4609
- const stats = stat8(path2, { bigint: true });
4609
+ const stats = stat9(path2, { bigint: true });
4610
4610
  return { dev: stats.dev, ino: stats.ino };
4611
4611
  } catch {
4612
4612
  return null;
@@ -16489,6 +16489,13 @@ var init_pty2 = __esm({
16489
16489
  }
16490
16490
  });
16491
16491
 
16492
+ // ../../packages/host-api/src/resources.ts
16493
+ var init_resources = __esm({
16494
+ "../../packages/host-api/src/resources.ts"() {
16495
+ "use strict";
16496
+ }
16497
+ });
16498
+
16492
16499
  // ../../packages/host-api/src/index.ts
16493
16500
  var init_src3 = __esm({
16494
16501
  "../../packages/host-api/src/index.ts"() {
@@ -16498,6 +16505,7 @@ var init_src3 = __esm({
16498
16505
  init_git_run();
16499
16506
  init_host();
16500
16507
  init_pty2();
16508
+ init_resources();
16501
16509
  }
16502
16510
  });
16503
16511
 
@@ -16835,6 +16843,8 @@ var init_rpc = __esm({
16835
16843
  "fs.copy": 5 * 6e4,
16836
16844
  "fs.rm": 2 * 6e4,
16837
16845
  "fs.du": 2 * 6e4,
16846
+ // Measures every worktree of a worker, three `du` at a time.
16847
+ "resources.storage": 10 * 6e4,
16838
16848
  "fs.glob": 6e4,
16839
16849
  "search.listFiles": 6e4,
16840
16850
  "scripts.runHidden": 10 * 6e4,
@@ -17061,6 +17071,10 @@ var init_remote_host = __esm({
17061
17071
  return duplexOf(this.rpc.channel(reply.chan));
17062
17072
  }
17063
17073
  };
17074
+ resources = {
17075
+ snapshot: () => this.rpc.call("resources.snapshot", {}),
17076
+ storage: (request) => this.rpc.call("resources.storage", request)
17077
+ };
17064
17078
  speech = {
17065
17079
  transcribe: async (req) => {
17066
17080
  const { audio, ...rest } = req;
@@ -17128,7 +17142,7 @@ var init_remote_host = __esm({
17128
17142
  // The worker keeps the browser. `browser.connect` opens one channel of length-prefixed CDP
17129
17143
  // messages, and resetting it drops the connection but not the browser.
17130
17144
  browser = {
17131
- open: (spec) => this.rpc.call("browser.open", spec, { timeoutMs: 6e4 }),
17145
+ open: (spec) => this.rpc.call("browser.open", spec, { timeoutMs: 15e4 }),
17132
17146
  connect: async (worktreeId4) => {
17133
17147
  const reply = await this.rpc.request("browser.connect", { worktreeId: worktreeId4 });
17134
17148
  const ch = this.rpc.channel(reply.chan);
@@ -20859,9 +20873,9 @@ function parseURLObject(trimmed, def) {
20859
20873
  function stripTabAndNewline(value) {
20860
20874
  return value.replace(asciiTabOrNewline, "");
20861
20875
  }
20862
- function urlHostnameOk(url3, hostname6) {
20863
- hostname6.lastIndex = 0;
20864
- return hostname6.test(url3.hostname);
20876
+ function urlHostnameOk(url3, hostname7) {
20877
+ hostname7.lastIndex = 0;
20878
+ return hostname7.test(url3.hostname);
20865
20879
  }
20866
20880
  function urlProtocolOk(url3, protocol) {
20867
20881
  protocol.lastIndex = 0;
@@ -38570,7 +38584,7 @@ function visit(schema, fnOrHandlers) {
38570
38584
  return h ? h(node2, rewritten) : node2;
38571
38585
  };
38572
38586
  const cache2 = /* @__PURE__ */ new Map();
38573
- function run3(s2) {
38587
+ function run4(s2) {
38574
38588
  const cached4 = cache2.get(s2);
38575
38589
  if (cached4 === RESOLVING) {
38576
38590
  return new $ZodLazy({
@@ -38596,21 +38610,21 @@ function visit(schema, fnOrHandlers) {
38596
38610
  let changed = false;
38597
38611
  const newShape = {};
38598
38612
  for (const k2 of keys) {
38599
- const mapped = run3(oldShape[k2]);
38613
+ const mapped = run4(oldShape[k2]);
38600
38614
  if (mapped !== oldShape[k2])
38601
38615
  changed = true;
38602
38616
  newShape[k2] = mapped;
38603
38617
  }
38604
38618
  let newCatchall = def.catchall;
38605
38619
  if (def.catchall) {
38606
- newCatchall = run3(def.catchall);
38620
+ newCatchall = run4(def.catchall);
38607
38621
  if (newCatchall !== def.catchall)
38608
38622
  changed = true;
38609
38623
  }
38610
38624
  return changed ? clone(s2, { ...def, shape: newShape, catchall: newCatchall }) : s2;
38611
38625
  }
38612
38626
  case "array": {
38613
- const mapped = run3(def.element);
38627
+ const mapped = run4(def.element);
38614
38628
  return mapped === def.element ? s2 : clone(s2, { ...def, element: mapped });
38615
38629
  }
38616
38630
  case "tuple": {
@@ -38618,14 +38632,14 @@ function visit(schema, fnOrHandlers) {
38618
38632
  let changed = false;
38619
38633
  const newItems = [];
38620
38634
  for (const item of oldItems) {
38621
- const mapped = run3(item);
38635
+ const mapped = run4(item);
38622
38636
  if (mapped !== item)
38623
38637
  changed = true;
38624
38638
  newItems.push(mapped);
38625
38639
  }
38626
38640
  let newRest = def.rest;
38627
38641
  if (def.rest) {
38628
- newRest = run3(def.rest);
38642
+ newRest = run4(def.rest);
38629
38643
  if (newRest !== def.rest)
38630
38644
  changed = true;
38631
38645
  }
@@ -38633,12 +38647,12 @@ function visit(schema, fnOrHandlers) {
38633
38647
  }
38634
38648
  case "record":
38635
38649
  case "map": {
38636
- const newKey = run3(def.keyType);
38637
- const newVal = run3(def.valueType);
38650
+ const newKey = run4(def.keyType);
38651
+ const newVal = run4(def.valueType);
38638
38652
  return newKey === def.keyType && newVal === def.valueType ? s2 : clone(s2, { ...def, keyType: newKey, valueType: newVal });
38639
38653
  }
38640
38654
  case "set": {
38641
- const newVal = run3(def.valueType);
38655
+ const newVal = run4(def.valueType);
38642
38656
  return newVal === def.valueType ? s2 : clone(s2, { ...def, valueType: newVal });
38643
38657
  }
38644
38658
  case "union": {
@@ -38646,7 +38660,7 @@ function visit(schema, fnOrHandlers) {
38646
38660
  let changed = false;
38647
38661
  const newOptions = [];
38648
38662
  for (const opt of oldOptions) {
38649
- const mapped = run3(opt);
38663
+ const mapped = run4(opt);
38650
38664
  if (mapped !== opt)
38651
38665
  changed = true;
38652
38666
  newOptions.push(mapped);
@@ -38654,8 +38668,8 @@ function visit(schema, fnOrHandlers) {
38654
38668
  return changed ? clone(s2, { ...def, options: newOptions }) : s2;
38655
38669
  }
38656
38670
  case "intersection": {
38657
- const newLeft = run3(def.left);
38658
- const newRight = run3(def.right);
38671
+ const newLeft = run4(def.left);
38672
+ const newRight = run4(def.right);
38659
38673
  return newLeft === def.left && newRight === def.right ? s2 : clone(s2, { ...def, left: newLeft, right: newRight });
38660
38674
  }
38661
38675
  case "optional":
@@ -38667,23 +38681,23 @@ function visit(schema, fnOrHandlers) {
38667
38681
  case "nonoptional":
38668
38682
  case "promise":
38669
38683
  case "success": {
38670
- const newInner = run3(def.innerType);
38684
+ const newInner = run4(def.innerType);
38671
38685
  return newInner === def.innerType ? s2 : clone(s2, { ...def, innerType: newInner });
38672
38686
  }
38673
38687
  case "pipe": {
38674
- const newIn = run3(def.in);
38675
- const newOut = run3(def.out);
38688
+ const newIn = run4(def.in);
38689
+ const newOut = run4(def.out);
38676
38690
  return newIn === def.in && newOut === def.out ? s2 : clone(s2, { ...def, in: newIn, out: newOut });
38677
38691
  }
38678
38692
  case "function": {
38679
- const newInput = run3(def.input);
38680
- const newOutput = run3(def.output);
38693
+ const newInput = run4(def.input);
38694
+ const newOutput = run4(def.output);
38681
38695
  return newInput === def.input && newOutput === def.output ? s2 : clone(s2, { ...def, input: newInput, output: newOutput });
38682
38696
  }
38683
38697
  case "lazy": {
38684
38698
  const original = def.getter;
38685
38699
  const { _cachedInner, ...rest } = def;
38686
- return clone(s2, { ...rest, getter: () => run3(original()) });
38700
+ return clone(s2, { ...rest, getter: () => run4(original()) });
38687
38701
  }
38688
38702
  // A leaf by choice: `parts` are regex fragments, not data positions.
38689
38703
  case "template_literal":
@@ -38714,7 +38728,7 @@ function visit(schema, fnOrHandlers) {
38714
38728
  }
38715
38729
  }
38716
38730
  }
38717
- return run3(schema);
38731
+ return run4(schema);
38718
38732
  }
38719
38733
  var RESOLVING;
38720
38734
  var init_visit = __esm({
@@ -43517,27 +43531,27 @@ function textChunk(row) {
43517
43531
  }
43518
43532
  function rowsToEvents(rows) {
43519
43533
  const out = [];
43520
- let run3 = null;
43534
+ let run4 = null;
43521
43535
  const flush = () => {
43522
- if (!run3) return;
43536
+ if (!run4) return;
43523
43537
  out.push({
43524
43538
  type: "update",
43525
- update: { ...run3.update, content: { type: "text", text: run3.text } },
43526
- eventId: run3.lastId,
43527
- createdAt: run3.createdAt
43539
+ update: { ...run4.update, content: { type: "text", text: run4.text } },
43540
+ eventId: run4.lastId,
43541
+ createdAt: run4.createdAt
43528
43542
  });
43529
- run3 = null;
43543
+ run4 = null;
43530
43544
  };
43531
43545
  for (const row of rows) {
43532
43546
  const chunk = textChunk(row);
43533
- if (chunk && run3 && run3.update.sessionUpdate === chunk.sessionUpdate && (run3.update.messageId ?? null) === (chunk.messageId ?? null)) {
43534
- if (chunk.content.type === "text") run3.text += chunk.content.text;
43535
- run3.lastId = row.id;
43547
+ if (chunk && run4 && run4.update.sessionUpdate === chunk.sessionUpdate && (run4.update.messageId ?? null) === (chunk.messageId ?? null)) {
43548
+ if (chunk.content.type === "text") run4.text += chunk.content.text;
43549
+ run4.lastId = row.id;
43536
43550
  continue;
43537
43551
  }
43538
43552
  flush();
43539
43553
  if (chunk) {
43540
- run3 = {
43554
+ run4 = {
43541
43555
  update: chunk,
43542
43556
  text: chunk.content.type === "text" ? chunk.content.text : "",
43543
43557
  lastId: row.id,
@@ -43831,10 +43845,10 @@ var init_table = __esm({
43831
43845
  [IsDrizzleTable] = true;
43832
43846
  /** @internal */
43833
43847
  [ExtraConfigBuilder] = void 0;
43834
- constructor(name5, schema, baseName) {
43848
+ constructor(name5, schema, baseName2) {
43835
43849
  this[TableName] = this[OriginalName] = name5;
43836
43850
  this[TableSchema] = schema;
43837
- this[BaseName] = baseName;
43851
+ this[BaseName] = baseName2;
43838
43852
  }
43839
43853
  };
43840
43854
  }
@@ -44191,7 +44205,7 @@ var init_sql = __esm({
44191
44205
  return new SQL([new StringChunk(str3)]);
44192
44206
  }
44193
44207
  _sql.raw = raw;
44194
- function join62(chunks, separator) {
44208
+ function join63(chunks, separator) {
44195
44209
  const result = [];
44196
44210
  for (const [i, chunk] of chunks.entries()) {
44197
44211
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -44199,7 +44213,7 @@ var init_sql = __esm({
44199
44213
  }
44200
44214
  return new SQL(result);
44201
44215
  }
44202
- _sql.join = join62;
44216
+ _sql.join = join63;
44203
44217
  function identifier(value) {
44204
44218
  return new Name(value);
44205
44219
  }
@@ -45146,9 +45160,9 @@ var init_all = __esm({
45146
45160
  });
45147
45161
 
45148
45162
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.1_@opentelemetry+api@1.9.0_@types+better-sqlite3@7.6.13_better-sql_2010f6373f8103f640f869e889df39c3/node_modules/drizzle-orm/sqlite-core/table.js
45149
- function sqliteTableBase(name5, columns, extraConfig, schema, casing, baseName = name5) {
45163
+ function sqliteTableBase(name5, columns, extraConfig, schema, casing, baseName2 = name5) {
45150
45164
  const casingFn = getCasingFn(casing);
45151
- const rawTable = new SQLiteTable(name5, schema, baseName);
45165
+ const rawTable = new SQLiteTable(name5, schema, baseName2);
45152
45166
  const parsedColumns = typeof columns === "function" ? columns(getSQLiteColumnBuilders()) : columns;
45153
45167
  const builtColumns = Object.fromEntries(Object.entries(parsedColumns).map(([name6, colBuilderBase]) => {
45154
45168
  const colBuilder = colBuilderBase;
@@ -45743,10 +45757,10 @@ var init_table3 = __esm({
45743
45757
  [IsDrizzleTable2] = true;
45744
45758
  /** @internal */
45745
45759
  [ExtraConfigBuilder2] = void 0;
45746
- constructor(name5, schema, baseName) {
45760
+ constructor(name5, schema, baseName2) {
45747
45761
  this[TableName2] = this[OriginalName2] = name5;
45748
45762
  this[TableSchema2] = schema;
45749
- this[BaseName2] = baseName;
45763
+ this[BaseName2] = baseName2;
45750
45764
  }
45751
45765
  };
45752
45766
  }
@@ -46127,7 +46141,7 @@ var init_sql2 = __esm({
46127
46141
  return new SQL3([new StringChunk2(str3)]);
46128
46142
  }
46129
46143
  _sql.raw = raw;
46130
- function join62(chunks, separator) {
46144
+ function join63(chunks, separator) {
46131
46145
  const result = [];
46132
46146
  for (const [i, chunk] of chunks.entries()) {
46133
46147
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -46135,7 +46149,7 @@ var init_sql2 = __esm({
46135
46149
  }
46136
46150
  return new SQL3(result);
46137
46151
  }
46138
- _sql.join = join62;
46152
+ _sql.join = join63;
46139
46153
  function identifier(value) {
46140
46154
  return new Name2(value);
46141
46155
  }
@@ -49667,9 +49681,9 @@ var init_casing2 = __esm({
49667
49681
  });
49668
49682
 
49669
49683
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.1_@opentelemetry+api@1.9.0_@types+better-sqlite3@7.6.13_better-sql_95478898f63cc8c3fbbd0c5f8c1e464f/node_modules/drizzle-orm/pg-core/table.js
49670
- function pgTableWithSchema(name5, columns, extraConfig, schema, casing, baseName = name5) {
49684
+ function pgTableWithSchema(name5, columns, extraConfig, schema, casing, baseName2 = name5) {
49671
49685
  const casingFn = getCasingFn2(casing);
49672
- const rawTable = new PgTable(name5, schema, baseName);
49686
+ const rawTable = new PgTable(name5, schema, baseName2);
49673
49687
  const parsedColumns = typeof columns === "function" ? columns(getPgColumnBuilders()) : columns;
49674
49688
  const builtColumns = Object.fromEntries(Object.entries(parsedColumns).map(([name6, colBuilderBase]) => {
49675
49689
  const colBuilder = colBuilderBase;
@@ -51046,9 +51060,9 @@ var init_all3 = __esm({
51046
51060
  });
51047
51061
 
51048
51062
  // ../../node_modules/.pnpm/drizzle-orm@1.0.0-rc.1_@opentelemetry+api@1.9.0_@types+better-sqlite3@7.6.13_better-sql_95478898f63cc8c3fbbd0c5f8c1e464f/node_modules/drizzle-orm/sqlite-core/table.js
51049
- function sqliteTableBase2(name5, columns, extraConfig, schema, casing, baseName = name5) {
51063
+ function sqliteTableBase2(name5, columns, extraConfig, schema, casing, baseName2 = name5) {
51050
51064
  const casingFn = getCasingFn2(casing);
51051
- const rawTable = new SQLiteTable2(name5, schema, baseName);
51065
+ const rawTable = new SQLiteTable2(name5, schema, baseName2);
51052
51066
  const parsedColumns = typeof columns === "function" ? columns(getSQLiteColumnBuilders2()) : columns;
51053
51067
  const builtColumns = Object.fromEntries(Object.entries(parsedColumns).map(([name6, colBuilderBase]) => {
51054
51068
  const colBuilder = colBuilderBase;
@@ -51328,7 +51342,7 @@ var init_select3 = __esm({
51328
51342
  const baseTableName = this.tableName;
51329
51343
  const tableName = getTableLikeName(table);
51330
51344
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
51331
- if (typeof tableName === "string" && this.config.joins?.some((join62) => join62.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
51345
+ if (typeof tableName === "string" && this.config.joins?.some((join63) => join63.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
51332
51346
  if (!this.isPartialSelect) {
51333
51347
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
51334
51348
  if (typeof tableName === "string" && !is2(table, SQL3)) {
@@ -52593,7 +52607,7 @@ var init_dialect = __esm({
52593
52607
  if (!joins2) return;
52594
52608
  const withEntries = Object.entries(joins2).filter(([_2, v2]) => v2);
52595
52609
  if (!withEntries.length) return;
52596
- return sql2.join(withEntries.map(([k2, join62]) => {
52610
+ return sql2.join(withEntries.map(([k2, join63]) => {
52597
52611
  const relation = tableConfig.relations[k2];
52598
52612
  const isSingle2 = is2(relation, One);
52599
52613
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -52604,7 +52618,7 @@ var init_dialect = __esm({
52604
52618
  table: targetTable,
52605
52619
  mode: isSingle2 ? "first" : "many",
52606
52620
  schema,
52607
- queryConfig: join62,
52621
+ queryConfig: join63,
52608
52622
  tableConfig: schema[relation.targetTableName],
52609
52623
  relationWhere: filter,
52610
52624
  isNested: true,
@@ -52618,7 +52632,7 @@ var init_dialect = __esm({
52618
52632
  key: k2,
52619
52633
  selection: innerQuery.selection,
52620
52634
  isArray: !isSingle2,
52621
- isOptional: (relation.optional ?? false) || join62 !== true && !!join62.where
52635
+ isOptional: (relation.optional ?? false) || join63 !== true && !!join63.where
52622
52636
  });
52623
52637
  const jsonColumns = sql2.join(innerQuery.selection.map((s2) => {
52624
52638
  return sql2`${sql2.raw(this.escapeString(s2.key))}, ${s2.selection ? sql2`${jsonb2}(${sql2.identifier(s2.key)})` : sql2.identifier(s2.key)}`;
@@ -53137,7 +53151,7 @@ var init_update = __esm({
53137
53151
  createJoin(joinType) {
53138
53152
  return ((table, on) => {
53139
53153
  const tableName = getTableLikeName(table);
53140
- if (typeof tableName === "string" && this.config.joins.some((join62) => join62.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
53154
+ if (typeof tableName === "string" && this.config.joins.some((join63) => join63.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
53141
53155
  if (typeof on === "function") {
53142
53156
  const from = this.config.from ? is2(table, SQLiteTable2) ? table[Table2.Symbol.Columns] : is2(table, Subquery2) ? table._.selectedFields : is2(table, SQLiteViewBase) ? table[ViewBaseConfig2].selectedFields : void 0 : void 0;
53143
53157
  on = on(new Proxy(this.config.table[Table2.Symbol.Columns], new SelectionProxyHandler({
@@ -56294,7 +56308,7 @@ var init_held_agent = __esm({
56294
56308
  });
56295
56309
  if (!record4) return null;
56296
56310
  handle = new _HeldAgentProcess(holder, record4, offsets);
56297
- for (const run3 of pending2) run3();
56311
+ for (const run4 of pending2) run4();
56298
56312
  return handle;
56299
56313
  }
56300
56314
  get pid() {
@@ -56885,7 +56899,7 @@ var init_skills_install = __esm({
56885
56899
  // ../../packages/host-local/src/browser/chromium.ts
56886
56900
  import { spawn as spawn2 } from "node:child_process";
56887
56901
  import { closeSync as closeSync4, existsSync as existsSync10, openSync as openSync4, readdirSync as readdirSync7 } from "node:fs";
56888
- import { mkdir as mkdir2, readFile as readFile2, rm } from "node:fs/promises";
56902
+ import { mkdir as mkdir2, readFile as readFile2, rm, stat as stat3 } from "node:fs/promises";
56889
56903
  import { homedir as homedir11 } from "node:os";
56890
56904
  import { join as join22 } from "node:path";
56891
56905
  function playwrightCandidates() {
@@ -56935,9 +56949,19 @@ function findChromium() {
56935
56949
  ];
56936
56950
  return candidates.find((c) => existsSync10(c));
56937
56951
  }
56952
+ async function fileSize(path2) {
56953
+ try {
56954
+ return (await stat3(path2)).size;
56955
+ } catch {
56956
+ return 0;
56957
+ }
56958
+ }
56938
56959
  async function readDevToolsPort(profileDir, proc, logPath, timeoutMs) {
56939
56960
  const file3 = join22(profileDir, "DevToolsActivePort");
56940
- const deadline = Date.now() + timeoutMs;
56961
+ const startedAt = Date.now();
56962
+ const hardDeadline = startedAt + timeoutMs * PROGRESS_CAP_FACTOR;
56963
+ let deadline = startedAt + timeoutMs;
56964
+ let lastProgress = "";
56941
56965
  while (Date.now() < deadline) {
56942
56966
  if (proc.exitCode !== null || proc.signalCode !== null) {
56943
56967
  throw new Error("Chromium exited before it opened a DevTools port");
@@ -56950,6 +56974,16 @@ async function readDevToolsPort(profileDir, proc, logPath, timeoutMs) {
56950
56974
  if (port && path2) return { port: Number(port), path: path2.trim() };
56951
56975
  } catch {
56952
56976
  }
56977
+ let entries = 0;
56978
+ try {
56979
+ entries = readdirSync7(profileDir).length;
56980
+ } catch {
56981
+ }
56982
+ const progress = `${entries}:${await fileSize(logPath)}`;
56983
+ if (progress !== lastProgress) {
56984
+ lastProgress = progress;
56985
+ deadline = Math.min(Date.now() + timeoutMs, hardDeadline);
56986
+ }
56953
56987
  await sleep(50);
56954
56988
  }
56955
56989
  throw new StartTimeoutError("Chromium did not open a DevTools port in time");
@@ -57016,13 +57050,14 @@ function wrapSocket(ws) {
57016
57050
  }
57017
57051
  };
57018
57052
  }
57019
- var FIRST_ATTEMPT_TIMEOUT_MS, RETRY_TIMEOUT_FRACTION, START_ATTEMPTS, SINGLETON_FILES, PROCESS_GROUP_GONE_TIMEOUT_MS, CLOSE_GRACE_MS, sleep, StartTimeoutError, MAX_QUEUED_BYTES, ChromiumManager;
57053
+ var FIRST_ATTEMPT_TIMEOUT_MS, RETRY_TIMEOUT_FRACTION, START_ATTEMPTS, PROGRESS_CAP_FACTOR, SINGLETON_FILES, PROCESS_GROUP_GONE_TIMEOUT_MS, CLOSE_GRACE_MS, sleep, StartTimeoutError, MAX_QUEUED_BYTES, ChromiumManager;
57020
57054
  var init_chromium = __esm({
57021
57055
  "../../packages/host-local/src/browser/chromium.ts"() {
57022
57056
  "use strict";
57023
57057
  FIRST_ATTEMPT_TIMEOUT_MS = 2e4;
57024
57058
  RETRY_TIMEOUT_FRACTION = 0.6;
57025
57059
  START_ATTEMPTS = 3;
57060
+ PROGRESS_CAP_FACTOR = 3;
57026
57061
  SINGLETON_FILES = ["SingletonLock", "SingletonCookie", "SingletonSocket"];
57027
57062
  PROCESS_GROUP_GONE_TIMEOUT_MS = 5e3;
57028
57063
  CLOSE_GRACE_MS = 4e3;
@@ -57356,7 +57391,7 @@ parentPort.on("message", ({ id, command, args, options }) => {
57356
57391
 
57357
57392
  // ../../packages/host-local/src/git/git-client.ts
57358
57393
  import { execFile as execFile6 } from "node:child_process";
57359
- import { readFile as readFile3, stat as stat3 } from "node:fs/promises";
57394
+ import { readFile as readFile3, stat as stat4 } from "node:fs/promises";
57360
57395
  import { join as join24 } from "node:path";
57361
57396
  function parseGitRemoteUrl(url3) {
57362
57397
  const sshMatch = url3.match(/^[\w.-]+@([^:]+):([^/]+)\/(.+?)(?:\.git)?$/);
@@ -57387,7 +57422,7 @@ async function resolveDetachedBranch(worktreePath) {
57387
57422
  const dotGit = join24(worktreePath, ".git");
57388
57423
  let gitdir;
57389
57424
  try {
57390
- const st = await stat3(dotGit);
57425
+ const st = await stat4(dotGit);
57391
57426
  if (st.isDirectory()) {
57392
57427
  gitdir = dotGit;
57393
57428
  } else {
@@ -57489,9 +57524,9 @@ async function listWorktrees(repoPath) {
57489
57524
  if (currentPath) await pushCurrent();
57490
57525
  return worktrees2;
57491
57526
  }
57492
- async function getRepoInfo(worktreePath, run3 = execGit) {
57527
+ async function getRepoInfo(worktreePath, run4 = execGit) {
57493
57528
  try {
57494
- const remoteUrl = (await run3(["remote", "get-url", "origin"], worktreePath)).trim();
57529
+ const remoteUrl = (await run4(["remote", "get-url", "origin"], worktreePath)).trim();
57495
57530
  const parsed = parseGitRemoteUrl(remoteUrl);
57496
57531
  if (!parsed) {
57497
57532
  log12.debug('getRepoInfo: failed to parse remote URL "%s" for %s', remoteUrl, worktreePath);
@@ -62407,7 +62442,7 @@ var init_capabilities2 = __esm({
62407
62442
 
62408
62443
  // ../../packages/host-local/src/process/du.ts
62409
62444
  import { execFile as execFile8 } from "node:child_process";
62410
- import { readdir as readdir3, stat as stat4 } from "node:fs/promises";
62445
+ import { readdir as readdir3, stat as stat5 } from "node:fs/promises";
62411
62446
  import { join as join27 } from "node:path";
62412
62447
  async function duBytesNodeWalk(path2) {
62413
62448
  const deadline = Date.now() + DU_TIMEOUT_MS;
@@ -62430,7 +62465,7 @@ async function duBytesNodeWalk(path2) {
62430
62465
  if (Date.now() > deadline) break;
62431
62466
  const sizes = await Promise.all(
62432
62467
  filePaths.slice(i, i + STAT_CHUNK).map(
62433
- (p2) => stat4(p2).then(
62468
+ (p2) => stat5(p2).then(
62434
62469
  (s2) => s2.size,
62435
62470
  () => 0
62436
62471
  // vanished between readdir and stat — count as 0
@@ -62679,7 +62714,7 @@ var init_remote_url = __esm({
62679
62714
  import { execFile as execFile11 } from "node:child_process";
62680
62715
  import { createHash as createHash5, randomBytes as randomBytes4 } from "node:crypto";
62681
62716
  import { existsSync as existsSync11 } from "node:fs";
62682
- import { mkdir as mkdir3, readdir as readdir5, readFile as readFile5, realpath as realpath2, rename as rename2, stat as stat5, writeFile as writeFile2 } from "node:fs/promises";
62717
+ import { mkdir as mkdir3, readdir as readdir5, readFile as readFile5, realpath as realpath2, rename as rename2, stat as stat6, writeFile as writeFile2 } from "node:fs/promises";
62683
62718
  import { homedir as homedir13 } from "node:os";
62684
62719
  import { dirname as dirname9, join as join29, sep as sep3 } from "node:path";
62685
62720
  function defaultReposDir() {
@@ -62714,7 +62749,7 @@ function clone2(url3, dest) {
62714
62749
  }
62715
62750
  async function isDirectory(path2) {
62716
62751
  try {
62717
- return (await stat5(path2)).isDirectory();
62752
+ return (await stat6(path2)).isDirectory();
62718
62753
  } catch {
62719
62754
  return false;
62720
62755
  }
@@ -62825,11 +62860,11 @@ var init_host_repos = __esm({
62825
62860
  }
62826
62861
  const running = this.ensuring.get(id.key);
62827
62862
  if (running) return running;
62828
- const run3 = this.doEnsure(id.key, id.url, id.owner, id.name).finally(
62863
+ const run4 = this.doEnsure(id.key, id.url, id.owner, id.name).finally(
62829
62864
  () => this.ensuring.delete(id.key)
62830
62865
  );
62831
- this.ensuring.set(id.key, run3);
62832
- return run3;
62866
+ this.ensuring.set(id.key, run4);
62867
+ return run4;
62833
62868
  }
62834
62869
  async doEnsure(key2, url3, owner, name5) {
62835
62870
  const mappings = await this.load();
@@ -62859,8 +62894,462 @@ var init_host_repos = __esm({
62859
62894
  }
62860
62895
  });
62861
62896
 
62897
+ // ../../packages/host-local/src/resources/classify.ts
62898
+ function baseName(command2) {
62899
+ const first = command2.trim().split(/\s+/)[0] ?? "";
62900
+ const name5 = first.split("/").pop() ?? first;
62901
+ return name5.replace(/^-/, "");
62902
+ }
62903
+ function hasRunDir(command2, runDir) {
62904
+ const tokens2 = command2.split(/\s+/);
62905
+ const at = tokens2.indexOf("--run-dir");
62906
+ return at >= 0 && tokens2[at + 1] === runDir;
62907
+ }
62908
+ function classify(rows, opts) {
62909
+ const children = /* @__PURE__ */ new Map();
62910
+ const byPid = /* @__PURE__ */ new Map();
62911
+ for (const row of rows) {
62912
+ byPid.set(row.pid, row);
62913
+ const list = children.get(row.ppid) ?? [];
62914
+ list.push(row.pid);
62915
+ children.set(row.ppid, list);
62916
+ }
62917
+ const roots = [];
62918
+ const seen = /* @__PURE__ */ new Set();
62919
+ const add = (pid, kind, name5, subtree) => {
62920
+ if (seen.has(pid)) return;
62921
+ seen.add(pid);
62922
+ roots.push({ pid, kind, name: name5, subtree });
62923
+ };
62924
+ if (byPid.has(opts.selfPid))
62925
+ add(opts.selfPid, opts.selfKind, opts.selfKind === "hub" ? "Hub server" : "band-worker", false);
62926
+ for (const row of rows) {
62927
+ if (/terminal-daemon/.test(row.command) && hasRunDir(row.command, opts.runDir)) {
62928
+ add(row.pid, "terminal-daemon", "terminal daemon", false);
62929
+ for (const child of children.get(row.pid) ?? []) {
62930
+ const c = byPid.get(child);
62931
+ if (c) add(child, "terminal", baseName(c.command), true);
62932
+ }
62933
+ } else if (/agent-daemon/.test(row.command) && hasRunDir(row.command, `${opts.runDir}/agents`)) {
62934
+ add(row.pid, "agent-daemon", "agent daemon", false);
62935
+ for (const child of children.get(row.pid) ?? []) {
62936
+ const c = byPid.get(child);
62937
+ if (c) add(child, "agent", agentName(c.command), true);
62938
+ }
62939
+ }
62940
+ }
62941
+ for (const child of children.get(opts.selfPid) ?? []) {
62942
+ const c = byPid.get(child);
62943
+ if (!c || seen.has(child)) continue;
62944
+ const name5 = baseName(c.command);
62945
+ if (SHELLS.has(name5)) add(child, "terminal", name5, true);
62946
+ else if (LSP_NAMES.test(c.command)) add(child, "lsp", lspName(c.command), true);
62947
+ else if (BROWSER.test(c.command)) add(child, "browser", "Chromium", true);
62948
+ else if (SIMULATOR.test(c.command)) add(child, "simulator", "Simulator", true);
62949
+ else if (AGENT_NAMES.test(c.command)) add(child, "agent", agentName(c.command), true);
62950
+ else if (/mcp/i.test(c.command)) add(child, "mcp", name5, true);
62951
+ else if (name5 !== "ps" && name5 !== "lsof" && name5 !== "du" && name5 !== "df")
62952
+ add(child, "other", name5, true);
62953
+ }
62954
+ const subtreeRoots = new Set(roots.filter((r) => r.subtree).map((r) => r.pid));
62955
+ for (const row of rows) {
62956
+ if (seen.has(row.pid)) continue;
62957
+ if (hasAncestorIn(row.pid, subtreeRoots, byPid)) continue;
62958
+ if (LSP_NAMES.test(row.command) && isUnder(row.pid, opts.selfPid, byPid)) {
62959
+ add(row.pid, "lsp", lspName(row.command), true);
62960
+ } else if (BROWSER.test(row.command) && isUnder(row.pid, opts.selfPid, byPid)) {
62961
+ add(row.pid, "browser", "Chromium", true);
62962
+ }
62963
+ }
62964
+ return { roots, children };
62965
+ }
62966
+ function hasAncestorIn(pid, set2, byPid) {
62967
+ let cur = byPid.get(pid)?.ppid;
62968
+ for (let i = 0; cur !== void 0 && i < 64; i++) {
62969
+ if (set2.has(cur)) return true;
62970
+ cur = byPid.get(cur)?.ppid;
62971
+ }
62972
+ return false;
62973
+ }
62974
+ function isUnder(pid, ancestor, byPid) {
62975
+ let cur = byPid.get(pid)?.ppid;
62976
+ for (let i = 0; cur !== void 0 && i < 64; i++) {
62977
+ if (cur === ancestor) return true;
62978
+ cur = byPid.get(cur)?.ppid;
62979
+ }
62980
+ return false;
62981
+ }
62982
+ function lspName(command2) {
62983
+ return LSP_NAMES.exec(command2)?.[1] ?? "language server";
62984
+ }
62985
+ function agentName(command2) {
62986
+ if (/claude/i.test(command2)) return "Claude Code";
62987
+ if (/codex/i.test(command2)) return "Codex";
62988
+ if (/gemini/i.test(command2)) return "Gemini";
62989
+ if (/opencode/i.test(command2)) return "OpenCode";
62990
+ if (/cursor/i.test(command2)) return "Cursor";
62991
+ return baseName(command2);
62992
+ }
62993
+ function subtreeOf(root, children) {
62994
+ const out = [];
62995
+ const stack = [root];
62996
+ while (stack.length > 0 && out.length < 5e3) {
62997
+ const pid = stack.pop();
62998
+ out.push(pid);
62999
+ for (const c of children.get(pid) ?? []) stack.push(c);
63000
+ }
63001
+ return out;
63002
+ }
63003
+ function sumRoots(classified, first, second, windowMs) {
63004
+ const out = [];
63005
+ for (const root of classified.roots) {
63006
+ const pids = root.subtree ? subtreeOf(root.pid, classified.children) : [root.pid];
63007
+ let rss = 0;
63008
+ let cpuMs = 0;
63009
+ let count3 = 0;
63010
+ for (const pid of pids) {
63011
+ const b2 = second.get(pid);
63012
+ if (!b2) continue;
63013
+ count3++;
63014
+ rss += b2.rssBytes;
63015
+ const a = first.get(pid);
63016
+ cpuMs += Math.max(0, a ? b2.cpuMs - a.cpuMs : b2.cpuMs);
63017
+ }
63018
+ const self = second.get(root.pid);
63019
+ if (!self) continue;
63020
+ out.push({
63021
+ pid: root.pid,
63022
+ kind: root.kind,
63023
+ name: root.name,
63024
+ command: self.command.slice(0, 200),
63025
+ rssBytes: rss,
63026
+ cpuPercent: windowMs > 0 ? Math.round(cpuMs / windowMs * 1e3) / 10 : 0,
63027
+ processCount: count3
63028
+ });
63029
+ }
63030
+ return out;
63031
+ }
63032
+ var SHELLS, LSP_NAMES, AGENT_NAMES, BROWSER, SIMULATOR;
63033
+ var init_classify = __esm({
63034
+ "../../packages/host-local/src/resources/classify.ts"() {
63035
+ "use strict";
63036
+ SHELLS = /* @__PURE__ */ new Set(["sh", "bash", "zsh", "fish", "dash", "ksh", "tcsh", "csh", "nu", "pwsh"]);
63037
+ LSP_NAMES = /(typescript-language-server|tsserver|rust-analyzer|gopls|pyright|basedpyright|jdtls|clangd|lua-language-server|vscode-[a-z]+-language-server|yaml-language-server)/;
63038
+ AGENT_NAMES = /(claude-agent-acp|claude-code-acp|codex-acp|gemini|opencode|cursor-agent|-acp\b)/;
63039
+ BROWSER = /(chrom(e|ium)|headless_shell).*--remote-debugging-port/i;
63040
+ SIMULATOR = /(serve-sim|simctl|Simulator\.app|CoreSimulator)/;
63041
+ }
63042
+ });
63043
+
63044
+ // ../../packages/host-local/src/resources/process-table.ts
63045
+ import { execFile as execFile12 } from "node:child_process";
63046
+ import { readdir as readdir6, readFile as readFile6 } from "node:fs/promises";
63047
+ function run3(bin, args) {
63048
+ return new Promise((resolve16) => {
63049
+ execFile12(
63050
+ bin,
63051
+ args,
63052
+ { timeout: PS_TIMEOUT_MS, maxBuffer: PS_MAX_BUFFER },
63053
+ (_err, out) => resolve16(out ?? "")
63054
+ );
63055
+ });
63056
+ }
63057
+ function parsePsTime(text4) {
63058
+ const m2 = /^(?:(\d+)-)?(?:(\d+):)?(\d+):(\d+(?:\.\d+)?)$/.exec(text4.trim());
63059
+ if (!m2) return 0;
63060
+ const days = Number(m2[1] ?? 0);
63061
+ const hours = Number(m2[2] ?? 0);
63062
+ const minutes = Number(m2[3]);
63063
+ const seconds = Number(m2[4]);
63064
+ return Math.round((((days * 24 + hours) * 60 + minutes) * 60 + seconds) * 1e3);
63065
+ }
63066
+ function parsePs(output2) {
63067
+ const rows = [];
63068
+ for (const line2 of output2.split("\n")) {
63069
+ const m2 = /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(.*)$/.exec(line2);
63070
+ if (!m2) continue;
63071
+ rows.push({
63072
+ pid: Number(m2[1]),
63073
+ ppid: Number(m2[2]),
63074
+ rssBytes: Number(m2[3]) * 1024,
63075
+ cpuMs: parsePsTime(m2[4]),
63076
+ command: m2[5].trim()
63077
+ });
63078
+ }
63079
+ return rows;
63080
+ }
63081
+ function parseProcStat(stat9) {
63082
+ const close = stat9.lastIndexOf(")");
63083
+ if (close < 0) return null;
63084
+ const fields = stat9.slice(close + 2).trim().split(/\s+/);
63085
+ const ppid = Number(fields[1]);
63086
+ const utime = Number(fields[11]);
63087
+ const stime = Number(fields[12]);
63088
+ const rss = Number(fields[21]);
63089
+ if (![ppid, utime, stime, rss].every(Number.isFinite)) return null;
63090
+ return { ppid, cpuMs: (utime + stime) * 1e3 / CLK_TCK, rssPages: rss };
63091
+ }
63092
+ async function readLinux() {
63093
+ let names;
63094
+ try {
63095
+ names = await readdir6("/proc");
63096
+ } catch {
63097
+ return [];
63098
+ }
63099
+ const rows = await Promise.all(
63100
+ names.filter((n) => /^\d+$/.test(n)).map(async (n) => {
63101
+ try {
63102
+ const [stat9, cmd] = await Promise.all([
63103
+ readFile6(`/proc/${n}/stat`, "utf8"),
63104
+ readFile6(`/proc/${n}/cmdline`, "utf8").catch(() => "")
63105
+ ]);
63106
+ const parsed = parseProcStat(stat9);
63107
+ if (!parsed) return null;
63108
+ const comm = /\((.*)\)/s.exec(stat9)?.[1] ?? "";
63109
+ return {
63110
+ pid: Number(n),
63111
+ ppid: parsed.ppid,
63112
+ rssBytes: parsed.rssPages * PAGE_SIZE,
63113
+ cpuMs: parsed.cpuMs,
63114
+ command: cmd.replace(/\0/g, " ").trim() || comm
63115
+ };
63116
+ } catch {
63117
+ return null;
63118
+ }
63119
+ })
63120
+ );
63121
+ return rows.filter((r) => r !== null);
63122
+ }
63123
+ async function readProcessTable() {
63124
+ if (process.platform === "linux") {
63125
+ const rows = await readLinux();
63126
+ if (rows.length > 0) return rows;
63127
+ }
63128
+ if (process.platform === "win32") return [];
63129
+ return parsePs(await run3("ps", ["-axww", "-o", "pid=,ppid=,rss=,time=,command="]));
63130
+ }
63131
+ async function readProcessEnv(pid, names) {
63132
+ const out = {};
63133
+ let text4 = "";
63134
+ if (process.platform === "linux") {
63135
+ text4 = (await readFile6(`/proc/${pid}/environ`, "utf8").catch(() => "")).replace(/\0/g, " ");
63136
+ } else if (process.platform === "darwin") {
63137
+ text4 = await run3("ps", ["-E", "-ww", "-o", "command=", "-p", String(pid)]);
63138
+ }
63139
+ for (const name5 of names) {
63140
+ const m2 = new RegExp(`(?:^|\\s)${name5}=(\\S+)`).exec(text4);
63141
+ if (m2) out[name5] = m2[1];
63142
+ }
63143
+ return out;
63144
+ }
63145
+ async function readProcessCwds(pids) {
63146
+ const out = /* @__PURE__ */ new Map();
63147
+ if (pids.length === 0) return out;
63148
+ if (process.platform === "linux") {
63149
+ const { readlink } = await import("node:fs/promises");
63150
+ await Promise.all(
63151
+ pids.map(async (pid) => {
63152
+ try {
63153
+ out.set(pid, await readlink(`/proc/${pid}/cwd`));
63154
+ } catch {
63155
+ }
63156
+ })
63157
+ );
63158
+ return out;
63159
+ }
63160
+ if (process.platform === "darwin") {
63161
+ const text4 = await run3("lsof", ["-a", "-d", "cwd", "-Fpn", "-p", pids.join(",")]);
63162
+ let current3 = 0;
63163
+ for (const line2 of text4.split("\n")) {
63164
+ if (line2.startsWith("p")) current3 = Number(line2.slice(1));
63165
+ else if (line2.startsWith("n") && current3) out.set(current3, line2.slice(1));
63166
+ }
63167
+ }
63168
+ return out;
63169
+ }
63170
+ var PS_TIMEOUT_MS, PS_MAX_BUFFER, CLK_TCK, PAGE_SIZE;
63171
+ var init_process_table = __esm({
63172
+ "../../packages/host-local/src/resources/process-table.ts"() {
63173
+ "use strict";
63174
+ PS_TIMEOUT_MS = 5e3;
63175
+ PS_MAX_BUFFER = 64 * 1024 * 1024;
63176
+ CLK_TCK = 100;
63177
+ PAGE_SIZE = 4096;
63178
+ }
63179
+ });
63180
+
63181
+ // ../../packages/host-local/src/resources/resources.ts
63182
+ import { execFile as execFile13 } from "node:child_process";
63183
+ import { readdir as readdir7, readFile as readFile7 } from "node:fs/promises";
63184
+ import { cpus, freemem, hostname as hostname4, loadavg, totalmem } from "node:os";
63185
+ import { join as join30 } from "node:path";
63186
+ function execOut(bin, args) {
63187
+ return new Promise((resolve16) => {
63188
+ execFile13(bin, args, { timeout: 5e3 }, (_e, out) => resolve16(out ?? ""));
63189
+ });
63190
+ }
63191
+ async function memoryUsedBytes(total) {
63192
+ if (process.platform === "linux") {
63193
+ const meminfo = await readFile7("/proc/meminfo", "utf8").catch(() => "");
63194
+ const m2 = /MemAvailable:\s+(\d+) kB/.exec(meminfo);
63195
+ if (m2) return Math.max(0, total - Number(m2[1]) * 1024);
63196
+ }
63197
+ if (process.platform === "darwin") {
63198
+ const out = await execOut("vm_stat", []);
63199
+ const page = Number(/page size of (\d+) bytes/.exec(out)?.[1] ?? 16384);
63200
+ const pages = (label2) => Number(new RegExp(`${label2}:\\s+(\\d+)`).exec(out)?.[1] ?? 0);
63201
+ const reclaimable = pages("Pages free") + pages("Pages inactive") + pages("Pages speculative");
63202
+ if (reclaimable > 0) return Math.max(0, total - reclaimable * page);
63203
+ }
63204
+ return Math.max(0, total - freemem());
63205
+ }
63206
+ function cpuTimes() {
63207
+ let busy = 0;
63208
+ let total = 0;
63209
+ for (const c of cpus()) {
63210
+ const t2 = c.times;
63211
+ total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
63212
+ busy += t2.user + t2.nice + t2.sys + t2.irq;
63213
+ }
63214
+ return { busy, total };
63215
+ }
63216
+ async function diskOf(path2) {
63217
+ const out = await execOut("df", ["-k", path2]);
63218
+ const line2 = out.trim().split("\n").pop();
63219
+ const f2 = line2?.trim().split(/\s+/);
63220
+ if (!f2 || f2.length < 4) return null;
63221
+ const total = Number(f2[1]);
63222
+ const free = Number(f2[3]);
63223
+ if (!Number.isFinite(total) || !Number.isFinite(free)) return null;
63224
+ return { path: path2, totalBytes: total * 1024, freeBytes: free * 1024 };
63225
+ }
63226
+ async function limited(items, limit, fn) {
63227
+ const results = new Array(items.length);
63228
+ let next = 0;
63229
+ await Promise.all(
63230
+ Array.from({ length: Math.min(limit, items.length) }, async () => {
63231
+ while (next < items.length) {
63232
+ const i = next++;
63233
+ results[i] = await fn(items[i]);
63234
+ }
63235
+ })
63236
+ );
63237
+ return results;
63238
+ }
63239
+ var SAMPLE_WINDOW_MS, CACHE_MS, DU_CONCURRENCY, ENV_NAMES, LocalResources;
63240
+ var init_resources2 = __esm({
63241
+ "../../packages/host-local/src/resources/resources.ts"() {
63242
+ "use strict";
63243
+ init_du();
63244
+ init_classify();
63245
+ init_process_table();
63246
+ SAMPLE_WINDOW_MS = 500;
63247
+ CACHE_MS = 3e3;
63248
+ DU_CONCURRENCY = 3;
63249
+ ENV_NAMES = ["BAND_WORKTREE_ID", "BAND_CHAT_ID", "BAND_TERMINAL_ID"];
63250
+ LocalResources = class {
63251
+ constructor(options) {
63252
+ this.options = options;
63253
+ }
63254
+ cached = null;
63255
+ snapshot() {
63256
+ const now = Date.now();
63257
+ if (this.cached && now - this.cached.at < CACHE_MS) return this.cached.value;
63258
+ const value = this.sample();
63259
+ this.cached = { at: now, value };
63260
+ value.catch(() => {
63261
+ if (this.cached?.value === value) this.cached = null;
63262
+ });
63263
+ return value;
63264
+ }
63265
+ async sample() {
63266
+ const stateDir = this.options.stateDir();
63267
+ const cpu1 = cpuTimes();
63268
+ const started = Date.now();
63269
+ const firstRows = await readProcessTable();
63270
+ await new Promise((r) => setTimeout(r, SAMPLE_WINDOW_MS));
63271
+ const secondRows = await readProcessTable();
63272
+ const windowMs = Date.now() - started;
63273
+ const cpu2 = cpuTimes();
63274
+ const first = new Map(firstRows.map((r) => [r.pid, r]));
63275
+ const second = new Map(secondRows.map((r) => [r.pid, r]));
63276
+ const classified = classify(secondRows, {
63277
+ selfPid: process.pid,
63278
+ selfKind: this.options.selfKind,
63279
+ runDir: join30(stateDir, "run")
63280
+ });
63281
+ const processes = sumRoots(classified, first, second, windowMs);
63282
+ await this.attachIds(processes);
63283
+ const total = totalmem();
63284
+ const totalDelta = cpu2.total - cpu1.total;
63285
+ return {
63286
+ hostname: hostname4(),
63287
+ os: process.platform,
63288
+ cores: cpus().length,
63289
+ memTotalBytes: total,
63290
+ memUsedBytes: await memoryUsedBytes(total),
63291
+ machineCpuPercent: totalDelta > 0 ? Math.round((cpu2.busy - cpu1.busy) / totalDelta * 1e3) / 10 : null,
63292
+ loadAverage: loadavg()[0],
63293
+ windowMs,
63294
+ takenAt: Date.now(),
63295
+ processes
63296
+ };
63297
+ }
63298
+ /** Reads the ids a terminal or agent was started with, and its folder. */
63299
+ async attachIds(processes) {
63300
+ const wanted = processes.filter(
63301
+ (p2) => p2.kind === "terminal" || p2.kind === "agent" || p2.kind === "lsp" || p2.kind === "browser"
63302
+ );
63303
+ const cwds = await readProcessCwds(wanted.map((p2) => p2.pid));
63304
+ await limited(wanted, 6, async (p2) => {
63305
+ const cwd = cwds.get(p2.pid);
63306
+ if (cwd) p2.cwd = cwd;
63307
+ if (p2.kind !== "terminal" && p2.kind !== "agent") return;
63308
+ const env = await readProcessEnv(p2.pid, ENV_NAMES);
63309
+ if (env.BAND_WORKTREE_ID) p2.worktreeId = env.BAND_WORKTREE_ID;
63310
+ if (env.BAND_CHAT_ID) p2.chatId = env.BAND_CHAT_ID;
63311
+ if (env.BAND_TERMINAL_ID) p2.terminalId = env.BAND_TERMINAL_ID;
63312
+ });
63313
+ }
63314
+ /** Calls with the same worktrees share one run, so a repeated refresh does not stack `du` passes. */
63315
+ storageRuns = /* @__PURE__ */ new Map();
63316
+ storage(request) {
63317
+ const key2 = JSON.stringify(request.worktrees);
63318
+ const running = this.storageRuns.get(key2);
63319
+ if (running) return running;
63320
+ const run4 = this.measureStorage(request);
63321
+ this.storageRuns.set(key2, run4);
63322
+ const done = () => this.storageRuns.delete(key2);
63323
+ run4.then(done, done);
63324
+ return run4;
63325
+ }
63326
+ async measureStorage(request) {
63327
+ const stateDir = this.options.stateDir();
63328
+ const worktrees2 = await limited(request.worktrees, DU_CONCURRENCY, async (wt) => {
63329
+ try {
63330
+ return { id: wt.id, sizeBytes: await duBytes(wt.path) };
63331
+ } catch (err) {
63332
+ return {
63333
+ id: wt.id,
63334
+ sizeBytes: 0,
63335
+ error: err instanceof Error ? err.message : String(err)
63336
+ };
63337
+ }
63338
+ });
63339
+ const names = await readdir7(stateDir).catch(() => []);
63340
+ const state2 = await limited(names, DU_CONCURRENCY, async (name5) => ({
63341
+ name: name5,
63342
+ sizeBytes: await duBytes(join30(stateDir, name5)).catch(() => 0)
63343
+ }));
63344
+ state2.sort((a, b2) => b2.sizeBytes - a.sizeBytes);
63345
+ return { worktrees: worktrees2, state: state2, disk: await diskOf(stateDir) };
63346
+ }
63347
+ };
63348
+ }
63349
+ });
63350
+
62862
63351
  // ../../packages/host-local/src/search/ripgrep-client.ts
62863
- import { execFile as execFile12, spawn as spawn4 } from "node:child_process";
63352
+ import { execFile as execFile14, spawn as spawn4 } from "node:child_process";
62864
63353
  import { rgPath } from "@vscode/ripgrep";
62865
63354
  function streamMatches(options) {
62866
63355
  return {
@@ -62981,7 +63470,7 @@ function listFiles(cwd) {
62981
63470
  "!**/.DS_Store"
62982
63471
  ];
62983
63472
  return new Promise((resolve16, reject) => {
62984
- execFile12(
63473
+ execFile14(
62985
63474
  rgPath,
62986
63475
  args,
62987
63476
  { cwd, maxBuffer: LIST_FILES_MAX_BUFFER, encoding: "utf-8" },
@@ -63005,10 +63494,10 @@ var init_ripgrep_client = __esm({
63005
63494
  });
63006
63495
 
63007
63496
  // ../../packages/host-local/src/setup/repo-config.ts
63008
- import { join as join30 } from "node:path";
63497
+ import { join as join31 } from "node:path";
63009
63498
  async function loadRepoConfig(host, worktreePath, repoPath) {
63010
63499
  for (const base of [worktreePath, repoPath]) {
63011
- const text4 = await readConfig(host, join30(base, ".band", "config.json"));
63500
+ const text4 = await readConfig(host, join31(base, ".band", "config.json"));
63012
63501
  if (text4 === null) continue;
63013
63502
  try {
63014
63503
  return JSON.parse(text4);
@@ -63019,10 +63508,10 @@ async function loadRepoConfig(host, worktreePath, repoPath) {
63019
63508
  }
63020
63509
  async function loadEnvironment(host, worktreePath, repoPath) {
63021
63510
  for (const base of [worktreePath, repoPath]) {
63022
- const file3 = join30(base, ENVIRONMENT_FILE);
63511
+ const file3 = join31(base, ENVIRONMENT_FILE);
63023
63512
  const text4 = await readConfig(host, file3);
63024
63513
  if (text4 === null) continue;
63025
- const exists4 = (relative2) => host.fs.stat(join30(base, relative2)).then(
63514
+ const exists4 = (relative2) => host.fs.stat(join31(base, relative2)).then(
63026
63515
  () => true,
63027
63516
  () => false
63028
63517
  );
@@ -63053,7 +63542,7 @@ async function readConfig(host, configPath) {
63053
63542
  }
63054
63543
  }
63055
63544
  async function getCopyFiles(host, repoPath) {
63056
- const configPath = join30(repoPath, ".band", "config.json");
63545
+ const configPath = join31(repoPath, ".band", "config.json");
63057
63546
  const text4 = await readConfig(host, configPath);
63058
63547
  if (text4 === null) return null;
63059
63548
  let raw;
@@ -63088,14 +63577,14 @@ var init_repo_config = __esm({
63088
63577
  });
63089
63578
 
63090
63579
  // ../../packages/host-local/src/setup/script-run.ts
63091
- import { join as join31 } from "node:path";
63580
+ import { join as join32 } from "node:path";
63092
63581
  function quote(value) {
63093
63582
  return `'${value.replace(/'/g, `'\\''`)}'`;
63094
63583
  }
63095
63584
  async function prepareScriptRun(host, script, label2) {
63096
63585
  const dir = await host.fs.mkdtemp("band-script-");
63097
- const scriptFile = join31(dir, `${label2}.sh`);
63098
- const exitFile = join31(dir, "exit-code");
63586
+ const scriptFile = join32(dir, `${label2}.sh`);
63587
+ const exitFile = join32(dir, "exit-code");
63099
63588
  const partialFile = `${exitFile}.partial`;
63100
63589
  const onExit = [
63101
63590
  "rc=$?",
@@ -63164,7 +63653,7 @@ var init_script_run = __esm({
63164
63653
  });
63165
63654
 
63166
63655
  // ../../packages/host-local/src/setup/worktree-files.ts
63167
- import { dirname as dirname10, isAbsolute, join as join32, relative, resolve as resolve6, sep as sep4 } from "node:path";
63656
+ import { dirname as dirname10, isAbsolute, join as join33, relative, resolve as resolve6, sep as sep4 } from "node:path";
63168
63657
  async function copyWorktreeFiles(host, repoPath, worktreePath) {
63169
63658
  const byAbs = /* @__PURE__ */ new Map();
63170
63659
  const missingFromConfig = [];
@@ -63192,7 +63681,7 @@ async function copyWorktreeFiles(host, repoPath, worktreePath) {
63192
63681
  }
63193
63682
  for (const [absSource, source] of byAbs) {
63194
63683
  const rel = relative(repoPath, absSource);
63195
- const dest = join32(worktreePath, rel);
63684
+ const dest = join33(worktreePath, rel);
63196
63685
  if (rel.startsWith("..") || isAbsolute(rel)) {
63197
63686
  log16.warn({ source, entry: absSource }, "refusing to copy file outside repo root \u2014 skipping");
63198
63687
  continue;
@@ -63281,7 +63770,7 @@ async function resolveFromConfig(host, repoPath, missing) {
63281
63770
  return out;
63282
63771
  }
63283
63772
  async function resolveFromWorktreeInclude(host, repoPath) {
63284
- const includePath = join32(repoPath, ".worktreeinclude");
63773
+ const includePath = join33(repoPath, ".worktreeinclude");
63285
63774
  let includeContent;
63286
63775
  try {
63287
63776
  includeContent = new TextDecoder().decode(await host.fs.readFile(includePath));
@@ -63399,11 +63888,11 @@ var init_common4 = __esm({
63399
63888
  });
63400
63889
 
63401
63890
  // ../../packages/host-local/src/usage/claude-usage.ts
63402
- import { execFile as execFile13 } from "node:child_process";
63891
+ import { execFile as execFile15 } from "node:child_process";
63403
63892
  import { createHash as createHash6 } from "node:crypto";
63404
- import { readFile as readFile6 } from "node:fs/promises";
63893
+ import { readFile as readFile8 } from "node:fs/promises";
63405
63894
  import { homedir as homedir14, userInfo } from "node:os";
63406
- import { join as join33 } from "node:path";
63895
+ import { join as join34 } from "node:path";
63407
63896
  function windowOf(label2, raw) {
63408
63897
  if (!raw || typeof raw !== "object") return null;
63409
63898
  const percent = percentOf(raw.utilization ?? raw.used_percentage);
@@ -63423,7 +63912,7 @@ function mapClaudeUsage(data) {
63423
63912
  );
63424
63913
  }
63425
63914
  function claudeConfigDir3() {
63426
- return process.env.CLAUDE_CONFIG_DIR || join33(homedir14(), ".claude");
63915
+ return process.env.CLAUDE_CONFIG_DIR || join34(homedir14(), ".claude");
63427
63916
  }
63428
63917
  function parseCredentials(raw) {
63429
63918
  try {
@@ -63438,7 +63927,7 @@ function parseCredentials(raw) {
63438
63927
  }
63439
63928
  function keychainPassword(service) {
63440
63929
  return new Promise((resolve16) => {
63441
- execFile13(
63930
+ execFile15(
63442
63931
  "security",
63443
63932
  ["find-generic-password", "-s", service, "-a", userInfo().username, "-w"],
63444
63933
  { timeout: KEYCHAIN_TIMEOUT_MS },
@@ -63449,7 +63938,7 @@ function keychainPassword(service) {
63449
63938
  async function readLogin() {
63450
63939
  const dir = claudeConfigDir3();
63451
63940
  try {
63452
- const fromFile = parseCredentials(await readFile6(join33(dir, ".credentials.json"), "utf8"));
63941
+ const fromFile = parseCredentials(await readFile8(join34(dir, ".credentials.json"), "utf8"));
63453
63942
  if (fromFile) return fromFile;
63454
63943
  } catch {
63455
63944
  }
@@ -63459,9 +63948,9 @@ async function readLogin() {
63459
63948
  return raw ? parseCredentials(raw) : null;
63460
63949
  }
63461
63950
  async function readIdentity() {
63462
- const file3 = process.env.CLAUDE_CONFIG_DIR ? join33(process.env.CLAUDE_CONFIG_DIR, ".claude.json") : join33(homedir14(), ".claude.json");
63951
+ const file3 = process.env.CLAUDE_CONFIG_DIR ? join34(process.env.CLAUDE_CONFIG_DIR, ".claude.json") : join34(homedir14(), ".claude.json");
63463
63952
  try {
63464
- const account = JSON.parse(await readFile6(file3, "utf8")).oauthAccount;
63953
+ const account = JSON.parse(await readFile8(file3, "utf8")).oauthAccount;
63465
63954
  const email4 = account?.emailAddress;
63466
63955
  if (typeof email4 === "string" && email4) return email4;
63467
63956
  const id = account?.accountUuid;
@@ -63502,9 +63991,9 @@ var init_claude_usage = __esm({
63502
63991
  });
63503
63992
 
63504
63993
  // ../../packages/host-local/src/usage/codex-usage.ts
63505
- import { readFile as readFile7 } from "node:fs/promises";
63994
+ import { readFile as readFile9 } from "node:fs/promises";
63506
63995
  import { homedir as homedir15 } from "node:os";
63507
- import { join as join34 } from "node:path";
63996
+ import { join as join35 } from "node:path";
63508
63997
  function labelFor(raw, fallback) {
63509
63998
  const seconds = raw.limit_window_seconds;
63510
63999
  if (typeof seconds === "number" && Number.isFinite(seconds) && seconds > 0) {
@@ -63538,9 +64027,9 @@ function emailOfIdToken(idToken) {
63538
64027
  }
63539
64028
  }
63540
64029
  async function readLogin2() {
63541
- const home = process.env.CODEX_HOME || join34(homedir15(), ".codex");
64030
+ const home = process.env.CODEX_HOME || join35(homedir15(), ".codex");
63542
64031
  try {
63543
- const auth2 = JSON.parse(await readFile7(join34(home, "auth.json"), "utf8"));
64032
+ const auth2 = JSON.parse(await readFile9(join35(home, "auth.json"), "utf8"));
63544
64033
  const token = auth2.tokens?.access_token;
63545
64034
  if (typeof token !== "string" || token === "") return null;
63546
64035
  const accountId = auth2.tokens?.account_id;
@@ -63645,7 +64134,7 @@ var init_account_usage = __esm({
63645
64134
  });
63646
64135
 
63647
64136
  // ../../packages/host-local/src/local-host.ts
63648
- import { execFile as execFile14, spawn as spawn5 } from "node:child_process";
64137
+ import { execFile as execFile16, spawn as spawn5 } from "node:child_process";
63649
64138
  import { createReadStream as createReadStream3, watch as fsWatch } from "node:fs";
63650
64139
  import {
63651
64140
  cp,
@@ -63653,16 +64142,16 @@ import {
63653
64142
  lstat,
63654
64143
  mkdir as mkdir4,
63655
64144
  mkdtemp,
63656
- readdir as readdir6,
63657
- readFile as readFile8,
64145
+ readdir as readdir8,
64146
+ readFile as readFile10,
63658
64147
  realpath as realpath3,
63659
64148
  rename as rename3,
63660
64149
  rm as rm2,
63661
- stat as stat6,
64150
+ stat as stat7,
63662
64151
  writeFile as writeFile3
63663
64152
  } from "node:fs/promises";
63664
- import { homedir as homedir16, hostname as hostname4, tmpdir as tmpdir2 } from "node:os";
63665
- import { join as join35 } from "node:path";
64153
+ import { homedir as homedir16, hostname as hostname5, tmpdir as tmpdir2 } from "node:os";
64154
+ import { join as join36 } from "node:path";
63666
64155
  async function createWorktree(spec) {
63667
64156
  const refs = await execGit(
63668
64157
  ["for-each-ref", "--format=%(refname)", "refs/heads", "refs/remotes/origin"],
@@ -63815,6 +64304,7 @@ var init_local_host = __esm({
63815
64304
  init_power();
63816
64305
  init_tools();
63817
64306
  init_host_repos();
64307
+ init_resources2();
63818
64308
  init_ripgrep_client();
63819
64309
  init_repo_config();
63820
64310
  init_script_run();
@@ -63829,11 +64319,15 @@ var init_local_host = __esm({
63829
64319
  LocalHost = class {
63830
64320
  constructor(options) {
63831
64321
  this.options = options;
63832
- const bandHome2 = () => process.env.BAND_HOME ?? join35(homedir16(), ".band");
64322
+ const bandHome2 = () => process.env.BAND_HOME ?? join36(homedir16(), ".band");
63833
64323
  this.repos = new LocalRepos({
63834
- mappingsFile: options.repos?.mappingsFile ?? (() => join35(bandHome2(), "repo-mappings.json")),
64324
+ mappingsFile: options.repos?.mappingsFile ?? (() => join36(bandHome2(), "repo-mappings.json")),
63835
64325
  reposDir: options.repos?.reposDir ?? defaultReposDir
63836
64326
  });
64327
+ this.resources = new LocalResources({
64328
+ selfKind: options.resources?.selfKind ?? "worker",
64329
+ stateDir: options.resources?.stateDir ?? bandHome2
64330
+ });
63837
64331
  void this.toolVersions();
63838
64332
  }
63839
64333
  id = LOCAL_HOST_ID;
@@ -63870,7 +64364,7 @@ var init_local_host = __esm({
63870
64364
  openStdio: (spec) => openMcpStdio(spec)
63871
64365
  };
63872
64366
  chromium = new ChromiumManager(
63873
- () => join35(process.env.BAND_HOME ?? join35(homedir16(), ".band"), "browser-profiles")
64367
+ () => join36(process.env.BAND_HOME ?? join36(homedir16(), ".band"), "browser-profiles")
63874
64368
  );
63875
64369
  browser = {
63876
64370
  open: (spec) => this.chromium.open(spec),
@@ -63879,6 +64373,7 @@ var init_local_host = __esm({
63879
64373
  };
63880
64374
  desktop = { open: () => openDesktop() };
63881
64375
  speech = { transcribe: (req) => transcribeLocally(req) };
64376
+ resources;
63882
64377
  scripts = {
63883
64378
  command: (worktree) => scriptCommand(this, worktree),
63884
64379
  runHidden: (script, cwd, timeoutMs) => runScriptHidden(script, cwd, timeoutMs),
@@ -64018,7 +64513,7 @@ var init_local_host = __esm({
64018
64513
  id: this.id,
64019
64514
  os: process.platform,
64020
64515
  arch: process.arch,
64021
- hostname: hostname4(),
64516
+ hostname: hostname5(),
64022
64517
  home: homedir16(),
64023
64518
  labels: [],
64024
64519
  roots: [],
@@ -64043,7 +64538,7 @@ var init_local_host = __esm({
64043
64538
  return new Promise((resolve16, reject) => {
64044
64539
  const env = { ...process.env, ...options.env };
64045
64540
  env.PATH = prependBinDirs(env.PATH);
64046
- execFile14(
64541
+ execFile16(
64047
64542
  bin,
64048
64543
  args,
64049
64544
  { cwd: options.cwd, env, maxBuffer: EXEC_MAX_BUFFER, timeout: options.timeoutMs },
@@ -64060,11 +64555,11 @@ var init_local_host = __esm({
64060
64555
  };
64061
64556
  localFs = {
64062
64557
  async stat(path2, options) {
64063
- const stats = options?.followSymlinks ? await stat6(path2) : await lstat(path2);
64558
+ const stats = options?.followSymlinks ? await stat7(path2) : await lstat(path2);
64064
64559
  return { kind: kindOf(stats), size: stats.size, mtimeMs: stats.mtimeMs };
64065
64560
  },
64066
64561
  async readFile(path2) {
64067
- return new Uint8Array(await readFile8(path2));
64562
+ return new Uint8Array(await readFile10(path2));
64068
64563
  },
64069
64564
  realpath: (path2) => realpath3(path2),
64070
64565
  async *readStream(path2, range) {
@@ -64082,9 +64577,9 @@ var init_local_host = __esm({
64082
64577
  for await (const match of fsGlob(pattern, { cwd })) matches2.push(match);
64083
64578
  return matches2;
64084
64579
  },
64085
- mkdtemp: (prefix) => mkdtemp(join35(tmpdir2(), prefix)),
64580
+ mkdtemp: (prefix) => mkdtemp(join36(tmpdir2(), prefix)),
64086
64581
  async list(path2) {
64087
- const entries = await readdir6(path2, { withFileTypes: true });
64582
+ const entries = await readdir8(path2, { withFileTypes: true });
64088
64583
  return entries.map((entry) => ({ name: entry.name, kind: kindOf(entry) }));
64089
64584
  },
64090
64585
  async mkdir(path2, options) {
@@ -64124,10 +64619,10 @@ var init_drizzle_orm2 = __esm({
64124
64619
 
64125
64620
  // src/server/infra/db/queries/repos.ts
64126
64621
  import { existsSync as existsSync12 } from "node:fs";
64127
- import { join as join36 } from "node:path";
64622
+ import { join as join37 } from "node:path";
64128
64623
  function reconcileKindForRepo(repo) {
64129
64624
  if (!repo.path || !existsSync12(repo.path)) return false;
64130
- const detectedKind = existsSync12(join36(repo.path, ".git")) ? "git" : "plain";
64625
+ const detectedKind = existsSync12(join37(repo.path, ".git")) ? "git" : "plain";
64131
64626
  if (detectedKind === repo.kind) return false;
64132
64627
  repo.kind = detectedKind;
64133
64628
  if (detectedKind === "plain") {
@@ -64239,7 +64734,9 @@ var init_repos = __esm({
64239
64734
  allowedHostIds: repos.allowedHostIds,
64240
64735
  primaryHostId: repos.primaryHostId,
64241
64736
  checkpointsEnabled: repos.checkpointsEnabled,
64242
- autoContinue: repos.autoContinue
64737
+ autoContinue: repos.autoContinue,
64738
+ remoteUrl: repos.remoteUrl,
64739
+ remoteKey: repos.remoteKey
64243
64740
  }).from(repos).all().map((r) => [r.name, r])
64244
64741
  );
64245
64742
  const originByWorktree = new Map(
@@ -64273,8 +64770,10 @@ var init_repos = __esm({
64273
64770
  tx.insert(repos).values({
64274
64771
  name: repo.name,
64275
64772
  path: repo.path,
64276
- remoteUrl: repo.remoteUrl ?? null,
64277
- remoteKey: repo.remoteKey ?? null,
64773
+ // `setRemote` writes the remote on its own, so a snapshot read before it ran must not
64774
+ // erase it.
64775
+ remoteUrl: repo.remoteUrl ?? kept.get(repo.name)?.remoteUrl ?? null,
64776
+ remoteKey: repo.remoteKey ?? kept.get(repo.name)?.remoteKey ?? null,
64278
64777
  defaultBranch: repo.defaultBranch,
64279
64778
  sortOrder: i,
64280
64779
  kind: repo.kind,
@@ -64885,7 +65384,7 @@ var init_isolation = __esm({
64885
65384
 
64886
65385
  // src/server/services/_utils/runner-config.ts
64887
65386
  import { existsSync as existsSync13 } from "node:fs";
64888
- import { dirname as dirname11, isAbsolute as isAbsolute2, join as join37, resolve as resolve7 } from "node:path";
65387
+ import { dirname as dirname11, isAbsolute as isAbsolute2, join as join38, resolve as resolve7 } from "node:path";
64889
65388
  function parseRunners(raw) {
64890
65389
  if (raw === void 0 || raw === null) return { runners: [], errors: [] };
64891
65390
  if (!Array.isArray(raw)) return { runners: [], errors: ["runners must be a list"] };
@@ -64910,8 +65409,8 @@ function bundledRunnersDir() {
64910
65409
  if (fromEnv) return resolve7(fromEnv);
64911
65410
  let dir = import.meta.dirname;
64912
65411
  for (let i = 0; i < 10; i++) {
64913
- const candidate = join37(dir, "runners");
64914
- if (existsSync13(join37(candidate, "local", "spawn.sh"))) return candidate;
65412
+ const candidate = join38(dir, "runners");
65413
+ if (existsSync13(join38(candidate, "local", "spawn.sh"))) return candidate;
64915
65414
  const parent = dirname11(dir);
64916
65415
  if (parent === dir) break;
64917
65416
  dir = parent;
@@ -64922,7 +65421,7 @@ function resolveHookPath(spec, script) {
64922
65421
  if (spec.startsWith(BUNDLED_PREFIX)) {
64923
65422
  const name5 = spec.slice(BUNDLED_PREFIX.length);
64924
65423
  if (!/^[a-z][a-z0-9-]*$/.test(name5)) throw new Error(`invalid bundled hook "${spec}"`);
64925
- return join37(bundledRunnersDir(), name5, `${script}.sh`);
65424
+ return join38(bundledRunnersDir(), name5, `${script}.sh`);
64926
65425
  }
64927
65426
  return isAbsolute2(spec) ? spec : resolve7(bandHome(), spec);
64928
65427
  }
@@ -65021,7 +65520,7 @@ var init_runner_config = __esm({
65021
65520
  });
65022
65521
 
65023
65522
  // src/server/services/settings-service.ts
65024
- import { join as join38 } from "node:path";
65523
+ import { join as join39 } from "node:path";
65025
65524
  function agentModeFromVia(via) {
65026
65525
  if (via === "chat") return "gui";
65027
65526
  if (via === "terminal") return "tui";
@@ -65239,7 +65738,7 @@ var init_settings_service = __esm({
65239
65738
  */
65240
65739
  worktreesDir() {
65241
65740
  const raw = this.rawWorktreesDir();
65242
- return raw ?? join38(bandHome(), "worktrees");
65741
+ return raw ?? join39(bandHome(), "worktrees");
65243
65742
  }
65244
65743
  /**
65245
65744
  * Return the raw `worktreesDir` value from settings without applying the
@@ -65665,6 +66164,7 @@ var init_registry = __esm({
65665
66164
  terminalBackend = null;
65666
66165
  hostRegistry = new HostRegistry(
65667
66166
  new LocalHost({
66167
+ resources: { selfKind: "hub" },
65668
66168
  // `gh` is the GitHub plugin's tool: with that plugin disabled the host never runs it. The
65669
66169
  // import is dynamic because the services import this registry.
65670
66170
  ghEnabled: async () => {
@@ -65909,11 +66409,11 @@ var init_credential_events = __esm({
65909
66409
  // src/server/services/_utils/shared-dir.ts
65910
66410
  import { readdirSync as readdirSync8 } from "node:fs";
65911
66411
  import { mkdir as mkdir5 } from "node:fs/promises";
65912
- import { join as join39 } from "node:path";
66412
+ import { join as join40 } from "node:path";
65913
66413
  async function openSharedDir(worktreeId4, chatId) {
65914
66414
  const host = hostRegistry.hostFor(worktreeId4);
65915
66415
  if (host.id === hostRegistry.local.id) {
65916
- const path3 = join39(bandHome(), "shared", worktreeId4, chatId);
66416
+ const path3 = join40(bandHome(), "shared", worktreeId4, chatId);
65917
66417
  await mkdir5(path3, { recursive: true });
65918
66418
  return {
65919
66419
  path: path3,
@@ -65928,7 +66428,7 @@ async function openSharedDir(worktreeId4, chatId) {
65928
66428
  }
65929
66429
  const dirs = (await host.info()).dirs;
65930
66430
  if (!dirs) throw new Error(`Worker ${host.id} has no directory for shared files`);
65931
- const path2 = join39(dirs.shared, worktreeId4, chatId);
66431
+ const path2 = join40(dirs.shared, worktreeId4, chatId);
65932
66432
  await host.fs.mkdir(path2, { recursive: true });
65933
66433
  return {
65934
66434
  path: path2,
@@ -65944,7 +66444,7 @@ async function openSharedDir(worktreeId4, chatId) {
65944
66444
  async function agentExtraDirs(worktreeId4) {
65945
66445
  const host = hostRegistry.hostFor(worktreeId4);
65946
66446
  if (host.id === hostRegistry.local.id) {
65947
- return [join39(bandHome(), "uploads"), join39(bandHome(), "shared")];
66447
+ return [join40(bandHome(), "uploads"), join40(bandHome(), "shared")];
65948
66448
  }
65949
66449
  const dirs = (await host.info()).dirs;
65950
66450
  return dirs ? [dirs.uploads, dirs.shared] : [];
@@ -66458,9 +66958,9 @@ var init_oauth_client = __esm({
66458
66958
  // src/server/services/_utils/vault-crypto.ts
66459
66959
  import { createCipheriv, createDecipheriv, randomBytes as randomBytes6 } from "node:crypto";
66460
66960
  import { chmodSync as chmodSync2, existsSync as existsSync14, readFileSync as readFileSync9, renameSync as renameSync7, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "node:fs";
66461
- import { join as join40 } from "node:path";
66961
+ import { join as join41 } from "node:path";
66462
66962
  function vaultKeyFile() {
66463
- return join40(bandHome(), "vault.key");
66963
+ return join41(bandHome(), "vault.key");
66464
66964
  }
66465
66965
  function keySource() {
66466
66966
  return process.env.BAND_VAULT_KEY?.trim() ? "env" : "file";
@@ -66534,9 +67034,9 @@ var init_vault_crypto = __esm({
66534
67034
  // src/server/infra/subscriptions/webhook-secret.ts
66535
67035
  import { randomBytes as randomBytes7 } from "node:crypto";
66536
67036
  import { chmodSync as chmodSync3, existsSync as existsSync15, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "node:fs";
66537
- import { dirname as dirname12, join as join41 } from "node:path";
67037
+ import { dirname as dirname12, join as join42 } from "node:path";
66538
67038
  function secretPath() {
66539
- return join41(bandHome(), "github-webhook-secret");
67039
+ return join42(bandHome(), "github-webhook-secret");
66540
67040
  }
66541
67041
  function readWebhookSecret() {
66542
67042
  const fromEnv = process.env.BAND_GITHUB_WEBHOOK_SECRET;
@@ -66607,10 +67107,10 @@ async function hubGhEnv() {
66607
67107
  async function hubGhHasNoCredential() {
66608
67108
  return !await machineHasLogin() && vaultService.findGitHubToken() === void 0;
66609
67109
  }
66610
- async function withHubGhCredential(run3) {
67110
+ async function withHubGhCredential(run4) {
66611
67111
  const env = await hubGhEnv();
66612
67112
  try {
66613
- return await run3(env);
67113
+ return await run4(env);
66614
67114
  } catch (err) {
66615
67115
  const message = err instanceof Error ? err.message : String(err);
66616
67116
  if (env.GH_TOKEN === void 0 && UNAUTHENTICATED.test(message) && await hubGhHasNoCredential()) {
@@ -67051,20 +67551,20 @@ function parseBranchStatusResponse(data, branches) {
67051
67551
  }
67052
67552
  let aggregatedState = "success";
67053
67553
  let aggregatedUrl = null;
67054
- for (const run3 of latestByWorkflow.values()) {
67554
+ for (const run4 of latestByWorkflow.values()) {
67055
67555
  let runState;
67056
- if (run3.status === "IN_PROGRESS" || run3.status === "QUEUED") {
67057
- runState = run3.status === "QUEUED" ? "pending" : "running";
67058
- } else if (run3.conclusion === "FAILURE") {
67556
+ if (run4.status === "IN_PROGRESS" || run4.status === "QUEUED") {
67557
+ runState = run4.status === "QUEUED" ? "pending" : "running";
67558
+ } else if (run4.conclusion === "FAILURE") {
67059
67559
  runState = "failure";
67060
- } else if (run3.conclusion === "CANCELLED") {
67560
+ } else if (run4.conclusion === "CANCELLED") {
67061
67561
  runState = "cancelled";
67062
67562
  } else {
67063
67563
  runState = "success";
67064
67564
  }
67065
67565
  if (statePriority(runState) >= statePriority(aggregatedState)) {
67066
67566
  aggregatedState = runState;
67067
- aggregatedUrl = run3.url;
67567
+ aggregatedUrl = run4.url;
67068
67568
  }
67069
67569
  }
67070
67570
  results[branch] = { state: aggregatedState, url: reviewUrl ?? aggregatedUrl, review };
@@ -67199,11 +67699,11 @@ function parseBranchChecks(data) {
67199
67699
  if (!suite.workflowRun) continue;
67200
67700
  const workflowName = suite.workflowRun.workflow.name;
67201
67701
  for (const node2 of suite.checkRuns.nodes) {
67202
- const run3 = fromCheckRun(node2, workflowName);
67203
- const key2 = `${workflowName}\0${run3.name}`;
67702
+ const run4 = fromCheckRun(node2, workflowName);
67703
+ const key2 = `${workflowName}\0${run4.name}`;
67204
67704
  const existing = latest.get(key2);
67205
- if (!existing || (run3.startedAt ?? "") > (existing.startedAt ?? "")) {
67206
- latest.set(key2, run3);
67705
+ if (!existing || (run4.startedAt ?? "") > (existing.startedAt ?? "")) {
67706
+ latest.set(key2, run4);
67207
67707
  }
67208
67708
  }
67209
67709
  }
@@ -67554,15 +68054,15 @@ function parseCheckRuns(output2) {
67554
68054
  const runs = parsed?.check_runs;
67555
68055
  if (!Array.isArray(runs)) throw new Error("Unexpected check-runs response");
67556
68056
  return runs.flatMap((r) => {
67557
- const run3 = obj(r);
67558
- if (!run3) return [];
68057
+ const run4 = obj(r);
68058
+ if (!run4) return [];
67559
68059
  return [
67560
68060
  {
67561
- name: str2(run3.name) || "unnamed check",
67562
- status: str2(run3.status),
67563
- conclusion: typeof run3.conclusion === "string" ? run3.conclusion : null,
67564
- url: str2(run3.html_url) || void 0,
67565
- headSha: str2(run3.head_sha) || void 0
68061
+ name: str2(run4.name) || "unnamed check",
68062
+ status: str2(run4.status),
68063
+ conclusion: typeof run4.conclusion === "string" ? run4.conclusion : null,
68064
+ url: str2(run4.html_url) || void 0,
68065
+ headSha: str2(run4.head_sha) || void 0
67566
68066
  }
67567
68067
  ];
67568
68068
  });
@@ -67806,10 +68306,10 @@ function parseGithubDelivery(eventType, delivery, payload, now = Date.now()) {
67806
68306
  case "check_suite":
67807
68307
  case "workflow_run": {
67808
68308
  if (action !== "completed") return { type: "ignored" };
67809
- const run3 = obj(body[eventType]);
67810
- const suite = obj(run3?.check_suite);
67811
- const branch = str2(run3?.head_branch) || str2(suite?.head_branch);
67812
- const sha = str2(run3?.head_sha) || str2(suite?.head_sha);
68309
+ const run4 = obj(body[eventType]);
68310
+ const suite = obj(run4?.check_suite);
68311
+ const branch = str2(run4?.head_branch) || str2(suite?.head_branch);
68312
+ const sha = str2(run4?.head_sha) || str2(suite?.head_sha);
67813
68313
  if (!branch || !/^[0-9a-f]{7,64}$/i.test(sha)) return { type: "ignored" };
67814
68314
  return { type: "check", trigger: { repo, branch, sha } };
67815
68315
  }
@@ -67847,9 +68347,9 @@ function reviewTargetOf(eventType, payload) {
67847
68347
  return match ? target("", match[1]) : { repo };
67848
68348
  }
67849
68349
  default: {
67850
- const run3 = obj(body[eventType]);
67851
- const suite = obj(run3?.check_suite);
67852
- const branch = str2(run3?.head_branch) || str2(suite?.head_branch);
68350
+ const run4 = obj(body[eventType]);
68351
+ const suite = obj(run4?.check_suite);
68352
+ const branch = str2(run4?.head_branch) || str2(suite?.head_branch);
67853
68353
  return branch ? target(branch, void 0) : { repo };
67854
68354
  }
67855
68355
  }
@@ -68092,14 +68592,14 @@ var init_server3 = __esm({
68092
68592
  const handoff2 = /* @__PURE__ */ new Map();
68093
68593
  const keyOf2 = (repo, branch) => `${repoArg(repo)}#${branch}`;
68094
68594
  const noMergeQueue = /* @__PURE__ */ new Set();
68095
- async function withMergeQueueFallback(repo, run3) {
68096
- if (noMergeQueue.has(repo.host)) return run3(false);
68595
+ async function withMergeQueueFallback(repo, run4) {
68596
+ if (noMergeQueue.has(repo.host)) return run4(false);
68097
68597
  try {
68098
- return await run3(true);
68598
+ return await run4(true);
68099
68599
  } catch (error63) {
68100
68600
  if (!isUnknownMergeQueueField(error63)) throw error63;
68101
68601
  noMergeQueue.add(repo.host);
68102
- return run3(false);
68602
+ return run4(false);
68103
68603
  }
68104
68604
  }
68105
68605
  function query(repo, branch, ctx) {
@@ -69056,12 +69556,12 @@ var init_worktree_checkpoints = __esm({
69056
69556
 
69057
69557
  // src/server/services/_utils/checkpoint-store.ts
69058
69558
  import { rmSync as rmSync4 } from "node:fs";
69059
- import { join as join42 } from "node:path";
69559
+ import { join as join43 } from "node:path";
69060
69560
  function worktreeCheckpointDir(worktreeId4) {
69061
- return join42(bandHome(), "checkpoints", worktreeId4);
69561
+ return join43(bandHome(), "checkpoints", worktreeId4);
69062
69562
  }
69063
69563
  function checkpointDir(worktreeId4, checkpointId2) {
69064
- return join42(worktreeCheckpointDir(worktreeId4), checkpointId2);
69564
+ return join43(worktreeCheckpointDir(worktreeId4), checkpointId2);
69065
69565
  }
69066
69566
  function forgetCheckpoints(worktreeId4) {
69067
69567
  queries.deleteForWorktree(worktreeId4);
@@ -72276,7 +72776,7 @@ var init_chat_ownership_service = __esm({
72276
72776
  this.deliverAgain.add(hostId2);
72277
72777
  return;
72278
72778
  }
72279
- const run3 = (async () => {
72779
+ const run4 = (async () => {
72280
72780
  do {
72281
72781
  this.deliverAgain.delete(hostId2);
72282
72782
  for (; ; ) {
@@ -72298,8 +72798,8 @@ var init_chat_ownership_service = __esm({
72298
72798
  }
72299
72799
  } while (this.deliverAgain.has(hostId2));
72300
72800
  })();
72301
- this.delivering.set(hostId2, run3);
72302
- void run3.catch((err) => log24.warn({ hostId: hostId2, err }, "chat outbox delivery failed")).finally(() => {
72801
+ this.delivering.set(hostId2, run4);
72802
+ void run4.catch((err) => log24.warn({ hostId: hostId2, err }, "chat outbox delivery failed")).finally(() => {
72303
72803
  this.delivering.delete(hostId2);
72304
72804
  if (this.deliverAgain.delete(hostId2) && !this.retryTimers.has(hostId2)) {
72305
72805
  this.deliver(hostId2);
@@ -76327,7 +76827,7 @@ var init_git_credential_service = __esm({
76327
76827
  import { spawn as spawn6 } from "node:child_process";
76328
76828
  import { randomBytes as randomBytes10 } from "node:crypto";
76329
76829
  import { appendFileSync, mkdirSync as mkdirSync8, readFileSync as readFileSync11, rmSync as rmSync5, statSync as statSync14 } from "node:fs";
76330
- import { dirname as dirname13, join as join43 } from "node:path";
76830
+ import { dirname as dirname13, join as join44 } from "node:path";
76331
76831
  function snapshotSweepMs() {
76332
76832
  const raw = Number(process.env.BAND_SNAPSHOT_SWEEP_MS);
76333
76833
  return Number.isFinite(raw) && raw > 0 ? raw : SNAPSHOT_SWEEP_MS;
@@ -76524,7 +77024,7 @@ var init_runner_service = __esm({
76524
77024
  }
76525
77025
  }
76526
77026
  logFile(requestId2) {
76527
- return join43(bandHome(), "runners", "logs", `${requestId2}.log`);
77027
+ return join44(bandHome(), "runners", "logs", `${requestId2}.log`);
76528
77028
  }
76529
77029
  /** Every valid runner in settings. */
76530
77030
  configs() {
@@ -76540,12 +77040,12 @@ var init_runner_service = __esm({
76540
77040
  }
76541
77041
  /** Whether the worker id belongs to an attempt in flight. */
76542
77042
  isAttempting(workerId) {
76543
- for (const run3 of this.running.values()) if (run3.workerId === workerId) return true;
77043
+ for (const run4 of this.running.values()) if (run4.workerId === workerId) return true;
76544
77044
  return false;
76545
77045
  }
76546
77046
  runningCount(runnerId2) {
76547
77047
  let n = 0;
76548
- for (const run3 of this.running.values()) if (run3.runnerId === runnerId2) n++;
77048
+ for (const run4 of this.running.values()) if (run4.runnerId === runnerId2) n++;
76549
77049
  return n;
76550
77050
  }
76551
77051
  // ---- leasing -------------------------------------------------------------
@@ -76581,7 +77081,7 @@ var init_runner_service = __esm({
76581
77081
  }
76582
77082
  }
76583
77083
  begin(runner, row) {
76584
- const run3 = {
77084
+ const run4 = {
76585
77085
  requestId: row.id,
76586
77086
  runnerId: runner.id,
76587
77087
  worktreeId: row.worktreeId,
@@ -76592,27 +77092,27 @@ var init_runner_service = __esm({
76592
77092
  endedAt: null,
76593
77093
  error: null
76594
77094
  };
76595
- this.running.set(row.id, run3);
76596
- const done = this.run(runner, row, run3).catch(
77095
+ this.running.set(row.id, run4);
77096
+ const done = this.run(runner, row, run4).catch(
76597
77097
  (err) => log32.error(`run of ${row.id} crashed: ${err instanceof Error ? err.stack : err}`)
76598
77098
  ).finally(() => {
76599
77099
  this.running.delete(row.id);
76600
- run3.endedAt = Date.now();
76601
- this.history.push(run3);
77100
+ run4.endedAt = Date.now();
77101
+ this.history.push(run4);
76602
77102
  if (this.history.length > HISTORY_LIMIT) this.history.shift();
76603
77103
  this.settled.delete(done);
76604
77104
  });
76605
77105
  this.settled.add(done);
76606
77106
  }
76607
77107
  // ---- one request ---------------------------------------------------------
76608
- async run(runner, row, run3) {
77108
+ async run(runner, row, run4) {
76609
77109
  const runLog = new RunLog(this.logFile(row.id));
76610
77110
  runLog.write("hub", `runner ${runner.id} took request ${row.id} for ${row.worktreeId}`);
76611
77111
  const environment = parseRequestEnvironment(row);
76612
77112
  if (!environment.ok) {
76613
77113
  runLog.write("hub", environment.error);
76614
- run3.status = "failed";
76615
- run3.error = environment.error;
77114
+ run4.status = "failed";
77115
+ run4.error = environment.error;
76616
77116
  try {
76617
77117
  placementService.fail(row.id, environment.error);
76618
77118
  } catch (err) {
@@ -76622,19 +77122,19 @@ var init_runner_service = __esm({
76622
77122
  }
76623
77123
  let lastError = "";
76624
77124
  for (let attempt = 1; attempt <= ATTEMPTS; attempt++) {
76625
- run3.attempt = attempt;
77125
+ run4.attempt = attempt;
76626
77126
  runLog.write("hub", `attempt ${attempt} of ${ATTEMPTS}`);
76627
77127
  const attemptState = { hostId: null, token: null };
76628
77128
  try {
76629
- const hostId2 = await this.attempt(runner, row, run3, runLog, attemptState);
76630
- run3.workerId = hostId2;
76631
- run3.status = "ready";
77129
+ const hostId2 = await this.attempt(runner, row, run4, runLog, attemptState);
77130
+ run4.workerId = hostId2;
77131
+ run4.status = "ready";
76632
77132
  runLog.write("hub", `worker ${hostId2} said hello; request fulfilled`);
76633
77133
  return;
76634
77134
  } catch (err) {
76635
77135
  if (err instanceof Aborted) {
76636
- run3.status = "aborted";
76637
- run3.error = err.message;
77136
+ run4.status = "aborted";
77137
+ run4.error = err.message;
76638
77138
  runLog.write("hub", `stopped: ${err.message}`);
76639
77139
  await this.cleanup(runner, row, attemptState, runLog);
76640
77140
  return;
@@ -76645,8 +77145,8 @@ var init_runner_service = __esm({
76645
77145
  }
76646
77146
  }
76647
77147
  const reason = this.failureReason(runner, lastError, runLog);
76648
- run3.status = "failed";
76649
- run3.error = lastError;
77148
+ run4.status = "failed";
77149
+ run4.error = lastError;
76650
77150
  try {
76651
77151
  placementService.fail(row.id, reason);
76652
77152
  } catch (err) {
@@ -76719,13 +77219,13 @@ ${tail}` : head;
76719
77219
  * runner holds a snapshot for tries `restore` first, and starts a fresh worker with `spawn` when
76720
77220
  * that fails, so the git and session state the sleep stored is what brings the worktree back.
76721
77221
  */
76722
- async attempt(runner, row, run3, runLog, state2) {
77222
+ async attempt(runner, row, run4, runLog, state2) {
76723
77223
  const wake = wakeOf(row);
76724
77224
  const snapshot = wake ? this.restorableSnapshot(runner, wake.hostId) : void 0;
76725
77225
  if (snapshot) {
76726
77226
  this.restoring.add(snapshot.id);
76727
77227
  try {
76728
- return await this.launch(runner, row, run3, runLog, state2, "restore", snapshot);
77228
+ return await this.launch(runner, row, run4, runLog, state2, "restore", snapshot);
76729
77229
  } catch (err) {
76730
77230
  if (err instanceof Aborted) throw err;
76731
77231
  runLog.write(
@@ -76738,7 +77238,7 @@ ${tail}` : head;
76738
77238
  this.restoring.delete(snapshot.id);
76739
77239
  }
76740
77240
  }
76741
- return this.launch(runner, row, run3, runLog, state2, "spawn");
77241
+ return this.launch(runner, row, run4, runLog, state2, "spawn");
76742
77242
  }
76743
77243
  /** The snapshot a wake can restore from: this runner's, still alive, and the runner has a `restore` hook. */
76744
77244
  restorableSnapshot(runner, hostId2) {
@@ -76748,7 +77248,7 @@ ${tail}` : head;
76748
77248
  return void 0;
76749
77249
  return latest;
76750
77250
  }
76751
- async launch(runner, row, run3, runLog, state2, kind, snapshot) {
77251
+ async launch(runner, row, run4, runLog, state2, kind, snapshot) {
76752
77252
  const deadline = Date.now() + runner.timeoutSec * 1e3;
76753
77253
  const labelList = Object.entries(row.labels).map(([k2, v2]) => `${k2}=${v2}`);
76754
77254
  const wanted = requestedIsolation(row.environment);
@@ -76766,7 +77266,7 @@ ${tail}` : head;
76766
77266
  state2.reused = wake !== null;
76767
77267
  state2.token = issued.token;
76768
77268
  runLog.addSecret(issued.token);
76769
- run3.workerId = issued.hostId;
77269
+ run4.workerId = issued.hostId;
76770
77270
  runLog.write("hub", `issued worker ${issued.hostId}`);
76771
77271
  const machineId = this.recordMachine(runner, row, issued.hostId);
76772
77272
  state2.machineId = machineId;
@@ -76901,11 +77401,11 @@ ${tail}` : head;
76901
77401
  destroyMachine(machineId, reason) {
76902
77402
  const inflight = this.destroying.get(machineId);
76903
77403
  if (inflight) return inflight;
76904
- const run3 = this.doDestroyMachine(machineId, reason).finally(
77404
+ const run4 = this.doDestroyMachine(machineId, reason).finally(
76905
77405
  () => this.destroying.delete(machineId)
76906
77406
  );
76907
- this.destroying.set(machineId, run3);
76908
- return run3;
77407
+ this.destroying.set(machineId, run4);
77408
+ return run4;
76909
77409
  }
76910
77410
  async doDestroyMachine(machineId, reason) {
76911
77411
  const machine = this.machines.get(machineId);
@@ -76914,7 +77414,7 @@ ${tail}` : head;
76914
77414
  const runner = this.findRunner(machine.runnerId);
76915
77415
  const request = machine.requestId ? placementService.get(machine.requestId) : void 0;
76916
77416
  const runLog = new RunLog(
76917
- machine.requestId ? this.logFile(machine.requestId) : join43(bandHome(), "runners", "logs", `${machine.id}.log`)
77417
+ machine.requestId ? this.logFile(machine.requestId) : join44(bandHome(), "runners", "logs", `${machine.id}.log`)
76918
77418
  );
76919
77419
  runLog.write(
76920
77420
  "hub",
@@ -76962,7 +77462,7 @@ ${tail}` : head;
76962
77462
  /** Runs `destroy` for a machine the hub has no record of, named only by the handle `status` printed. */
76963
77463
  async destroyHandle(runner, handle, reason) {
76964
77464
  if (!runner.destroy) return false;
76965
- const file3 = join43(bandHome(), "runners", "logs", "reaper.log");
77465
+ const file3 = join44(bandHome(), "runners", "logs", "reaper.log");
76966
77466
  try {
76967
77467
  if (statSync14(file3).size > LOG_FILE_LIMIT) rmSync5(file3, { force: true });
76968
77468
  } catch {
@@ -77184,7 +77684,7 @@ ${tail}` : head;
77184
77684
  // The repo's current environment image (plan step 3.2), empty before its first ready build.
77185
77685
  BAND_REPO_IMAGE: row ? this.repoImage(row.repo) : "",
77186
77686
  BAND_RUNNER_ID: runner.id,
77187
- BAND_RUNNER_DIR: join43(bandHome(), "runners", runner.id),
77687
+ BAND_RUNNER_DIR: join44(bandHome(), "runners", runner.id),
77188
77688
  BAND_NODE: process.execPath
77189
77689
  });
77190
77690
  if (runner.desktop) env.BAND_DESKTOP = "1";
@@ -77213,7 +77713,7 @@ ${tail}` : head;
77213
77713
  */
77214
77714
  runHook(opts) {
77215
77715
  const { runner, name: name5, path: path2, env, timeoutMs, runLog, watch, onStdout, onStderr } = opts;
77216
- const cwd = join43(bandHome(), "runners", runner.id);
77716
+ const cwd = join44(bandHome(), "runners", runner.id);
77217
77717
  mkdirSync8(cwd, { recursive: true, mode: 448 });
77218
77718
  return new Promise((resolve16, reject) => {
77219
77719
  let child;
@@ -77273,14 +77773,14 @@ ${tail}` : head;
77273
77773
 
77274
77774
  // src/server/services/ephemeral-lifecycle-service.ts
77275
77775
  import { rmSync as rmSync6 } from "node:fs";
77276
- import { mkdir as mkdir6, readFile as readFile9, writeFile as writeFile4 } from "node:fs/promises";
77277
- import { join as join44, posix as posix5 } from "node:path";
77776
+ import { mkdir as mkdir6, readFile as readFile11, writeFile as writeFile4 } from "node:fs/promises";
77777
+ import { join as join45, posix as posix5 } from "node:path";
77278
77778
  function idleTimeoutMs() {
77279
77779
  const raw = Number(process.env.BAND_EPHEMERAL_IDLE_TIMEOUT_MS);
77280
77780
  return Number.isFinite(raw) && raw > 0 ? raw : void 0;
77281
77781
  }
77282
77782
  function sleepDir(worktreeId4) {
77283
- return join44(bandHome(), "sleep", worktreeId4);
77783
+ return join45(bandHome(), "sleep", worktreeId4);
77284
77784
  }
77285
77785
  var log33, LOCAL_HOST_ID6, WAKE_POLL_MS, WAKE_GRACE_MS, EXIT_GRACE_MS2, SleepError, errorText2, EphemeralLifecycleService, ephemeralLifecycleService;
77286
77786
  var init_ephemeral_lifecycle_service = __esm({
@@ -77602,7 +78102,7 @@ var init_ephemeral_lifecycle_service = __esm({
77602
78102
  const dir = sleepDir(worktreeId4);
77603
78103
  try {
77604
78104
  await mkdir6(dir, { recursive: true, mode: 448 });
77605
- await writeFile4(join44(dir, "snapshot.bundle"), await host.fs.readFile(bundle), {
78105
+ await writeFile4(join45(dir, "snapshot.bundle"), await host.fs.readFile(bundle), {
77606
78106
  mode: 384
77607
78107
  });
77608
78108
  } catch (err) {
@@ -77626,7 +78126,7 @@ var init_ephemeral_lifecycle_service = __esm({
77626
78126
  try {
77627
78127
  const dir = sleepDir(worktreeId4);
77628
78128
  await mkdir6(dir, { recursive: true, mode: 448 });
77629
- await writeFile4(join44(dir, "sessions.json"), JSON.stringify({ files }), { mode: 384 });
78129
+ await writeFile4(join45(dir, "sessions.json"), JSON.stringify({ files }), { mode: 384 });
77630
78130
  } catch (err) {
77631
78131
  log33.warn(`could not keep the agent sessions of ${worktreeId4}: ${errorText2(err)}`);
77632
78132
  return [];
@@ -77752,7 +78252,7 @@ var init_ephemeral_lifecycle_service = __esm({
77752
78252
  const bundle = posix5.join(wipDir, `${row.worktreeId}.bundle`);
77753
78253
  await host.fs.writeFile(
77754
78254
  bundle,
77755
- await readFile9(join44(sleepDir(row.worktreeId), "snapshot.bundle"))
78255
+ await readFile11(join45(sleepDir(row.worktreeId), "snapshot.bundle"))
77756
78256
  );
77757
78257
  try {
77758
78258
  await git2(["fetch", "--force", bundle, `${local}:${local}`]);
@@ -77809,7 +78309,7 @@ var init_ephemeral_lifecycle_service = __esm({
77809
78309
  if (row.sessionIds.length === 0) return;
77810
78310
  let files;
77811
78311
  try {
77812
- files = JSON.parse(await readFile9(join44(sleepDir(row.worktreeId), "sessions.json"), "utf8")).files;
78312
+ files = JSON.parse(await readFile11(join45(sleepDir(row.worktreeId), "sessions.json"), "utf8")).files;
77813
78313
  } catch (err) {
77814
78314
  log33.warn(`${row.worktreeId}: no saved agent sessions: ${errorText2(err)}`);
77815
78315
  return;
@@ -78549,7 +79049,7 @@ var init_watcher_service = __esm({
78549
79049
  this.poller.start();
78550
79050
  const statuses = loadCurrentStatuses();
78551
79051
  const runningScripts = worktreeScriptService.getRunning();
78552
- const runningSetups = [...new Set(runningScripts.map((run3) => run3.worktreeId))];
79052
+ const runningSetups = [...new Set(runningScripts.map((run4) => run4.worktreeId))];
78553
79053
  listener({ kind: "snapshot", statuses, runningSetups });
78554
79054
  for (const event of this.loadCurrentBranchStatuses()) {
78555
79055
  listener(event);
@@ -80671,7 +81171,7 @@ var init_worker_lease_service = __esm({
80671
81171
  entry.again = true;
80672
81172
  return entry.running;
80673
81173
  }
80674
- const run3 = (async () => {
81174
+ const run4 = (async () => {
80675
81175
  do {
80676
81176
  entry.again = false;
80677
81177
  await this.renewOnce(hostId2, entry);
@@ -80680,8 +81180,8 @@ var init_worker_lease_service = __esm({
80680
81180
  entry.running = null;
80681
81181
  entry.again = false;
80682
81182
  });
80683
- entry.running = run3;
80684
- return run3;
81183
+ entry.running = run4;
81184
+ return run4;
80685
81185
  }
80686
81186
  async renewOnce(hostId2, entry) {
80687
81187
  const params = { ttlMs: leaseMs(), blockedPaths: this.blockedPaths(hostId2) };
@@ -80918,7 +81418,7 @@ __export(worktree_service_exports, {
80918
81418
  });
80919
81419
  import { randomUUID as randomUUID14 } from "node:crypto";
80920
81420
  import { unlinkSync as unlinkSync5 } from "node:fs";
80921
- import { join as join45, posix as posix6 } from "node:path";
81421
+ import { join as join46, posix as posix6 } from "node:path";
80922
81422
  function findWorktreeRow(worktrees2, name5, hostId2) {
80923
81423
  const named = worktrees2.filter((wt) => wt.name === name5);
80924
81424
  if (hostId2 !== void 0) return named.find((wt) => (wt.hostId ?? "local") === hostId2);
@@ -81379,8 +81879,8 @@ var init_worktree_service = __esm({
81379
81879
  try {
81380
81880
  repoPath = await this.checkoutOn(repo, host, input3.hostRepoPath);
81381
81881
  const wtDir = remote ? await this.remoteWorktreesDir(host) : worktreesDir();
81382
- worktreePath = remote ? posix6.join(wtDir, input3.repo, input3.branch) : join45(wtDir, input3.repo, input3.branch);
81383
- await host.fs.mkdir(remote ? posix6.join(wtDir, input3.repo) : join45(wtDir, input3.repo), {
81882
+ worktreePath = remote ? posix6.join(wtDir, input3.repo, input3.branch) : join46(wtDir, input3.repo, input3.branch);
81883
+ await host.fs.mkdir(remote ? posix6.join(wtDir, input3.repo) : join46(wtDir, input3.repo), {
81384
81884
  recursive: true
81385
81885
  });
81386
81886
  try {
@@ -81662,7 +82162,7 @@ var init_worktree_service = __esm({
81662
82162
  if (gone.supersededBy)
81663
82163
  void workerLeaseService.pushBlockedPaths(gone.hostId ?? hostRegistry.local.id);
81664
82164
  try {
81665
- unlinkSync5(join45(bandHome(), "workspace-prompts", `${worktreeId4}.json`));
82165
+ unlinkSync5(join46(bandHome(), "workspace-prompts", `${worktreeId4}.json`));
81666
82166
  } catch {
81667
82167
  }
81668
82168
  deleteWorktreeStatus(worktreeId4);
@@ -82269,7 +82769,7 @@ var init_worktree_service = __esm({
82269
82769
  if (!/^[a-zA-Z0-9._-]+$/.test(input3.scriptType) || input3.scriptType.includes("..")) {
82270
82770
  throw new Error(`Invalid script type "${input3.scriptType}"`);
82271
82771
  }
82272
- const scriptPath = join45(input3.path, ".band", input3.scriptType);
82772
+ const scriptPath = join46(input3.path, ".band", input3.scriptType);
82273
82773
  const host = hostRegistry.local;
82274
82774
  try {
82275
82775
  await host.fs.stat(scriptPath);
@@ -82847,11 +83347,11 @@ var init_subscription_source_service = __esm({
82847
83347
  if (running) {
82848
83348
  await running;
82849
83349
  }
82850
- const run3 = this.fetchAndIngest(provider, check3.trigger).finally(() => {
82851
- if (checking.get(check3.flight) === run3) checking.delete(check3.flight);
83350
+ const run4 = this.fetchAndIngest(provider, check3.trigger).finally(() => {
83351
+ if (checking.get(check3.flight) === run4) checking.delete(check3.flight);
82852
83352
  });
82853
- checking.set(check3.flight, run3);
82854
- await run3;
83353
+ checking.set(check3.flight, run4);
83354
+ await run4;
82855
83355
  }
82856
83356
  async fetchAndIngest(provider, trigger) {
82857
83357
  const event = await provider.aggregateChecks(trigger, subscriptionContext());
@@ -82878,11 +83378,11 @@ var init_subscription_source_service = __esm({
82878
83378
  const repo = sub.config.repo;
82879
83379
  if (sub.source !== GITHUB || !repo) return;
82880
83380
  const previous = registering.get(repo) ?? Promise.resolve();
82881
- const run3 = previous.then(() => this.register(sub.id, repo, sub.source)).finally(() => {
82882
- if (registering.get(repo) === run3) registering.delete(repo);
83381
+ const run4 = previous.then(() => this.register(sub.id, repo, sub.source)).finally(() => {
83382
+ if (registering.get(repo) === run4) registering.delete(repo);
82883
83383
  });
82884
- registering.set(repo, run3);
82885
- await run3;
83384
+ registering.set(repo, run4);
83385
+ await run4;
82886
83386
  }
82887
83387
  async register(subscriptionId, repo, source) {
82888
83388
  const set2 = (status, error63) => {
@@ -85465,6 +85965,15 @@ var init_agent_session_service = __esm({
85465
85965
  observeBackgroundTasks(observer) {
85466
85966
  backgroundObserver = observer;
85467
85967
  }
85968
+ /** The agent process of each chat that has one: the chat, its worktree and the pid on the worker. */
85969
+ agentPids() {
85970
+ const out = [];
85971
+ for (const rt of runtimes.values()) {
85972
+ const pid = rt.process?.pid;
85973
+ if (pid !== void 0) out.push({ chatId: rt.chatId, worktreeId: rt.worktreeId, pid });
85974
+ }
85975
+ return out;
85976
+ }
85468
85977
  /** When the chat's agent last sent anything (ms since epoch), or null. */
85469
85978
  lastActivityAt(chatId) {
85470
85979
  return runtimes.get(chatId)?.lastActivityAt ?? null;
@@ -92855,7 +93364,7 @@ import {
92855
93364
  statSync as statSync17
92856
93365
  } from "node:fs";
92857
93366
  import { createServer as createServer3 } from "node:http";
92858
- import { basename as basename7, join as join61, resolve as resolve15, sep as sep12 } from "node:path";
93367
+ import { basename as basename7, join as join62, resolve as resolve15, sep as sep12 } from "node:path";
92859
93368
  import { pipeline as pipeline3, Readable as Readable2 } from "node:stream";
92860
93369
  import { parseArgs } from "node:util";
92861
93370
 
@@ -96278,7 +96787,7 @@ var sessionIdSchema = external_exports2.string().regex(SESSION_ID_PATTERN2, "inv
96278
96787
  init_registry();
96279
96788
  init_state();
96280
96789
  import { mkdir as mkdir7, writeFile as writeFile5 } from "node:fs/promises";
96281
- import { join as join46, resolve as resolve8, sep as sep5 } from "node:path";
96790
+ import { join as join47, resolve as resolve8, sep as sep5 } from "node:path";
96282
96791
  function decodeParts(fileParts) {
96283
96792
  const baseTimestamp = Date.now();
96284
96793
  const decoded = [];
@@ -96298,11 +96807,11 @@ function decodeParts(fileParts) {
96298
96807
  return decoded;
96299
96808
  }
96300
96809
  async function saveUploadedFilesDetailed(fileParts) {
96301
- const uploadDir = join46(bandHome(), "uploads");
96810
+ const uploadDir = join47(bandHome(), "uploads");
96302
96811
  await mkdir7(uploadDir, { recursive: true });
96303
96812
  const saved = [];
96304
96813
  for (const part of decodeParts(fileParts)) {
96305
- const filePath = join46(uploadDir, part.storedName);
96814
+ const filePath = join47(uploadDir, part.storedName);
96306
96815
  await writeFile5(filePath, part.buffer);
96307
96816
  saved.push({
96308
96817
  path: filePath,
@@ -96317,7 +96826,7 @@ async function saveUploadedFilesDetailed(fileParts) {
96317
96826
  async function remoteUploadDir(host, worktreeId4) {
96318
96827
  const dirs = (await host.info()).dirs;
96319
96828
  if (!dirs) throw new Error(`Worker ${host.id} has no directory for uploads`);
96320
- return join46(dirs.uploads, worktreeId4);
96829
+ return join47(dirs.uploads, worktreeId4);
96321
96830
  }
96322
96831
  async function saveWorktreeUploads(worktreeId4, fileParts) {
96323
96832
  const host = hostRegistry.hostFor(worktreeId4);
@@ -96326,7 +96835,7 @@ async function saveWorktreeUploads(worktreeId4, fileParts) {
96326
96835
  await host.fs.mkdir(dir, { recursive: true });
96327
96836
  const saved = [];
96328
96837
  for (const part of decodeParts(fileParts)) {
96329
- const filePath = join46(dir, part.storedName);
96838
+ const filePath = join47(dir, part.storedName);
96330
96839
  await host.fs.writeFile(filePath, part.buffer, { exclusive: true, mode: 384 });
96331
96840
  saved.push({
96332
96841
  path: filePath,
@@ -96342,19 +96851,19 @@ async function uploadPathFromUrl(worktreeId4, url3) {
96342
96851
  const host = hostRegistry.hostFor(worktreeId4);
96343
96852
  const match = url3.match(/^\/api\/uploads\/(.+)$/);
96344
96853
  if (!match) return null;
96345
- if (host.id === hostRegistry.local.id) return join46(bandHome(), "uploads", match[1]);
96854
+ if (host.id === hostRegistry.local.id) return join47(bandHome(), "uploads", match[1]);
96346
96855
  const rest = match[1].split("/");
96347
96856
  if (rest.length !== 2) return null;
96348
96857
  try {
96349
96858
  if (decodeURIComponent(rest[0]) !== worktreeId4) return null;
96350
- return join46(await remoteUploadDir(host, worktreeId4), decodeURIComponent(rest[1]));
96859
+ return join47(await remoteUploadDir(host, worktreeId4), decodeURIComponent(rest[1]));
96351
96860
  } catch {
96352
96861
  return null;
96353
96862
  }
96354
96863
  }
96355
96864
  async function isWithinUploads(worktreeId4, path2) {
96356
96865
  const host = hostRegistry.hostFor(worktreeId4);
96357
- const dir = host.id === hostRegistry.local.id ? join46(bandHome(), "uploads") : await remoteUploadDir(host, worktreeId4).catch(() => null);
96866
+ const dir = host.id === hostRegistry.local.id ? join47(bandHome(), "uploads") : await remoteUploadDir(host, worktreeId4).catch(() => null);
96358
96867
  if (!dir) return false;
96359
96868
  const normalized2 = resolve8(path2);
96360
96869
  return normalized2 === dir || normalized2.startsWith(dir + sep5);
@@ -96406,8 +96915,8 @@ init_src4();
96406
96915
  init_src2();
96407
96916
  init_src();
96408
96917
  import { createHash as createHash12, randomBytes as randomBytes15 } from "node:crypto";
96409
- import { mkdir as mkdir9, readFile as readFile11, rm as rm3, writeFile as writeFile7 } from "node:fs/promises";
96410
- import { join as join49, posix as posix8 } from "node:path";
96918
+ import { mkdir as mkdir9, readFile as readFile13, rm as rm3, writeFile as writeFile7 } from "node:fs/promises";
96919
+ import { join as join50, posix as posix8 } from "node:path";
96411
96920
  init_repo_hosts();
96412
96921
  init_worktree_id();
96413
96922
  init_errors6();
@@ -96476,7 +96985,7 @@ init_remote_worktrees();
96476
96985
  init_repo_host_policy();
96477
96986
  init_ephemeral_lifecycle_service();
96478
96987
  import { existsSync as existsSync16 } from "node:fs";
96479
- import { basename as basename2, join as join48, posix as posix7, resolve as resolve9 } from "node:path";
96988
+ import { basename as basename2, join as join49, posix as posix7, resolve as resolve9 } from "node:path";
96480
96989
 
96481
96990
  // src/server/services/repo-avatar-service.ts
96482
96991
  init_src3();
@@ -96484,8 +96993,8 @@ init_git_client();
96484
96993
  init_src();
96485
96994
  init_repos();
96486
96995
  init_settings();
96487
- import { mkdir as mkdir8, readFile as readFile10, rename as rename4, writeFile as writeFile6 } from "node:fs/promises";
96488
- import { join as join47 } from "node:path";
96996
+ import { mkdir as mkdir8, readFile as readFile12, rename as rename4, writeFile as writeFile6 } from "node:fs/promises";
96997
+ import { join as join48 } from "node:path";
96489
96998
 
96490
96999
  // src/server/infra/github/github-client.ts
96491
97000
  var FETCH_TIMEOUT_MS2 = 1e4;
@@ -96635,7 +97144,7 @@ var RepoAvatarService = class {
96635
97144
  return null;
96636
97145
  }
96637
97146
  await mkdir8(cacheDir(), { recursive: true });
96638
- const imagePath = join47(cacheDir(), `${key2}.img`);
97147
+ const imagePath = join48(cacheDir(), `${key2}.img`);
96639
97148
  await writeFile6(`${imagePath}.tmp`, result.bytes);
96640
97149
  await rename4(`${imagePath}.tmp`, imagePath);
96641
97150
  await this.writeMeta(key2, entry, {
@@ -96653,7 +97162,7 @@ var RepoAvatarService = class {
96653
97162
  async readCached(key2, meta3) {
96654
97163
  if (meta3?.status !== "ok" || !meta3.contentType) return null;
96655
97164
  try {
96656
- const bytes = await readFile10(join47(cacheDir(), `${key2}.img`));
97165
+ const bytes = await readFile12(join48(cacheDir(), `${key2}.img`));
96657
97166
  return { bytes, contentType: meta3.contentType };
96658
97167
  } catch {
96659
97168
  return null;
@@ -96663,7 +97172,7 @@ var RepoAvatarService = class {
96663
97172
  entry.meta = meta3;
96664
97173
  entry.retryAfter = 0;
96665
97174
  await mkdir8(cacheDir(), { recursive: true });
96666
- await writeFile6(join47(cacheDir(), `${key2}.json`), JSON.stringify(meta3));
97175
+ await writeFile6(join48(cacheDir(), `${key2}.json`), JSON.stringify(meta3));
96667
97176
  }
96668
97177
  /** In-memory view of one owner's cache sidecar, loaded from disk once. */
96669
97178
  async entry(ref) {
@@ -96672,7 +97181,7 @@ var RepoAvatarService = class {
96672
97181
  if (entry) return entry;
96673
97182
  let meta3 = null;
96674
97183
  try {
96675
- meta3 = JSON.parse(await readFile10(join47(cacheDir(), `${key2}.json`), "utf-8"));
97184
+ meta3 = JSON.parse(await readFile12(join48(cacheDir(), `${key2}.json`), "utf-8"));
96676
97185
  } catch {
96677
97186
  }
96678
97187
  entry = this.entries.get(key2) ?? { meta: meta3, retryAfter: 0 };
@@ -96694,7 +97203,7 @@ var RepoAvatarService = class {
96694
97203
  }
96695
97204
  };
96696
97205
  function cacheDir() {
96697
- return join47(bandHome(), "cache", "github-avatars");
97206
+ return join48(bandHome(), "cache", "github-avatars");
96698
97207
  }
96699
97208
  function cacheKey(ref) {
96700
97209
  return `${ref.host.replace(/[^a-z0-9.-]/g, "_")}__${ref.owner.toLowerCase()}`;
@@ -96864,7 +97373,7 @@ var RepoService = class {
96864
97373
  throw new Error(`Repo "${name5}" already registered`);
96865
97374
  }
96866
97375
  const resolvedPath = resolve9(path2);
96867
- const kind = existsSync16(join48(resolvedPath, ".git")) ? "git" : "plain";
97376
+ const kind = existsSync16(join49(resolvedPath, ".git")) ? "git" : "plain";
96868
97377
  let defaultBranch = "main";
96869
97378
  let worktrees2 = [];
96870
97379
  if (kind === "git") {
@@ -97499,10 +98008,10 @@ function sessionsHashOf(files) {
97499
98008
  }
97500
98009
  return hash2.digest("hex");
97501
98010
  }
97502
- async function retryRefLock(run3) {
98011
+ async function retryRefLock(run4) {
97503
98012
  for (let attempt = 1; ; attempt++) {
97504
98013
  try {
97505
- return await run3();
98014
+ return await run4();
97506
98015
  } catch (err) {
97507
98016
  if (attempt >= 4 || !/cannot lock ref/i.test(errorText3(err))) throw err;
97508
98017
  await new Promise((r) => setTimeout(r, 50 * attempt));
@@ -97610,13 +98119,13 @@ var CheckpointService = class {
97610
98119
  */
97611
98120
  take(worktreeId4, trigger, opts = {}) {
97612
98121
  const previous = this.inflight.get(worktreeId4) ?? Promise.resolve();
97613
- const run3 = previous.catch(() => void 0).then(() => this.doTake(worktreeId4, trigger, opts));
97614
- this.inflight.set(worktreeId4, run3);
98122
+ const run4 = previous.catch(() => void 0).then(() => this.doTake(worktreeId4, trigger, opts));
98123
+ this.inflight.set(worktreeId4, run4);
97615
98124
  const clear = () => {
97616
- if (this.inflight.get(worktreeId4) === run3) this.inflight.delete(worktreeId4);
98125
+ if (this.inflight.get(worktreeId4) === run4) this.inflight.delete(worktreeId4);
97617
98126
  };
97618
- run3.then(clear, clear);
97619
- return run3;
98127
+ run4.then(clear, clear);
98128
+ return run4;
97620
98129
  }
97621
98130
  async takeAllOn(hostId2, trigger) {
97622
98131
  let stored = 0;
@@ -97729,12 +98238,12 @@ var CheckpointService = class {
97729
98238
  try {
97730
98239
  await mkdir9(dir, { recursive: true, mode: 448 });
97731
98240
  if (hasBundle) {
97732
- await writeFile7(join49(dir, "bundle.pack"), await host.fs.readFile(remoteBundle), {
98241
+ await writeFile7(join50(dir, "bundle.pack"), await host.fs.readFile(remoteBundle), {
97733
98242
  mode: 384
97734
98243
  });
97735
98244
  }
97736
98245
  if (sessionsJson)
97737
- await writeFile7(join49(dir, "sessions.json"), sessionsJson, { mode: 384 });
98246
+ await writeFile7(join50(dir, "sessions.json"), sessionsJson, { mode: 384 });
97738
98247
  } catch (err) {
97739
98248
  await rm3(dir, { recursive: true, force: true }).catch(() => void 0);
97740
98249
  throw new CheckpointError(
@@ -97852,7 +98361,7 @@ var CheckpointService = class {
97852
98361
  }
97853
98362
  await this.withViewLock(
97854
98363
  worktreeId4,
97855
- () => rm3(join49(worktreeCheckpointDir(worktreeId4), "view.git"), {
98364
+ () => rm3(join50(worktreeCheckpointDir(worktreeId4), "view.git"), {
97856
98365
  recursive: true,
97857
98366
  force: true
97858
98367
  }).catch(() => void 0)
@@ -97925,8 +98434,8 @@ ${diff}`).digest("hex");
97925
98434
  /** Builds and removals of one worktree's view repo run one at a time, because parallel fetches into a bare repo can fail on ref locks. */
97926
98435
  withViewLock(worktreeId4, fn) {
97927
98436
  const previous = this.viewLocks.get(worktreeId4) ?? Promise.resolve();
97928
- const run3 = previous.then(fn, fn);
97929
- const tail = run3.then(
98437
+ const run4 = previous.then(fn, fn);
98438
+ const tail = run4.then(
97930
98439
  () => void 0,
97931
98440
  () => void 0
97932
98441
  );
@@ -97934,11 +98443,11 @@ ${diff}`).digest("hex");
97934
98443
  void tail.then(() => {
97935
98444
  if (this.viewLocks.get(worktreeId4) === tail) this.viewLocks.delete(worktreeId4);
97936
98445
  });
97937
- return run3;
98446
+ return run4;
97938
98447
  }
97939
98448
  async buildViewRepo(worktreeId4, row) {
97940
98449
  const local = hostRegistry.local;
97941
- const dir = join49(worktreeCheckpointDir(worktreeId4), "view.git");
98450
+ const dir = join50(worktreeCheckpointDir(worktreeId4), "view.git");
97942
98451
  const git2 = gitIn(local, dir);
97943
98452
  await mkdir9(dir, { recursive: true, mode: 448 });
97944
98453
  const hasRef = async () => git2(["cat-file", "-e", `${row.snapshotSha}^{commit}`]).then(
@@ -97964,7 +98473,7 @@ ${diff}`).digest("hex");
97964
98473
  "fetch",
97965
98474
  "-q",
97966
98475
  "--force",
97967
- join49(checkpointDir(worktreeId4, r.id), "bundle.pack"),
98476
+ join50(checkpointDir(worktreeId4, r.id), "bundle.pack"),
97968
98477
  `refs/band/wip/${worktreeId4}:refs/checkpoints/${r.id}`
97969
98478
  ]).catch((err) => {
97970
98479
  log58.debug(
@@ -98209,7 +98718,7 @@ ${diff}`).digest("hex");
98209
98718
  const bundle = posix8.join(wipDir, `${newId}.restore.bundle`);
98210
98719
  await host.fs.writeFile(
98211
98720
  bundle,
98212
- await readFile11(join49(checkpointDir(worktreeId4, row.id), "bundle.pack"))
98721
+ await readFile13(join50(checkpointDir(worktreeId4, row.id), "bundle.pack"))
98213
98722
  );
98214
98723
  try {
98215
98724
  await retryRefLock(
@@ -98351,7 +98860,7 @@ ${diff}`).digest("hex");
98351
98860
  let files;
98352
98861
  try {
98353
98862
  files = JSON.parse(
98354
- await readFile11(join49(checkpointDir(row.worktreeId, row.id), "sessions.json"), "utf8")
98863
+ await readFile13(join50(checkpointDir(row.worktreeId, row.id), "sessions.json"), "utf8")
98355
98864
  ).files;
98356
98865
  } catch (err) {
98357
98866
  log58.warn(
@@ -99071,9 +99580,9 @@ var FollowService = class {
99071
99580
  continueOn(input3) {
99072
99581
  const running = this.inflight.get(input3.worktreeId);
99073
99582
  if (running) return running;
99074
- const run3 = this.doContinue(input3).finally(() => this.inflight.delete(input3.worktreeId));
99075
- this.inflight.set(input3.worktreeId, run3);
99076
- return run3;
99583
+ const run4 = this.doContinue(input3).finally(() => this.inflight.delete(input3.worktreeId));
99584
+ this.inflight.set(input3.worktreeId, run4);
99585
+ return run4;
99077
99586
  }
99078
99587
  async doContinue(input3) {
99079
99588
  const { worktreeId: worktreeId4 } = input3;
@@ -100310,7 +100819,7 @@ var cidrv43 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5
100310
100819
  var cidrv63 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
100311
100820
  var base643 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;
100312
100821
  var base64url3 = /^[A-Za-z0-9_-]*$/;
100313
- var hostname5 = /^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+$/;
100822
+ var hostname6 = /^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+$/;
100314
100823
  var e1643 = /^\+(?:[0-9]){6,14}[0-9]$/;
100315
100824
  var dateSource2 = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`;
100316
100825
  var date6 = /* @__PURE__ */ new RegExp(`^${dateSource2}$`);
@@ -100923,7 +101432,7 @@ var $ZodURL2 = /* @__PURE__ */ $constructor2("$ZodURL", (inst, def) => {
100923
101432
  code: "invalid_format",
100924
101433
  format: "url",
100925
101434
  note: "Invalid hostname",
100926
- pattern: hostname5.source,
101435
+ pattern: hostname6.source,
100927
101436
  input: payload.value,
100928
101437
  inst,
100929
101438
  continue: !def.abort
@@ -112430,7 +112939,7 @@ init_zod();
112430
112939
  // src/server/services/cli-service.ts
112431
112940
  init_cli_binary();
112432
112941
  init_local_host_enabled();
112433
- import { execFile as execFile15 } from "node:child_process";
112942
+ import { execFile as execFile17 } from "node:child_process";
112434
112943
  import {
112435
112944
  accessSync as accessSync3,
112436
112945
  constants as constants3,
@@ -112444,12 +112953,12 @@ import {
112444
112953
  writeFileSync as writeFileSync7
112445
112954
  } from "node:fs";
112446
112955
  import { homedir as homedir17, platform as platform2 } from "node:os";
112447
- import { basename as basename3, dirname as dirname14, join as join50 } from "node:path";
112956
+ import { basename as basename3, dirname as dirname14, join as join51 } from "node:path";
112448
112957
  function windowsBinDir() {
112449
- const localAppData = process.env.LOCALAPPDATA || join50(homedir17(), "AppData", "Local");
112450
- return join50(localAppData, "band", "bin");
112958
+ const localAppData = process.env.LOCALAPPDATA || join51(homedir17(), "AppData", "Local");
112959
+ return join51(localAppData, "band", "bin");
112451
112960
  }
112452
- var SYMLINK_PATH = platform2() === "win32" ? join50(windowsBinDir(), "band.cmd") : "/usr/local/bin/band";
112961
+ var SYMLINK_PATH = platform2() === "win32" ? join51(windowsBinDir(), "band.cmd") : "/usr/local/bin/band";
112453
112962
  function symlinkPath() {
112454
112963
  if (platform2() === "win32") return SYMLINK_PATH;
112455
112964
  return process.env.BAND_CLI_SYMLINK_PATH?.trim() || SYMLINK_PATH;
@@ -112478,8 +112987,8 @@ async function checkCli() {
112478
112987
  }
112479
112988
  const linkPath = symlinkPath();
112480
112989
  try {
112481
- const stat8 = lstatSync4(linkPath);
112482
- if (!stat8.isSymbolicLink()) {
112990
+ const stat9 = lstatSync4(linkPath);
112991
+ if (!stat9.isSymbolicLink()) {
112483
112992
  return "ConflictingBinary";
112484
112993
  }
112485
112994
  let target;
@@ -112488,8 +112997,8 @@ async function checkCli() {
112488
112997
  } catch {
112489
112998
  return "NotInstalled";
112490
112999
  }
112491
- const isCargoBuild = target.includes(join50("apps", "cli", "target"));
112492
- const isElectronSidecar = target.endsWith(join50("binaries", "band"));
113000
+ const isCargoBuild = target.includes(join51("apps", "cli", "target"));
113001
+ const isElectronSidecar = target.endsWith(join51("binaries", "band"));
112493
113002
  if (isCargoBuild || isElectronSidecar) {
112494
113003
  return "Installed";
112495
113004
  }
@@ -112539,7 +113048,7 @@ function noBinaryError(env = process.env) {
112539
113048
  }
112540
113049
  function runReg(args) {
112541
113050
  return new Promise((resolve16) => {
112542
- execFile15("reg", args, { windowsHide: true }, (err, stdout) => {
113051
+ execFile17("reg", args, { windowsHide: true }, (err, stdout) => {
112543
113052
  resolve16(err ? "" : stdout ?? "");
112544
113053
  });
112545
113054
  });
@@ -112753,7 +113262,7 @@ function formatFileLocation(filePath, line2, options) {
112753
113262
 
112754
113263
  // ../../packages/worktree-ops/src/resolve-path.ts
112755
113264
  init_resolver();
112756
- import { isAbsolute as isAbsolute4, join as join51, resolve as resolve10, sep as sep6 } from "node:path";
113265
+ import { isAbsolute as isAbsolute4, join as join52, resolve as resolve10, sep as sep6 } from "node:path";
112757
113266
  var PathsService = class {
112758
113267
  constructor(worktrees2) {
112759
113268
  this.worktrees = worktrees2;
@@ -112804,7 +113313,7 @@ async function canonicalizeMaybeMissing(fs3, p2) {
112804
113313
  const prefix = parts.slice(0, i).join(sep6) || sep6;
112805
113314
  try {
112806
113315
  const canonicalPrefix = await fs3.realpath(prefix);
112807
- return join51(canonicalPrefix, ...parts.slice(i));
113316
+ return join52(canonicalPrefix, ...parts.slice(i));
112808
113317
  } catch {
112809
113318
  }
112810
113319
  }
@@ -112920,7 +113429,7 @@ function subscribeToFileChanges2(worktreeId4, listener) {
112920
113429
  // src/server/services/formatter.ts
112921
113430
  init_src();
112922
113431
  init_registry();
112923
- import { basename as basename4, dirname as dirname15, isAbsolute as isAbsolute5, join as join52, resolve as resolvePath3 } from "node:path";
113432
+ import { basename as basename4, dirname as dirname15, isAbsolute as isAbsolute5, join as join53, resolve as resolvePath3 } from "node:path";
112924
113433
  import prettier from "prettier";
112925
113434
  var log65 = createLogger("formatter");
112926
113435
  var FormatterError = class extends Error {
@@ -113002,10 +113511,10 @@ async function resolveConfigOnHost(fs3, absFile, worktreePath) {
113002
113511
  let dir = dirname15(absFile);
113003
113512
  for (; ; ) {
113004
113513
  for (const name5 of JSON_CONFIGS) {
113005
- const parsed = await readJson2(fs3, join52(dir, name5));
113514
+ const parsed = await readJson2(fs3, join53(dir, name5));
113006
113515
  if (parsed && typeof parsed === "object") return withoutPlugins(parsed);
113007
113516
  }
113008
- const pkg = await readJson2(fs3, join52(dir, "package.json"));
113517
+ const pkg = await readJson2(fs3, join53(dir, "package.json"));
113009
113518
  if (pkg && typeof pkg.prettier === "object" && pkg.prettier !== null) {
113010
113519
  return withoutPlugins(pkg.prettier);
113011
113520
  }
@@ -113043,7 +113552,7 @@ async function isInsideWorktree(fs3, absFile, worktreePath) {
113043
113552
  realFile = await fs3.realpath(absFile);
113044
113553
  } catch {
113045
113554
  try {
113046
- realFile = join52(await fs3.realpath(dirname15(absFile)), basename4(absFile));
113555
+ realFile = join53(await fs3.realpath(dirname15(absFile)), basename4(absFile));
113047
113556
  } catch {
113048
113557
  realFile = absFile;
113049
113558
  }
@@ -113302,8 +113811,8 @@ init_http_files();
113302
113811
  init_settings();
113303
113812
  import { createHash as createHash13, randomBytes as randomBytes16 } from "node:crypto";
113304
113813
  import { createReadStream as createReadStream4 } from "node:fs";
113305
- import { mkdir as mkdir10, readdir as readdir7, readFile as readFile12, realpath as realpath4, rename as rename5, rm as rm4, stat as stat7, writeFile as writeFile8 } from "node:fs/promises";
113306
- import { dirname as dirname17, join as join53, sep as sep7 } from "node:path";
113814
+ import { mkdir as mkdir10, readdir as readdir9, readFile as readFile14, realpath as realpath4, rename as rename5, rm as rm4, stat as stat8, writeFile as writeFile8 } from "node:fs/promises";
113815
+ import { dirname as dirname17, join as join54, sep as sep7 } from "node:path";
113307
113816
 
113308
113817
  // src/server/services/_utils/tar-extract.ts
113309
113818
  import { gunzipSync } from "node:zlib";
@@ -113406,16 +113915,23 @@ var ID_PATTERN = /^[a-z][a-z0-9-]{0,63}$/;
113406
113915
  var ExtensionService = class {
113407
113916
  loaded = null;
113408
113917
  loading = null;
113918
+ /** Counts scans started. Only the newest scan may replace `loaded`. */
113919
+ scanSeq = 0;
113409
113920
  root() {
113410
- return join53(bandHome(), "extensions");
113921
+ return join54(bandHome(), "extensions");
113411
113922
  }
113412
113923
  /** Reads every manifest again. A manifest that fails validation is skipped and listed as an error. */
113413
113924
  async reload() {
113925
+ const seq = ++this.scanSeq;
113414
113926
  const pending2 = this.scan();
113415
113927
  this.loading = pending2;
113416
113928
  try {
113417
- this.loaded = await pending2;
113418
- return this.loaded;
113929
+ const result = await pending2;
113930
+ if (seq === this.scanSeq) {
113931
+ this.loaded = result;
113932
+ return result;
113933
+ }
113934
+ return await this.loading ?? this.loaded ?? result;
113419
113935
  } finally {
113420
113936
  if (this.loading === pending2) this.loading = null;
113421
113937
  }
@@ -113432,7 +113948,7 @@ var ExtensionService = class {
113432
113948
  const errors = [];
113433
113949
  let folders;
113434
113950
  try {
113435
- folders = (await readdir7(this.root(), { withFileTypes: true })).filter((d) => (d.isDirectory() || d.isSymbolicLink()) && !d.name.startsWith(".")).map((d) => d.name).sort();
113951
+ folders = (await readdir9(this.root(), { withFileTypes: true })).filter((d) => (d.isDirectory() || d.isSymbolicLink()) && !d.name.startsWith(".")).map((d) => d.name).sort();
113436
113952
  } catch {
113437
113953
  return { extensions, errors };
113438
113954
  }
@@ -113443,7 +113959,7 @@ var ExtensionService = class {
113443
113959
  };
113444
113960
  let raw;
113445
113961
  try {
113446
- raw = await readFile12(join53(this.root(), folder, MANIFEST_FILE), "utf8");
113962
+ raw = await readFile14(join54(this.root(), folder, MANIFEST_FILE), "utf8");
113447
113963
  } catch {
113448
113964
  problem2(`${MANIFEST_FILE} not found`);
113449
113965
  continue;
@@ -113543,12 +114059,12 @@ var ExtensionService = class {
113543
114059
  }
113544
114060
  const root = this.root();
113545
114061
  const tag = randomBytes16(6).toString("hex");
113546
- const staging = join53(root, `.install-${tag}`);
113547
- const target = join53(root, folder);
113548
- const backup = join53(root, `.old-${tag}`);
114062
+ const staging = join54(root, `.install-${tag}`);
114063
+ const target = join54(root, folder);
114064
+ const backup = join54(root, `.old-${tag}`);
113549
114065
  try {
113550
114066
  for (const file3 of files) {
113551
- const dest = join53(staging, file3.path);
114067
+ const dest = join54(staging, file3.path);
113552
114068
  await mkdir10(dirname17(dest), { recursive: true });
113553
114069
  await writeFile8(dest, file3.data, { mode: 420 });
113554
114070
  }
@@ -113559,7 +114075,7 @@ var ExtensionService = class {
113559
114075
  } catch {
113560
114076
  }
113561
114077
  try {
113562
- await rename5(join53(staging, folder), target);
114078
+ await rename5(join54(staging, folder), target);
113563
114079
  } catch (err) {
113564
114080
  if (hadOld) await rename5(backup, target).catch(() => {
113565
114081
  });
@@ -113577,9 +114093,9 @@ var ExtensionService = class {
113577
114093
  async remove(id) {
113578
114094
  if (!ID_PATTERN.test(id))
113579
114095
  throw new ExtensionInstallError(`"${id}" is not a valid extension id`);
113580
- const dir = join53(this.root(), id);
114096
+ const dir = join54(this.root(), id);
113581
114097
  try {
113582
- await stat7(dir);
114098
+ await stat8(dir);
113583
114099
  } catch {
113584
114100
  throw new ExtensionInstallError(`No extension "${id}" is installed`);
113585
114101
  }
@@ -113597,7 +114113,7 @@ var ExtensionService = class {
113597
114113
  if (segments.some((s2) => s2 === ".." || s2 === "." || s2 === "")) return void 0;
113598
114114
  let dir;
113599
114115
  try {
113600
- dir = await realpath4(join53(this.root(), id));
114116
+ dir = await realpath4(join54(this.root(), id));
113601
114117
  } catch {
113602
114118
  return void 0;
113603
114119
  }
@@ -113607,11 +114123,11 @@ var ExtensionService = class {
113607
114123
  if (/\bgzip\b/.test(acceptEncoding)) wanted.push({ suffix: ".gz", encoding: "gzip" });
113608
114124
  wanted.push({ suffix: "" });
113609
114125
  for (const { suffix, encoding } of wanted) {
113610
- const candidate = join53(dir, ...segments) + suffix;
114126
+ const candidate = join54(dir, ...segments) + suffix;
113611
114127
  try {
113612
114128
  const real4 = await realpath4(candidate);
113613
114129
  if (!real4.startsWith(dir + sep7)) return void 0;
113614
- const info = await stat7(real4);
114130
+ const info = await stat8(real4);
113615
114131
  if (!info.isFile()) continue;
113616
114132
  return { stream: createReadStream4(real4), size: info.size, contentType, encoding };
113617
114133
  } catch {
@@ -113685,9 +114201,9 @@ async function downloadChecksum(url3) {
113685
114201
  var extensionService = new ExtensionService();
113686
114202
 
113687
114203
  // src/server/api/extensions/router.ts
113688
- async function refuse(run3) {
114204
+ async function refuse(run4) {
113689
114205
  try {
113690
- return await run3();
114206
+ return await run4();
113691
114207
  } catch (err) {
113692
114208
  if (err instanceof ExtensionInstallError) {
113693
114209
  throw new TRPCError({ code: "BAD_REQUEST", message: err.message });
@@ -114334,7 +114850,7 @@ init_registry();
114334
114850
  // package.json
114335
114851
  var package_default = {
114336
114852
  name: "@band-app/server",
114337
- version: "0.57.0",
114853
+ version: "0.59.0",
114338
114854
  type: "module",
114339
114855
  types: "src/index.ts",
114340
114856
  exports: {
@@ -114626,7 +115142,7 @@ import {
114626
115142
  rmSync as rmSync7,
114627
115143
  writeFileSync as writeFileSync8
114628
115144
  } from "node:fs";
114629
- import { join as join54 } from "node:path";
115145
+ import { join as join55 } from "node:path";
114630
115146
  init_settings();
114631
115147
  init_agent_session_service();
114632
115148
 
@@ -114734,10 +115250,10 @@ var HubUpdateError = class extends Error {
114734
115250
  };
114735
115251
  var HubUpdateService = class {
114736
115252
  runPath() {
114737
- return join54(bandHome(), "hub-update.json");
115253
+ return join55(bandHome(), "hub-update.json");
114738
115254
  }
114739
115255
  logPath() {
114740
- return join54(bandHome(), "hub-update.log");
115256
+ return join55(bandHome(), "hub-update.log");
114741
115257
  }
114742
115258
  read() {
114743
115259
  try {
@@ -114747,8 +115263,8 @@ var HubUpdateService = class {
114747
115263
  return null;
114748
115264
  }
114749
115265
  }
114750
- write(run3) {
114751
- writeFileSync8(this.runPath(), JSON.stringify(run3), { mode: 384 });
115266
+ write(run4) {
115267
+ writeFileSync8(this.runPath(), JSON.stringify(run4), { mode: 384 });
114752
115268
  }
114753
115269
  command() {
114754
115270
  const raw = settingsService.get().hubUpdate?.command;
@@ -114763,12 +115279,12 @@ var HubUpdateService = class {
114763
115279
  return "";
114764
115280
  }
114765
115281
  }
114766
- failed(run3, message) {
115282
+ failed(run4, message) {
114767
115283
  const tail = this.logTail();
114768
115284
  return {
114769
115285
  configured: this.command() !== null,
114770
115286
  state: "failed",
114771
- target: run3.target,
115287
+ target: run4.target,
114772
115288
  error: tail ? `${message}
114773
115289
  ${tail}` : message
114774
115290
  };
@@ -114776,21 +115292,21 @@ ${tail}` : message
114776
115292
  /** Where the run stands. Reads the state file, so it also answers after the hub restarted. */
114777
115293
  status() {
114778
115294
  const configured = this.command() !== null;
114779
- const run3 = this.read();
114780
- if (!run3) return { configured, state: "idle", target: null, error: null };
114781
- if ((compareVersions(HUB_VERSION, run3.target) ?? -1) >= 0) {
115295
+ const run4 = this.read();
115296
+ if (!run4) return { configured, state: "idle", target: null, error: null };
115297
+ if ((compareVersions(HUB_VERSION, run4.target) ?? -1) >= 0) {
114782
115298
  rmSync7(this.runPath(), { force: true });
114783
115299
  return { configured, state: "idle", target: null, error: null };
114784
115300
  }
114785
- if (run3.failure) return this.failed(run3, run3.failure);
114786
- if (BOOT_AT > run3.startedAt) {
114787
- return this.failed(run3, `The hub restarted on ${HUB_VERSION}, not ${run3.target}.`);
115301
+ if (run4.failure) return this.failed(run4, run4.failure);
115302
+ if (BOOT_AT > run4.startedAt) {
115303
+ return this.failed(run4, `The hub restarted on ${HUB_VERSION}, not ${run4.target}.`);
114788
115304
  }
114789
115305
  const wait = Number(process.env.BAND_HUB_UPDATE_TIMEOUT_MS);
114790
- if (Date.now() - run3.startedAt > (wait > 0 ? wait : DEFAULT_TIMEOUT_MS2)) {
114791
- return this.failed(run3, `The hub did not come back on ${run3.target} in time.`);
115306
+ if (Date.now() - run4.startedAt > (wait > 0 ? wait : DEFAULT_TIMEOUT_MS2)) {
115307
+ return this.failed(run4, `The hub did not come back on ${run4.target} in time.`);
114792
115308
  }
114793
- return { configured, state: "updating", target: run3.target, error: null };
115309
+ return { configured, state: "updating", target: run4.target, error: null };
114794
115310
  }
114795
115311
  /**
114796
115312
  * The agents a hub restart ends, on every worker. A hub restart stops every agent it runs,
@@ -114818,8 +115334,8 @@ ${tail}` : message
114818
115334
  );
114819
115335
  }
114820
115336
  mkdirSync10(bandHome(), { recursive: true });
114821
- const run3 = { target, startedAt: Date.now() };
114822
- this.write(run3);
115337
+ const run4 = { target, startedAt: Date.now() };
115338
+ this.write(run4);
114823
115339
  const fd = openSync5(this.logPath(), "w", 384);
114824
115340
  try {
114825
115341
  writeFileSync8(fd, `$ ${command2}
@@ -114845,12 +115361,12 @@ ${tail}` : message
114845
115361
  env
114846
115362
  });
114847
115363
  child.on("error", (err) => {
114848
- this.write({ ...run3, failure: `The command could not start: ${err.message}` });
115364
+ this.write({ ...run4, failure: `The command could not start: ${err.message}` });
114849
115365
  });
114850
115366
  child.on("exit", (code, signal) => {
114851
115367
  if (code === 0) return;
114852
115368
  this.write({
114853
- ...run3,
115369
+ ...run4,
114854
115370
  failure: `The command ${signal ? `was stopped by ${signal}` : `exited with code ${code}`}.`
114855
115371
  });
114856
115372
  });
@@ -119001,10 +119517,10 @@ var pluginsRouter = t.router({
119001
119517
  });
119002
119518
 
119003
119519
  // ../../packages/host-local/src/process/install.ts
119004
- import { execFile as execFile16 } from "node:child_process";
119520
+ import { execFile as execFile18 } from "node:child_process";
119005
119521
  async function brewInstall(pkg, resolvedPath) {
119006
119522
  await new Promise((resolve16, reject) => {
119007
- execFile16(
119523
+ execFile18(
119008
119524
  "brew",
119009
119525
  ["install", pkg],
119010
119526
  { env: { ...process.env, PATH: resolvedPath }, timeout: 12e4 },
@@ -119139,7 +119655,7 @@ init_src();
119139
119655
  init_dist();
119140
119656
  import { createHash as createHash14, randomBytes as randomBytes17, randomUUID as randomUUID19 } from "node:crypto";
119141
119657
  import { createReadStream as createReadStream5, existsSync as existsSync19, mkdirSync as mkdirSync11, rmSync as rmSync8, statSync as statSync15 } from "node:fs";
119142
- import { join as join55 } from "node:path";
119658
+ import { join as join56 } from "node:path";
119143
119659
 
119144
119660
  // src/server/infra/db/queries/provisions.ts
119145
119661
  init_drizzle_orm2();
@@ -119459,8 +119975,8 @@ function sha2562(text4) {
119459
119975
  function newSecret(prefix) {
119460
119976
  return `${prefix}${randomBytes17(32).toString("base64url")}`;
119461
119977
  }
119462
- function isLoopbackHost2(hostname6) {
119463
- const h = hostname6.replace(/^\[|\]$/g, "").toLowerCase();
119978
+ function isLoopbackHost2(hostname7) {
119979
+ const h = hostname7.replace(/^\[|\]$/g, "").toLowerCase();
119464
119980
  return h === "localhost" || h === "::1" || /^127\.\d+\.\d+\.\d+$/.test(h);
119465
119981
  }
119466
119982
  function checkHubUrl(input3) {
@@ -119497,7 +120013,7 @@ var ProvisioningService = class {
119497
120013
  return Date.now();
119498
120014
  }
119499
120015
  dir(id) {
119500
- return join55(bandHome(), "provisioning", id);
120016
+ return join56(bandHome(), "provisioning", id);
119501
120017
  }
119502
120018
  settings() {
119503
120019
  const s2 = settingsService.get().provisioning ?? {};
@@ -119617,7 +120133,7 @@ var ProvisioningService = class {
119617
120133
  /** The bundle file and size for a code, once its run token is shown. */
119618
120134
  bundle(code, runToken) {
119619
120135
  const row = this.authorize(code, runToken);
119620
- const file3 = join55(this.dir(row.id), "bundle.tgz");
120136
+ const file3 = join56(this.dir(row.id), "bundle.tgz");
119621
120137
  if (!row.repoUrl || !existsSync19(file3)) throw new ProvisionAuthError();
119622
120138
  return { stream: createReadStream5(file3), size: statSync15(file3).size };
119623
120139
  }
@@ -119696,7 +120212,7 @@ band provision: the worker did not say hello within ${minutes} min. Marked faile
119696
120212
  async buildBundle(id, settings3) {
119697
120213
  const dir = this.dir(id);
119698
120214
  mkdirSync11(dir, { recursive: true });
119699
- const src = join55(dir, "src");
120215
+ const src = join56(dir, "src");
119700
120216
  const host = hostRegistry.local;
119701
120217
  const env = { GIT_TERMINAL_PROMPT: "0" };
119702
120218
  const key2 = parseRemoteUrl2(settings3.repoUrl);
@@ -119718,10 +120234,10 @@ band provision: the worker did not say hello within ${minutes} min. Marked faile
119718
120234
  await host.exec("git", args, { env, timeoutMs: 12e4 });
119719
120235
  const sha = (await host.exec("git", ["-C", src, "rev-parse", "HEAD"], { env })).stdout.trim();
119720
120236
  const command2 = settings3.command || DEFAULT_START_COMMAND;
119721
- if (!existsSync19(join55(src, command2))) {
120237
+ if (!existsSync19(join56(src, command2))) {
119722
120238
  throw new Error(`the repo at ${sha.slice(0, 12)} has no ${command2}`);
119723
120239
  }
119724
- await host.exec("tar", ["-czf", join55(dir, "bundle.tgz"), "--exclude=.git", "-C", src, "."], {
120240
+ await host.exec("tar", ["-czf", join56(dir, "bundle.tgz"), "--exclude=.git", "-C", src, "."], {
119725
120241
  timeoutMs: 12e4
119726
120242
  });
119727
120243
  rmSync8(src, { recursive: true, force: true });
@@ -119814,7 +120330,7 @@ init_zod();
119814
120330
  init_registry();
119815
120331
  init_queued_message_store();
119816
120332
  import { realpathSync as realpathSync6 } from "node:fs";
119817
- import { join as join56, resolve as resolve11, sep as sep8 } from "node:path";
120333
+ import { join as join57, resolve as resolve11, sep as sep8 } from "node:path";
119818
120334
  init_chat_ownership_service();
119819
120335
  init_chat_service();
119820
120336
  init_state();
@@ -119827,7 +120343,7 @@ var queuedFileSchema = external_exports2.object({
119827
120343
  filename: external_exports2.string().optional()
119828
120344
  });
119829
120345
  function isPathWithinUploadDir(p2) {
119830
- const uploadDir = join56(bandHome(), "uploads");
120346
+ const uploadDir = join57(bandHome(), "uploads");
119831
120347
  const normalized2 = resolve11(p2);
119832
120348
  if (normalized2 !== uploadDir && !normalized2.startsWith(uploadDir + sep8)) {
119833
120349
  return false;
@@ -120640,6 +121156,186 @@ var reposRouter = t.router({
120640
121156
  })
120641
121157
  });
120642
121158
 
121159
+ // src/server/api/resources/router.ts
121160
+ init_dist();
121161
+ init_zod();
121162
+
121163
+ // src/server/services/resources-service.ts
121164
+ init_worktree_id();
121165
+ init_registry();
121166
+ init_agent_session_service();
121167
+ init_chat_service();
121168
+ init_state();
121169
+ init_task_service();
121170
+ init_token_service();
121171
+ var LOCAL_HOST_ID13 = "local";
121172
+ var SNAPSHOT_TIMEOUT_MS = 8e3;
121173
+ var IDLE_AGENT_MS = 60 * 6e4;
121174
+ function withTimeout3(promise2, ms) {
121175
+ return new Promise((resolve16, reject) => {
121176
+ const timer = setTimeout(() => reject(new Error("timed out")), ms);
121177
+ promise2.then(
121178
+ (v2) => {
121179
+ clearTimeout(timer);
121180
+ resolve16(v2);
121181
+ },
121182
+ (e) => {
121183
+ clearTimeout(timer);
121184
+ reject(e);
121185
+ }
121186
+ );
121187
+ });
121188
+ }
121189
+ function knownWorktrees() {
121190
+ const out = [];
121191
+ for (const repo of loadState().repos) {
121192
+ for (const wt of repo.worktrees) {
121193
+ const hostId2 = wt.hostId ?? LOCAL_HOST_ID13;
121194
+ out.push({
121195
+ id: toWorktreeId(repo.name, wt.name, wt.hostId),
121196
+ repo: repo.name,
121197
+ branch: wt.branch,
121198
+ title: wt.title ?? null,
121199
+ hostId: hostId2,
121200
+ path: wt.path
121201
+ });
121202
+ }
121203
+ }
121204
+ return out;
121205
+ }
121206
+ function refOf(w2) {
121207
+ return { id: w2.id, repo: w2.repo, branch: w2.branch, title: w2.title };
121208
+ }
121209
+ function worktreeOf(proc, hostId2, worktrees2) {
121210
+ if (proc.worktreeId) {
121211
+ const byId = worktrees2.find((w2) => w2.id === proc.worktreeId);
121212
+ if (byId) return refOf(byId);
121213
+ }
121214
+ if (!proc.cwd) return void 0;
121215
+ const cwd = proc.cwd;
121216
+ let best;
121217
+ for (const w2 of worktrees2) {
121218
+ if (w2.hostId !== hostId2 || !w2.path) continue;
121219
+ if (cwd === w2.path || cwd.startsWith(`${w2.path}/`)) {
121220
+ if (!best || w2.path.length > best.path.length) best = w2;
121221
+ }
121222
+ }
121223
+ return best ? refOf(best) : void 0;
121224
+ }
121225
+ function chatOf(chatId, now) {
121226
+ if (!chatId) return void 0;
121227
+ const chat = chatService.get(chatId);
121228
+ if (!chat) return void 0;
121229
+ const running = hasRunningTask(chatId);
121230
+ const last = agentSessionService.lastActivityAt(chatId);
121231
+ const idleMs2 = last === null ? null : Math.max(0, now - last);
121232
+ return {
121233
+ id: chat.id,
121234
+ name: chat.name,
121235
+ agent: chat.agent,
121236
+ running,
121237
+ idleMs: idleMs2,
121238
+ idle: !running && idleMs2 !== null && idleMs2 >= IDLE_AGENT_MS
121239
+ };
121240
+ }
121241
+ function chatIdOf(p2, hostId2, pids) {
121242
+ if (p2.chatId) return p2.chatId;
121243
+ if (p2.kind !== "agent") return void 0;
121244
+ return pids.find(
121245
+ (a) => a.pid === p2.pid && (hostRegistry.hostIdOfScope(a.worktreeId) ?? LOCAL_HOST_ID13) === hostId2
121246
+ )?.chatId;
121247
+ }
121248
+ async function readMachine(host, builtInWorker, worktrees2, now, agentPids) {
121249
+ const isLocal = host.id === LOCAL_HOST_ID13;
121250
+ const base = {
121251
+ id: host.id,
121252
+ role: isLocal ? "hub" : "worker",
121253
+ name: isLocal ? "Hub" : host.name,
121254
+ version: host.version,
121255
+ builtInWorker: isLocal && builtInWorker,
121256
+ onBattery: null
121257
+ };
121258
+ if (!isLocal && host.status !== "online") {
121259
+ return { ...base, status: "unavailable", reason: "offline", snapshot: null };
121260
+ }
121261
+ try {
121262
+ const target = hostRegistry.hostById(host.id);
121263
+ const snap = await withTimeout3(target.resources.snapshot(), SNAPSHOT_TIMEOUT_MS);
121264
+ const processes = snap.processes.map((p2) => {
121265
+ const chatId = chatIdOf(p2, host.id, agentPids);
121266
+ const worktree = worktreeOf(
121267
+ chatId && !p2.worktreeId ? { ...p2, worktreeId: chatService.get(chatId)?.worktreeId ?? p2.worktreeId } : p2,
121268
+ host.id,
121269
+ worktrees2
121270
+ );
121271
+ const chat = chatOf(chatId, now);
121272
+ const { command: _command, cwd: _cwd, ...rest } = p2;
121273
+ return { ...rest, ...worktree ? { worktree } : {}, ...chat ? { chat } : {} };
121274
+ });
121275
+ return { ...base, status: "ok", reason: null, snapshot: { ...snap, processes } };
121276
+ } catch {
121277
+ return { ...base, status: "unavailable", reason: "no-answer", snapshot: null };
121278
+ }
121279
+ }
121280
+ async function listResources() {
121281
+ const now = Date.now();
121282
+ const worktrees2 = knownWorktrees();
121283
+ const agentPids = agentSessionService.agentPids();
121284
+ const hosts3 = tokenService.listHosts();
121285
+ const builtIn = hosts3.find((h) => h.id === LOCAL_HOST_ID13)?.usable ?? false;
121286
+ const wanted = hosts3.filter((h) => h.id !== LOCAL_HOST_ID13);
121287
+ const local = hosts3.find((h) => h.id === LOCAL_HOST_ID13) ?? {
121288
+ id: LOCAL_HOST_ID13,
121289
+ name: "Hub",
121290
+ version: null,
121291
+ status: "online"
121292
+ };
121293
+ const machines = await Promise.all(
121294
+ [local, ...wanted].map(
121295
+ (h) => readMachine(
121296
+ { id: h.id, name: h.name, version: h.version ?? null, status: h.status },
121297
+ builtIn,
121298
+ worktrees2,
121299
+ now,
121300
+ agentPids
121301
+ )
121302
+ )
121303
+ );
121304
+ return { takenAt: now, machines };
121305
+ }
121306
+ async function resourceStorage(hostId2) {
121307
+ const worktrees2 = knownWorktrees().filter((w2) => w2.hostId === hostId2 && w2.path);
121308
+ const host = hostRegistry.hostById(hostId2);
121309
+ const result = await host.resources.storage({
121310
+ worktrees: worktrees2.map((w2) => ({ id: w2.id, path: w2.path }))
121311
+ });
121312
+ const byId = new Map(worktrees2.map((w2) => [w2.id, w2]));
121313
+ return {
121314
+ worktrees: result.worktrees.flatMap((r) => {
121315
+ const w2 = byId.get(r.id);
121316
+ return w2 ? [{ ...refOf(w2), sizeBytes: r.sizeBytes, ...r.error ? { error: r.error } : {} }] : [];
121317
+ }),
121318
+ state: result.state,
121319
+ disk: result.disk
121320
+ };
121321
+ }
121322
+
121323
+ // src/server/api/resources/router.ts
121324
+ var resourcesRouter = t.router({
121325
+ snapshot: publicProcedure.query(() => listResources()),
121326
+ storage: publicProcedure.input(external_exports2.object({ hostId: external_exports2.string().min(1) })).query(async ({ input: input3 }) => {
121327
+ try {
121328
+ return await resourceStorage(input3.hostId);
121329
+ } catch (err) {
121330
+ console.error(`[resources] storage on ${input3.hostId} failed:`, err);
121331
+ throw new TRPCError({
121332
+ code: "SERVICE_UNAVAILABLE",
121333
+ message: `Could not measure storage on ${input3.hostId}`
121334
+ });
121335
+ }
121336
+ })
121337
+ });
121338
+
120643
121339
  // src/server/api/reviews/router.ts
120644
121340
  init_dist();
120645
121341
  init_zod();
@@ -120692,12 +121388,12 @@ function allowed(args) {
120692
121388
  var UNAUTHENTICATED2 = /gh auth login|GH_TOKEN|GITHUB_TOKEN|authentication|HTTP 401|bad credentials/i;
120693
121389
  var MISSING_GH = /ENOENT|command not found|executable file not found|no such file/i;
120694
121390
  var GH_TIMEOUT_MS2 = 3e4;
120695
- function withTimeout3(run3) {
121391
+ function withTimeout4(run4) {
120696
121392
  let timer;
120697
121393
  const timeout = new Promise((_2, reject) => {
120698
121394
  timer = setTimeout(() => reject(new Error("gh timed out")), GH_TIMEOUT_MS2);
120699
121395
  });
120700
- return Promise.race([run3, timeout]).finally(() => clearTimeout(timer));
121396
+ return Promise.race([run4, timeout]).finally(() => clearTimeout(timer));
120701
121397
  }
120702
121398
  function firstLine2(err) {
120703
121399
  return (err instanceof Error ? err.message : String(err)).split("\n")[0];
@@ -120724,17 +121420,17 @@ function fallbackGh(args, cwd) {
120724
121420
  function worktreeGh(host, localHostId, cwd) {
120725
121421
  return async (args) => {
120726
121422
  if (!allowed(args)) throw new Error(`gh ${args.slice(0, 2).join(" ")} is not allowed here`);
120727
- if (host.id === localHostId) return withTimeout3(localGh(args, cwd));
121423
+ if (host.id === localHostId) return withTimeout4(localGh(args, cwd));
120728
121424
  let hostError;
120729
121425
  try {
120730
- return (await withTimeout3(host.git.gh(args, cwd))).stdout;
121426
+ return (await withTimeout4(host.git.gh(args, cwd))).stdout;
120731
121427
  } catch (err) {
120732
121428
  if (err instanceof Error) err.message = err.message.trim();
120733
121429
  if (!hostCannotAnswer(err)) throw err;
120734
121430
  hostError = err;
120735
121431
  }
120736
121432
  try {
120737
- return await withTimeout3(fallbackGh(args, tmpdir5()));
121433
+ return await withTimeout4(fallbackGh(args, tmpdir5()));
120738
121434
  } catch (hubError) {
120739
121435
  if (!hostCannotAnswer(hubError)) throw hubError;
120740
121436
  throw new Error(
@@ -122548,7 +123244,7 @@ init_speech_transcription();
122548
123244
  init_registry();
122549
123245
  init_settings_service();
122550
123246
  init_vault_service();
122551
- var LOCAL_HOST_ID13 = "local";
123247
+ var LOCAL_HOST_ID14 = "local";
122552
123248
  function readConfig2() {
122553
123249
  return settingsService.get().voice ?? {};
122554
123250
  }
@@ -122598,7 +123294,7 @@ var VoiceService = class {
122598
123294
  }
122599
123295
  if (!config3.model?.trim()) throw new SpeechError("not_configured", "Enter a model first.");
122600
123296
  await this.send(config3, silentWav(1), "audio/wav");
122601
- return { ok: true, hostId: config3.hostId || LOCAL_HOST_ID13 };
123297
+ return { ok: true, hostId: config3.hostId || LOCAL_HOST_ID14 };
122602
123298
  }
122603
123299
  async send(config3, audio, mimeType) {
122604
123300
  if (audio.byteLength === 0) throw new SpeechError("bad_response", "The recording is empty.");
@@ -122611,7 +123307,7 @@ var VoiceService = class {
122611
123307
  const apiKey = await this.apiKey(config3.apiKeyItemId);
122612
123308
  try {
122613
123309
  const hostId2 = config3.hostId?.trim();
122614
- if (!hostId2 || hostId2 === LOCAL_HOST_ID13) {
123310
+ if (!hostId2 || hostId2 === LOCAL_HOST_ID14) {
122615
123311
  return await requestTranscription({ baseUrl, apiKey, model, language, audio, mimeType });
122616
123312
  }
122617
123313
  let host;
@@ -122622,7 +123318,7 @@ var VoiceService = class {
122622
123318
  }
122623
123319
  let result;
122624
123320
  try {
122625
- result = await withTimeout4(
123321
+ result = await withTimeout5(
122626
123322
  host.speech.transcribe({ baseUrl, apiKey, model, language, audio, mimeType }),
122627
123323
  WORKER_TRANSCRIBE_TIMEOUT_MS
122628
123324
  );
@@ -122667,7 +123363,7 @@ var VoiceService = class {
122667
123363
  function scrub2(message, apiKey) {
122668
123364
  return scrubSecrets(message, apiKey);
122669
123365
  }
122670
- function withTimeout4(promise2, ms) {
123366
+ function withTimeout5(promise2, ms) {
122671
123367
  let timer;
122672
123368
  const timeout = new Promise((_2, reject) => {
122673
123369
  timer = setTimeout(
@@ -122925,7 +123621,7 @@ function verifyWorktreePreviewGrant(worktreeId4, grant, filePath, now = Date.now
122925
123621
  init_src3();
122926
123622
  init_src();
122927
123623
  init_resolver();
122928
- import { join as join57, resolve as resolve12, sep as sep9 } from "node:path";
123624
+ import { join as join58, resolve as resolve12, sep as sep9 } from "node:path";
122929
123625
  var log82 = createLogger("diff-service");
122930
123626
  var EMPTY_TREE_ARGS = ["hash-object", "-t", "tree", "/dev/null"];
122931
123627
  var DEFAULT_BRANCH_LIMIT = 50;
@@ -123022,7 +123718,7 @@ function parseFileStatuses(nameStatusOutput) {
123022
123718
  return fileStatuses;
123023
123719
  }
123024
123720
  function assertWorktreeRelative(cwd, filePath) {
123025
- const target = resolve12(join57(cwd, filePath));
123721
+ const target = resolve12(join58(cwd, filePath));
123026
123722
  if (target !== cwd && !target.startsWith(cwd + sep9)) {
123027
123723
  throw new Error("Invalid path");
123028
123724
  }
@@ -123037,7 +123733,7 @@ function assertWorktreeRelative(cwd, filePath) {
123037
123733
  }
123038
123734
  async function readUntrackedFileLines(host, cwd, file3) {
123039
123735
  try {
123040
- const content = new TextDecoder().decode(await host.fs.readFile(join57(cwd, file3)));
123736
+ const content = new TextDecoder().decode(await host.fs.readFile(join58(cwd, file3)));
123041
123737
  const lines = content.split("\n");
123042
123738
  if (lines.length > 0 && lines[lines.length - 1] === "") {
123043
123739
  lines.pop();
@@ -123384,7 +124080,7 @@ var DiffService = class {
123384
124080
  const compareBranch = options.compareBranch ?? defaultBranch;
123385
124081
  const cwd = worktree.worktree.path;
123386
124082
  const execGit2 = gitRunner(worktree.host);
123387
- const hasGit = await worktree.host.fs.stat(join57(cwd, ".git")).then(
124083
+ const hasGit = await worktree.host.fs.stat(join58(cwd, ".git")).then(
123388
124084
  () => true,
123389
124085
  (err) => {
123390
124086
  if (err instanceof HostOfflineError || err instanceof HostTimeoutError) throw err;
@@ -123422,7 +124118,7 @@ var DiffService = class {
123422
124118
  applyLineCounts(status.staged, parseNumstat(stagedNumstat));
123423
124119
  await Promise.all(
123424
124120
  status.untracked.map(async (entry) => {
123425
- const lines = await countUntrackedLines(worktree.host, join57(cwd, entry.path));
124121
+ const lines = await countUntrackedLines(worktree.host, join58(cwd, entry.path));
123426
124122
  if (lines !== null) {
123427
124123
  entry.additions = lines;
123428
124124
  entry.deletions = 0;
@@ -123626,7 +124322,7 @@ var directAccessService = new DirectAccessService();
123626
124322
 
123627
124323
  // ../../packages/worktree-ops/src/files.ts
123628
124324
  init_resolver();
123629
- import { dirname as dirname18, extname as extname3, join as join58, resolve as resolve13, sep as sep10 } from "node:path";
124325
+ import { dirname as dirname18, extname as extname3, join as join59, resolve as resolve13, sep as sep10 } from "node:path";
123630
124326
  var MAX_FILE_SIZE2 = 1024 * 1024;
123631
124327
  var LANG_MAP2 = {
123632
124328
  ".js": "javascript",
@@ -123693,7 +124389,7 @@ var FilesService = class {
123693
124389
  throw new WorktreeNotFoundError(worktreeId4);
123694
124390
  }
123695
124391
  const root = worktree.worktree.path;
123696
- const target = resolve13(join58(root, relative2));
124392
+ const target = resolve13(join59(root, relative2));
123697
124393
  const insideRoot = target === root || target.startsWith(root + sep10);
123698
124394
  if (!insideRoot) {
123699
124395
  throw new Error("Invalid path");
@@ -125437,6 +126133,7 @@ var appRouter = t.router({
125437
126133
  ...terminalsRouters,
125438
126134
  cli: cliRouter,
125439
126135
  accountUsage: accountUsageRouter,
126136
+ resources: resourcesRouter,
125440
126137
  hooks: hooksRouter,
125441
126138
  host: hostRouter,
125442
126139
  workers: hostsRouter,
@@ -125484,7 +126181,8 @@ function discoverProcedures() {
125484
126181
  for (const [path2, procedure] of Object.entries(procRecord)) {
125485
126182
  const type = procedure._def.type;
125486
126183
  if (type === "subscription") continue;
125487
- if (path2.startsWith("tokens.") || path2.startsWith("vault.") || path2.startsWith("agentLogins.") || path2.startsWith("checkpoints.") || path2.startsWith("follow.") || path2.startsWith("mcp.") || path2.startsWith("hosts.") && path2 !== "hosts.forAgents" || path2.startsWith("workers.") && path2 !== "workers.forAgents" || path2.startsWith("hostRequests.") || path2.startsWith("runners.") || path2.startsWith("accountUsage.") || // The Simulator tab is a person's; an agent uses the simulator_* tools.
126184
+ if (path2.startsWith("tokens.") || path2.startsWith("vault.") || path2.startsWith("agentLogins.") || path2.startsWith("checkpoints.") || path2.startsWith("follow.") || path2.startsWith("mcp.") || path2.startsWith("hosts.") && path2 !== "hosts.forAgents" || path2.startsWith("workers.") && path2 !== "workers.forAgents" || path2.startsWith("hostRequests.") || path2.startsWith("runners.") || path2.startsWith("accountUsage.") || // The machine's process table and disk use are a person's page, not an agent's tool.
126185
+ path2.startsWith("resources.") || // The Simulator tab is a person's; an agent uses the simulator_* tools.
125488
126186
  path2.startsWith("simulators.") || path2.startsWith("voice.") || path2.startsWith("extensions.") || path2.startsWith("provisioning.") || // Writes ~/.claude/settings.json on a host; only a person's click may.
125489
126187
  path2.startsWith("hooks."))
125490
126188
  continue;
@@ -125968,12 +126666,12 @@ function lookUpToolsOnce(server, listPage) {
125968
126666
  if (running) return running;
125969
126667
  const last = lookupMissedAt.get(server.id);
125970
126668
  if (last !== void 0 && Date.now() - last < LOOKUP_COOLDOWN_MS) return Promise.resolve();
125971
- const run3 = lookUpTools(server, listPage).catch(() => void 0).finally(() => {
126669
+ const run4 = lookUpTools(server, listPage).catch(() => void 0).finally(() => {
125972
126670
  lookupsInFlight.delete(server.id);
125973
126671
  lookupMissedAt.set(server.id, Date.now());
125974
126672
  });
125975
- lookupsInFlight.set(server.id, run3);
125976
- return run3;
126673
+ lookupsInFlight.set(server.id, run4);
126674
+ return run4;
125977
126675
  }
125978
126676
  async function lookUpTools(server, listPage) {
125979
126677
  const tools = /* @__PURE__ */ new Map();
@@ -127324,14 +128022,14 @@ async function handleVoiceTranscribe(req, res) {
127324
128022
 
127325
128023
  // src/server/api/web-app-manifest.ts
127326
128024
  import { createReadStream as createReadStream6, statSync as statSync16 } from "node:fs";
127327
- import { join as join59 } from "node:path";
128025
+ import { join as join60 } from "node:path";
127328
128026
  var WEB_APP_MANIFEST_PATH = "/manifest.webmanifest";
127329
128027
  var ICON_FILES = ["band-192.png", "band-512.png", "apple-touch-icon.png"];
127330
128028
  function handleWebAppManifest(req, res, publicDir) {
127331
128029
  if (req.method !== "GET" && req.method !== "HEAD") return false;
127332
128030
  const pathname = req.url?.split("?")[0];
127333
128031
  if (pathname === WEB_APP_MANIFEST_PATH) {
127334
- sendFile(req, res, join59(publicDir, "manifest.webmanifest"), {
128032
+ sendFile(req, res, join60(publicDir, "manifest.webmanifest"), {
127335
128033
  "Content-Type": "application/manifest+json",
127336
128034
  "Cache-Control": "no-cache"
127337
128035
  });
@@ -127339,7 +128037,7 @@ function handleWebAppManifest(req, res, publicDir) {
127339
128037
  }
127340
128038
  const icon = ICON_FILES.find((name5) => pathname === `/icons/${name5}`);
127341
128039
  if (!icon) return false;
127342
- sendFile(req, res, join59(publicDir, "icons", icon), {
128040
+ sendFile(req, res, join60(publicDir, "icons", icon), {
127343
128041
  "Content-Type": "image/png",
127344
128042
  "Cache-Control": "public, max-age=86400"
127345
128043
  });
@@ -128132,7 +128830,7 @@ init_http_files();
128132
128830
 
128133
128831
  // src/server/services/_utils/hosted-file.ts
128134
128832
  init_registry();
128135
- import { basename as basename6, dirname as dirname19, join as join60 } from "node:path";
128833
+ import { basename as basename6, dirname as dirname19, join as join61 } from "node:path";
128136
128834
  async function openHostedFile(kind, worktreeId4, rawName, chatId) {
128137
128835
  const host = hostRegistry.hostFor(worktreeId4);
128138
128836
  if (host.id === hostRegistry.local.id) return null;
@@ -128146,12 +128844,12 @@ async function openHostedFile(kind, worktreeId4, rawName, chatId) {
128146
128844
  try {
128147
128845
  const dirs = (await host.info()).dirs;
128148
128846
  if (!dirs) return null;
128149
- const path2 = chatId ? join60(dirs[kind], worktreeId4, chatId, name5) : join60(dirs[kind], worktreeId4, name5);
128847
+ const path2 = chatId ? join61(dirs[kind], worktreeId4, chatId, name5) : join61(dirs[kind], worktreeId4, name5);
128150
128848
  const dir = await host.fs.realpath(dirname19(path2));
128151
128849
  if (!(await host.fs.realpath(path2)).startsWith(`${dir}/`)) return null;
128152
- const stat8 = await host.fs.stat(path2, { followSymlinks: true });
128153
- if (stat8.kind !== "file") return null;
128154
- return { size: stat8.size, stream: host.fs.readStream(path2) };
128850
+ const stat9 = await host.fs.stat(path2, { followSymlinks: true });
128851
+ if (stat9.kind !== "file") return null;
128852
+ return { size: stat9.size, stream: host.fs.readStream(path2) };
128155
128853
  } catch {
128156
128854
  return null;
128157
128855
  }
@@ -136514,7 +137212,7 @@ init_worktree_service();
136514
137212
  function logCrash(message) {
136515
137213
  try {
136516
137214
  mkdirSync12(bandHome(), { recursive: true });
136517
- appendFileSync2(join61(bandHome(), "server.log"), message, "utf-8");
137215
+ appendFileSync2(join62(bandHome(), "server.log"), message, "utf-8");
136518
137216
  } catch {
136519
137217
  }
136520
137218
  }
@@ -136554,9 +137252,9 @@ function resolveUiDir() {
136554
137252
  if (explicit) return resolve15(explicit);
136555
137253
  const candidates = [
136556
137254
  resolve15(SERVER_ROOT, "..", "..", "web", "dist", "client"),
136557
- join61(SERVER_ROOT, "client")
137255
+ join62(SERVER_ROOT, "client")
136558
137256
  ];
136559
- return candidates.find((dir) => existsSync20(join61(dir, "_shell.html"))) ?? candidates[1];
137257
+ return candidates.find((dir) => existsSync20(join62(dir, "_shell.html"))) ?? candidates[1];
136560
137258
  }
136561
137259
  var clientDir = resolveUiDir();
136562
137260
  var uiRoot = process.env.BAND_UI_ROOT ? resolve15(process.env.BAND_UI_ROOT) : resolve15(SERVER_ROOT, "..", "web");
@@ -136607,7 +137305,7 @@ function getOpenApiSpec() {
136607
137305
  if (isDev) {
136608
137306
  const { generateOpenAPIDocument } = await import("@trpc/openapi");
136609
137307
  const doc = await generateOpenAPIDocument(
136610
- join61(SERVER_ROOT, "src", "server", "api", "router.ts"),
137308
+ join62(SERVER_ROOT, "src", "server", "api", "router.ts"),
136611
137309
  {
136612
137310
  title: "Band API",
136613
137311
  version: "1.0.0"
@@ -136616,7 +137314,7 @@ function getOpenApiSpec() {
136616
137314
  doc.servers = [{ url: "/trpc" }];
136617
137315
  return JSON.stringify(doc, null, 2);
136618
137316
  }
136619
- const openApiDoc = JSON.parse(readFileSync14(join61(SERVER_ROOT, "openapi.json"), "utf-8"));
137317
+ const openApiDoc = JSON.parse(readFileSync14(join62(SERVER_ROOT, "openapi.json"), "utf-8"));
136620
137318
  openApiDoc.servers = [{ url: "/trpc" }];
136621
137319
  return JSON.stringify(openApiDoc, null, 2);
136622
137320
  })().catch((err) => {
@@ -136639,9 +137337,9 @@ function serveStaticFile(res, root, subdir, rawFilename) {
136639
137337
  res.end("Bad request");
136640
137338
  return;
136641
137339
  }
136642
- const filePath = join61(root, subdir, filename);
137340
+ const filePath = join62(root, subdir, filename);
136643
137341
  try {
136644
- const dir = realpathSync7(join61(root, subdir));
137342
+ const dir = realpathSync7(join62(root, subdir));
136645
137343
  if (!realpathSync7(filePath).startsWith(dir + sep12)) {
136646
137344
  res.writeHead(404);
136647
137345
  res.end("Not found");
@@ -136692,7 +137390,7 @@ async function serveWorktreeFile(res, worktreeId4, rawPath, extraHeaders = {}, v
136692
137390
  return;
136693
137391
  }
136694
137392
  const root = worktree.worktree.path;
136695
- const target = resolve15(join61(root, rawPath));
137393
+ const target = resolve15(join62(root, rawPath));
136696
137394
  if (!target.startsWith(root + sep12) && target !== root) {
136697
137395
  res.writeHead(400);
136698
137396
  res.end("Bad request");
@@ -137025,7 +137723,7 @@ async function main() {
137025
137723
  res.end(JSON.stringify({ status: "ok", app: "band-web-server" }));
137026
137724
  return;
137027
137725
  }
137028
- if (handleWebAppManifest(req, res, isDev ? join61(uiRoot, "public") : clientDir)) return;
137726
+ if (handleWebAppManifest(req, res, isDev ? join62(uiRoot, "public") : clientDir)) return;
137029
137727
  if (req.url?.split("?")[0] === WORKER_EXCHANGE_PATH) {
137030
137728
  await workerLinkService.handleExchange(req, res);
137031
137729
  return;
@@ -137137,7 +137835,7 @@ async function main() {
137137
137835
  const encodedName = encodeURIComponent(parsed.name);
137138
137836
  if (await serveHostedFile(res, "shared", parsed.worktreeId, encodedName, parsed.chatId))
137139
137837
  return;
137140
- const subdir = parsed.chatId ? join61("shared", parsed.worktreeId, parsed.chatId) : join61("shared", parsed.worktreeId);
137838
+ const subdir = parsed.chatId ? join62("shared", parsed.worktreeId, parsed.chatId) : join62("shared", parsed.worktreeId);
137141
137839
  serveStaticFile(res, bandHome(), subdir, encodedName);
137142
137840
  return;
137143
137841
  }
@@ -137363,7 +138061,7 @@ async function main() {
137363
138061
  if (pathname.startsWith("/_shell")) res.setHeader("Cache-Control", "no-cache");
137364
138062
  }
137365
138063
  });
137366
- const shellPath2 = join61(clientDir, "_shell.html");
138064
+ const shellPath2 = join62(clientDir, "_shell.html");
137367
138065
  if (!existsSync20(shellPath2)) {
137368
138066
  throw new Error(
137369
138067
  `UI build not found at ${clientDir} (no _shell.html). Run \`pnpm build\` or pass --ui-dir <path>.`