repoburg 1.3.201 → 1.3.202

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 (86) hide show
  1. package/agent-pane/backend/data.db-shm +0 -0
  2. package/agent-pane/backend/data.db-wal +0 -0
  3. package/agent-pane/backend/dist/index.js +478 -250
  4. package/agent-pane/backend/src/db/index.ts +6 -0
  5. package/agent-pane/backend/src/providers/runtime-provider.ts +6 -0
  6. package/agent-pane/backend/src/repoburg/action-mapping.test.ts +122 -0
  7. package/agent-pane/backend/src/repoburg/action-mapping.ts +89 -11
  8. package/agent-pane/backend/src/repoburg/agent-runtime-client.ts +23 -0
  9. package/agent-pane/backend/src/repoburg/backend-resolver.test.ts +85 -0
  10. package/agent-pane/backend/src/repoburg/backend-resolver.ts +28 -13
  11. package/agent-pane/backend/src/repoburg/repoburg-client.test.ts +21 -0
  12. package/agent-pane/backend/src/repoburg/repoburg-client.ts +13 -0
  13. package/agent-pane/backend/src/repoburg/repoburg-provider.test.ts +57 -0
  14. package/agent-pane/backend/src/repoburg/repoburg-provider.ts +49 -0
  15. package/agent-pane/backend/src/repoburg/turn-projector.test.ts +147 -1
  16. package/agent-pane/backend/src/repoburg/turn-projector.ts +101 -1
  17. package/agent-pane/backend/src/routes/sessions.test.ts +215 -1
  18. package/agent-pane/backend/src/routes/sessions.ts +70 -9
  19. package/agent-pane/frontend/dist/assets/index-CJxD4YmJ.js +370 -0
  20. package/agent-pane/frontend/dist/assets/{index-34WaZYsW.css → index-r-xwfOKQ.css} +1 -1
  21. package/agent-pane/frontend/dist/index.html +2 -2
  22. package/agent-pane/frontend/src/api/sessions.test.ts +1 -0
  23. package/agent-pane/frontend/src/api/websocket.test.ts +2 -2
  24. package/agent-pane/frontend/src/api/websocket.ts +3 -1
  25. package/agent-pane/frontend/src/components/AskUserItem.test.tsx +143 -0
  26. package/agent-pane/frontend/src/components/AskUserItem.tsx +207 -0
  27. package/agent-pane/frontend/src/components/TurnContent.test.tsx +79 -0
  28. package/agent-pane/frontend/src/components/TurnContent.tsx +49 -3
  29. package/agent-pane/frontend/src/components/panels/TurnsPanel.test.tsx +48 -0
  30. package/agent-pane/frontend/src/components/panels/TurnsPanel.tsx +7 -2
  31. package/agent-pane/frontend/src/store/store.test.ts +19 -0
  32. package/agent-pane/frontend/src/store/wsSlice.ts +10 -3
  33. package/agent-pane/frontend/src/styles/app.css +16 -0
  34. package/agent-pane/frontend/src/test/fixtures.ts +1 -0
  35. package/agent-pane/frontend/src/types/index.ts +2 -0
  36. package/agent-pane/frontend/src/utils/duration.test.ts +1 -0
  37. package/agent-pane/shared/types.ts +17 -0
  38. package/askuser-after-step5-postgres-selected.png +0 -0
  39. package/askuser-after-step7-answer-sent.png +0 -0
  40. package/askuser-card-visible.png +0 -0
  41. package/backend/dist/src/agent-runtime/agent-runtime-event-emitter.d.ts +16 -0
  42. package/backend/dist/src/agent-runtime/agent-runtime-event-emitter.js +87 -0
  43. package/backend/dist/src/agent-runtime/agent-runtime-event-emitter.js.map +1 -1
  44. package/backend/dist/src/agent-runtime/agent-runtime.types.d.ts +16 -1
  45. package/backend/dist/src/app.controller.d.ts +1 -0
  46. package/backend/dist/src/app.service.d.ts +1 -0
  47. package/backend/dist/src/app.service.js +4 -1
  48. package/backend/dist/src/app.service.js.map +1 -1
  49. package/backend/dist/src/interactive-chat/chat.service.d.ts +4 -0
  50. package/backend/dist/src/interactive-chat/chat.service.js +21 -1
  51. package/backend/dist/src/interactive-chat/chat.service.js.map +1 -1
  52. package/backend/dist/src/llm-orchestration/action-handlers/invoke-subagent.handler.js +12 -1
  53. package/backend/dist/src/llm-orchestration/action-handlers/invoke-subagent.handler.js.map +1 -1
  54. package/backend/dist/src/llm-orchestration/llm-orchestration.interfaces.d.ts +1 -0
  55. package/backend/dist/src/llm-orchestration/llm-orchestration.interfaces.js +1 -0
  56. package/backend/dist/src/llm-orchestration/llm-orchestration.interfaces.js.map +1 -1
  57. package/backend/dist/src/llm-orchestration/llm-turn-processor.service.js +2 -0
  58. package/backend/dist/src/llm-orchestration/llm-turn-processor.service.js.map +1 -1
  59. package/backend/dist/tsconfig.build.tsbuildinfo +1 -1
  60. package/daemon/dist/api/services.js +4 -0
  61. package/daemon/dist/serviceManager.js +30 -11
  62. package/daemon/dist/serviceManager.spec.js +26 -0
  63. package/daemon/dist/workspace-validation.js +63 -0
  64. package/daemon/dist/workspace-validation.spec.js +63 -0
  65. package/package.json +1 -1
  66. package/r2-step4-apple-banana.png +0 -0
  67. package/r2-step5-after-rewind-apple-last.png +0 -0
  68. package/r2-step7-apple-cherry.png +0 -0
  69. package/r2-step8-cherry-menu-no-restore.png +0 -0
  70. package/r3-step3-live-task-card-running.png +0 -0
  71. package/r3-step4-after-completion.png +0 -0
  72. package/r3-step5-persistence-after-reload.png +0 -0
  73. package/r3-step6-tasks-tab-card.png +0 -0
  74. package/reverify-answered-state-answer-sent.png +0 -0
  75. package/reverify-card-visible-after-completion.png +0 -0
  76. package/rewind-step3-apple-banana-turns.png +0 -0
  77. package/rewind-step5-ui-unchanged-after-confirmed-rewind.png +0 -0
  78. package/rewind-step6-apple-menu-no-restore.png +0 -0
  79. package/rewind-step7-final-turnlist-unchanged.png +0 -0
  80. package/rewind-step7-negative-error-toast.png +0 -0
  81. package/rewind-step7-negative-error-toast2.png +0 -0
  82. package/subagent-r2-step5-turn-after-reload-no-card.png +0 -0
  83. package/subagent-r2-step6-tasks-panel-card.png +0 -0
  84. package/subagent-step3-tasks-tab-done-card.png +0 -0
  85. package/subagent-step4-turn-stuck-no-cards.png +0 -0
  86. package/agent-pane/frontend/dist/assets/index-y7xlT86e.js +0 -362
@@ -6123,8 +6123,8 @@ var require_req = __commonJS({
6123
6123
  if (req.originalUrl) {
6124
6124
  _req.url = req.originalUrl;
6125
6125
  } else {
6126
- const path2 = req.path;
6127
- _req.url = typeof path2 === "string" ? path2 : req.url ? req.url.path || req.url : void 0;
6126
+ const path3 = req.path;
6127
+ _req.url = typeof path3 === "string" ? path3 : req.url ? req.url.path || req.url : void 0;
6128
6128
  }
6129
6129
  if (req.query) {
6130
6130
  _req.query = req.query;
@@ -6289,14 +6289,14 @@ var require_redact = __commonJS({
6289
6289
  }
6290
6290
  return obj;
6291
6291
  }
6292
- function parsePath(path2) {
6292
+ function parsePath(path3) {
6293
6293
  const parts = [];
6294
6294
  let current = "";
6295
6295
  let inBrackets = false;
6296
6296
  let inQuotes = false;
6297
6297
  let quoteChar = "";
6298
- for (let i = 0; i < path2.length; i++) {
6299
- const char = path2[i];
6298
+ for (let i = 0; i < path3.length; i++) {
6299
+ const char = path3[i];
6300
6300
  if (!inBrackets && char === ".") {
6301
6301
  if (current) {
6302
6302
  parts.push(current);
@@ -6427,10 +6427,10 @@ var require_redact = __commonJS({
6427
6427
  return current;
6428
6428
  }
6429
6429
  function redactPaths(obj, paths, censor, remove = false) {
6430
- for (const path2 of paths) {
6431
- const parts = parsePath(path2);
6430
+ for (const path3 of paths) {
6431
+ const parts = parsePath(path3);
6432
6432
  if (parts.includes("*")) {
6433
- redactWildcardPath(obj, parts, censor, path2, remove);
6433
+ redactWildcardPath(obj, parts, censor, path3, remove);
6434
6434
  } else {
6435
6435
  if (remove) {
6436
6436
  removeKey(obj, parts);
@@ -6515,8 +6515,8 @@ var require_redact = __commonJS({
6515
6515
  }
6516
6516
  } else {
6517
6517
  if (afterWildcard.includes("*")) {
6518
- const wrappedCensor = typeof censor === "function" ? (value, path2) => {
6519
- const fullPath = [...pathArray.slice(0, pathLength), ...path2];
6518
+ const wrappedCensor = typeof censor === "function" ? (value, path3) => {
6519
+ const fullPath = [...pathArray.slice(0, pathLength), ...path3];
6520
6520
  return censor(value, fullPath);
6521
6521
  } : censor;
6522
6522
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -6551,8 +6551,8 @@ var require_redact = __commonJS({
6551
6551
  return null;
6552
6552
  }
6553
6553
  const pathStructure = /* @__PURE__ */ new Map();
6554
- for (const path2 of pathsToClone) {
6555
- const parts = parsePath(path2);
6554
+ for (const path3 of pathsToClone) {
6555
+ const parts = parsePath(path3);
6556
6556
  let current = pathStructure;
6557
6557
  for (let i = 0; i < parts.length; i++) {
6558
6558
  const part = parts[i];
@@ -6604,24 +6604,24 @@ var require_redact = __commonJS({
6604
6604
  }
6605
6605
  return cloneSelectively(obj, pathStructure);
6606
6606
  }
6607
- function validatePath(path2) {
6608
- if (typeof path2 !== "string") {
6607
+ function validatePath(path3) {
6608
+ if (typeof path3 !== "string") {
6609
6609
  throw new Error("Paths must be (non-empty) strings");
6610
6610
  }
6611
- if (path2 === "") {
6611
+ if (path3 === "") {
6612
6612
  throw new Error("Invalid redaction path ()");
6613
6613
  }
6614
- if (path2.includes("..")) {
6615
- throw new Error(`Invalid redaction path (${path2})`);
6614
+ if (path3.includes("..")) {
6615
+ throw new Error(`Invalid redaction path (${path3})`);
6616
6616
  }
6617
- if (path2.includes(",")) {
6618
- throw new Error(`Invalid redaction path (${path2})`);
6617
+ if (path3.includes(",")) {
6618
+ throw new Error(`Invalid redaction path (${path3})`);
6619
6619
  }
6620
6620
  let bracketCount = 0;
6621
6621
  let inQuotes = false;
6622
6622
  let quoteChar = "";
6623
- for (let i = 0; i < path2.length; i++) {
6624
- const char = path2[i];
6623
+ for (let i = 0; i < path3.length; i++) {
6624
+ const char = path3[i];
6625
6625
  if ((char === '"' || char === "'") && bracketCount > 0) {
6626
6626
  if (!inQuotes) {
6627
6627
  inQuotes = true;
@@ -6635,20 +6635,20 @@ var require_redact = __commonJS({
6635
6635
  } else if (char === "]" && !inQuotes) {
6636
6636
  bracketCount--;
6637
6637
  if (bracketCount < 0) {
6638
- throw new Error(`Invalid redaction path (${path2})`);
6638
+ throw new Error(`Invalid redaction path (${path3})`);
6639
6639
  }
6640
6640
  }
6641
6641
  }
6642
6642
  if (bracketCount !== 0) {
6643
- throw new Error(`Invalid redaction path (${path2})`);
6643
+ throw new Error(`Invalid redaction path (${path3})`);
6644
6644
  }
6645
6645
  }
6646
6646
  function validatePaths(paths) {
6647
6647
  if (!Array.isArray(paths)) {
6648
6648
  throw new TypeError("paths must be an array");
6649
6649
  }
6650
- for (const path2 of paths) {
6651
- validatePath(path2);
6650
+ for (const path3 of paths) {
6651
+ validatePath(path3);
6652
6652
  }
6653
6653
  }
6654
6654
  function slowRedact(options = {}) {
@@ -6816,8 +6816,8 @@ var require_redaction = __commonJS({
6816
6816
  if (shape[k2] === null) {
6817
6817
  o[k2] = (value) => topCensor(value, [k2]);
6818
6818
  } else {
6819
- const wrappedCensor = typeof censor === "function" ? (value, path2) => {
6820
- return censor(value, [k2, ...path2]);
6819
+ const wrappedCensor = typeof censor === "function" ? (value, path3) => {
6820
+ return censor(value, [k2, ...path3]);
6821
6821
  } : censor;
6822
6822
  o[k2] = Redact({
6823
6823
  paths: shape[k2],
@@ -7038,7 +7038,7 @@ var require_sonic_boom = __commonJS({
7038
7038
  var fs = __require("fs");
7039
7039
  var EventEmitter2 = __require("events");
7040
7040
  var inherits = __require("util").inherits;
7041
- var path2 = __require("path");
7041
+ var path3 = __require("path");
7042
7042
  var sleep = require_atomic_sleep();
7043
7043
  var assert = __require("assert");
7044
7044
  var BUSY_WRITE_TIMEOUT = 100;
@@ -7092,7 +7092,7 @@ var require_sonic_boom = __commonJS({
7092
7092
  const mode = sonic.mode;
7093
7093
  if (sonic.sync) {
7094
7094
  try {
7095
- if (sonic.mkdir) fs.mkdirSync(path2.dirname(file), { recursive: true });
7095
+ if (sonic.mkdir) fs.mkdirSync(path3.dirname(file), { recursive: true });
7096
7096
  const fd2 = fs.openSync(file, flags, mode);
7097
7097
  fileOpened(null, fd2);
7098
7098
  } catch (err) {
@@ -7100,7 +7100,7 @@ var require_sonic_boom = __commonJS({
7100
7100
  throw err;
7101
7101
  }
7102
7102
  } else if (sonic.mkdir) {
7103
- fs.mkdir(path2.dirname(file), { recursive: true }, (err) => {
7103
+ fs.mkdir(path3.dirname(file), { recursive: true }, (err) => {
7104
7104
  if (err) return fileOpened(err);
7105
7105
  fs.open(file, flags, mode, fileOpened);
7106
7106
  });
@@ -8432,15 +8432,15 @@ var require_transport = __commonJS({
8432
8432
  if (!unquoted) {
8433
8433
  return false;
8434
8434
  }
8435
- let path2 = unquoted;
8436
- if (path2.startsWith("file://")) {
8435
+ let path3 = unquoted;
8436
+ if (path3.startsWith("file://")) {
8437
8437
  try {
8438
- path2 = fileURLToPath(path2);
8438
+ path3 = fileURLToPath(path3);
8439
8439
  } catch {
8440
8440
  return false;
8441
8441
  }
8442
8442
  }
8443
- return isAbsolute4(path2) && !existsSync2(path2);
8443
+ return isAbsolute4(path3) && !existsSync2(path3);
8444
8444
  }
8445
8445
  function stripQuotes(value) {
8446
8446
  const first = value[0];
@@ -17116,8 +17116,8 @@ var require_utils = __commonJS({
17116
17116
  }
17117
17117
  return ind;
17118
17118
  }
17119
- function removeDotSegments(path2) {
17120
- let input = path2;
17119
+ function removeDotSegments(path3) {
17120
+ let input = path3;
17121
17121
  const output = [];
17122
17122
  let nextSlash = -1;
17123
17123
  let len = 0;
@@ -17369,8 +17369,8 @@ var require_schemes = __commonJS({
17369
17369
  wsComponent.secure = void 0;
17370
17370
  }
17371
17371
  if (wsComponent.resourceName) {
17372
- const [path2, query] = wsComponent.resourceName.split("?");
17373
- wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
17372
+ const [path3, query] = wsComponent.resourceName.split("?");
17373
+ wsComponent.path = path3 && path3 !== "/" ? path3 : void 0;
17374
17374
  wsComponent.query = query;
17375
17375
  wsComponent.resourceName = void 0;
17376
17376
  }
@@ -22307,8 +22307,8 @@ var require_utils2 = __commonJS({
22307
22307
  }
22308
22308
  return ind;
22309
22309
  }
22310
- function removeDotSegments(path2) {
22311
- let input = path2;
22310
+ function removeDotSegments(path3) {
22311
+ let input = path3;
22312
22312
  const output = [];
22313
22313
  let nextSlash = -1;
22314
22314
  let len = 0;
@@ -22653,8 +22653,8 @@ var require_schemes2 = __commonJS({
22653
22653
  wsComponent.secure = void 0;
22654
22654
  }
22655
22655
  if (wsComponent.resourceName) {
22656
- const [path2, query] = wsComponent.resourceName.split("?");
22657
- wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
22656
+ const [path3, query] = wsComponent.resourceName.split("?");
22657
+ wsComponent.path = path3 && path3 !== "/" ? path3 : void 0;
22658
22658
  wsComponent.query = query;
22659
22659
  wsComponent.resourceName = void 0;
22660
22660
  }
@@ -24138,8 +24138,8 @@ var require_utils3 = __commonJS({
24138
24138
  }
24139
24139
  return ind;
24140
24140
  }
24141
- function removeDotSegments(path2) {
24142
- let input = path2;
24141
+ function removeDotSegments(path3) {
24142
+ let input = path3;
24143
24143
  const output = [];
24144
24144
  let nextSlash = -1;
24145
24145
  let len = 0;
@@ -24484,8 +24484,8 @@ var require_schemes3 = __commonJS({
24484
24484
  wsComponent.secure = void 0;
24485
24485
  }
24486
24486
  if (wsComponent.resourceName) {
24487
- const [path2, query] = wsComponent.resourceName.split("?");
24488
- wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
24487
+ const [path3, query] = wsComponent.resourceName.split("?");
24488
+ wsComponent.path = path3 && path3 !== "/" ? path3 : void 0;
24489
24489
  wsComponent.query = query;
24490
24490
  wsComponent.resourceName = void 0;
24491
24491
  }
@@ -32002,13 +32002,13 @@ var require_node = __commonJS({
32002
32002
  this.staticChildrenNodes[index] = node;
32003
32003
  }
32004
32004
  }
32005
- findStaticMatchingChild(path2, pathIndex) {
32006
- const charCode = path2.charCodeAt(pathIndex);
32005
+ findStaticMatchingChild(path3, pathIndex) {
32006
+ const charCode = path3.charCodeAt(pathIndex);
32007
32007
  const charCodes = this.staticChildrenCharCodes;
32008
32008
  for (let i = 0; i < charCodes.length; i++) {
32009
32009
  if (charCodes[i] === charCode) {
32010
32010
  const staticChild = this.staticChildrenNodes[i];
32011
- if (staticChild.matchPrefix(path2, pathIndex)) {
32011
+ if (staticChild.matchPrefix(path3, pathIndex)) {
32012
32012
  return staticChild;
32013
32013
  }
32014
32014
  return null;
@@ -32016,34 +32016,34 @@ var require_node = __commonJS({
32016
32016
  }
32017
32017
  return null;
32018
32018
  }
32019
- getStaticChild(path2, pathIndex = 0) {
32020
- if (path2.length === pathIndex) {
32019
+ getStaticChild(path3, pathIndex = 0) {
32020
+ if (path3.length === pathIndex) {
32021
32021
  return this;
32022
32022
  }
32023
- const staticChild = this.findStaticMatchingChild(path2, pathIndex);
32023
+ const staticChild = this.findStaticMatchingChild(path3, pathIndex);
32024
32024
  if (staticChild) {
32025
- return staticChild.getStaticChild(path2, pathIndex + staticChild.prefix.length);
32025
+ return staticChild.getStaticChild(path3, pathIndex + staticChild.prefix.length);
32026
32026
  }
32027
32027
  return null;
32028
32028
  }
32029
- createStaticChild(path2) {
32030
- if (path2.length === 0) {
32029
+ createStaticChild(path3) {
32030
+ if (path3.length === 0) {
32031
32031
  return this;
32032
32032
  }
32033
- const childIndex = this.staticChildrenCharCodes.indexOf(path2.charCodeAt(0));
32033
+ const childIndex = this.staticChildrenCharCodes.indexOf(path3.charCodeAt(0));
32034
32034
  let staticChild = childIndex === -1 ? void 0 : this.staticChildrenNodes[childIndex];
32035
32035
  if (staticChild) {
32036
32036
  let i = 1;
32037
32037
  for (; i < staticChild.prefix.length; i++) {
32038
- if (path2.charCodeAt(i) !== staticChild.prefix.charCodeAt(i)) {
32038
+ if (path3.charCodeAt(i) !== staticChild.prefix.charCodeAt(i)) {
32039
32039
  staticChild = staticChild.split(this, i);
32040
32040
  break;
32041
32041
  }
32042
32042
  }
32043
- return staticChild.createStaticChild(path2.slice(i));
32043
+ return staticChild.createStaticChild(path3.slice(i));
32044
32044
  }
32045
- const node = new StaticNode(path2);
32046
- this.setStaticChild(path2.charAt(0), node);
32045
+ const node = new StaticNode(path3);
32046
+ this.setStaticChild(path3.charAt(0), node);
32047
32047
  return node;
32048
32048
  }
32049
32049
  };
@@ -32103,8 +32103,8 @@ var require_node = __commonJS({
32103
32103
  parentNode.setStaticChild(parentPrefix.charAt(0), staticNode);
32104
32104
  return staticNode;
32105
32105
  }
32106
- getNextNode(path2, pathIndex, nodeStack, paramsCount) {
32107
- let node = this.findStaticMatchingChild(path2, pathIndex);
32106
+ getNextNode(path3, pathIndex, nodeStack, paramsCount) {
32107
+ let node = this.findStaticMatchingChild(path3, pathIndex);
32108
32108
  let parametricBrotherNodeIndex = 0;
32109
32109
  if (node === null) {
32110
32110
  if (this.parametricChildren.length === 0) {
@@ -32151,8 +32151,8 @@ var require_node = __commonJS({
32151
32151
  this.kind = NODE_TYPES.PARAMETRIC;
32152
32152
  this.nodePaths = /* @__PURE__ */ new Set([nodePath]);
32153
32153
  }
32154
- getNextNode(path2, pathIndex) {
32155
- return this.findStaticMatchingChild(path2, pathIndex);
32154
+ getNextNode(path3, pathIndex) {
32155
+ return this.findStaticMatchingChild(path3, pathIndex);
32156
32156
  }
32157
32157
  };
32158
32158
  var WildcardNode = class extends Node {
@@ -32508,81 +32508,81 @@ var require_url_sanitizer = __commonJS({
32508
32508
  return String.fromCharCode(charCode);
32509
32509
  }
32510
32510
  var MIN_NATIVE_SCAN_LENGTH = 12;
32511
- function safeDecodeURI(path2, useSemicolonDelimiter) {
32512
- if (path2.length >= MIN_NATIVE_SCAN_LENGTH) {
32513
- return safeDecodeURINativeScan(path2, useSemicolonDelimiter);
32511
+ function safeDecodeURI(path3, useSemicolonDelimiter) {
32512
+ if (path3.length >= MIN_NATIVE_SCAN_LENGTH) {
32513
+ return safeDecodeURINativeScan(path3, useSemicolonDelimiter);
32514
32514
  }
32515
- return safeDecodeURICharScan(path2, useSemicolonDelimiter, 1);
32515
+ return safeDecodeURICharScan(path3, useSemicolonDelimiter, 1);
32516
32516
  }
32517
- function safeDecodeURINativeScan(path2, useSemicolonDelimiter) {
32518
- const percentIndex = path2.indexOf("%", 1);
32519
- let delimIndex = path2.indexOf("?", 1);
32520
- const hashIndex = path2.indexOf("#", 1);
32517
+ function safeDecodeURINativeScan(path3, useSemicolonDelimiter) {
32518
+ const percentIndex = path3.indexOf("%", 1);
32519
+ let delimIndex = path3.indexOf("?", 1);
32520
+ const hashIndex = path3.indexOf("#", 1);
32521
32521
  if (hashIndex !== -1 && (delimIndex === -1 || hashIndex < delimIndex)) {
32522
32522
  delimIndex = hashIndex;
32523
32523
  }
32524
32524
  if (useSemicolonDelimiter) {
32525
- const semicolonIndex = path2.indexOf(";", 1);
32525
+ const semicolonIndex = path3.indexOf(";", 1);
32526
32526
  if (semicolonIndex !== -1 && (delimIndex === -1 || semicolonIndex < delimIndex)) {
32527
32527
  delimIndex = semicolonIndex;
32528
32528
  }
32529
32529
  }
32530
32530
  if (percentIndex === -1 || delimIndex !== -1 && percentIndex > delimIndex) {
32531
32531
  if (delimIndex === -1) {
32532
- return { path: path2, querystring: "", shouldDecodeParam: false };
32532
+ return { path: path3, querystring: "", shouldDecodeParam: false };
32533
32533
  }
32534
32534
  return {
32535
- path: path2.slice(0, delimIndex),
32536
- querystring: path2.slice(delimIndex + 1),
32535
+ path: path3.slice(0, delimIndex),
32536
+ querystring: path3.slice(delimIndex + 1),
32537
32537
  shouldDecodeParam: false
32538
32538
  };
32539
32539
  }
32540
- return safeDecodeURIPercentScan(path2, useSemicolonDelimiter, percentIndex);
32540
+ return safeDecodeURIPercentScan(path3, useSemicolonDelimiter, percentIndex);
32541
32541
  }
32542
- function safeDecodeURICharScan(path2, useSemicolonDelimiter, startIndex) {
32543
- for (let i = startIndex; i < path2.length; i++) {
32544
- const charCode = path2.charCodeAt(i);
32542
+ function safeDecodeURICharScan(path3, useSemicolonDelimiter, startIndex) {
32543
+ for (let i = startIndex; i < path3.length; i++) {
32544
+ const charCode = path3.charCodeAt(i);
32545
32545
  if (charCode === 37) {
32546
- return safeDecodeURIPercentScan(path2, useSemicolonDelimiter, i);
32546
+ return safeDecodeURIPercentScan(path3, useSemicolonDelimiter, i);
32547
32547
  } else if (charCode === 63 || charCode === 35 || charCode === 59 && useSemicolonDelimiter) {
32548
32548
  return {
32549
- path: path2.slice(0, i),
32550
- querystring: path2.slice(i + 1),
32549
+ path: path3.slice(0, i),
32550
+ querystring: path3.slice(i + 1),
32551
32551
  shouldDecodeParam: false
32552
32552
  };
32553
32553
  }
32554
32554
  }
32555
- return { path: path2, querystring: "", shouldDecodeParam: false };
32555
+ return { path: path3, querystring: "", shouldDecodeParam: false };
32556
32556
  }
32557
- function reencodePercentChar(path2, index) {
32558
- return path2.slice(0, index + 1) + "25" + path2.slice(index + 1);
32557
+ function reencodePercentChar(path3, index) {
32558
+ return path3.slice(0, index + 1) + "25" + path3.slice(index + 1);
32559
32559
  }
32560
- function safeDecodeURIPercentScan(path2, useSemicolonDelimiter, startIndex) {
32560
+ function safeDecodeURIPercentScan(path3, useSemicolonDelimiter, startIndex) {
32561
32561
  let shouldDecode = false;
32562
32562
  let shouldDecodeParam = false;
32563
32563
  let querystring = "";
32564
- for (let i = startIndex; i < path2.length; i++) {
32565
- const charCode = path2.charCodeAt(i);
32564
+ for (let i = startIndex; i < path3.length; i++) {
32565
+ const charCode = path3.charCodeAt(i);
32566
32566
  if (charCode === 37) {
32567
- const componentCharCode = decodeComponentCharCode(path2.charCodeAt(i + 1), path2.charCodeAt(i + 2));
32567
+ const componentCharCode = decodeComponentCharCode(path3.charCodeAt(i + 1), path3.charCodeAt(i + 2));
32568
32568
  if (componentCharCode === 0) {
32569
32569
  shouldDecode = true;
32570
32570
  } else {
32571
32571
  shouldDecodeParam = true;
32572
32572
  if (componentCharCode === 37) {
32573
32573
  shouldDecode = true;
32574
- path2 = reencodePercentChar(path2, i);
32574
+ path3 = reencodePercentChar(path3, i);
32575
32575
  i += 2;
32576
32576
  }
32577
32577
  i += 2;
32578
32578
  }
32579
32579
  } else if (charCode === 63 || charCode === 35 || charCode === 59 && useSemicolonDelimiter) {
32580
- querystring = path2.slice(i + 1);
32581
- path2 = path2.slice(0, i);
32580
+ querystring = path3.slice(i + 1);
32581
+ path3 = path3.slice(0, i);
32582
32582
  break;
32583
32583
  }
32584
32584
  }
32585
- const decodedPath = shouldDecode ? decodeURI(path2) : path2;
32585
+ const decodedPath = shouldDecode ? decodeURI(path3) : path3;
32586
32586
  return { path: decodedPath, querystring, shouldDecodeParam };
32587
32587
  }
32588
32588
  function safeDecodeURIComponent(uriComponent) {
@@ -32677,7 +32677,7 @@ var require_find_my_way = __commonJS({
32677
32677
  this.trees = /* @__PURE__ */ Object.create(null);
32678
32678
  this._treeGET = null;
32679
32679
  }
32680
- Router.prototype.on = function on2(method, path2, opts, handler, store) {
32680
+ Router.prototype.on = function on2(method, path3, opts, handler, store) {
32681
32681
  if (typeof opts === "function") {
32682
32682
  if (handler !== void 0) {
32683
32683
  store = handler;
@@ -32685,34 +32685,34 @@ var require_find_my_way = __commonJS({
32685
32685
  handler = opts;
32686
32686
  opts = {};
32687
32687
  }
32688
- assert(typeof path2 === "string", "Path should be a string");
32689
- assert(path2.length > 0, "The path could not be empty");
32690
- assert(path2[0] === "/" || path2[0] === "*", "The first character of a path should be `/` or `*`");
32688
+ assert(typeof path3 === "string", "Path should be a string");
32689
+ assert(path3.length > 0, "The path could not be empty");
32690
+ assert(path3[0] === "/" || path3[0] === "*", "The first character of a path should be `/` or `*`");
32691
32691
  assert(typeof handler === "function", "Handler should be a function");
32692
- const optionalParamMatch = path2.match(OPTIONAL_PARAM_REGEXP);
32692
+ const optionalParamMatch = path3.match(OPTIONAL_PARAM_REGEXP);
32693
32693
  if (optionalParamMatch) {
32694
- assert(path2.length === optionalParamMatch.index + optionalParamMatch[0].length, "Optional Parameter needs to be the last parameter of the path");
32695
- const pathFull = path2.replace(OPTIONAL_PARAM_REGEXP, "$1$2");
32696
- const pathOptional = path2.replace(OPTIONAL_PARAM_REGEXP, "$2") || "/";
32694
+ assert(path3.length === optionalParamMatch.index + optionalParamMatch[0].length, "Optional Parameter needs to be the last parameter of the path");
32695
+ const pathFull = path3.replace(OPTIONAL_PARAM_REGEXP, "$1$2");
32696
+ const pathOptional = path3.replace(OPTIONAL_PARAM_REGEXP, "$2") || "/";
32697
32697
  this.on(method, pathFull, opts, handler, store);
32698
32698
  this.on(method, pathOptional, opts, handler, store);
32699
32699
  return;
32700
32700
  }
32701
- const route = path2;
32701
+ const route = path3;
32702
32702
  if (this.ignoreDuplicateSlashes) {
32703
- path2 = removeDuplicateSlashes(path2);
32703
+ path3 = removeDuplicateSlashes(path3);
32704
32704
  }
32705
32705
  if (this.ignoreTrailingSlash) {
32706
- path2 = trimLastSlash(path2);
32706
+ path3 = trimLastSlash(path3);
32707
32707
  }
32708
32708
  const methods = Array.isArray(method) ? method : [method];
32709
32709
  for (const method2 of methods) {
32710
32710
  assert(typeof method2 === "string", "Method should be a string");
32711
32711
  assert(httpMethods.includes(method2), `Method '${method2}' is not an http method.`);
32712
- this._on(method2, path2, opts, handler, store, route);
32712
+ this._on(method2, path3, opts, handler, store, route);
32713
32713
  }
32714
32714
  };
32715
- Router.prototype._on = function _on(method, path2, opts, handler, store) {
32715
+ Router.prototype._on = function _on(method, path3, opts, handler, store) {
32716
32716
  let constraints = {};
32717
32717
  if (opts.constraints !== void 0) {
32718
32718
  assert(typeof opts.constraints === "object" && opts.constraints !== null, "Constraints should be an object");
@@ -32725,7 +32725,7 @@ var require_find_my_way = __commonJS({
32725
32725
  if (this.trees[method] === void 0) {
32726
32726
  this.trees[method] = new StaticNode("/");
32727
32727
  }
32728
- let pattern = path2;
32728
+ let pattern = path3;
32729
32729
  if (pattern === "*" && this.trees[method].prefix.length !== 0) {
32730
32730
  const currentRoot = this.trees[method];
32731
32731
  this.trees[method] = new StaticNode("");
@@ -32833,19 +32833,19 @@ var require_find_my_way = __commonJS({
32833
32833
  throw new Error(`Method '${method}' already declared for route '${pattern}' with constraints '${JSON.stringify(constraints)}'`);
32834
32834
  }
32835
32835
  }
32836
- const route = { method, path: path2, pattern, params, opts, handler, store };
32836
+ const route = { method, path: path3, pattern, params, opts, handler, store };
32837
32837
  this.routes.push(route);
32838
32838
  currentNode.addRoute(route, this.constrainer);
32839
32839
  };
32840
- Router.prototype.hasRoute = function hasRoute(method, path2, constraints) {
32841
- const route = this.findRoute(method, path2, constraints);
32840
+ Router.prototype.hasRoute = function hasRoute(method, path3, constraints) {
32841
+ const route = this.findRoute(method, path3, constraints);
32842
32842
  return route !== null;
32843
32843
  };
32844
- Router.prototype.findRoute = function findNode(method, path2, constraints = {}) {
32844
+ Router.prototype.findRoute = function findNode(method, path3, constraints = {}) {
32845
32845
  if (this.trees[method] === void 0) {
32846
32846
  return null;
32847
32847
  }
32848
- let pattern = path2;
32848
+ let pattern = path3;
32849
32849
  let currentNode = this.trees[method];
32850
32850
  let parentNodePathIndex = currentNode.prefix.length;
32851
32851
  const params = [];
@@ -32966,39 +32966,39 @@ var require_find_my_way = __commonJS({
32966
32966
  this._treeGET = null;
32967
32967
  this.routes = [];
32968
32968
  };
32969
- Router.prototype.off = function off(method, path2, constraints) {
32970
- assert(typeof path2 === "string", "Path should be a string");
32971
- assert(path2.length > 0, "The path could not be empty");
32972
- assert(path2[0] === "/" || path2[0] === "*", "The first character of a path should be `/` or `*`");
32969
+ Router.prototype.off = function off(method, path3, constraints) {
32970
+ assert(typeof path3 === "string", "Path should be a string");
32971
+ assert(path3.length > 0, "The path could not be empty");
32972
+ assert(path3[0] === "/" || path3[0] === "*", "The first character of a path should be `/` or `*`");
32973
32973
  assert(
32974
32974
  typeof constraints === "undefined" || typeof constraints === "object" && !Array.isArray(constraints) && constraints !== null,
32975
32975
  "Constraints should be an object or undefined."
32976
32976
  );
32977
- const optionalParamMatch = path2.match(OPTIONAL_PARAM_REGEXP);
32977
+ const optionalParamMatch = path3.match(OPTIONAL_PARAM_REGEXP);
32978
32978
  if (optionalParamMatch) {
32979
- assert(path2.length === optionalParamMatch.index + optionalParamMatch[0].length, "Optional Parameter needs to be the last parameter of the path");
32980
- const pathFull = path2.replace(OPTIONAL_PARAM_REGEXP, "$1$2");
32981
- const pathOptional = path2.replace(OPTIONAL_PARAM_REGEXP, "$2") || "/";
32979
+ assert(path3.length === optionalParamMatch.index + optionalParamMatch[0].length, "Optional Parameter needs to be the last parameter of the path");
32980
+ const pathFull = path3.replace(OPTIONAL_PARAM_REGEXP, "$1$2");
32981
+ const pathOptional = path3.replace(OPTIONAL_PARAM_REGEXP, "$2") || "/";
32982
32982
  this.off(method, pathFull, constraints);
32983
32983
  this.off(method, pathOptional, constraints);
32984
32984
  return;
32985
32985
  }
32986
32986
  if (this.ignoreDuplicateSlashes) {
32987
- path2 = removeDuplicateSlashes(path2);
32987
+ path3 = removeDuplicateSlashes(path3);
32988
32988
  }
32989
32989
  if (this.ignoreTrailingSlash) {
32990
- path2 = trimLastSlash(path2);
32990
+ path3 = trimLastSlash(path3);
32991
32991
  }
32992
32992
  const methods = Array.isArray(method) ? method : [method];
32993
32993
  for (const method2 of methods) {
32994
- this._off(method2, path2, constraints);
32994
+ this._off(method2, path3, constraints);
32995
32995
  }
32996
32996
  };
32997
- Router.prototype._off = function _off(method, path2, constraints) {
32997
+ Router.prototype._off = function _off(method, path3, constraints) {
32998
32998
  assert(typeof method === "string", "Method should be a string");
32999
32999
  assert(httpMethods.includes(method), `Method '${method}' is not an http method.`);
33000
33000
  function matcherWithoutConstraints(route) {
33001
- return method !== route.method || path2 !== route.path;
33001
+ return method !== route.method || path3 !== route.path;
33002
33002
  }
33003
33003
  function matcherWithConstraints(route) {
33004
33004
  return matcherWithoutConstraints(route) || !deepEqual(constraints, route.opts.constraints || {});
@@ -33035,37 +33035,37 @@ var require_find_my_way = __commonJS({
33035
33035
  if (handle === null) return this._defaultRoute(req, res, ctx);
33036
33036
  return ctx === void 0 ? handle.handler(req, res, handle.params, handle.store, handle.searchParams) : handle.handler.call(ctx, req, res, handle.params, handle.store, handle.searchParams);
33037
33037
  };
33038
- Router.prototype.find = function find(method, path2, derivedConstraints) {
33038
+ Router.prototype.find = function find(method, path3, derivedConstraints) {
33039
33039
  let currentNode = method === "GET" ? this._treeGET : this.trees[method];
33040
33040
  if (currentNode == null) return null;
33041
- if (path2.charCodeAt(0) !== 47) {
33042
- path2 = path2.replace(FULL_PATH_REGEXP, "/");
33041
+ if (path3.charCodeAt(0) !== 47) {
33042
+ path3 = path3.replace(FULL_PATH_REGEXP, "/");
33043
33043
  }
33044
33044
  if (this.ignoreDuplicateSlashes) {
33045
- path2 = removeDuplicateSlashes(path2);
33045
+ path3 = removeDuplicateSlashes(path3);
33046
33046
  }
33047
33047
  let sanitizedUrl;
33048
33048
  let querystring2;
33049
33049
  let shouldDecodeParam;
33050
33050
  try {
33051
- sanitizedUrl = path2.length >= MIN_NATIVE_SCAN_LENGTH ? safeDecodeURINativeScan(path2, this.useSemicolonDelimiter) : safeDecodeURICharScan(path2, this.useSemicolonDelimiter, 1);
33052
- path2 = sanitizedUrl.path;
33051
+ sanitizedUrl = path3.length >= MIN_NATIVE_SCAN_LENGTH ? safeDecodeURINativeScan(path3, this.useSemicolonDelimiter) : safeDecodeURICharScan(path3, this.useSemicolonDelimiter, 1);
33052
+ path3 = sanitizedUrl.path;
33053
33053
  querystring2 = sanitizedUrl.querystring;
33054
33054
  shouldDecodeParam = sanitizedUrl.shouldDecodeParam;
33055
33055
  } catch (error) {
33056
- return this._onBadUrl(path2);
33056
+ return this._onBadUrl(path3);
33057
33057
  }
33058
33058
  if (this.ignoreTrailingSlash) {
33059
- path2 = trimLastSlash(path2);
33059
+ path3 = trimLastSlash(path3);
33060
33060
  }
33061
- const originPath = path2;
33061
+ const originPath = path3;
33062
33062
  if (this.caseSensitive === false) {
33063
- path2 = path2.toLowerCase();
33063
+ path3 = path3.toLowerCase();
33064
33064
  }
33065
33065
  const maxParamLength = this.maxParamLength;
33066
33066
  let pathIndex = currentNode.prefix.length;
33067
33067
  const params = [];
33068
- const pathLen = path2.length;
33068
+ const pathLen = path3.length;
33069
33069
  const brothersNodesStack = [];
33070
33070
  let maxParamLengthExceeded = false;
33071
33071
  while (true) {
@@ -33080,7 +33080,7 @@ var require_find_my_way = __commonJS({
33080
33080
  };
33081
33081
  }
33082
33082
  }
33083
- let node = currentNode.getNextNode(path2, pathIndex, brothersNodesStack, params.length);
33083
+ let node = currentNode.getNextNode(path3, pathIndex, brothersNodesStack, params.length);
33084
33084
  if (node === null) {
33085
33085
  if (brothersNodesStack.length === 0) {
33086
33086
  if (maxParamLengthExceeded && this.onMaxParamLength) {
@@ -33181,8 +33181,8 @@ var require_find_my_way = __commonJS({
33181
33181
  Router.prototype._rebuild = function(routes) {
33182
33182
  this.reset();
33183
33183
  for (const route of routes) {
33184
- const { method, path: path2, opts, handler, store } = route;
33185
- this._on(method, path2, opts, handler, store);
33184
+ const { method, path: path3, opts, handler, store } = route;
33185
+ this._on(method, path3, opts, handler, store);
33186
33186
  }
33187
33187
  };
33188
33188
  Router.prototype._defaultRoute = function(req, res, ctx) {
@@ -33193,24 +33193,24 @@ var require_find_my_way = __commonJS({
33193
33193
  res.end();
33194
33194
  }
33195
33195
  };
33196
- Router.prototype._onBadUrl = function(path2) {
33196
+ Router.prototype._onBadUrl = function(path3) {
33197
33197
  if (this.onBadUrl === null) {
33198
33198
  return null;
33199
33199
  }
33200
33200
  const onBadUrl = this.onBadUrl;
33201
33201
  return {
33202
- handler: (req, res, ctx) => onBadUrl(path2, req, res),
33202
+ handler: (req, res, ctx) => onBadUrl(path3, req, res),
33203
33203
  params: {},
33204
33204
  store: null
33205
33205
  };
33206
33206
  };
33207
- Router.prototype._onMaxParamLength = function(path2) {
33207
+ Router.prototype._onMaxParamLength = function(path3) {
33208
33208
  if (this.onMaxParamLength === null) {
33209
33209
  return null;
33210
33210
  }
33211
33211
  const onMaxParamLength = this.onMaxParamLength;
33212
33212
  return {
33213
- handler: (req, res, ctx) => onMaxParamLength(path2, req, res),
33213
+ handler: (req, res, ctx) => onMaxParamLength(path3, req, res),
33214
33214
  params: {},
33215
33215
  store: null
33216
33216
  };
@@ -33242,12 +33242,12 @@ var require_find_my_way = __commonJS({
33242
33242
  if (!httpMethods.hasOwnProperty(i)) continue;
33243
33243
  const m = httpMethods[i];
33244
33244
  const methodName = m.toLowerCase();
33245
- Router.prototype[methodName] = function(path2, handler, store) {
33246
- return this.on(m, path2, handler, store);
33245
+ Router.prototype[methodName] = function(path3, handler, store) {
33246
+ return this.on(m, path3, handler, store);
33247
33247
  };
33248
33248
  }
33249
- Router.prototype.all = function(path2, handler, store) {
33250
- this.on(httpMethods, path2, handler, store);
33249
+ Router.prototype.all = function(path3, handler, store) {
33250
+ this.on(httpMethods, path3, handler, store);
33251
33251
  };
33252
33252
  Router.sanitizeUrlPath = function sanitizeUrlPath(url, useSemicolonDelimiter) {
33253
33253
  const decoded = safeDecodeURI(url, useSemicolonDelimiter);
@@ -33262,14 +33262,14 @@ var require_find_my_way = __commonJS({
33262
33262
  function escapeRegExp(string) {
33263
33263
  return string.replace(ESCAPE_REGEXP, "\\$&");
33264
33264
  }
33265
- function removeDuplicateSlashes(path2) {
33266
- return path2.indexOf("//") !== -1 ? path2.replace(REMOVE_DUPLICATE_SLASHES_REGEXP, "/") : path2;
33265
+ function removeDuplicateSlashes(path3) {
33266
+ return path3.indexOf("//") !== -1 ? path3.replace(REMOVE_DUPLICATE_SLASHES_REGEXP, "/") : path3;
33267
33267
  }
33268
- function trimLastSlash(path2) {
33269
- if (path2.length > 1 && path2.charCodeAt(path2.length - 1) === 47) {
33270
- return path2.slice(0, -1);
33268
+ function trimLastSlash(path3) {
33269
+ if (path3.length > 1 && path3.charCodeAt(path3.length - 1) === 47) {
33270
+ return path3.slice(0, -1);
33271
33271
  }
33272
- return path2;
33272
+ return path3;
33273
33273
  }
33274
33274
  function trimRegExpStartAndEnd(regexString) {
33275
33275
  if (regexString.charCodeAt(1) === 94) {
@@ -33280,22 +33280,22 @@ var require_find_my_way = __commonJS({
33280
33280
  }
33281
33281
  return regexString;
33282
33282
  }
33283
- function getClosingParenthensePosition(path2, idx) {
33283
+ function getClosingParenthensePosition(path3, idx) {
33284
33284
  let parentheses = 1;
33285
- while (idx < path2.length) {
33285
+ while (idx < path3.length) {
33286
33286
  idx++;
33287
- if (path2.charCodeAt(idx) === 92) {
33287
+ if (path3.charCodeAt(idx) === 92) {
33288
33288
  idx++;
33289
33289
  continue;
33290
33290
  }
33291
- if (path2.charCodeAt(idx) === 41) {
33291
+ if (path3.charCodeAt(idx) === 41) {
33292
33292
  parentheses--;
33293
- } else if (path2.charCodeAt(idx) === 40) {
33293
+ } else if (path3.charCodeAt(idx) === 40) {
33294
33294
  parentheses++;
33295
33295
  }
33296
33296
  if (!parentheses) return idx;
33297
33297
  }
33298
- throw new TypeError('Invalid regexp expression in "' + path2 + '"');
33298
+ throw new TypeError('Invalid regexp expression in "' + path3 + '"');
33299
33299
  }
33300
33300
  function defaultBuildPrettyMeta(route) {
33301
33301
  if (!route) return {};
@@ -33528,12 +33528,12 @@ var require_route = __commonJS({
33528
33528
  function route({ options: options2, isFastify }) {
33529
33529
  throwIfAlreadyStarted("Cannot add route!");
33530
33530
  const opts = { ...options2 };
33531
- const path2 = opts.url || opts.path || "";
33531
+ const path3 = opts.url || opts.path || "";
33532
33532
  if (!opts.handler) {
33533
- throw new FST_ERR_ROUTE_MISSING_HANDLER(opts.method, path2);
33533
+ throw new FST_ERR_ROUTE_MISSING_HANDLER(opts.method, path3);
33534
33534
  }
33535
33535
  if (opts.errorHandler !== void 0 && typeof opts.errorHandler !== "function") {
33536
- throw new FST_ERR_ROUTE_HANDLER_NOT_FN(opts.method, path2);
33536
+ throw new FST_ERR_ROUTE_HANDLER_NOT_FN(opts.method, path3);
33537
33537
  }
33538
33538
  validateBodyLimitOption(opts.bodyLimit);
33539
33539
  validateHandlerTimeoutOption(opts.handlerTimeout);
@@ -33543,22 +33543,22 @@ var require_route = __commonJS({
33543
33543
  if (Array.isArray(opts.method)) {
33544
33544
  for (let i = 0; i < opts.method.length; ++i) {
33545
33545
  opts.method[i] = normalizeAndValidateMethod.call(this, opts.method[i]);
33546
- validateSchemaBodyOption.call(this, opts.method[i], path2, opts.schema);
33546
+ validateSchemaBodyOption.call(this, opts.method[i], path3, opts.schema);
33547
33547
  isGetRoute = opts.method.includes("GET");
33548
33548
  isHeadRoute = opts.method.includes("HEAD");
33549
33549
  }
33550
33550
  } else {
33551
33551
  opts.method = normalizeAndValidateMethod.call(this, opts.method);
33552
- validateSchemaBodyOption.call(this, opts.method, path2, opts.schema);
33552
+ validateSchemaBodyOption.call(this, opts.method, path3, opts.schema);
33553
33553
  isGetRoute = opts.method === "GET";
33554
33554
  isHeadRoute = opts.method === "HEAD";
33555
33555
  }
33556
33556
  const headOpts = shouldExposeHead && isGetRoute ? { ...options2 } : null;
33557
33557
  const prefix = this[kRoutePrefix];
33558
- if (path2 === "/" && prefix.length > 0 && opts.method !== "HEAD") {
33558
+ if (path3 === "/" && prefix.length > 0 && opts.method !== "HEAD") {
33559
33559
  switch (opts.prefixTrailingSlash) {
33560
33560
  case "slash":
33561
- addNewRoute.call(this, { path: path2, isFastify });
33561
+ addNewRoute.call(this, { path: path3, isFastify });
33562
33562
  break;
33563
33563
  case "no-slash":
33564
33564
  addNewRoute.call(this, { path: "", isFastify });
@@ -33567,20 +33567,20 @@ var require_route = __commonJS({
33567
33567
  default:
33568
33568
  addNewRoute.call(this, { path: "", isFastify });
33569
33569
  if (ignoreTrailingSlash !== true && (ignoreDuplicateSlashes !== true || !prefix.endsWith("/"))) {
33570
- addNewRoute.call(this, { path: path2, prefixing: true, isFastify });
33570
+ addNewRoute.call(this, { path: path3, prefixing: true, isFastify });
33571
33571
  }
33572
33572
  }
33573
- } else if (path2[0] === "/" && prefix.endsWith("/")) {
33574
- addNewRoute.call(this, { path: path2.slice(1), isFastify });
33573
+ } else if (path3[0] === "/" && prefix.endsWith("/")) {
33574
+ addNewRoute.call(this, { path: path3.slice(1), isFastify });
33575
33575
  } else {
33576
- addNewRoute.call(this, { path: path2, isFastify });
33576
+ addNewRoute.call(this, { path: path3, isFastify });
33577
33577
  }
33578
33578
  return this;
33579
- function addNewRoute({ path: path3, prefixing = false, isFastify: isFastify2 = false }) {
33580
- const url = prefix + path3;
33579
+ function addNewRoute({ path: path4, prefixing = false, isFastify: isFastify2 = false }) {
33580
+ const url = prefix + path4;
33581
33581
  opts.url = url;
33582
33582
  opts.path = url;
33583
- opts.routePath = path3;
33583
+ opts.routePath = path4;
33584
33584
  opts.prefix = prefix;
33585
33585
  opts.logLevel = opts.logLevel || this[kLogLevel];
33586
33586
  validateLogLevelOption(opts.logLevel, opts.method, opts.url, logger);
@@ -33712,7 +33712,7 @@ var require_route = __commonJS({
33712
33712
  });
33713
33713
  if (shouldExposeHead && isGetRoute && !isHeadRoute && !hasHEADHandler) {
33714
33714
  const onSendHandlers = parseHeadOnSendHandlers(headOpts.onSend);
33715
- prepareRoute.call(this, { method: "HEAD", url: path3, options: { ...headOpts, onSend: onSendHandlers }, isFastify: true });
33715
+ prepareRoute.call(this, { method: "HEAD", url: path4, options: { ...headOpts, onSend: onSendHandlers }, isFastify: true });
33716
33716
  }
33717
33717
  }
33718
33718
  }
@@ -33836,9 +33836,9 @@ var require_route = __commonJS({
33836
33836
  }
33837
33837
  return method;
33838
33838
  }
33839
- function validateSchemaBodyOption(method, path2, schema) {
33839
+ function validateSchemaBodyOption(method, path3, schema) {
33840
33840
  if (this[kSupportedHTTPMethods].bodyless.has(method) && schema?.body) {
33841
- throw new FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED(method, path2);
33841
+ throw new FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED(method, path3);
33842
33842
  }
33843
33843
  }
33844
33844
  function validateBodyLimitOption(bodyLimit) {
@@ -33853,11 +33853,11 @@ var require_route = __commonJS({
33853
33853
  throw new FST_ERR_ROUTE_HANDLER_TIMEOUT_OPTION_NOT_INT(handlerTimeout);
33854
33854
  }
33855
33855
  }
33856
- function validateLogLevelOption(logLevel, method, path2, logger) {
33856
+ function validateLogLevelOption(logLevel, method, path3, logger) {
33857
33857
  if (logLevel == null || logLevel === "") return;
33858
33858
  if (logger?.levels?.values == null) return;
33859
33859
  if (typeof logLevel !== "string" || logger.levels.values[logLevel] === void 0) {
33860
- throw new FST_ERR_ROUTE_LOG_LEVEL_INVALID(method, path2, logLevel);
33860
+ throw new FST_ERR_ROUTE_LOG_LEVEL_INVALID(method, path3, logLevel);
33861
33861
  }
33862
33862
  }
33863
33863
  function runPreParsing(err, request, reply) {
@@ -33946,7 +33946,7 @@ var require_four_oh_four = __commonJS({
33946
33946
  });
33947
33947
  }
33948
33948
  function createRouteEventHandler() {
33949
- return function onRouteEvent(path2, req, res) {
33949
+ return function onRouteEvent(path3, req, res) {
33950
33950
  const fourOhFourContext = this[kFourOhFourLevelInstance][kFourOhFourContext];
33951
33951
  const id2 = getGenReqId(fourOhFourContext.server, req);
33952
33952
  const childLogger = createChildLogger(fourOhFourContext, logger, req, id2);
@@ -36617,19 +36617,19 @@ var require_fastify = __commonJS({
36617
36617
  }
36618
36618
  fourOhFour.router.lookup(req, res);
36619
36619
  }
36620
- function onBadUrl(path2, req, res) {
36620
+ function onBadUrl(path3, req, res) {
36621
36621
  if (options.frameworkErrors) {
36622
36622
  const id2 = getGenReqId(routeEventContext.server, req);
36623
36623
  const childLogger = createChildLogger(routeEventContext, options.logger, req, id2);
36624
36624
  const request = new Request(id2, null, req, null, childLogger, routeEventContext);
36625
36625
  const reply = new Reply(res, request, childLogger);
36626
36626
  routeEventContext.server[kLogController].incomingRequest(request, reply);
36627
- return options.frameworkErrors(new FST_ERR_BAD_URL(path2), request, reply);
36627
+ return options.frameworkErrors(new FST_ERR_BAD_URL(path3), request, reply);
36628
36628
  }
36629
36629
  const body = JSON.stringify({
36630
36630
  error: "Bad Request",
36631
36631
  code: "FST_ERR_BAD_URL",
36632
- message: `'${path2}' is not a valid url component`,
36632
+ message: `'${path3}' is not a valid url component`,
36633
36633
  statusCode: 400
36634
36634
  });
36635
36635
  res.writeHead(400, {
@@ -36638,19 +36638,19 @@ var require_fastify = __commonJS({
36638
36638
  });
36639
36639
  res.end(body);
36640
36640
  }
36641
- function onMaxParamLength(path2, req, res) {
36641
+ function onMaxParamLength(path3, req, res) {
36642
36642
  if (options.frameworkErrors) {
36643
36643
  const id2 = getGenReqId(routeEventContext.server, req);
36644
36644
  const childLogger = createChildLogger(routeEventContext, options.logger, req, id2);
36645
36645
  const request = new Request(id2, null, req, null, childLogger, routeEventContext);
36646
36646
  const reply = new Reply(res, request, childLogger);
36647
36647
  routeEventContext.server[kLogController].incomingRequest(request, reply);
36648
- return options.frameworkErrors(new FST_ERR_MAX_PARAM_LENGTH(path2), request, reply);
36648
+ return options.frameworkErrors(new FST_ERR_MAX_PARAM_LENGTH(path3), request, reply);
36649
36649
  }
36650
36650
  const body = JSON.stringify({
36651
36651
  error: "Bad Request",
36652
36652
  code: "FST_ERR_MAX_PARAM_LENGTH",
36653
- message: `'${path2}' is exceeding the max param length`,
36653
+ message: `'${path3}' is exceeding the max param length`,
36654
36654
  statusCode: 414
36655
36655
  });
36656
36656
  res.writeHead(414, {
@@ -37376,20 +37376,20 @@ var require_file_uri_to_path = __commonJS({
37376
37376
  var rest = decodeURI(uri.substring(7));
37377
37377
  var firstSlash = rest.indexOf("/");
37378
37378
  var host = rest.substring(0, firstSlash);
37379
- var path2 = rest.substring(firstSlash + 1);
37379
+ var path3 = rest.substring(firstSlash + 1);
37380
37380
  if ("localhost" == host) host = "";
37381
37381
  if (host) {
37382
37382
  host = sep5 + sep5 + host;
37383
37383
  }
37384
- path2 = path2.replace(/^(.+)\|/, "$1:");
37384
+ path3 = path3.replace(/^(.+)\|/, "$1:");
37385
37385
  if (sep5 == "\\") {
37386
- path2 = path2.replace(/\//g, "\\");
37386
+ path3 = path3.replace(/\//g, "\\");
37387
37387
  }
37388
- if (/^.+\:/.test(path2)) {
37388
+ if (/^.+\:/.test(path3)) {
37389
37389
  } else {
37390
- path2 = sep5 + path2;
37390
+ path3 = sep5 + path3;
37391
37391
  }
37392
- return host + path2;
37392
+ return host + path3;
37393
37393
  }
37394
37394
  }
37395
37395
  });
@@ -37398,18 +37398,18 @@ var require_file_uri_to_path = __commonJS({
37398
37398
  var require_bindings = __commonJS({
37399
37399
  "node_modules/bindings/bindings.js"(exports, module) {
37400
37400
  var fs = __require("fs");
37401
- var path2 = __require("path");
37401
+ var path3 = __require("path");
37402
37402
  var fileURLToPath = require_file_uri_to_path();
37403
- var join6 = path2.join;
37404
- var dirname4 = path2.dirname;
37405
- var exists = fs.accessSync && function(path3) {
37403
+ var join6 = path3.join;
37404
+ var dirname4 = path3.dirname;
37405
+ var exists = fs.accessSync && function(path4) {
37406
37406
  try {
37407
- fs.accessSync(path3);
37407
+ fs.accessSync(path4);
37408
37408
  } catch (e) {
37409
37409
  return false;
37410
37410
  }
37411
37411
  return true;
37412
- } || fs.existsSync || path2.existsSync;
37412
+ } || fs.existsSync || path3.existsSync;
37413
37413
  var defaults = {
37414
37414
  arrow: process.env.NODE_BINDINGS_ARROW || " \u2192 ",
37415
37415
  compiled: process.env.NODE_BINDINGS_COMPILED_DIR || "compiled",
@@ -37454,7 +37454,7 @@ var require_bindings = __commonJS({
37454
37454
  if (!opts.module_root) {
37455
37455
  opts.module_root = exports.getRoot(exports.getFileName());
37456
37456
  }
37457
- if (path2.extname(opts.bindings) != ".node") {
37457
+ if (path3.extname(opts.bindings) != ".node") {
37458
37458
  opts.bindings += ".node";
37459
37459
  }
37460
37460
  var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
@@ -37693,7 +37693,7 @@ var require_backup = __commonJS({
37693
37693
  "node_modules/better-sqlite3/lib/methods/backup.js"(exports, module) {
37694
37694
  "use strict";
37695
37695
  var fs = __require("fs");
37696
- var path2 = __require("path");
37696
+ var path3 = __require("path");
37697
37697
  var { promisify: promisify2 } = __require("util");
37698
37698
  var { cppdb } = require_util3();
37699
37699
  var fsAccess = promisify2(fs.access);
@@ -37709,7 +37709,7 @@ var require_backup = __commonJS({
37709
37709
  if (typeof attachedName !== "string") throw new TypeError('Expected the "attached" option to be a string');
37710
37710
  if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
37711
37711
  if (handler != null && typeof handler !== "function") throw new TypeError('Expected the "progress" option to be a function');
37712
- await fsAccess(path2.dirname(filename)).catch(() => {
37712
+ await fsAccess(path3.dirname(filename)).catch(() => {
37713
37713
  throw new TypeError("Cannot save backup because the directory does not exist");
37714
37714
  });
37715
37715
  const isNewFile = await fsAccess(filename).then(() => false, () => true);
@@ -38015,7 +38015,7 @@ var require_database = __commonJS({
38015
38015
  "node_modules/better-sqlite3/lib/database.js"(exports, module) {
38016
38016
  "use strict";
38017
38017
  var fs = __require("fs");
38018
- var path2 = __require("path");
38018
+ var path3 = __require("path");
38019
38019
  var util = require_util3();
38020
38020
  var SqliteError = require_sqlite_error();
38021
38021
  var DEFAULT_ADDON;
@@ -38051,7 +38051,7 @@ var require_database = __commonJS({
38051
38051
  addon = DEFAULT_ADDON || (DEFAULT_ADDON = require_bindings()("better_sqlite3.node"));
38052
38052
  } else if (typeof nativeBinding === "string") {
38053
38053
  const requireFunc = typeof __non_webpack_require__ === "function" ? __non_webpack_require__ : __require;
38054
- addon = requireFunc(path2.resolve(nativeBinding).replace(/(\.node)?$/, ".node"));
38054
+ addon = requireFunc(path3.resolve(nativeBinding).replace(/(\.node)?$/, ".node"));
38055
38055
  } else {
38056
38056
  addon = nativeBinding;
38057
38057
  }
@@ -38059,7 +38059,7 @@ var require_database = __commonJS({
38059
38059
  addon.setErrorConstructor(SqliteError);
38060
38060
  addon.isInitialized = true;
38061
38061
  }
38062
- if (!anonymous && !fs.existsSync(path2.dirname(filename))) {
38062
+ if (!anonymous && !fs.existsSync(path3.dirname(filename))) {
38063
38063
  throw new TypeError("Cannot open database because the directory does not exist");
38064
38064
  }
38065
38065
  Object.defineProperties(this, {
@@ -41772,8 +41772,8 @@ var import_cors = __toESM(require_cors(), 1);
41772
41772
  // src/db/index.ts
41773
41773
  var import_better_sqlite3 = __toESM(require_lib2(), 1);
41774
41774
  var db;
41775
- function initDb(path2 = "data.db") {
41776
- db = new import_better_sqlite3.default(path2);
41775
+ function initDb(path3 = "data.db") {
41776
+ db = new import_better_sqlite3.default(path3);
41777
41777
  db.pragma("journal_mode = WAL");
41778
41778
  db.pragma("foreign_keys = ON");
41779
41779
  createTables(db);
@@ -41902,6 +41902,9 @@ function createTables(database) {
41902
41902
  if (!turnColumns.some((c) => c.name === "attachments")) {
41903
41903
  database.exec("ALTER TABLE turns ADD COLUMN attachments TEXT");
41904
41904
  }
41905
+ if (!turnColumns.some((c) => c.name === "runtime_input_ids")) {
41906
+ database.exec("ALTER TABLE turns ADD COLUMN runtime_input_ids TEXT");
41907
+ }
41905
41908
  const threadColumns = database.prepare("PRAGMA table_info(discussion_threads)").all();
41906
41909
  if (!threadColumns.some((c) => c.name === "external_thread_id")) {
41907
41910
  database.exec("ALTER TABLE discussion_threads ADD COLUMN external_thread_id TEXT");
@@ -41969,6 +41972,9 @@ function getWss() {
41969
41972
  return wss;
41970
41973
  }
41971
41974
 
41975
+ // src/routes/sessions.ts
41976
+ import path from "node:path";
41977
+
41972
41978
  // node_modules/uuid/dist/esm/stringify.js
41973
41979
  var byteToHex = [];
41974
41980
  for (let i = 0; i < 256; ++i) {
@@ -42075,6 +42081,7 @@ async function registerSessionRoutes(fastify) {
42075
42081
  ...row,
42076
42082
  token_usage: row.token_usage ? JSON.parse(row.token_usage) : null,
42077
42083
  attachments: row.attachments ? JSON.parse(row.attachments) : null,
42084
+ runtime_input_ids: row.runtime_input_ids ? JSON.parse(row.runtime_input_ids) : null,
42078
42085
  items: itemsByTurn.get(row.id) ?? []
42079
42086
  }))
42080
42087
  };
@@ -42149,13 +42156,14 @@ async function registerSessionRoutes(fastify) {
42149
42156
  model: { type: ["string", "null"] },
42150
42157
  model_reasoning_effort: { type: ["string", "null"] },
42151
42158
  runtime_config: { type: ["string", "null"] },
42152
- runtime_type: { type: "string" }
42159
+ runtime_type: { type: "string" },
42160
+ cwd: { type: ["string", "null"] }
42153
42161
  }
42154
42162
  }
42155
42163
  }
42156
42164
  }, async (request, reply) => {
42157
42165
  const { id: id2 } = request.params;
42158
- const { title, lifecycle, has_unreviewed, model, model_reasoning_effort, runtime_config, runtime_type } = request.body || {};
42166
+ const { title, lifecycle, has_unreviewed, model, model_reasoning_effort, runtime_config, runtime_type, cwd } = request.body || {};
42159
42167
  const db3 = getDb();
42160
42168
  const existing = db3.prepare("SELECT * FROM sessions WHERE id = ?").get(id2);
42161
42169
  if (!existing) {
@@ -42193,6 +42201,17 @@ async function registerSessionRoutes(fastify) {
42193
42201
  params.push(null);
42194
42202
  }
42195
42203
  }
42204
+ let workspaceChanged = false;
42205
+ if (cwd !== void 0) {
42206
+ const oldAbs = existing.cwd ? path.resolve(existing.cwd) : null;
42207
+ const newAbs = cwd ? path.resolve(cwd) : null;
42208
+ workspaceChanged = oldAbs !== newAbs;
42209
+ if (workspaceChanged && existing.is_running) {
42210
+ return reply.code(409).send({ error: "Cannot change workspace while a turn is running" });
42211
+ }
42212
+ updates.push("cwd = ?");
42213
+ params.push(cwd);
42214
+ }
42196
42215
  if (model !== void 0) {
42197
42216
  updates.push("model = ?");
42198
42217
  params.push(model);
@@ -42214,8 +42233,10 @@ async function registerSessionRoutes(fastify) {
42214
42233
  params.push(runtime_config);
42215
42234
  }
42216
42235
  db3.prepare(`UPDATE sessions SET ${updates.join(", ")} WHERE id = ?`).run(...params, id2);
42217
- if (providerChanged && existing.external_thread_id) {
42218
- db3.prepare("UPDATE sessions SET external_thread_id = NULL, rewound_at_turn_id = NULL, pre_rewind_thread_id = NULL, updated_at = ? WHERE id = ?").run(now, id2);
42236
+ if (providerChanged || workspaceChanged) {
42237
+ if (existing.external_thread_id) {
42238
+ db3.prepare("UPDATE sessions SET external_thread_id = NULL, rewound_at_turn_id = NULL, pre_rewind_thread_id = NULL, updated_at = ? WHERE id = ?").run(now, id2);
42239
+ }
42219
42240
  getProvider(existing.runtime_type).clearThread(id2);
42220
42241
  }
42221
42242
  const session = db3.prepare("SELECT * FROM sessions WHERE id = ?").get(id2);
@@ -42252,6 +42273,23 @@ async function registerSessionRoutes(fastify) {
42252
42273
  if (!targetTurnFull) {
42253
42274
  return reply.code(404).send({ error: "Turn not found" });
42254
42275
  }
42276
+ const provider = getProvider(session.runtime_type);
42277
+ if (provider.rewindRuntime) {
42278
+ await provider.rewindRuntime(session, targetTurnFull);
42279
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
42280
+ db3.prepare(
42281
+ "DELETE FROM items WHERE turn_id IN (SELECT id FROM turns WHERE session_id = ? AND created_at > ?)"
42282
+ ).run(id2, targetTurnFull.created_at);
42283
+ db3.prepare("DELETE FROM turns WHERE session_id = ? AND created_at > ?").run(
42284
+ id2,
42285
+ targetTurnFull.created_at
42286
+ );
42287
+ db3.prepare(
42288
+ "UPDATE sessions SET rewound_at_turn_id = NULL, pre_rewind_thread_id = NULL, updated_at = ? WHERE id = ?"
42289
+ ).run(now2, id2);
42290
+ const truncated = db3.prepare("SELECT * FROM sessions WHERE id = ?").get(id2);
42291
+ return truncated;
42292
+ }
42255
42293
  const now = (/* @__PURE__ */ new Date()).toISOString();
42256
42294
  if (!session.pre_rewind_thread_id && session.external_thread_id) {
42257
42295
  db3.prepare(
@@ -42264,7 +42302,6 @@ async function registerSessionRoutes(fastify) {
42264
42302
  ).run(turn_id, now, id2);
42265
42303
  console.log(`[rewind] pre_rewind_thread_id already set (${session.pre_rewind_thread_id}) or external_thread_id is null for session ${id2}`);
42266
42304
  }
42267
- const provider = getProvider(session.runtime_type);
42268
42305
  if (provider.forkSession) {
42269
42306
  try {
42270
42307
  const forkedId = await provider.forkSession(session, targetTurnFull);
@@ -42293,6 +42330,11 @@ async function registerSessionRoutes(fastify) {
42293
42330
  if (!session.rewound_at_turn_id) {
42294
42331
  return reply.code(409).send({ error: "Session is not rewound" });
42295
42332
  }
42333
+ if (session.runtime_type === "repoburg") {
42334
+ return reply.code(409).send({
42335
+ error: "Restore is not available for repoburg sessions \u2014 the rewind permanently deleted the runtime history."
42336
+ });
42337
+ }
42296
42338
  const now = (/* @__PURE__ */ new Date()).toISOString();
42297
42339
  db3.prepare(
42298
42340
  "UPDATE sessions SET rewound_at_turn_id = NULL, pre_rewind_thread_id = NULL, external_thread_id = COALESCE(pre_rewind_thread_id, external_thread_id), updated_at = ? WHERE id = ?"
@@ -42709,11 +42751,11 @@ async function registerWorkspaceRoutes(fastify) {
42709
42751
  }
42710
42752
  }
42711
42753
  }, async (request, reply) => {
42712
- const { path: path2, label = null } = request.body || {};
42713
- if (!path2 || !path2.trim()) {
42754
+ const { path: path3, label = null } = request.body || {};
42755
+ if (!path3 || !path3.trim()) {
42714
42756
  return reply.code(400).send({ error: "Path is required" });
42715
42757
  }
42716
- const trimmedPath = path2.trim();
42758
+ const trimmedPath = path3.trim();
42717
42759
  const db3 = getDb();
42718
42760
  const existing = db3.prepare("SELECT * FROM workspaces WHERE path = ?").get(trimmedPath);
42719
42761
  if (existing) {
@@ -42741,8 +42783,8 @@ async function registerWorkspaceRoutes(fastify) {
42741
42783
  "-e",
42742
42784
  'POSIX path of (choose folder with prompt "Select a workspace directory")'
42743
42785
  ]);
42744
- const path2 = stdout.trim().replace(/\/$/, "");
42745
- return { path: path2 };
42786
+ const path3 = stdout.trim().replace(/\/$/, "");
42787
+ return { path: path3 };
42746
42788
  } catch {
42747
42789
  return reply.code(204).send({ cancelled: true });
42748
42790
  }
@@ -42758,11 +42800,11 @@ async function registerWorkspaceRoutes(fastify) {
42758
42800
  }
42759
42801
  }
42760
42802
  }, async (request, reply) => {
42761
- const { path: path2 } = request.body || {};
42762
- if (!path2 || !path2.trim()) {
42803
+ const { path: path3 } = request.body || {};
42804
+ if (!path3 || !path3.trim()) {
42763
42805
  return reply.code(400).send({ error: "Path is required" });
42764
42806
  }
42765
- const trimmedPath = path2.trim();
42807
+ const trimmedPath = path3.trim();
42766
42808
  const db3 = getDb();
42767
42809
  const existing = db3.prepare("SELECT * FROM workspaces WHERE path = ?").get(trimmedPath);
42768
42810
  if (existing) {
@@ -72940,9 +72982,9 @@ function mapToolUse(block) {
72940
72982
  };
72941
72983
  }
72942
72984
  function deriveFileChangeData(input, toolName) {
72943
- const path2 = input.file_path ?? input.notebook_path ?? "";
72985
+ const path3 = input.file_path ?? input.notebook_path ?? "";
72944
72986
  const kind = toolName === "Write" ? "add" : "modify";
72945
- return { changes: [{ path: path2, kind }], status: "in_progress" };
72987
+ return { changes: [{ path: path3, kind }], status: "in_progress" };
72946
72988
  }
72947
72989
  function extractToolResultText(content) {
72948
72990
  if (!content) return "";
@@ -73836,8 +73878,8 @@ var RepoburgHttpClient = class {
73836
73878
  this.baseUrl = baseUrl.replace(/\/+$/, "");
73837
73879
  }
73838
73880
  /** Perform a JSON request. Throws a concise error on non-OK/non-JSON responses. */
73839
- async request(method, path2, body) {
73840
- const response = await fetch(`${this.baseUrl}${path2}`, {
73881
+ async request(method, path3, body) {
73882
+ const response = await fetch(`${this.baseUrl}${path3}`, {
73841
73883
  method,
73842
73884
  headers: { "Content-Type": "application/json" },
73843
73885
  body: body === void 0 ? void 0 : JSON.stringify(body)
@@ -73846,16 +73888,17 @@ var RepoburgHttpClient = class {
73846
73888
  if (!response.ok) {
73847
73889
  if (isHtml(text)) {
73848
73890
  throw new Error(
73849
- `${method} ${path2} failed: ${response.status} HTML response from ${this.baseUrl} \u2014 the URL points to the wrong server`
73891
+ `${method} ${path3} failed: ${response.status} HTML response from ${this.baseUrl} \u2014 the URL points to the wrong server`
73850
73892
  );
73851
73893
  }
73852
- throw new Error(`${method} ${path2} failed: ${response.status} ${text}`);
73894
+ throw new Error(`${method} ${path3} failed: ${response.status} ${text}`);
73853
73895
  }
73896
+ if (text.length === 0) return void 0;
73854
73897
  try {
73855
73898
  return JSON.parse(text);
73856
73899
  } catch {
73857
73900
  throw new Error(
73858
- `${method} ${path2} failed: non-JSON response from ${this.baseUrl} \u2014 the URL points to the wrong server`
73901
+ `${method} ${path3} failed: non-JSON response from ${this.baseUrl} \u2014 the URL points to the wrong server`
73859
73902
  );
73860
73903
  }
73861
73904
  }
@@ -73880,6 +73923,12 @@ var RepoburgHttpClient = class {
73880
73923
  async getSessionInputs(sessionId) {
73881
73924
  return this.request("GET", `/sessions/${sessionId}/inputs`);
73882
73925
  }
73926
+ async deleteInputsUntilHere(sessionId, anchorInputId) {
73927
+ await this.request(
73928
+ "DELETE",
73929
+ `/sessions/${sessionId}/inputs/${anchorInputId}/until-here`
73930
+ );
73931
+ }
73883
73932
  async cancel(sessionId) {
73884
73933
  return this.request(
73885
73934
  "POST",
@@ -73893,7 +73942,7 @@ var RepoburgHttpClient = class {
73893
73942
  };
73894
73943
 
73895
73944
  // src/repoburg/backend-resolver.ts
73896
- import path from "node:path";
73945
+ import path2 from "node:path";
73897
73946
  var HEALTH_POLL_INTERVAL_MS = 1e3;
73898
73947
  var HEALTH_TIMEOUT_MS = 3e4;
73899
73948
  function daemonBaseUrl() {
@@ -73943,18 +73992,22 @@ function invalidateBackend(baseUrl) {
73943
73992
  if (value.baseUrl === baseUrl) resolvedCache.delete(key);
73944
73993
  }
73945
73994
  }
73946
- async function backendHealthy(baseUrl) {
73995
+ async function backendHealthy(baseUrl, expectedPath) {
73947
73996
  try {
73948
- await fetchJson(`${baseUrl}/health`, void 0, 2e3);
73997
+ const health = await fetchJson(`${baseUrl}/health`, void 0, 2e3);
73998
+ if (health.status !== "ok") return false;
73999
+ if (expectedPath && health.projectPath) {
74000
+ return path2.resolve(health.projectPath) === path2.resolve(expectedPath);
74001
+ }
73949
74002
  return true;
73950
74003
  } catch {
73951
74004
  return false;
73952
74005
  }
73953
74006
  }
73954
- async function waitForHealthy(baseUrl, name) {
74007
+ async function waitForHealthy(baseUrl, name, expectedPath) {
73955
74008
  const deadline = Date.now() + HEALTH_TIMEOUT_MS;
73956
74009
  while (Date.now() < deadline) {
73957
- if (await backendHealthy(baseUrl)) return;
74010
+ if (await backendHealthy(baseUrl, expectedPath)) return;
73958
74011
  await new Promise((resolve5) => setTimeout(resolve5, HEALTH_POLL_INTERVAL_MS));
73959
74012
  }
73960
74013
  throw new Error(
@@ -73997,10 +74050,10 @@ async function resolveBackendUrl(projectPath, opts = {}) {
73997
74050
  if (envUrl) {
73998
74051
  return { baseUrl: envUrl.replace(/\/+$/, ""), port: 0, name: "REPOBURG_BACKEND_URL" };
73999
74052
  }
74000
- const absPath = path.resolve(projectPath);
74053
+ const absPath = path2.resolve(projectPath);
74001
74054
  const daemon = daemonBaseUrl();
74002
74055
  const cached = resolvedCache.get(absPath);
74003
- if (cached && await backendHealthy(cached.baseUrl)) {
74056
+ if (cached && await backendHealthy(cached.baseUrl, absPath)) {
74004
74057
  return cached;
74005
74058
  }
74006
74059
  try {
@@ -74013,22 +74066,22 @@ async function resolveBackendUrl(projectPath, opts = {}) {
74013
74066
  const services = await fetchJson(`${daemon}/services`);
74014
74067
  const match = services.find((s) => s.path === absPath);
74015
74068
  if (match && match.status === "running") {
74016
- if (await backendHealthy(serviceBaseUrl(match))) {
74069
+ if (await backendHealthy(serviceBaseUrl(match), absPath)) {
74017
74070
  return cache(absPath, match);
74018
74071
  }
74019
74072
  if (!autoStart) return null;
74020
74073
  await restartService(daemon, match.name);
74021
- await waitForHealthy(serviceBaseUrl(match), match.name);
74074
+ await waitForHealthy(serviceBaseUrl(match), match.name, absPath);
74022
74075
  return cache(absPath, match);
74023
74076
  }
74024
74077
  if (!autoStart) return null;
74025
74078
  if (match) {
74026
74079
  await restartService(daemon, match.name);
74027
- await waitForHealthy(serviceBaseUrl(match), match.name);
74080
+ await waitForHealthy(serviceBaseUrl(match), match.name, absPath);
74028
74081
  return cache(absPath, match);
74029
74082
  }
74030
74083
  const service = await startService(daemon, absPath);
74031
- await waitForHealthy(serviceBaseUrl(service), service.name);
74084
+ await waitForHealthy(serviceBaseUrl(service), service.name, absPath);
74032
74085
  return cache(absPath, service);
74033
74086
  }
74034
74087
 
@@ -74042,6 +74095,35 @@ function parseJsonArgs(raw) {
74042
74095
  return null;
74043
74096
  }
74044
74097
  }
74098
+ function parseSelectionGroups(raw) {
74099
+ if (!raw) return [];
74100
+ let parsed;
74101
+ try {
74102
+ parsed = JSON.parse(raw);
74103
+ } catch {
74104
+ return [];
74105
+ }
74106
+ if (!Array.isArray(parsed)) return [];
74107
+ return parsed.map((item) => {
74108
+ if (item && typeof item === "object" && !Array.isArray(item)) {
74109
+ const obj = item;
74110
+ if (Array.isArray(obj.selections)) {
74111
+ const opts = obj.selections.filter((s) => typeof s === "string");
74112
+ if (opts.length > 0) {
74113
+ return {
74114
+ question: typeof obj.question === "string" ? obj.question : "",
74115
+ selections: opts
74116
+ };
74117
+ }
74118
+ }
74119
+ return null;
74120
+ }
74121
+ if (typeof item === "string") {
74122
+ return { question: "", selections: [item] };
74123
+ }
74124
+ return null;
74125
+ }).filter((g2) => g2 !== null);
74126
+ }
74045
74127
  function mapActionToItem(action) {
74046
74128
  const failed = action.status === "EXECUTION_FAILED";
74047
74129
  const status = failed ? "failed" : "completed";
@@ -74077,18 +74159,22 @@ function mapActionToItem(action) {
74077
74159
  };
74078
74160
  case "invoke_subagent": {
74079
74161
  const args = parseJsonArgs(action.arguments);
74162
+ const agentName = args?.agent_name ?? args?.agentName ?? "Sub-agent";
74163
+ const prompt = args?.prompt ?? "";
74080
74164
  return {
74081
- type: "mcp_tool_call",
74165
+ type: "background_task",
74082
74166
  data: {
74083
- server: null,
74084
- tool: "Agent",
74085
- arguments: {
74086
- description: args?.agent_name ?? args?.agentName ?? "Subagent",
74087
- prompt: args?.prompt ?? ""
74088
- },
74089
- result: output ? [{ type: "text", text: output }] : null,
74090
- error: failed ? errorMsg || "Sub-agent failed" : null,
74091
- status
74167
+ task_id: args?.childSessionId ?? "",
74168
+ description: prompt || agentName,
74169
+ task_type: "subagent",
74170
+ subagent_type: agentName,
74171
+ prompt: prompt || null,
74172
+ status: failed ? "failed" : "completed",
74173
+ summary: output || (failed ? errorMsg || "Sub-agent failed" : ""),
74174
+ output_file: null,
74175
+ output: "",
74176
+ token_count: null,
74177
+ last_tool_name: null
74092
74178
  },
74093
74179
  status
74094
74180
  };
@@ -74097,9 +74183,20 @@ function mapActionToItem(action) {
74097
74183
  const args = parseJsonArgs(action.arguments);
74098
74184
  return { type: "web_search", data: { query: args?.query ?? "" }, status };
74099
74185
  }
74186
+ case "ask_user": {
74187
+ const groups = parseSelectionGroups(action.selections);
74188
+ const data = {
74189
+ question: groups.length ? "" : action.selections ?? "",
74190
+ groups
74191
+ };
74192
+ return {
74193
+ type: "ask_user",
74194
+ data: { question: data.question, groups: data.groups },
74195
+ status
74196
+ };
74197
+ }
74100
74198
  case "final":
74101
74199
  case "html_final":
74102
- case "ask_user":
74103
74200
  return null;
74104
74201
  default: {
74105
74202
  const isMcp = !!(action.server_name && action.tool_name);
@@ -74127,6 +74224,17 @@ function mapUsage2(u) {
74127
74224
  reasoning_output_tokens: 0
74128
74225
  };
74129
74226
  }
74227
+ function updateItem(db3, sessionId, turnId, item, data, status) {
74228
+ const now = (/* @__PURE__ */ new Date()).toISOString();
74229
+ db3.prepare("UPDATE items SET data = ?, status = ?, updated_at = ? WHERE id = ?").run(
74230
+ JSON.stringify(data),
74231
+ status,
74232
+ now,
74233
+ item.id
74234
+ );
74235
+ const updated = { ...item, data, status, updated_at: now };
74236
+ broadcast("item:updated", { sessionId, turnId, item: updated });
74237
+ }
74130
74238
  function setSessionStatus3(db3, sessionId, isRunning, status, now, hasUnreviewed = false) {
74131
74239
  if (hasUnreviewed) {
74132
74240
  db3.prepare("UPDATE sessions SET is_running = ?, status = ?, has_unreviewed = 1, updated_at = ? WHERE id = ?").run(
@@ -74206,6 +74314,9 @@ var TurnProjector = class {
74206
74314
  case "user":
74207
74315
  this.handleUser(message);
74208
74316
  break;
74317
+ case "subagent":
74318
+ this.handleSubagent(message);
74319
+ break;
74209
74320
  case "result":
74210
74321
  this.handleResult(message);
74211
74322
  break;
@@ -74237,9 +74348,31 @@ var TurnProjector = class {
74237
74348
  finalPlain: null
74238
74349
  };
74239
74350
  this.rounds.set(inputId, info);
74351
+ this.recordRuntimeInput(inputId);
74240
74352
  }
74241
74353
  return info;
74242
74354
  }
74355
+ /** Append a runtime input id to the turn row's runtime_input_ids column —
74356
+ * the rewind anchor mapping (anchor = LAST id of the target turn). */
74357
+ recordRuntimeInput(inputId) {
74358
+ try {
74359
+ const db3 = getDb();
74360
+ const row = db3.prepare("SELECT runtime_input_ids FROM turns WHERE id = ?").get(this.deps.turnId);
74361
+ if (!row) return;
74362
+ let ids = [];
74363
+ if (row.runtime_input_ids) {
74364
+ const parsed = JSON.parse(row.runtime_input_ids);
74365
+ if (Array.isArray(parsed)) ids = parsed;
74366
+ }
74367
+ if (ids.includes(inputId)) return;
74368
+ ids.push(inputId);
74369
+ db3.prepare("UPDATE turns SET runtime_input_ids = ? WHERE id = ?").run(
74370
+ JSON.stringify(ids),
74371
+ this.deps.turnId
74372
+ );
74373
+ } catch {
74374
+ }
74375
+ }
74243
74376
  handleStreamEvent(msg) {
74244
74377
  const db3 = getDb();
74245
74378
  const info = this.round(msg.inputId);
@@ -74344,6 +74477,61 @@ var TurnProjector = class {
74344
74477
  }
74345
74478
  this.touch();
74346
74479
  }
74480
+ /** Sub-agent lifecycle → background_task item (Claude data shape),
74481
+ * idempotent upsert keyed `<inputId>-action-<actionId>` — the same
74482
+ * external id the invoke_subagent tool_result/reconcile uses, so all
74483
+ * paths converge on ONE card. */
74484
+ handleSubagent(msg) {
74485
+ const db3 = getDb();
74486
+ const externalId = `${msg.input_id}-action-${msg.action_id}`;
74487
+ const terminal = msg.event === "completed" || msg.event === "failed";
74488
+ const itemStatus = terminal ? msg.event === "completed" ? "completed" : "failed" : "in_progress";
74489
+ const row = db3.prepare("SELECT * FROM items WHERE turn_id = ? AND external_item_id = ?").get(this.deps.turnId, externalId);
74490
+ if (row) {
74491
+ const prev = row.data ? JSON.parse(row.data) : {};
74492
+ const item = { ...row, data: prev };
74493
+ updateItem(
74494
+ db3,
74495
+ this.deps.agentPaneSessionId,
74496
+ this.deps.turnId,
74497
+ item,
74498
+ {
74499
+ ...prev,
74500
+ description: msg.description,
74501
+ subagent_type: msg.agent_name,
74502
+ status: terminal ? msg.event : "running",
74503
+ last_tool_name: msg.last_tool_name ?? prev.last_tool_name ?? null,
74504
+ token_count: msg.token_count ?? prev.token_count ?? null,
74505
+ ...terminal ? { summary: msg.summary ?? "" } : {}
74506
+ },
74507
+ itemStatus
74508
+ );
74509
+ } else {
74510
+ insertItem(
74511
+ db3,
74512
+ this.deps.agentPaneSessionId,
74513
+ this.deps.turnId,
74514
+ externalId,
74515
+ "background_task",
74516
+ {
74517
+ task_id: msg.task_id,
74518
+ description: msg.description,
74519
+ task_type: "subagent",
74520
+ subagent_type: msg.agent_name,
74521
+ prompt: null,
74522
+ status: terminal ? msg.event : "running",
74523
+ summary: terminal ? msg.summary ?? "" : null,
74524
+ output_file: null,
74525
+ output: "",
74526
+ token_count: msg.token_count ?? null,
74527
+ last_tool_name: msg.last_tool_name ?? null
74528
+ },
74529
+ itemStatus,
74530
+ terminal ? "item:completed" : "item:started"
74531
+ );
74532
+ }
74533
+ this.touch();
74534
+ }
74347
74535
  handleResult(msg) {
74348
74536
  switch (msg.subtype) {
74349
74537
  case "success":
@@ -74380,7 +74568,10 @@ var TurnProjector = class {
74380
74568
  sessionId: this.deps.agentPaneSessionId,
74381
74569
  turnId: this.deps.turnId,
74382
74570
  ...usage ? { usage } : {},
74383
- hasUnreviewed: true
74571
+ hasUnreviewed: true,
74572
+ // Final text — the FE renders it when the turn has no agent_message
74573
+ // item (final-action rounds).
74574
+ response: responseText || null
74384
74575
  });
74385
74576
  void this.syncTitle();
74386
74577
  this.finalize();
@@ -74507,7 +74698,8 @@ var TurnProjector = class {
74507
74698
  sessionId: this.deps.agentPaneSessionId,
74508
74699
  turnId: this.deps.turnId,
74509
74700
  ...usage ? { usage } : {},
74510
- hasUnreviewed: true
74701
+ hasUnreviewed: true,
74702
+ response: responseText || null
74511
74703
  });
74512
74704
  void this.syncTitle();
74513
74705
  this.finalize();
@@ -74826,6 +75018,12 @@ async function startTurn3(session, turn) {
74826
75018
  failTurnBeforeStart(db3, session.id, turn.id, `Failed to resolve repoburg backend: ${err.message}`);
74827
75019
  return;
74828
75020
  }
75021
+ const pinned = sessionMap3.get(session.id);
75022
+ if (pinned && pinned.baseUrl !== baseUrl) {
75023
+ console.warn(
75024
+ `[repoburg] resolved backend ${baseUrl} differs from pinned ${pinned.baseUrl} for session ${session.id} \u2014 keeping the pinned entry.`
75025
+ );
75026
+ }
74829
75027
  let entry;
74830
75028
  try {
74831
75029
  entry = await ensureSession(session, client, baseUrl);
@@ -74905,6 +75103,35 @@ function clearThread3(sessionId) {
74905
75103
  }
74906
75104
  sessionMap3.delete(sessionId);
74907
75105
  }
75106
+ function parseRuntimeInputIds(turn) {
75107
+ const raw = turn.runtime_input_ids;
75108
+ if (Array.isArray(raw)) return raw;
75109
+ if (typeof raw === "string" && raw) {
75110
+ try {
75111
+ const parsed = JSON.parse(raw);
75112
+ if (Array.isArray(parsed)) return parsed;
75113
+ } catch {
75114
+ }
75115
+ }
75116
+ return [];
75117
+ }
75118
+ async function rewindRuntime(session, targetTurn) {
75119
+ if (!session.external_thread_id) return;
75120
+ const anchor = parseRuntimeInputIds(targetTurn).pop();
75121
+ if (!anchor) {
75122
+ throw new Error(
75123
+ "Cannot truncate runtime history \u2014 the target turn has no runtime input ids (turn predates rewind support or never ran on repoburg)."
75124
+ );
75125
+ }
75126
+ const entry = sessionMap3.get(session.id);
75127
+ let client = entry?.client ?? null;
75128
+ if (!client) {
75129
+ const resolved = await resolveBackendUrl(session.cwd ?? process.cwd());
75130
+ if (!resolved) throw new Error("No repoburg backend resolved.");
75131
+ client = new RepoburgHttpClient(resolved.baseUrl);
75132
+ }
75133
+ await client.deleteInputsUntilHere(session.external_thread_id, anchor);
75134
+ }
74908
75135
  function clearAllThreads3() {
74909
75136
  for (const entry of sessionMap3.values()) {
74910
75137
  if (entry.activeTurn) {
@@ -74942,6 +75169,7 @@ var repoburgProvider = {
74942
75169
  clearThread: clearThread3,
74943
75170
  clearAllThreads: clearAllThreads3,
74944
75171
  getModels: getModels3,
75172
+ rewindRuntime,
74945
75173
  shutdown: shutdown3
74946
75174
  };
74947
75175