@probelabs/probe 0.6.0-rc254 → 0.6.0-rc255

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 (47) hide show
  1. package/README.md +166 -3
  2. package/bin/binaries/probe-v0.6.0-rc255-aarch64-apple-darwin.tar.gz +0 -0
  3. package/bin/binaries/probe-v0.6.0-rc255-aarch64-unknown-linux-musl.tar.gz +0 -0
  4. package/bin/binaries/probe-v0.6.0-rc255-x86_64-apple-darwin.tar.gz +0 -0
  5. package/bin/binaries/probe-v0.6.0-rc255-x86_64-pc-windows-msvc.zip +0 -0
  6. package/bin/binaries/probe-v0.6.0-rc255-x86_64-unknown-linux-musl.tar.gz +0 -0
  7. package/build/agent/ProbeAgent.d.ts +1 -1
  8. package/build/agent/ProbeAgent.js +24 -16
  9. package/build/agent/acp/tools.js +2 -1
  10. package/build/agent/acp/tools.test.js +2 -1
  11. package/build/agent/index.js +1425 -410
  12. package/build/agent/tools.js +0 -28
  13. package/build/delegate.js +3 -0
  14. package/build/index.js +2 -0
  15. package/build/tools/common.js +6 -5
  16. package/build/tools/edit.js +457 -65
  17. package/build/tools/fileTracker.js +318 -0
  18. package/build/tools/fuzzyMatch.js +271 -0
  19. package/build/tools/hashline.js +131 -0
  20. package/build/tools/lineEditHeuristics.js +138 -0
  21. package/build/tools/symbolEdit.js +119 -0
  22. package/build/tools/vercel.js +40 -9
  23. package/cjs/agent/ProbeAgent.cjs +1528 -514
  24. package/cjs/index.cjs +1556 -540
  25. package/index.d.ts +189 -1
  26. package/package.json +1 -1
  27. package/src/agent/ProbeAgent.d.ts +1 -1
  28. package/src/agent/ProbeAgent.js +24 -16
  29. package/src/agent/acp/tools.js +2 -1
  30. package/src/agent/acp/tools.test.js +2 -1
  31. package/src/agent/index.js +14 -3
  32. package/src/agent/tools.js +0 -28
  33. package/src/delegate.js +3 -0
  34. package/src/index.js +2 -0
  35. package/src/tools/common.js +6 -5
  36. package/src/tools/edit.js +457 -65
  37. package/src/tools/fileTracker.js +318 -0
  38. package/src/tools/fuzzyMatch.js +271 -0
  39. package/src/tools/hashline.js +131 -0
  40. package/src/tools/lineEditHeuristics.js +138 -0
  41. package/src/tools/symbolEdit.js +119 -0
  42. package/src/tools/vercel.js +40 -9
  43. package/bin/binaries/probe-v0.6.0-rc254-aarch64-apple-darwin.tar.gz +0 -0
  44. package/bin/binaries/probe-v0.6.0-rc254-aarch64-unknown-linux-musl.tar.gz +0 -0
  45. package/bin/binaries/probe-v0.6.0-rc254-x86_64-apple-darwin.tar.gz +0 -0
  46. package/bin/binaries/probe-v0.6.0-rc254-x86_64-pc-windows-msvc.zip +0 -0
  47. package/bin/binaries/probe-v0.6.0-rc254-x86_64-unknown-linux-musl.tar.gz +0 -0
package/cjs/index.cjs CHANGED
@@ -720,7 +720,7 @@ async function waitForFileLock(lockPath, binaryPath) {
720
720
  }
721
721
  } catch {
722
722
  }
723
- await new Promise((resolve7) => setTimeout(resolve7, LOCK_POLL_INTERVAL_MS));
723
+ await new Promise((resolve8) => setTimeout(resolve8, LOCK_POLL_INTERVAL_MS));
724
724
  }
725
725
  if (process.env.DEBUG === "1" || process.env.VERBOSE === "1") {
726
726
  console.log(`Timeout waiting for file lock`);
@@ -2075,7 +2075,7 @@ Cwd: ${cwd}`;
2075
2075
  }
2076
2076
  }
2077
2077
  function extractWithStdin(binaryPath, cliArgs, content, options, cwd) {
2078
- return new Promise((resolve7, reject2) => {
2078
+ return new Promise((resolve8, reject2) => {
2079
2079
  const childProcess = (0, import_child_process4.spawn)(binaryPath, ["extract", ...cliArgs], {
2080
2080
  stdio: ["pipe", "pipe", "pipe"],
2081
2081
  cwd
@@ -2098,7 +2098,7 @@ function extractWithStdin(binaryPath, cliArgs, content, options, cwd) {
2098
2098
  }
2099
2099
  try {
2100
2100
  const result = processExtractOutput(stdout, options);
2101
- resolve7(result);
2101
+ resolve8(result);
2102
2102
  } catch (error2) {
2103
2103
  reject2(error2);
2104
2104
  }
@@ -4186,7 +4186,7 @@ var require_headStream = __commonJS({
4186
4186
  if ((0, stream_type_check_1.isReadableStream)(stream2)) {
4187
4187
  return (0, headStream_browser_1.headStream)(stream2, bytes);
4188
4188
  }
4189
- return new Promise((resolve7, reject2) => {
4189
+ return new Promise((resolve8, reject2) => {
4190
4190
  const collector = new Collector();
4191
4191
  collector.limit = bytes;
4192
4192
  stream2.pipe(collector);
@@ -4197,7 +4197,7 @@ var require_headStream = __commonJS({
4197
4197
  collector.on("error", reject2);
4198
4198
  collector.on("finish", function() {
4199
4199
  const bytes2 = new Uint8Array(Buffer.concat(this.buffers));
4200
- resolve7(bytes2);
4200
+ resolve8(bytes2);
4201
4201
  });
4202
4202
  });
4203
4203
  };
@@ -4385,21 +4385,21 @@ var require_dist_cjs15 = __commonJS({
4385
4385
  let sendBody = true;
4386
4386
  if (!externalAgent && expect === "100-continue") {
4387
4387
  sendBody = await Promise.race([
4388
- new Promise((resolve7) => {
4389
- timeoutId = Number(timing.setTimeout(() => resolve7(true), Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
4388
+ new Promise((resolve8) => {
4389
+ timeoutId = Number(timing.setTimeout(() => resolve8(true), Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
4390
4390
  }),
4391
- new Promise((resolve7) => {
4391
+ new Promise((resolve8) => {
4392
4392
  httpRequest.on("continue", () => {
4393
4393
  timing.clearTimeout(timeoutId);
4394
- resolve7(true);
4394
+ resolve8(true);
4395
4395
  });
4396
4396
  httpRequest.on("response", () => {
4397
4397
  timing.clearTimeout(timeoutId);
4398
- resolve7(false);
4398
+ resolve8(false);
4399
4399
  });
4400
4400
  httpRequest.on("error", () => {
4401
4401
  timing.clearTimeout(timeoutId);
4402
- resolve7(false);
4402
+ resolve8(false);
4403
4403
  });
4404
4404
  })
4405
4405
  ]);
@@ -4471,13 +4471,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
4471
4471
  return socketWarningTimestamp;
4472
4472
  }
4473
4473
  constructor(options) {
4474
- this.configProvider = new Promise((resolve7, reject2) => {
4474
+ this.configProvider = new Promise((resolve8, reject2) => {
4475
4475
  if (typeof options === "function") {
4476
4476
  options().then((_options) => {
4477
- resolve7(this.resolveDefaultConfig(_options));
4477
+ resolve8(this.resolveDefaultConfig(_options));
4478
4478
  }).catch(reject2);
4479
4479
  } else {
4480
- resolve7(this.resolveDefaultConfig(options));
4480
+ resolve8(this.resolveDefaultConfig(options));
4481
4481
  }
4482
4482
  });
4483
4483
  }
@@ -4520,7 +4520,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
4520
4520
  const config = this.config;
4521
4521
  let writeRequestBodyPromise = void 0;
4522
4522
  const timeouts = [];
4523
- const resolve7 = async (arg) => {
4523
+ const resolve8 = async (arg) => {
4524
4524
  await writeRequestBodyPromise;
4525
4525
  timeouts.forEach(timing.clearTimeout);
4526
4526
  _resolve(arg);
@@ -4586,7 +4586,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
4586
4586
  headers: getTransformedHeaders(res.headers),
4587
4587
  body: res
4588
4588
  });
4589
- resolve7({ response: httpResponse });
4589
+ resolve8({ response: httpResponse });
4590
4590
  });
4591
4591
  req.on("error", (err) => {
4592
4592
  if (NODEJS_TIMEOUT_ERROR_CODES.includes(err.code)) {
@@ -4766,13 +4766,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
4766
4766
  return new _NodeHttp2Handler(instanceOrOptions);
4767
4767
  }
4768
4768
  constructor(options) {
4769
- this.configProvider = new Promise((resolve7, reject2) => {
4769
+ this.configProvider = new Promise((resolve8, reject2) => {
4770
4770
  if (typeof options === "function") {
4771
4771
  options().then((opts) => {
4772
- resolve7(opts || {});
4772
+ resolve8(opts || {});
4773
4773
  }).catch(reject2);
4774
4774
  } else {
4775
- resolve7(options || {});
4775
+ resolve8(options || {});
4776
4776
  }
4777
4777
  });
4778
4778
  }
@@ -4792,7 +4792,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
4792
4792
  return new Promise((_resolve, _reject) => {
4793
4793
  let fulfilled = false;
4794
4794
  let writeRequestBodyPromise = void 0;
4795
- const resolve7 = async (arg) => {
4795
+ const resolve8 = async (arg) => {
4796
4796
  await writeRequestBodyPromise;
4797
4797
  _resolve(arg);
4798
4798
  };
@@ -4848,7 +4848,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
4848
4848
  body: req
4849
4849
  });
4850
4850
  fulfilled = true;
4851
- resolve7({ response: httpResponse });
4851
+ resolve8({ response: httpResponse });
4852
4852
  if (disableConcurrentStreams) {
4853
4853
  session.close();
4854
4854
  this.connectionManager.deleteSession(authority, session);
@@ -4925,7 +4925,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
4925
4925
  if (isReadableStreamInstance(stream3)) {
4926
4926
  return collectReadableStream(stream3);
4927
4927
  }
4928
- return new Promise((resolve7, reject2) => {
4928
+ return new Promise((resolve8, reject2) => {
4929
4929
  const collector = new Collector();
4930
4930
  stream3.pipe(collector);
4931
4931
  stream3.on("error", (err) => {
@@ -4935,7 +4935,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
4935
4935
  collector.on("error", reject2);
4936
4936
  collector.on("finish", function() {
4937
4937
  const bytes = new Uint8Array(Buffer.concat(this.bufferedBytes));
4938
- resolve7(bytes);
4938
+ resolve8(bytes);
4939
4939
  });
4940
4940
  });
4941
4941
  };
@@ -4979,7 +4979,7 @@ var require_dist_cjs16 = __commonJS({
4979
4979
  return new Request(url, requestOptions);
4980
4980
  }
4981
4981
  function requestTimeout(timeoutInMs = 0) {
4982
- return new Promise((resolve7, reject2) => {
4982
+ return new Promise((resolve8, reject2) => {
4983
4983
  if (timeoutInMs) {
4984
4984
  setTimeout(() => {
4985
4985
  const timeoutError = new Error(`Request did not complete within ${timeoutInMs} ms`);
@@ -5097,7 +5097,7 @@ var require_dist_cjs16 = __commonJS({
5097
5097
  requestTimeout(requestTimeoutInMs)
5098
5098
  ];
5099
5099
  if (abortSignal) {
5100
- raceOfPromises.push(new Promise((resolve7, reject2) => {
5100
+ raceOfPromises.push(new Promise((resolve8, reject2) => {
5101
5101
  const onAbort = () => {
5102
5102
  const abortError = new Error("Request aborted");
5103
5103
  abortError.name = "AbortError";
@@ -5161,7 +5161,7 @@ var require_dist_cjs16 = __commonJS({
5161
5161
  return collected;
5162
5162
  }
5163
5163
  function readToBase64(blob) {
5164
- return new Promise((resolve7, reject2) => {
5164
+ return new Promise((resolve8, reject2) => {
5165
5165
  const reader = new FileReader();
5166
5166
  reader.onloadend = () => {
5167
5167
  if (reader.readyState !== 2) {
@@ -5170,7 +5170,7 @@ var require_dist_cjs16 = __commonJS({
5170
5170
  const result = reader.result ?? "";
5171
5171
  const commaIndex = result.indexOf(",");
5172
5172
  const dataOffset = commaIndex > -1 ? commaIndex + 1 : result.length;
5173
- resolve7(result.substring(dataOffset));
5173
+ resolve8(result.substring(dataOffset));
5174
5174
  };
5175
5175
  reader.onabort = () => reject2(new Error("Read aborted"));
5176
5176
  reader.onerror = () => reject2(reader.error);
@@ -6838,11 +6838,11 @@ function __metadata(metadataKey, metadataValue) {
6838
6838
  }
6839
6839
  function __awaiter(thisArg, _arguments, P, generator) {
6840
6840
  function adopt(value) {
6841
- return value instanceof P ? value : new P(function(resolve7) {
6842
- resolve7(value);
6841
+ return value instanceof P ? value : new P(function(resolve8) {
6842
+ resolve8(value);
6843
6843
  });
6844
6844
  }
6845
- return new (P || (P = Promise))(function(resolve7, reject2) {
6845
+ return new (P || (P = Promise))(function(resolve8, reject2) {
6846
6846
  function fulfilled(value) {
6847
6847
  try {
6848
6848
  step(generator.next(value));
@@ -6858,7 +6858,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
6858
6858
  }
6859
6859
  }
6860
6860
  function step(result) {
6861
- result.done ? resolve7(result.value) : adopt(result.value).then(fulfilled, rejected);
6861
+ result.done ? resolve8(result.value) : adopt(result.value).then(fulfilled, rejected);
6862
6862
  }
6863
6863
  step((generator = generator.apply(thisArg, _arguments || [])).next());
6864
6864
  });
@@ -7049,14 +7049,14 @@ function __asyncValues(o5) {
7049
7049
  }, i5);
7050
7050
  function verb(n5) {
7051
7051
  i5[n5] = o5[n5] && function(v5) {
7052
- return new Promise(function(resolve7, reject2) {
7053
- v5 = o5[n5](v5), settle(resolve7, reject2, v5.done, v5.value);
7052
+ return new Promise(function(resolve8, reject2) {
7053
+ v5 = o5[n5](v5), settle(resolve8, reject2, v5.done, v5.value);
7054
7054
  });
7055
7055
  };
7056
7056
  }
7057
- function settle(resolve7, reject2, d5, v5) {
7057
+ function settle(resolve8, reject2, d5, v5) {
7058
7058
  Promise.resolve(v5).then(function(v6) {
7059
- resolve7({ value: v6, done: d5 });
7059
+ resolve8({ value: v6, done: d5 });
7060
7060
  }, reject2);
7061
7061
  }
7062
7062
  }
@@ -17457,7 +17457,7 @@ var require_dist_cjs37 = __commonJS({
17457
17457
  this.sockets[url] = (this.sockets[url] ?? []).filter((socket) => ![WebSocket.CLOSING, WebSocket.CLOSED].includes(socket.readyState));
17458
17458
  }
17459
17459
  waitForReady(socket, connectionTimeout) {
17460
- return new Promise((resolve7, reject2) => {
17460
+ return new Promise((resolve8, reject2) => {
17461
17461
  const timeout = setTimeout(() => {
17462
17462
  this.removeNotUsableSockets(socket.url);
17463
17463
  reject2({
@@ -17469,7 +17469,7 @@ var require_dist_cjs37 = __commonJS({
17469
17469
  }, connectionTimeout);
17470
17470
  socket.onopen = () => {
17471
17471
  clearTimeout(timeout);
17472
- resolve7();
17472
+ resolve8();
17473
17473
  };
17474
17474
  });
17475
17475
  }
@@ -17522,8 +17522,8 @@ var require_dist_cjs37 = __commonJS({
17522
17522
  }
17523
17523
  return { done: item.done, value: item.value };
17524
17524
  }
17525
- return new Promise((resolve7, reject2) => {
17526
- pendingResolve = resolve7;
17525
+ return new Promise((resolve8, reject2) => {
17526
+ pendingResolve = resolve8;
17527
17527
  pendingReject = reject2;
17528
17528
  });
17529
17529
  }
@@ -18736,7 +18736,7 @@ var require_dist_cjs46 = __commonJS({
18736
18736
  this.refillTokenBucket();
18737
18737
  if (amount > this.currentCapacity) {
18738
18738
  const delay = (amount - this.currentCapacity) / this.fillRate * 1e3;
18739
- await new Promise((resolve7) => _DefaultRateLimiter.setTimeoutFn(resolve7, delay));
18739
+ await new Promise((resolve8) => _DefaultRateLimiter.setTimeoutFn(resolve8, delay));
18740
18740
  }
18741
18741
  this.currentCapacity = this.currentCapacity - amount;
18742
18742
  }
@@ -19071,7 +19071,7 @@ var require_dist_cjs47 = __commonJS({
19071
19071
  const delayFromResponse = getDelayFromRetryAfterHeader(err.$response);
19072
19072
  const delay = Math.max(delayFromResponse || 0, delayFromDecider);
19073
19073
  totalDelay += delay;
19074
- await new Promise((resolve7) => setTimeout(resolve7, delay));
19074
+ await new Promise((resolve8) => setTimeout(resolve8, delay));
19075
19075
  continue;
19076
19076
  }
19077
19077
  if (!err.$metadata) {
@@ -19229,7 +19229,7 @@ var require_dist_cjs47 = __commonJS({
19229
19229
  attempts = retryToken.getRetryCount();
19230
19230
  const delay = retryToken.getRetryDelay();
19231
19231
  totalRetryDelay += delay;
19232
- await new Promise((resolve7) => setTimeout(resolve7, delay));
19232
+ await new Promise((resolve8) => setTimeout(resolve8, delay));
19233
19233
  }
19234
19234
  }
19235
19235
  } else {
@@ -19381,7 +19381,7 @@ var require_package2 = __commonJS({
19381
19381
  module2.exports = {
19382
19382
  name: "@aws-sdk/client-bedrock-runtime",
19383
19383
  description: "AWS SDK for JavaScript Bedrock Runtime Client for Node.js, Browser and React Native",
19384
- version: "3.994.0",
19384
+ version: "3.995.0",
19385
19385
  scripts: {
19386
19386
  build: "concurrently 'yarn:build:types' 'yarn:build:es' && yarn build:cjs",
19387
19387
  "build:cjs": "node ../../scripts/compilation/inline client-bedrock-runtime",
@@ -19411,11 +19411,11 @@ var require_package2 = __commonJS({
19411
19411
  "@aws-sdk/middleware-user-agent": "^3.972.11",
19412
19412
  "@aws-sdk/middleware-websocket": "^3.972.6",
19413
19413
  "@aws-sdk/region-config-resolver": "^3.972.3",
19414
- "@aws-sdk/token-providers": "3.994.0",
19414
+ "@aws-sdk/token-providers": "3.995.0",
19415
19415
  "@aws-sdk/types": "^3.973.1",
19416
- "@aws-sdk/util-endpoints": "3.994.0",
19416
+ "@aws-sdk/util-endpoints": "3.995.0",
19417
19417
  "@aws-sdk/util-user-agent-browser": "^3.972.3",
19418
- "@aws-sdk/util-user-agent-node": "^3.972.9",
19418
+ "@aws-sdk/util-user-agent-node": "^3.972.10",
19419
19419
  "@smithy/config-resolver": "^4.4.6",
19420
19420
  "@smithy/core": "^3.23.2",
19421
19421
  "@smithy/eventstream-serde-browser": "^4.2.8",
@@ -19544,7 +19544,7 @@ var require_dist_cjs49 = __commonJS({
19544
19544
  var nodeConfigProvider = require_dist_cjs43();
19545
19545
  var urlParser = require_dist_cjs22();
19546
19546
  function httpRequest(options) {
19547
- return new Promise((resolve7, reject2) => {
19547
+ return new Promise((resolve8, reject2) => {
19548
19548
  const req = http.request({
19549
19549
  method: "GET",
19550
19550
  ...options,
@@ -19569,7 +19569,7 @@ var require_dist_cjs49 = __commonJS({
19569
19569
  chunks.push(chunk);
19570
19570
  });
19571
19571
  res.on("end", () => {
19572
- resolve7(buffer.Buffer.concat(chunks));
19572
+ resolve8(buffer.Buffer.concat(chunks));
19573
19573
  req.destroy();
19574
19574
  });
19575
19575
  });
@@ -19989,7 +19989,7 @@ var require_retry_wrapper = __commonJS({
19989
19989
  try {
19990
19990
  return await toRetry();
19991
19991
  } catch (e5) {
19992
- await new Promise((resolve7) => setTimeout(resolve7, delayMs));
19992
+ await new Promise((resolve8) => setTimeout(resolve8, delayMs));
19993
19993
  }
19994
19994
  }
19995
19995
  return await toRetry();
@@ -20297,6 +20297,15 @@ var require_dist_cjs51 = __commonJS({
20297
20297
  var os4 = require("os");
20298
20298
  var process2 = require("process");
20299
20299
  var middlewareUserAgent = require_dist_cjs29();
20300
+ var getRuntimeUserAgentPair = () => {
20301
+ const runtimesToCheck = ["deno", "bun", "llrt"];
20302
+ for (const runtime of runtimesToCheck) {
20303
+ if (process2.versions[runtime]) {
20304
+ return [`md/${runtime}`, process2.versions[runtime]];
20305
+ }
20306
+ }
20307
+ return ["md/nodejs", process2.versions.node];
20308
+ };
20300
20309
  var crtAvailability = {
20301
20310
  isCrtAvailable: false
20302
20311
  };
@@ -20307,13 +20316,14 @@ var require_dist_cjs51 = __commonJS({
20307
20316
  return null;
20308
20317
  };
20309
20318
  var createDefaultUserAgentProvider5 = ({ serviceId, clientVersion }) => {
20319
+ const runtimeUserAgentPair = getRuntimeUserAgentPair();
20310
20320
  return async (config) => {
20311
20321
  const sections = [
20312
20322
  ["aws-sdk-js", clientVersion],
20313
20323
  ["ua", "2.1"],
20314
20324
  [`os/${os4.platform()}`, os4.release()],
20315
20325
  ["lang/js"],
20316
- ["md/nodejs", `${process2.versions.node}`]
20326
+ runtimeUserAgentPair
20317
20327
  ];
20318
20328
  const crtAvailable = isCrtAvailable();
20319
20329
  if (crtAvailable) {
@@ -25876,8 +25886,8 @@ var require_dist_cjs66 = __commonJS({
25876
25886
  systemClockOffsetProvider: this.systemClockOffsetProvider
25877
25887
  });
25878
25888
  let resolvePipeline;
25879
- const pipelineError = new Promise((resolve7, reject2) => {
25880
- resolvePipeline = () => resolve7(void 0);
25889
+ const pipelineError = new Promise((resolve8, reject2) => {
25890
+ resolvePipeline = () => resolve8(void 0);
25881
25891
  node_stream.pipeline(payloadStream, signingStream, request.body, (err) => {
25882
25892
  if (err) {
25883
25893
  reject2(new Error(`Pipeline error in @aws-sdk/eventstream-handler-node: ${err.message}`, { cause: err }));
@@ -25983,7 +25993,7 @@ var init_package2 = __esm({
25983
25993
  "node_modules/@aws-sdk/token-providers/node_modules/@aws-sdk/nested-clients/package.json"() {
25984
25994
  package_default2 = {
25985
25995
  name: "@aws-sdk/nested-clients",
25986
- version: "3.994.0",
25996
+ version: "3.995.0",
25987
25997
  description: "Nested clients for AWS SDK packages.",
25988
25998
  main: "./dist-cjs/index.js",
25989
25999
  module: "./dist-es/index.js",
@@ -26019,9 +26029,9 @@ var init_package2 = __esm({
26019
26029
  "@aws-sdk/middleware-user-agent": "^3.972.11",
26020
26030
  "@aws-sdk/region-config-resolver": "^3.972.3",
26021
26031
  "@aws-sdk/types": "^3.973.1",
26022
- "@aws-sdk/util-endpoints": "3.994.0",
26032
+ "@aws-sdk/util-endpoints": "3.995.0",
26023
26033
  "@aws-sdk/util-user-agent-browser": "^3.972.3",
26024
- "@aws-sdk/util-user-agent-node": "^3.972.9",
26034
+ "@aws-sdk/util-user-agent-node": "^3.972.10",
26025
26035
  "@smithy/config-resolver": "^4.4.6",
26026
26036
  "@smithy/core": "^3.23.2",
26027
26037
  "@smithy/fetch-http-handler": "^5.3.9",
@@ -27431,7 +27441,7 @@ var require_dist_cjs69 = __commonJS({
27431
27441
  streamEnded = true;
27432
27442
  });
27433
27443
  while (!generationEnded) {
27434
- const value = await new Promise((resolve7) => setTimeout(() => resolve7(records.shift()), 0));
27444
+ const value = await new Promise((resolve8) => setTimeout(() => resolve8(records.shift()), 0));
27435
27445
  if (value) {
27436
27446
  yield value;
27437
27447
  }
@@ -37471,6 +37481,400 @@ var init_zod = __esm({
37471
37481
  }
37472
37482
  });
37473
37483
 
37484
+ // src/tools/fuzzyMatch.js
37485
+ function findFuzzyMatch(content, searchString) {
37486
+ if (!searchString || searchString.trim().length === 0) {
37487
+ return null;
37488
+ }
37489
+ const normalizedContent = content.replace(/\r\n/g, "\n");
37490
+ const normalizedSearch = searchString.replace(/\r\n/g, "\n");
37491
+ const contentLines = normalizedContent.split("\n");
37492
+ const searchLines = normalizedSearch.split("\n");
37493
+ const trimmed = lineTrimmedMatch(contentLines, searchLines);
37494
+ if (trimmed) return { ...trimmed, strategy: "line-trimmed" };
37495
+ const normalized = whitespaceNormalizedMatch(normalizedContent, normalizedSearch);
37496
+ if (normalized) return { ...normalized, strategy: "whitespace-normalized" };
37497
+ const indentFlex = indentFlexibleMatch(contentLines, searchLines);
37498
+ if (indentFlex) return { ...indentFlex, strategy: "indent-flexible" };
37499
+ return null;
37500
+ }
37501
+ function lineTrimmedMatch(contentLines, searchLines) {
37502
+ if (searchLines.length === 0) return null;
37503
+ const trimmedSearchLines = searchLines.map((line) => line.trim());
37504
+ if (trimmedSearchLines.every((line) => line === "")) return null;
37505
+ const windowSize = searchLines.length;
37506
+ const matches = [];
37507
+ for (let i5 = 0; i5 <= contentLines.length - windowSize; i5++) {
37508
+ let allMatch = true;
37509
+ for (let j5 = 0; j5 < windowSize; j5++) {
37510
+ if (contentLines[i5 + j5].trim() !== trimmedSearchLines[j5]) {
37511
+ allMatch = false;
37512
+ break;
37513
+ }
37514
+ }
37515
+ if (allMatch) {
37516
+ const matchedText = contentLines.slice(i5, i5 + windowSize).join("\n");
37517
+ matches.push(matchedText);
37518
+ }
37519
+ }
37520
+ if (matches.length === 0) return null;
37521
+ return {
37522
+ matchedText: matches[0],
37523
+ count: matches.length
37524
+ };
37525
+ }
37526
+ function whitespaceNormalizedMatch(content, search2) {
37527
+ if (!search2 || search2.trim().length === 0) return null;
37528
+ const { normalized: normContent, indexMap: contentMap } = buildNormalizedMap(content);
37529
+ const { normalized: normSearch } = buildNormalizedMap(search2);
37530
+ if (normSearch.length === 0) return null;
37531
+ const matches = [];
37532
+ let searchStart = 0;
37533
+ while (searchStart <= normContent.length - normSearch.length) {
37534
+ const idx = normContent.indexOf(normSearch, searchStart);
37535
+ if (idx === -1) break;
37536
+ const originalStart = contentMap[idx];
37537
+ const originalEnd = contentMap[idx + normSearch.length - 1];
37538
+ let actualEnd = originalEnd + 1;
37539
+ while (actualEnd < content.length && /[ \t]/.test(content[actualEnd]) && (actualEnd === originalEnd + 1 || /[ \t]/.test(content[actualEnd - 1]))) {
37540
+ if (contentMap.indexOf(actualEnd) > idx + normSearch.length - 1 || contentMap.indexOf(actualEnd) === -1) {
37541
+ break;
37542
+ }
37543
+ actualEnd++;
37544
+ }
37545
+ const matchedText = content.substring(originalStart, actualEnd);
37546
+ matches.push(matchedText);
37547
+ searchStart = idx + 1;
37548
+ }
37549
+ if (matches.length === 0) return null;
37550
+ return {
37551
+ matchedText: matches[0],
37552
+ count: matches.length
37553
+ };
37554
+ }
37555
+ function buildNormalizedMap(str) {
37556
+ const normalized = [];
37557
+ const indexMap = [];
37558
+ let i5 = 0;
37559
+ while (i5 < str.length) {
37560
+ const ch = str[i5];
37561
+ if (ch === " " || ch === " ") {
37562
+ normalized.push(" ");
37563
+ indexMap.push(i5);
37564
+ while (i5 < str.length && (str[i5] === " " || str[i5] === " ")) {
37565
+ i5++;
37566
+ }
37567
+ } else {
37568
+ normalized.push(ch);
37569
+ indexMap.push(i5);
37570
+ i5++;
37571
+ }
37572
+ }
37573
+ return {
37574
+ normalized: normalized.join(""),
37575
+ indexMap
37576
+ };
37577
+ }
37578
+ function indentFlexibleMatch(contentLines, searchLines) {
37579
+ if (searchLines.length === 0) return null;
37580
+ if (searchLines.every((line) => line.trim() === "")) return null;
37581
+ const searchMinIndent = getMinIndent(searchLines);
37582
+ const strippedSearch = searchLines.map((line) => stripIndent(line, searchMinIndent));
37583
+ const windowSize = searchLines.length;
37584
+ const matches = [];
37585
+ for (let i5 = 0; i5 <= contentLines.length - windowSize; i5++) {
37586
+ const windowLines = contentLines.slice(i5, i5 + windowSize);
37587
+ const windowMinIndent = getMinIndent(windowLines);
37588
+ const strippedWindow = windowLines.map((line) => stripIndent(line, windowMinIndent));
37589
+ let allMatch = true;
37590
+ for (let j5 = 0; j5 < windowSize; j5++) {
37591
+ if (strippedWindow[j5] !== strippedSearch[j5]) {
37592
+ allMatch = false;
37593
+ break;
37594
+ }
37595
+ }
37596
+ if (allMatch) {
37597
+ const matchedText = windowLines.join("\n");
37598
+ matches.push(matchedText);
37599
+ }
37600
+ }
37601
+ if (matches.length === 0) return null;
37602
+ return {
37603
+ matchedText: matches[0],
37604
+ count: matches.length
37605
+ };
37606
+ }
37607
+ function getMinIndent(lines) {
37608
+ let min = Infinity;
37609
+ for (const line of lines) {
37610
+ if (line.trim() === "") continue;
37611
+ const match2 = line.match(/^([ \t]*)/);
37612
+ if (match2) {
37613
+ min = Math.min(min, match2[1].length);
37614
+ }
37615
+ }
37616
+ return min === Infinity ? 0 : min;
37617
+ }
37618
+ function stripIndent(line, amount) {
37619
+ if (line.trim() === "") return "";
37620
+ if (amount <= 0) return line;
37621
+ return line.substring(Math.min(amount, line.length));
37622
+ }
37623
+ var init_fuzzyMatch = __esm({
37624
+ "src/tools/fuzzyMatch.js"() {
37625
+ "use strict";
37626
+ }
37627
+ });
37628
+
37629
+ // src/tools/symbolEdit.js
37630
+ async function findSymbol(filePath, symbolName, cwd) {
37631
+ try {
37632
+ const result = await extract({
37633
+ files: [`${filePath}#${symbolName}`],
37634
+ format: "json",
37635
+ json: true,
37636
+ cwd
37637
+ });
37638
+ if (!result || !result.results || result.results.length === 0) {
37639
+ return null;
37640
+ }
37641
+ const match2 = result.results[0];
37642
+ return {
37643
+ startLine: match2.lines[0],
37644
+ // 1-indexed
37645
+ endLine: match2.lines[1],
37646
+ // 1-indexed
37647
+ code: match2.code,
37648
+ nodeType: match2.node_type,
37649
+ file: match2.file
37650
+ };
37651
+ } catch (error2) {
37652
+ if (process.env.DEBUG === "1") {
37653
+ console.error(`[SymbolEdit] findSymbol error for "${symbolName}" in ${filePath}: ${error2.message}`);
37654
+ }
37655
+ return null;
37656
+ }
37657
+ }
37658
+ async function findAllSymbols(filePath, symbolName, cwd) {
37659
+ try {
37660
+ const result = await extract({
37661
+ files: [`${filePath}#${symbolName}`],
37662
+ format: "json",
37663
+ json: true,
37664
+ cwd
37665
+ });
37666
+ if (!result || !result.results || result.results.length === 0) {
37667
+ return [];
37668
+ }
37669
+ return result.results.map((match2) => ({
37670
+ startLine: match2.lines[0],
37671
+ endLine: match2.lines[1],
37672
+ code: match2.code,
37673
+ nodeType: match2.node_type,
37674
+ file: match2.file,
37675
+ qualifiedName: match2.symbol_signature || symbolName
37676
+ }));
37677
+ } catch (error2) {
37678
+ if (process.env.DEBUG === "1") {
37679
+ console.error(`[SymbolEdit] findAllSymbols error for "${symbolName}" in ${filePath}: ${error2.message}`);
37680
+ }
37681
+ return [];
37682
+ }
37683
+ }
37684
+ function detectBaseIndent(code) {
37685
+ const lines = code.split("\n");
37686
+ for (const line of lines) {
37687
+ if (line.trim().length > 0) {
37688
+ const match2 = line.match(/^(\s*)/);
37689
+ return match2 ? match2[1] : "";
37690
+ }
37691
+ }
37692
+ return "";
37693
+ }
37694
+ function reindent(newContent, targetIndent) {
37695
+ const lines = newContent.split("\n");
37696
+ const sourceIndent = detectBaseIndent(newContent);
37697
+ return lines.map((line) => {
37698
+ if (line.trim().length === 0) {
37699
+ return "";
37700
+ }
37701
+ if (line.startsWith(sourceIndent)) {
37702
+ return targetIndent + line.slice(sourceIndent.length);
37703
+ }
37704
+ return line;
37705
+ }).join("\n");
37706
+ }
37707
+ var init_symbolEdit = __esm({
37708
+ "src/tools/symbolEdit.js"() {
37709
+ "use strict";
37710
+ init_extract();
37711
+ }
37712
+ });
37713
+
37714
+ // src/tools/hashline.js
37715
+ function computeLineHash(line) {
37716
+ const stripped = (line || "").replace(/\s+/g, "");
37717
+ let h5 = 5381;
37718
+ for (let i5 = 0; i5 < stripped.length; i5++) {
37719
+ h5 = (h5 << 5) + h5 + stripped.charCodeAt(i5) & 4294967295;
37720
+ }
37721
+ return ((h5 >>> 0) % 256).toString(16).padStart(2, "0");
37722
+ }
37723
+ function parseLineRef(ref2) {
37724
+ if (ref2 === void 0 || ref2 === null) return null;
37725
+ const str = String(ref2).trim();
37726
+ if (!str) return null;
37727
+ const hashMatch = str.match(/^(\d+):([0-9a-fA-F]{2})$/);
37728
+ if (hashMatch) {
37729
+ const line = parseInt(hashMatch[1], 10);
37730
+ if (line < 1 || !isFinite(line)) return null;
37731
+ return { line, hash: hashMatch[2].toLowerCase() };
37732
+ }
37733
+ const lineMatch = str.match(/^(\d+)$/);
37734
+ if (lineMatch) {
37735
+ const line = parseInt(lineMatch[1], 10);
37736
+ if (line < 1 || !isFinite(line)) return null;
37737
+ return { line, hash: null };
37738
+ }
37739
+ return null;
37740
+ }
37741
+ function validateLineHash(lineNum, hash, fileLines) {
37742
+ const idx = lineNum - 1;
37743
+ if (idx < 0 || idx >= fileLines.length) {
37744
+ return { valid: false, actualHash: "", actualContent: "" };
37745
+ }
37746
+ const actualContent = fileLines[idx];
37747
+ const actualHash = computeLineHash(actualContent);
37748
+ return {
37749
+ valid: actualHash === hash.toLowerCase(),
37750
+ actualHash,
37751
+ actualContent
37752
+ };
37753
+ }
37754
+ function annotateOutputWithHashes(output) {
37755
+ if (!output || typeof output !== "string") return output;
37756
+ return output.split("\n").map((line) => {
37757
+ const cleanLine = line.endsWith("\r") ? line.slice(0, -1) : line;
37758
+ const match2 = cleanLine.match(/^(\s*)(\d+)(\s*\|)(.*)$/);
37759
+ if (!match2) return line;
37760
+ const [, prefix, lineNum, pipeSection, content] = match2;
37761
+ const hash = computeLineHash(content);
37762
+ const cr = line.endsWith("\r") ? "\r" : "";
37763
+ return `${prefix}${lineNum}:${hash}${pipeSection}${content}${cr}`;
37764
+ }).join("\n");
37765
+ }
37766
+ function stripHashlinePrefixes(text) {
37767
+ if (!text || typeof text !== "string") return { cleaned: text || "", stripped: false };
37768
+ const lines = text.split("\n");
37769
+ if (lines.length === 0) return { cleaned: "", stripped: false };
37770
+ const nonEmptyLines = lines.filter((l5) => l5.trim().length > 0);
37771
+ if (nonEmptyLines.length === 0) return { cleaned: text, stripped: false };
37772
+ const prefixPattern = /^\s*\d+(?::[0-9a-fA-F]{2})?\s*\|\s?/;
37773
+ const matchCount = nonEmptyLines.filter((l5) => prefixPattern.test(l5)).length;
37774
+ if (matchCount / nonEmptyLines.length <= 0.5) {
37775
+ return { cleaned: text, stripped: false };
37776
+ }
37777
+ const cleaned = lines.map((line) => {
37778
+ if (line.trim().length === 0) return line;
37779
+ return line.replace(prefixPattern, "");
37780
+ }).join("\n");
37781
+ return { cleaned, stripped: true };
37782
+ }
37783
+ var init_hashline = __esm({
37784
+ "src/tools/hashline.js"() {
37785
+ "use strict";
37786
+ }
37787
+ });
37788
+
37789
+ // src/tools/lineEditHeuristics.js
37790
+ function stripEchoedBoundaries(newStr, fileLines, startLine, endLine, position) {
37791
+ const modifications = [];
37792
+ let lines = newStr.split("\n");
37793
+ if (lines.length === 0) return { result: newStr, modifications };
37794
+ if (position === "after") {
37795
+ const anchorIdx = startLine - 1;
37796
+ if (anchorIdx >= 0 && anchorIdx < fileLines.length) {
37797
+ const anchorTrimmed = fileLines[anchorIdx].trim();
37798
+ if (anchorTrimmed.length > 0 && lines.length > 0 && lines[0].trim() === anchorTrimmed) {
37799
+ lines = lines.slice(1);
37800
+ modifications.push("stripped echoed anchor line (insert-after)");
37801
+ }
37802
+ }
37803
+ } else if (position === "before") {
37804
+ const anchorIdx = startLine - 1;
37805
+ if (anchorIdx >= 0 && anchorIdx < fileLines.length) {
37806
+ const anchorTrimmed = fileLines[anchorIdx].trim();
37807
+ if (anchorTrimmed.length > 0 && lines.length > 0 && lines[lines.length - 1].trim() === anchorTrimmed) {
37808
+ lines = lines.slice(0, -1);
37809
+ modifications.push("stripped echoed anchor line (insert-before)");
37810
+ }
37811
+ }
37812
+ } else {
37813
+ const beforeIdx = startLine - 2;
37814
+ if (beforeIdx >= 0 && beforeIdx < fileLines.length) {
37815
+ const beforeTrimmed = fileLines[beforeIdx].trim();
37816
+ if (beforeTrimmed.length > 0 && lines.length > 0 && lines[0].trim() === beforeTrimmed) {
37817
+ lines = lines.slice(1);
37818
+ modifications.push("stripped echoed line before range");
37819
+ }
37820
+ }
37821
+ const afterIdx = endLine;
37822
+ if (afterIdx >= 0 && afterIdx < fileLines.length) {
37823
+ const afterTrimmed = fileLines[afterIdx].trim();
37824
+ if (afterTrimmed.length > 0 && lines.length > 0 && lines[lines.length - 1].trim() === afterTrimmed) {
37825
+ lines = lines.slice(0, -1);
37826
+ modifications.push("stripped echoed line after range");
37827
+ }
37828
+ }
37829
+ }
37830
+ return { result: lines.join("\n"), modifications };
37831
+ }
37832
+ function restoreIndentation(newStr, originalLines) {
37833
+ const modifications = [];
37834
+ if (!newStr || !originalLines || originalLines.length === 0) {
37835
+ return { result: newStr || "", modifications };
37836
+ }
37837
+ const originalCode = originalLines.join("\n");
37838
+ const targetIndent = detectBaseIndent(originalCode);
37839
+ const newIndent = detectBaseIndent(newStr);
37840
+ if (targetIndent !== newIndent) {
37841
+ const reindented = reindent(newStr, targetIndent);
37842
+ if (reindented !== newStr) {
37843
+ modifications.push(`reindented from "${newIndent}" to "${targetIndent}"`);
37844
+ return { result: reindented, modifications };
37845
+ }
37846
+ }
37847
+ return { result: newStr, modifications };
37848
+ }
37849
+ function cleanNewString(newStr, fileLines, startLine, endLine, position) {
37850
+ const modifications = [];
37851
+ if (!newStr && newStr !== "") return { cleaned: "", modifications };
37852
+ const { cleaned: afterPrefixes, stripped } = stripHashlinePrefixes(newStr);
37853
+ if (stripped) modifications.push("stripped line-number prefixes");
37854
+ const { result: afterEchoes, modifications: echoMods } = stripEchoedBoundaries(
37855
+ afterPrefixes,
37856
+ fileLines,
37857
+ startLine,
37858
+ endLine,
37859
+ position
37860
+ );
37861
+ modifications.push(...echoMods);
37862
+ if (!position) {
37863
+ const originalLines = fileLines.slice(startLine - 1, endLine);
37864
+ const { result: afterIndent, modifications: indentMods } = restoreIndentation(afterEchoes, originalLines);
37865
+ modifications.push(...indentMods);
37866
+ return { cleaned: afterIndent, modifications };
37867
+ }
37868
+ return { cleaned: afterEchoes, modifications };
37869
+ }
37870
+ var init_lineEditHeuristics = __esm({
37871
+ "src/tools/lineEditHeuristics.js"() {
37872
+ "use strict";
37873
+ init_symbolEdit();
37874
+ init_hashline();
37875
+ }
37876
+ });
37877
+
37474
37878
  // src/tools/edit.js
37475
37879
  function isPathAllowed(filePath, allowedFolders) {
37476
37880
  if (!allowedFolders || allowedFolders.length === 0) {
@@ -37494,6 +37898,174 @@ function parseFileToolOptions(options = {}) {
37494
37898
  workspaceRoot: options.workspaceRoot || options.cwd || allowedFolders.length > 0 && allowedFolders[0] || process.cwd()
37495
37899
  };
37496
37900
  }
37901
+ async function handleSymbolEdit({ resolvedPath: resolvedPath2, file_path, symbol: symbol15, new_string, position, debug, cwd, fileTracker }) {
37902
+ if (typeof symbol15 !== "string" || symbol15.trim() === "") {
37903
+ return 'Error editing file: Invalid symbol - must be a non-empty string. Provide the name of a function, class, method, or other named code definition (e.g. "myFunction" or "MyClass.myMethod"). To edit by text matching instead, use old_string + new_string.';
37904
+ }
37905
+ if (position !== void 0 && position !== null && position !== "before" && position !== "after") {
37906
+ return 'Error editing file: Invalid position - must be "before" or "after". Use position="before" to insert code above the symbol, or position="after" to insert code below it. Omit position entirely to replace the symbol with new_string.';
37907
+ }
37908
+ const allMatches = await findAllSymbols(resolvedPath2, symbol15, cwd || process.cwd());
37909
+ if (allMatches.length === 0) {
37910
+ return `Error editing file: Symbol "${symbol15}" not found in ${file_path}. Verify the symbol name matches a top-level function, class, method, or other named definition exactly as declared in the source. Use 'search' or 'extract' to inspect the file and find the correct symbol name. Alternatively, use old_string + new_string for text-based editing instead.`;
37911
+ }
37912
+ if (allMatches.length > 1) {
37913
+ const suggestions = allMatches.map(
37914
+ (m5) => ` - ${m5.qualifiedName} (${m5.nodeType}, line ${m5.startLine})`
37915
+ ).join("\n");
37916
+ return `Error editing ${file_path}: Found ${allMatches.length} symbols named "${symbol15}". Use a qualified name to specify which one:
37917
+ ${suggestions}
37918
+
37919
+ Example: <edit><file_path>${file_path}</file_path><symbol>${allMatches[0].qualifiedName}</symbol><new_string>...</new_string></edit>`;
37920
+ }
37921
+ const symbolInfo = allMatches[0];
37922
+ if (fileTracker) {
37923
+ const check = fileTracker.checkSymbolContent(resolvedPath2, symbol15, symbolInfo.code);
37924
+ if (!check.ok && check.reason === "stale") {
37925
+ return `Error editing ${file_path}: Symbol "${symbol15}" has changed since you last read it. Use extract to re-read the current content, then retry.
37926
+
37927
+ Example: <extract><targets>${file_path}#${symbol15}</targets></extract>`;
37928
+ }
37929
+ }
37930
+ const content = await import_fs4.promises.readFile(resolvedPath2, "utf-8");
37931
+ const lines = content.split("\n");
37932
+ if (position) {
37933
+ const refIndent = detectBaseIndent(symbolInfo.code);
37934
+ const reindented = reindent(new_string, refIndent);
37935
+ const newLines = reindented.split("\n");
37936
+ if (position === "after") {
37937
+ lines.splice(symbolInfo.endLine, 0, "", ...newLines);
37938
+ } else {
37939
+ lines.splice(symbolInfo.startLine - 1, 0, ...newLines, "");
37940
+ }
37941
+ await import_fs4.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
37942
+ if (fileTracker) {
37943
+ const updated = await findSymbol(resolvedPath2, symbol15, cwd || process.cwd());
37944
+ if (updated) {
37945
+ fileTracker.trackSymbolAfterWrite(resolvedPath2, symbol15, updated.code, updated.startLine, updated.endLine);
37946
+ }
37947
+ fileTracker.markFileSeen(resolvedPath2);
37948
+ }
37949
+ const insertLine = position === "after" ? symbolInfo.endLine + 1 : symbolInfo.startLine;
37950
+ if (debug) {
37951
+ console.error(`[Edit] Successfully inserted ${newLines.length} lines ${position} "${symbol15}" at line ${insertLine} in ${resolvedPath2}`);
37952
+ }
37953
+ return `Successfully inserted ${newLines.length} lines ${position} symbol "${symbol15}" in ${file_path} (at line ${insertLine})`;
37954
+ } else {
37955
+ const originalIndent = detectBaseIndent(symbolInfo.code);
37956
+ const reindented = reindent(new_string, originalIndent);
37957
+ const newLines = reindented.split("\n");
37958
+ lines.splice(symbolInfo.startLine - 1, symbolInfo.endLine - symbolInfo.startLine + 1, ...newLines);
37959
+ await import_fs4.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
37960
+ if (fileTracker) {
37961
+ const updated = await findSymbol(resolvedPath2, symbol15, cwd || process.cwd());
37962
+ if (updated) {
37963
+ fileTracker.trackSymbolAfterWrite(resolvedPath2, symbol15, updated.code, updated.startLine, updated.endLine);
37964
+ }
37965
+ fileTracker.markFileSeen(resolvedPath2);
37966
+ }
37967
+ if (debug) {
37968
+ console.error(`[Edit] Successfully replaced symbol "${symbol15}" in ${resolvedPath2} (lines ${symbolInfo.startLine}-${symbolInfo.endLine})`);
37969
+ }
37970
+ return `Successfully replaced symbol "${symbol15}" in ${file_path} (was lines ${symbolInfo.startLine}-${symbolInfo.endLine}, now ${newLines.length} lines)`;
37971
+ }
37972
+ }
37973
+ function buildLineEditResponse(file_path, startLine, endLine, newLineCount, updatedLines, insertOffset, action, heuristicMods) {
37974
+ const contextBefore = 1;
37975
+ const contextAfter = 1;
37976
+ const contextStart = Math.max(0, insertOffset - contextBefore);
37977
+ const contextEnd = Math.min(updatedLines.length, insertOffset + newLineCount + contextAfter);
37978
+ let context = "Context:\n";
37979
+ for (let i5 = contextStart; i5 < contextEnd; i5++) {
37980
+ const lineNum = i5 + 1;
37981
+ const hash = computeLineHash(updatedLines[i5]);
37982
+ const isNew = i5 >= insertOffset && i5 < insertOffset + newLineCount;
37983
+ const marker15 = isNew ? ">" : " ";
37984
+ context += `${marker15} ${lineNum}:${hash} | ${updatedLines[i5]}
37985
+ `;
37986
+ }
37987
+ let msg = `Successfully edited ${file_path} (${action})`;
37988
+ if (heuristicMods.length > 0) {
37989
+ msg += ` [auto-corrected: ${heuristicMods.join(", ")}]`;
37990
+ }
37991
+ msg += "\n" + context;
37992
+ return msg;
37993
+ }
37994
+ async function handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_line, end_line, new_string, position, debug, fileTracker }) {
37995
+ const startRef = parseLineRef(start_line);
37996
+ if (!startRef) {
37997
+ return `Error editing file: Invalid start_line '${start_line}'. Use a line number (e.g. "42") or line:hash (e.g. "42:ab"). Line numbers are 1-indexed.`;
37998
+ }
37999
+ let endRef = null;
38000
+ if (end_line !== void 0 && end_line !== null) {
38001
+ endRef = parseLineRef(end_line);
38002
+ if (!endRef) {
38003
+ return `Error editing file: Invalid end_line '${end_line}'. Use a line number (e.g. "55") or line:hash (e.g. "55:cd"). Must be >= start_line.`;
38004
+ }
38005
+ }
38006
+ const startLine = startRef.line;
38007
+ const endLine = endRef ? endRef.line : startLine;
38008
+ if (endLine < startLine) {
38009
+ return `Error editing file: end_line (${endLine}) must be >= start_line (${startLine}).`;
38010
+ }
38011
+ if (position !== void 0 && position !== null && position !== "before" && position !== "after") {
38012
+ return 'Error editing file: Invalid position - must be "before" or "after". Use position="before" to insert before the line, or position="after" to insert after it.';
38013
+ }
38014
+ const content = await import_fs4.promises.readFile(resolvedPath2, "utf-8");
38015
+ const fileLines = content.split("\n");
38016
+ if (startLine > fileLines.length) {
38017
+ return `Error editing file: Line ${startLine} is beyond file length (${fileLines.length} lines). Use 'extract' to read the current file content.`;
38018
+ }
38019
+ if (endLine > fileLines.length) {
38020
+ return `Error editing file: Line ${endLine} is beyond file length (${fileLines.length} lines). Use 'extract' to read the current file content.`;
38021
+ }
38022
+ if (startRef.hash) {
38023
+ const validation = validateLineHash(startLine, startRef.hash, fileLines);
38024
+ if (!validation.valid) {
38025
+ return `Error editing file: Line ${startLine} has changed since last read. Expected hash '${startRef.hash}' but content is now: ${startLine}:${validation.actualHash} | ${validation.actualContent}. Use '${startLine}:${validation.actualHash}' instead.`;
38026
+ }
38027
+ }
38028
+ if (endRef && endRef.hash) {
38029
+ const validation = validateLineHash(endLine, endRef.hash, fileLines);
38030
+ if (!validation.valid) {
38031
+ return `Error editing file: Line ${endLine} has changed since last read. Expected hash '${endRef.hash}' but content is now: ${endLine}:${validation.actualHash} | ${validation.actualContent}. Use '${endLine}:${validation.actualHash}' instead.`;
38032
+ }
38033
+ }
38034
+ const { cleaned, modifications } = cleanNewString(new_string, fileLines, startLine, endLine, position);
38035
+ if (debug) {
38036
+ if (modifications.length > 0) {
38037
+ console.error(`[Edit] Heuristic corrections: ${modifications.join(", ")}`);
38038
+ }
38039
+ }
38040
+ const newLines = cleaned === "" ? [] : cleaned.split("\n");
38041
+ if (position === "after") {
38042
+ fileLines.splice(startLine, 0, ...newLines);
38043
+ await import_fs4.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
38044
+ if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
38045
+ const action = `${newLines.length} line${newLines.length !== 1 ? "s" : ""} inserted after line ${startLine}`;
38046
+ return buildLineEditResponse(file_path, startLine, startLine, newLines.length, fileLines, startLine, action, modifications);
38047
+ } else if (position === "before") {
38048
+ fileLines.splice(startLine - 1, 0, ...newLines);
38049
+ await import_fs4.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
38050
+ if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
38051
+ const action = `${newLines.length} line${newLines.length !== 1 ? "s" : ""} inserted before line ${startLine}`;
38052
+ return buildLineEditResponse(file_path, startLine, startLine, newLines.length, fileLines, startLine - 1, action, modifications);
38053
+ } else {
38054
+ const replacedCount = endLine - startLine + 1;
38055
+ fileLines.splice(startLine - 1, replacedCount, ...newLines);
38056
+ await import_fs4.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
38057
+ if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
38058
+ let action;
38059
+ if (newLines.length === 0) {
38060
+ action = `${replacedCount} line${replacedCount !== 1 ? "s" : ""} deleted (lines ${startLine}-${endLine})`;
38061
+ } else if (startLine === endLine) {
38062
+ action = `line ${startLine} replaced with ${newLines.length} line${newLines.length !== 1 ? "s" : ""}`;
38063
+ } else {
38064
+ action = `lines ${startLine}-${endLine} replaced with ${newLines.length} line${newLines.length !== 1 ? "s" : ""}`;
38065
+ }
38066
+ return buildLineEditResponse(file_path, startLine, endLine, newLines.length, fileLines, startLine - 1, action, modifications);
38067
+ }
38068
+ }
37497
38069
  var import_ai, import_fs4, import_path5, import_fs5, editTool, createTool, editSchema, createSchema, editDescription, createDescription, editToolDefinition, createToolDefinition;
37498
38070
  var init_edit = __esm({
37499
38071
  "src/tools/edit.js"() {
@@ -37503,24 +38075,31 @@ var init_edit = __esm({
37503
38075
  import_path5 = require("path");
37504
38076
  import_fs5 = require("fs");
37505
38077
  init_path_validation();
38078
+ init_fuzzyMatch();
38079
+ init_symbolEdit();
38080
+ init_hashline();
38081
+ init_lineEditHeuristics();
37506
38082
  editTool = (options = {}) => {
37507
38083
  const { debug, allowedFolders, cwd, workspaceRoot } = parseFileToolOptions(options);
37508
38084
  return (0, import_ai.tool)({
37509
38085
  name: "edit",
37510
- description: `Edit files using exact string replacement (Claude Code style).
38086
+ description: `Edit files using text replacement, AST-aware symbol operations, or line-targeted editing.
37511
38087
 
37512
- This tool performs exact string replacements in files. It requires the old_string to match exactly what's in the file, including all whitespace and indentation.
38088
+ Modes:
38089
+ 1. Text edit: Provide old_string + new_string to find and replace text (with fuzzy matching fallback)
38090
+ 2. Symbol replace: Provide symbol + new_string to replace an entire function/class/method by name
38091
+ 3. Symbol insert: Provide symbol + new_string + position to insert code before/after a symbol
38092
+ 4. Line-targeted edit: Provide start_line + new_string to edit by line number (from extract/search output)
37513
38093
 
37514
38094
  Parameters:
37515
38095
  - file_path: Path to the file to edit (absolute or relative)
37516
- - old_string: Exact text to find and replace (must be unique in the file unless replace_all is true)
37517
- - new_string: Text to replace with
37518
- - replace_all: (optional) Replace all occurrences instead of requiring uniqueness
37519
-
37520
- Important:
37521
- - The old_string must match EXACTLY including whitespace
37522
- - If old_string appears multiple times and replace_all is false, the edit will fail
37523
- - Use larger context around the string to ensure uniqueness when needed`,
38096
+ - new_string: Replacement text or new code content
38097
+ - old_string: (optional) Text to find and replace. If omitted, symbol or start_line must be provided.
38098
+ - replace_all: (optional) Replace all occurrences (text mode only)
38099
+ - symbol: (optional) Symbol name for AST-aware editing (e.g. "myFunction", "MyClass.myMethod")
38100
+ - position: (optional) "before" or "after" \u2014 insert code near a symbol or line instead of replacing it
38101
+ - start_line: (optional) Line reference (e.g. "42" or "42:ab") for line-targeted editing
38102
+ - end_line: (optional) End of line range, inclusive (e.g. "55" or "55:cd")`,
37524
38103
  inputSchema: {
37525
38104
  type: "object",
37526
38105
  properties: {
@@ -37530,30 +38109,44 @@ Important:
37530
38109
  },
37531
38110
  old_string: {
37532
38111
  type: "string",
37533
- description: "Exact text to find and replace"
38112
+ description: "Text to find and replace (for text-based editing)"
37534
38113
  },
37535
38114
  new_string: {
37536
38115
  type: "string",
37537
- description: "Text to replace with"
38116
+ description: "Replacement text or new code content"
37538
38117
  },
37539
38118
  replace_all: {
37540
38119
  type: "boolean",
37541
- description: "Replace all occurrences (default: false)",
38120
+ description: "Replace all occurrences (default: false, text mode only)",
37542
38121
  default: false
38122
+ },
38123
+ symbol: {
38124
+ type: "string",
38125
+ description: 'Symbol name for AST-aware editing (e.g. "myFunction", "MyClass.myMethod")'
38126
+ },
38127
+ position: {
38128
+ type: "string",
38129
+ enum: ["before", "after"],
38130
+ description: "Insert before/after symbol or line (requires symbol or start_line, omit to replace)"
38131
+ },
38132
+ start_line: {
38133
+ type: "string",
38134
+ description: 'Line reference for line-targeted editing (e.g. "42" or "42:ab" with hash)'
38135
+ },
38136
+ end_line: {
38137
+ type: "string",
38138
+ description: 'End of line range, inclusive (e.g. "55" or "55:cd"). Defaults to start_line.'
37543
38139
  }
37544
38140
  },
37545
- required: ["file_path", "old_string", "new_string"]
38141
+ required: ["file_path", "new_string"]
37546
38142
  },
37547
- execute: async ({ file_path, old_string, new_string, replace_all = false }) => {
38143
+ execute: async ({ file_path, old_string, new_string, replace_all = false, symbol: symbol15, position, start_line, end_line }) => {
37548
38144
  try {
37549
38145
  if (!file_path || typeof file_path !== "string" || file_path.trim() === "") {
37550
- return `Error editing file: Invalid file_path - must be a non-empty string`;
37551
- }
37552
- if (old_string === void 0 || old_string === null || typeof old_string !== "string") {
37553
- return `Error editing file: Invalid old_string - must be a string`;
38146
+ return `Error editing file: Invalid file_path - must be a non-empty string. Provide an absolute path or a path relative to the working directory (e.g. "src/main.js").`;
37554
38147
  }
37555
38148
  if (new_string === void 0 || new_string === null || typeof new_string !== "string") {
37556
- return `Error editing file: Invalid new_string - must be a string`;
38149
+ return `Error editing file: Invalid new_string - must be a string. Provide the replacement content as a string value (empty string "" is valid for deletions).`;
37557
38150
  }
37558
38151
  const resolvedPath2 = (0, import_path5.isAbsolute)(file_path) ? file_path : (0, import_path5.resolve)(cwd || process.cwd(), file_path);
37559
38152
  if (debug) {
@@ -37561,34 +38154,64 @@ Important:
37561
38154
  }
37562
38155
  if (!isPathAllowed(resolvedPath2, allowedFolders)) {
37563
38156
  const relativePath = toRelativePath(resolvedPath2, workspaceRoot);
37564
- return `Error editing file: Permission denied - ${relativePath} is outside allowed directories`;
38157
+ return `Error editing file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
37565
38158
  }
37566
38159
  if (!(0, import_fs5.existsSync)(resolvedPath2)) {
37567
- return `Error editing file: File not found - ${file_path}`;
38160
+ return `Error editing file: File not found - ${file_path}. Verify the path is correct and the file exists. Use 'search' to find files by name, or 'create' to make a new file.`;
38161
+ }
38162
+ if (options.fileTracker && !options.fileTracker.isFileSeen(resolvedPath2)) {
38163
+ const displayPath = toRelativePath(resolvedPath2, workspaceRoot);
38164
+ return `Error editing ${displayPath}: This file has not been read yet in this session. Use 'extract' to read the file first, then retry your edit. This ensures you are working with the current file content.
38165
+
38166
+ Example: <extract><targets>${displayPath}</targets></extract>`;
38167
+ }
38168
+ if (symbol15 !== void 0 && symbol15 !== null) {
38169
+ return await handleSymbolEdit({ resolvedPath: resolvedPath2, file_path, symbol: symbol15, new_string, position, debug, cwd, fileTracker: options.fileTracker });
38170
+ }
38171
+ if (start_line !== void 0 && start_line !== null) {
38172
+ return await handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_line, end_line, new_string, position, debug, fileTracker: options.fileTracker });
38173
+ }
38174
+ if (old_string === void 0 || old_string === null) {
38175
+ return 'Error editing file: Must provide either old_string (for text edit), symbol (for AST-aware edit), or start_line (for line-targeted edit). For text editing: set old_string to the exact text to find and new_string to its replacement. For symbol editing: set symbol to a function/class/method name (e.g. "myFunction"). For line-targeted editing: set start_line to a line number from extract/search output (e.g. "42" or "42:ab").';
38176
+ }
38177
+ if (typeof old_string !== "string") {
38178
+ return `Error editing file: Invalid old_string - must be a string. Provide the exact text to find in the file, or use the symbol parameter instead for AST-aware editing by name.`;
37568
38179
  }
37569
38180
  const content = await import_fs4.promises.readFile(resolvedPath2, "utf-8");
38181
+ let matchTarget = old_string;
38182
+ let matchStrategy = "exact";
37570
38183
  if (!content.includes(old_string)) {
37571
- return `Error editing file: String not found - the specified old_string was not found in ${file_path}`;
38184
+ const fuzzy = findFuzzyMatch(content, old_string);
38185
+ if (!fuzzy) {
38186
+ return `Error editing file: String not found - the specified old_string was not found in ${file_path}. The text may have changed or differ from what you expected. Try: (1) Use 'search' or 'extract' to read the current file content and copy the exact text. (2) Use the symbol parameter to edit by function/class name instead. (3) Verify the file_path is correct.`;
38187
+ }
38188
+ matchTarget = fuzzy.matchedText;
38189
+ matchStrategy = fuzzy.strategy;
38190
+ if (debug) {
38191
+ console.error(`[Edit] Exact match failed, used ${matchStrategy} matching`);
38192
+ }
37572
38193
  }
37573
- const occurrences = content.split(old_string).length - 1;
38194
+ const occurrences = content.split(matchTarget).length - 1;
37574
38195
  if (!replace_all && occurrences > 1) {
37575
- return `Error editing file: Multiple occurrences found - the old_string appears ${occurrences} times. Use replace_all: true to replace all occurrences, or provide more context to make the string unique.`;
38196
+ return `Error editing file: Multiple occurrences found - the old_string appears ${occurrences} times in ${file_path}. To fix: (1) Set replace_all=true to replace all occurrences, or (2) Include more surrounding lines in old_string to make the match unique (add the full line or adjacent lines for context).`;
37576
38197
  }
37577
38198
  let newContent;
37578
38199
  if (replace_all) {
37579
- newContent = content.replaceAll(old_string, new_string);
38200
+ newContent = content.replaceAll(matchTarget, new_string);
37580
38201
  } else {
37581
- newContent = content.replace(old_string, new_string);
38202
+ newContent = content.replace(matchTarget, new_string);
37582
38203
  }
37583
38204
  if (newContent === content) {
37584
- return `Error editing file: No changes made - old_string and new_string might be the same`;
38205
+ return `Error editing file: No changes made - the replacement result is identical to the original. Verify that old_string and new_string are actually different. If fuzzy matching was used, the matched text may already equal new_string.`;
37585
38206
  }
37586
38207
  await import_fs4.promises.writeFile(resolvedPath2, newContent, "utf-8");
38208
+ if (options.fileTracker) await options.fileTracker.trackFileAfterWrite(resolvedPath2);
37587
38209
  const replacedCount = replace_all ? occurrences : 1;
37588
38210
  if (debug) {
37589
38211
  console.error(`[Edit] Successfully edited ${resolvedPath2}, replaced ${replacedCount} occurrence(s)`);
37590
38212
  }
37591
- return `Successfully edited ${file_path} (${replacedCount} replacement${replacedCount !== 1 ? "s" : ""})`;
38213
+ const strategyNote = matchStrategy !== "exact" ? `, matched via ${matchStrategy}` : "";
38214
+ return `Successfully edited ${file_path} (${replacedCount} replacement${replacedCount !== 1 ? "s" : ""}${strategyNote})`;
37592
38215
  } catch (error2) {
37593
38216
  console.error("[Edit] Error:", error2);
37594
38217
  return `Error editing file: ${error2.message}`;
@@ -37635,10 +38258,10 @@ Important:
37635
38258
  execute: async ({ file_path, content, overwrite = false }) => {
37636
38259
  try {
37637
38260
  if (!file_path || typeof file_path !== "string" || file_path.trim() === "") {
37638
- return `Error creating file: Invalid file_path - must be a non-empty string`;
38261
+ return `Error creating file: Invalid file_path - must be a non-empty string. Provide an absolute path or a path relative to the working directory (e.g. "src/newFile.js").`;
37639
38262
  }
37640
38263
  if (content === void 0 || content === null || typeof content !== "string") {
37641
- return `Error creating file: Invalid content - must be a string`;
38264
+ return `Error creating file: Invalid content - must be a string. Provide the file content as a string value (empty string "" is valid for an empty file).`;
37642
38265
  }
37643
38266
  const resolvedPath2 = (0, import_path5.isAbsolute)(file_path) ? file_path : (0, import_path5.resolve)(cwd || process.cwd(), file_path);
37644
38267
  if (debug) {
@@ -37646,15 +38269,17 @@ Important:
37646
38269
  }
37647
38270
  if (!isPathAllowed(resolvedPath2, allowedFolders)) {
37648
38271
  const relativePath = toRelativePath(resolvedPath2, workspaceRoot);
37649
- return `Error creating file: Permission denied - ${relativePath} is outside allowed directories`;
38272
+ return `Error creating file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
37650
38273
  }
37651
38274
  if ((0, import_fs5.existsSync)(resolvedPath2) && !overwrite) {
37652
38275
  return `Error creating file: File already exists - ${file_path}. Use overwrite: true to replace it.`;
37653
38276
  }
38277
+ const existed = (0, import_fs5.existsSync)(resolvedPath2);
37654
38278
  const dir = (0, import_path5.dirname)(resolvedPath2);
37655
38279
  await import_fs4.promises.mkdir(dir, { recursive: true });
37656
38280
  await import_fs4.promises.writeFile(resolvedPath2, content, "utf-8");
37657
- const action = (0, import_fs5.existsSync)(resolvedPath2) && overwrite ? "overwrote" : "created";
38281
+ if (options.fileTracker) await options.fileTracker.trackFileAfterWrite(resolvedPath2);
38282
+ const action = existed && overwrite ? "overwrote" : "created";
37658
38283
  const bytes = Buffer.byteLength(content, "utf-8");
37659
38284
  if (debug) {
37660
38285
  console.error(`[Create] Successfully ${action} ${resolvedPath2}`);
@@ -37676,18 +38301,35 @@ Important:
37676
38301
  },
37677
38302
  old_string: {
37678
38303
  type: "string",
37679
- description: "Exact text to find and replace"
38304
+ description: "Text to find and replace (for text-based editing)"
37680
38305
  },
37681
38306
  new_string: {
37682
38307
  type: "string",
37683
- description: "Text to replace with"
38308
+ description: "Replacement text or new code content"
37684
38309
  },
37685
38310
  replace_all: {
37686
38311
  type: "boolean",
37687
- description: "Replace all occurrences (default: false)"
38312
+ description: "Replace all occurrences (default: false, text mode only)"
38313
+ },
38314
+ symbol: {
38315
+ type: "string",
38316
+ description: 'Symbol name for AST-aware editing (e.g. "myFunction", "MyClass.myMethod")'
38317
+ },
38318
+ position: {
38319
+ type: "string",
38320
+ enum: ["before", "after"],
38321
+ description: "Insert before/after symbol or line (requires symbol or start_line, omit to replace)"
38322
+ },
38323
+ start_line: {
38324
+ type: "string",
38325
+ description: 'Line reference for line-targeted editing (e.g. "42" or "42:ab" with hash)'
38326
+ },
38327
+ end_line: {
38328
+ type: "string",
38329
+ description: 'End of line range, inclusive (e.g. "55" or "55:cd"). Defaults to start_line.'
37688
38330
  }
37689
38331
  },
37690
- required: ["file_path", "old_string", "new_string"]
38332
+ required: ["file_path", "new_string"]
37691
38333
  };
37692
38334
  createSchema = {
37693
38335
  type: "object",
@@ -37707,50 +38349,123 @@ Important:
37707
38349
  },
37708
38350
  required: ["file_path", "content"]
37709
38351
  };
37710
- editDescription = "Edit files using exact string replacement. Requires exact match including whitespace.";
38352
+ editDescription = "Edit files using text replacement, AST-aware symbol operations, or line-targeted editing. Supports fuzzy matching for text edits and optional hash-based integrity verification for line edits.";
37711
38353
  createDescription = "Create new files with specified content. Will create parent directories if needed.";
37712
38354
  editToolDefinition = `
37713
38355
  ## edit
37714
38356
  Description: ${editDescription}
37715
38357
 
37716
- When to use:
37717
- - For precise, surgical edits to existing files
37718
- - When you need to change specific lines or blocks of code
37719
- - For renaming functions, variables, or updating configuration values
37720
- - When the exact text to replace is known and unique (or use replace_all for multiple occurrences)
38358
+ Four editing modes \u2014 choose based on the scope of your change:
37721
38359
 
37722
- When NOT to use:
37723
- - For creating new files (use 'create' tool instead)
37724
- - When you cannot determine the exact text to replace
37725
- - When changes span multiple locations that would be better handled together
38360
+ 1. **Text edit** (old_string + new_string): For small, precise changes \u2014 fix a condition, rename a variable, update a value. Provide old_string copied verbatim from the file and new_string with the replacement. Fuzzy matching handles minor whitespace/indentation differences automatically, but always try to copy the exact text.
38361
+
38362
+ 2. **Symbol replace** (symbol + new_string): For replacing an entire function, class, or method by name. No need to quote the old code \u2014 just provide the symbol name and the full new implementation. Indentation is automatically adjusted to match the original. Prefer this mode when rewriting whole definitions.
38363
+
38364
+ 3. **Symbol insert** (symbol + new_string + position): For adding new code before or after an existing symbol. Set position to "before" or "after".
38365
+
38366
+ 4. **Line-targeted edit** (start_line + new_string): For precise edits using line numbers from extract/search output. Use start_line with a line number (e.g. "42") or line:hash (e.g. "42:ab") for integrity verification. Add end_line for multi-line ranges. Use position="before" or "after" to insert instead of replace.
37726
38367
 
37727
38368
  Parameters:
37728
38369
  - file_path: (required) Path to the file to edit
37729
- - old_string: (required) Exact text to find and replace (must match including whitespace, newlines, and indentation)
37730
- - new_string: (required) Text to replace with
37731
- - replace_all: (optional, default: false) Replace all occurrences if the string appears multiple times
37732
-
37733
- Important notes:
37734
- - The old_string MUST match EXACTLY, including all whitespace, indentation, and line breaks
37735
- - If old_string appears multiple times and replace_all is false, the tool will fail
37736
- - Always verify the exact formatting of the text you want to replace
38370
+ - new_string: (required) Replacement text or new code content
38371
+ - old_string: (optional) Text to find and replace \u2014 copy verbatim from the file, do not paraphrase or reformat
38372
+ - replace_all: (optional, default: false) Replace all occurrences of old_string (text mode only)
38373
+ - symbol: (optional) Name of a code symbol (e.g. "myFunction", "MyClass.myMethod") \u2014 must match a function, class, or method definition
38374
+ - position: (optional) "before" or "after" \u2014 insert new_string near the symbol or line instead of replacing it
38375
+ - start_line: (optional) Line reference for line-targeted editing (e.g. "42" or "42:ab")
38376
+ - end_line: (optional) End of line range, inclusive (e.g. "55" or "55:cd"). Defaults to start_line.
38377
+
38378
+ Mode selection rules (priority order):
38379
+ - If symbol is provided, symbol mode is used (old_string and start_line are ignored)
38380
+ - If start_line is provided (without symbol), line-targeted mode is used
38381
+ - If old_string is provided (without symbol or start_line), text mode is used
38382
+ - If none are provided, the tool returns an error with guidance
38383
+
38384
+ When to use each mode:
38385
+ - Small edits (a line or a few lines): use text mode with old_string
38386
+ - Replacing entire functions/classes/methods: use symbol mode \u2014 no exact text matching needed
38387
+ - Editing specific lines from extract/search output: use line-targeted mode with start_line
38388
+ - Editing inside large functions without rewriting them entirely: first use extract with the symbol target (e.g. "file.js#myFunction") to see the function with line numbers, then use start_line/end_line to edit specific lines within it
38389
+
38390
+ Error handling:
38391
+ - If an edit fails, read the error message carefully \u2014 it contains specific instructions for how to fix the call and retry
38392
+ - Common fixes: use 'search'/'extract' to get exact file content, add more context to old_string, switch between text and symbol modes
38393
+ - Line-targeted hash mismatch: the file changed since last read; the error provides updated line:hash references
37737
38394
 
37738
38395
  Examples:
38396
+
38397
+ Text edit (find and replace):
37739
38398
  <edit>
37740
38399
  <file_path>src/main.js</file_path>
37741
- <old_string>function oldName() {
37742
- return 42;
37743
- }</old_string>
37744
- <new_string>function newName() {
37745
- return 42;
37746
- }</new_string>
38400
+ <old_string>return false;</old_string>
38401
+ <new_string>return true;</new_string>
37747
38402
  </edit>
37748
38403
 
38404
+ Text edit with replace_all:
37749
38405
  <edit>
37750
38406
  <file_path>config.json</file_path>
37751
38407
  <old_string>"debug": false</old_string>
37752
38408
  <new_string>"debug": true</new_string>
37753
38409
  <replace_all>true</replace_all>
38410
+ </edit>
38411
+
38412
+ Symbol replace (rewrite entire function by name):
38413
+ <edit>
38414
+ <file_path>src/utils.js</file_path>
38415
+ <symbol>calculateTotal</symbol>
38416
+ <new_string>function calculateTotal(items) {
38417
+ return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
38418
+ }</new_string>
38419
+ </edit>
38420
+
38421
+ Symbol insert (add new function after existing one):
38422
+ <edit>
38423
+ <file_path>src/utils.js</file_path>
38424
+ <symbol>calculateTotal</symbol>
38425
+ <position>after</position>
38426
+ <new_string>function calculateTax(total, rate) {
38427
+ return total * rate;
38428
+ }</new_string>
38429
+ </edit>
38430
+
38431
+ Line-targeted edit (replace a line):
38432
+ <edit>
38433
+ <file_path>src/main.js</file_path>
38434
+ <start_line>42</start_line>
38435
+ <new_string> return processItems(order.items);</new_string>
38436
+ </edit>
38437
+
38438
+ Line-targeted edit (replace a range of lines):
38439
+ <edit>
38440
+ <file_path>src/main.js</file_path>
38441
+ <start_line>42</start_line>
38442
+ <end_line>55</end_line>
38443
+ <new_string> // simplified implementation
38444
+ return processItems(order.items);</new_string>
38445
+ </edit>
38446
+
38447
+ Line-targeted edit with hash verification:
38448
+ <edit>
38449
+ <file_path>src/main.js</file_path>
38450
+ <start_line>42:ab</start_line>
38451
+ <end_line>55:cd</end_line>
38452
+ <new_string> return processItems(order.items);</new_string>
38453
+ </edit>
38454
+
38455
+ Line-targeted insert (add code after a line):
38456
+ <edit>
38457
+ <file_path>src/main.js</file_path>
38458
+ <start_line>42</start_line>
38459
+ <position>after</position>
38460
+ <new_string> const validated = validate(input);</new_string>
38461
+ </edit>
38462
+
38463
+ Line-targeted delete (remove lines):
38464
+ <edit>
38465
+ <file_path>src/main.js</file_path>
38466
+ <start_line>42</start_line>
38467
+ <end_line>45</end_line>
38468
+ <new_string></new_string>
37754
38469
  </edit>`;
37755
38470
  createToolDefinition = `
37756
38471
  ## create
@@ -38287,7 +39002,7 @@ function getValidParamsForTool(toolName) {
38287
39002
  };
38288
39003
  const schema = schemaMap[toolName];
38289
39004
  if (!schema) {
38290
- return ["path", "directory", "pattern", "recursive", "includeHidden", "task", "files", "autoCommits", "result"];
39005
+ return ["path", "directory", "pattern", "recursive", "includeHidden", "task", "files", "result"];
38291
39006
  }
38292
39007
  if (toolName === "attempt_completion") {
38293
39008
  return ["result"];
@@ -38408,7 +39123,6 @@ function detectUnrecognizedToolCall(xmlString, validTools) {
38408
39123
  "listSkills",
38409
39124
  "useSkill",
38410
39125
  "readImage",
38411
- "implement",
38412
39126
  "edit",
38413
39127
  "create",
38414
39128
  "delegate",
@@ -38783,6 +39497,8 @@ User: Read file inside the dependency
38783
39497
  </extract>
38784
39498
 
38785
39499
  </examples>
39500
+
39501
+ **Edit Integration:** The line numbers shown in extract output (e.g. "42 | code") can be used directly with the edit tool's start_line/end_line parameters for precise line-targeted editing. To edit inside a large function: extract it by symbol name first (e.g. "file.js#myFunction"), then use the line numbers from the output to make surgical edits with start_line/end_line.
38786
39502
  `;
38787
39503
  delegateToolDefinition = `
38788
39504
  ## delegate
@@ -38938,7 +39654,7 @@ Capabilities:
38938
39654
  `;
38939
39655
  searchDescription = "Search code in the repository. Free-form questions are accepted, but Elasticsearch-style keyword queries work best. Use this tool first for any code-related questions.";
38940
39656
  queryDescription = "Search code using ast-grep structural pattern matching. Use this tool to find specific code structures like functions, classes, or methods.";
38941
- extractDescription = "Extract code blocks from files based on file paths and optional line numbers. Use this tool to see complete context after finding relevant files.";
39657
+ extractDescription = "Extract code blocks from files based on file paths and optional line numbers. Use this tool to see complete context after finding relevant files. Line numbers from output can be used with edit start_line/end_line for precise editing.";
38942
39658
  delegateDescription = "Automatically delegate big distinct tasks to specialized probe subagents within the agentic loop. Used by AI agents to break down complex requests into focused, parallel tasks.";
38943
39659
  bashDescription = "Execute bash commands for system exploration and development tasks. Secure by default with built-in allow/deny lists.";
38944
39660
  analyzeAllDescription = 'Answer questions that require analyzing ALL matching data in the codebase. Use for aggregate questions like "What features exist?", "List all API endpoints", "Count TODO comments". The AI automatically plans the search strategy, processes all results via map-reduce, and synthesizes a comprehensive answer. WARNING: Slower than search - only use when you need complete coverage.';
@@ -38954,7 +39670,6 @@ Capabilities:
38954
39670
  "useSkill",
38955
39671
  "listFiles",
38956
39672
  "searchFiles",
38957
- "implement",
38958
39673
  "bash",
38959
39674
  "task",
38960
39675
  "attempt_completion"
@@ -39634,7 +40349,7 @@ function parseXmlToolCallWithThinking(xmlString, validTools) {
39634
40349
  const toolCall = parseXmlToolCall(cleanedXmlString, validTools);
39635
40350
  return toolCall ? { ...toolCall, thinkingContent } : null;
39636
40351
  }
39637
- var import_crypto2, implementToolDefinition, listFilesToolDefinition, searchFilesToolDefinition, listSkillsToolDefinition, useSkillToolDefinition, readImageToolDefinition;
40352
+ var import_crypto2, listFilesToolDefinition, searchFilesToolDefinition, listSkillsToolDefinition, useSkillToolDefinition, readImageToolDefinition;
39638
40353
  var init_tools = __esm({
39639
40354
  "src/agent/tools.js"() {
39640
40355
  "use strict";
@@ -39642,31 +40357,6 @@ var init_tools = __esm({
39642
40357
  import_crypto2 = require("crypto");
39643
40358
  init_xmlParsingUtils();
39644
40359
  init_tasks();
39645
- implementToolDefinition = `
39646
- ## implement
39647
- Description: Implement a given task. Can modify files. Can be used ONLY if task explicitly stated that something requires modification or implementation.
39648
-
39649
- Parameters:
39650
- - task: (required) The task description. Should be as detailed as possible, ideally pointing to exact files which needs be modified or created.
39651
- - autoCommits: (optional) Whether to enable auto-commits in aider. Default is false.
39652
-
39653
- Usage Example:
39654
-
39655
- <examples>
39656
-
39657
- User: Can you implement a function to calculate Fibonacci numbers in main.js?
39658
- <implement>
39659
- <task>Implement a recursive function to calculate the nth Fibonacci number in main.js</task>
39660
- </implement>
39661
-
39662
- User: Can you implement a function to calculate Fibonacci numbers in main.js with auto-commits?
39663
- <implement>
39664
- <task>Implement a recursive function to calculate the nth Fibonacci number in main.js</task>
39665
- <autoCommits>true</autoCommits>
39666
- </implement>
39667
-
39668
- </examples>
39669
- `;
39670
40360
  listFilesToolDefinition = `
39671
40361
  ## listFiles
39672
40362
  Description: List files and directories in a specified location.
@@ -39782,33 +40472,289 @@ User: Analyze the diagram in docs/architecture.svg
39782
40472
  }
39783
40473
  });
39784
40474
 
39785
- // node_modules/balanced-match/index.js
39786
- var require_balanced_match = __commonJS({
39787
- "node_modules/balanced-match/index.js"(exports2, module2) {
40475
+ // src/tools/fileTracker.js
40476
+ function computeContentHash(content) {
40477
+ const normalized = (content || "").split("\n").map((l5) => l5.trimEnd()).join("\n");
40478
+ return (0, import_crypto3.createHash)("sha256").update(normalized).digest("hex").slice(0, 16);
40479
+ }
40480
+ function extractFilePath(target) {
40481
+ const hashIdx = target.indexOf("#");
40482
+ if (hashIdx !== -1) {
40483
+ return target.slice(0, hashIdx);
40484
+ }
40485
+ const colonIdx = target.lastIndexOf(":");
40486
+ if (colonIdx !== -1) {
40487
+ const after = target.slice(colonIdx + 1);
40488
+ if (/^\d+(-\d+)?$/.test(after)) {
40489
+ return target.slice(0, colonIdx);
40490
+ }
40491
+ }
40492
+ return target;
40493
+ }
40494
+ function extractSymbolName(target) {
40495
+ const hashIdx = target.indexOf("#");
40496
+ if (hashIdx !== -1) {
40497
+ const symbol15 = target.slice(hashIdx + 1);
40498
+ return symbol15 || null;
40499
+ }
40500
+ return null;
40501
+ }
40502
+ function parseFilePathsFromOutput(output) {
40503
+ const paths = [];
40504
+ const regex = /^(?:File:\s+|---\s+)([^\s].*?)(?:\s+---)?$/gm;
40505
+ let match2;
40506
+ while ((match2 = regex.exec(output)) !== null) {
40507
+ const path9 = match2[1].trim();
40508
+ if (path9 && !path9.startsWith("Results") && !path9.startsWith("Page") && (path9.includes("/") || path9.includes(".") || path9.includes("\\"))) {
40509
+ paths.push(path9);
40510
+ }
40511
+ }
40512
+ return paths;
40513
+ }
40514
+ var import_crypto3, import_path7, FileTracker;
40515
+ var init_fileTracker = __esm({
40516
+ "src/tools/fileTracker.js"() {
39788
40517
  "use strict";
39789
- module2.exports = balanced;
39790
- function balanced(a5, b5, str) {
39791
- if (a5 instanceof RegExp) a5 = maybeMatch(a5, str);
39792
- if (b5 instanceof RegExp) b5 = maybeMatch(b5, str);
39793
- var r5 = range2(a5, b5, str);
40518
+ import_crypto3 = require("crypto");
40519
+ import_path7 = require("path");
40520
+ init_symbolEdit();
40521
+ FileTracker = class {
40522
+ /**
40523
+ * @param {Object} [options]
40524
+ * @param {boolean} [options.debug=false] - Enable debug logging
40525
+ */
40526
+ constructor(options = {}) {
40527
+ this.debug = options.debug || false;
40528
+ this._seenFiles = /* @__PURE__ */ new Set();
40529
+ this._contentRecords = /* @__PURE__ */ new Map();
40530
+ }
40531
+ /**
40532
+ * Mark a file as "seen" — the LLM has read its content.
40533
+ * @param {string} resolvedPath - Absolute path to the file
40534
+ */
40535
+ markFileSeen(resolvedPath2) {
40536
+ this._seenFiles.add(resolvedPath2);
40537
+ if (this.debug) {
40538
+ console.error(`[FileTracker] Marked as seen: ${resolvedPath2}`);
40539
+ }
40540
+ }
40541
+ /**
40542
+ * Check if a file has been seen in this session.
40543
+ * @param {string} resolvedPath - Absolute path to the file
40544
+ * @returns {boolean}
40545
+ */
40546
+ isFileSeen(resolvedPath2) {
40547
+ return this._seenFiles.has(resolvedPath2);
40548
+ }
40549
+ /**
40550
+ * Store a content hash for a symbol in a file.
40551
+ * @param {string} resolvedPath - Absolute path to the file
40552
+ * @param {string} symbolName - Symbol name (e.g. "calculateTotal")
40553
+ * @param {string} code - The symbol's source code
40554
+ * @param {number} startLine - 1-indexed start line
40555
+ * @param {number} endLine - 1-indexed end line
40556
+ * @param {string} [source='extract'] - How the content was obtained
40557
+ */
40558
+ trackSymbolContent(resolvedPath2, symbolName, code, startLine, endLine, source = "extract") {
40559
+ const key = `${resolvedPath2}#${symbolName}`;
40560
+ const contentHash = computeContentHash(code);
40561
+ this._contentRecords.set(key, {
40562
+ contentHash,
40563
+ startLine,
40564
+ endLine,
40565
+ symbolName,
40566
+ source,
40567
+ timestamp: Date.now()
40568
+ });
40569
+ if (this.debug) {
40570
+ console.error(`[FileTracker] Tracked symbol ${key} (hash: ${contentHash}, lines ${startLine}-${endLine})`);
40571
+ }
40572
+ }
40573
+ /**
40574
+ * Look up a stored content record for a symbol.
40575
+ * @param {string} resolvedPath - Absolute path to the file
40576
+ * @param {string} symbolName - Symbol name
40577
+ * @returns {Object|null} The stored record or null
40578
+ */
40579
+ getSymbolRecord(resolvedPath2, symbolName) {
40580
+ return this._contentRecords.get(`${resolvedPath2}#${symbolName}`) || null;
40581
+ }
40582
+ /**
40583
+ * Check if a symbol's current content matches what was stored.
40584
+ * @param {string} resolvedPath - Absolute path to the file
40585
+ * @param {string} symbolName - Symbol name
40586
+ * @param {string} currentCode - The symbol's current source code (from findSymbol)
40587
+ * @returns {{ok: boolean, reason?: string, message?: string}}
40588
+ */
40589
+ checkSymbolContent(resolvedPath2, symbolName, currentCode) {
40590
+ const key = `${resolvedPath2}#${symbolName}`;
40591
+ const record = this._contentRecords.get(key);
40592
+ if (!record) {
40593
+ return { ok: true };
40594
+ }
40595
+ const currentHash = computeContentHash(currentCode);
40596
+ if (currentHash === record.contentHash) {
40597
+ return { ok: true };
40598
+ }
40599
+ return {
40600
+ ok: false,
40601
+ reason: "stale",
40602
+ message: `Symbol "${symbolName}" has changed since you last read it (hash: ${record.contentHash} \u2192 ${currentHash}).`
40603
+ };
40604
+ }
40605
+ /**
40606
+ * Track files from extract target strings.
40607
+ * Marks each file as seen. For #symbol targets, calls findSymbol to get and hash the code.
40608
+ * @param {string[]} targets - Array of extract targets (e.g. ["file.js#fn", "file.js:10-20"])
40609
+ * @param {string} cwd - Working directory for resolving relative paths
40610
+ */
40611
+ async trackFilesFromExtract(targets, cwd) {
40612
+ const seenPaths = /* @__PURE__ */ new Set();
40613
+ const symbolPromises = [];
40614
+ for (const target of targets) {
40615
+ const filePath = extractFilePath(target);
40616
+ const resolved = (0, import_path7.isAbsolute)(filePath) ? filePath : (0, import_path7.resolve)(cwd, filePath);
40617
+ if (!seenPaths.has(resolved)) {
40618
+ seenPaths.add(resolved);
40619
+ this.markFileSeen(resolved);
40620
+ }
40621
+ const symbolName = extractSymbolName(target);
40622
+ if (symbolName) {
40623
+ symbolPromises.push(
40624
+ findSymbol(resolved, symbolName, cwd).then((symbolInfo) => {
40625
+ if (symbolInfo) {
40626
+ this.trackSymbolContent(
40627
+ resolved,
40628
+ symbolName,
40629
+ symbolInfo.code,
40630
+ symbolInfo.startLine,
40631
+ symbolInfo.endLine,
40632
+ "extract"
40633
+ );
40634
+ }
40635
+ }).catch((err) => {
40636
+ if (this.debug) {
40637
+ console.error(`[FileTracker] Failed to track symbol "${symbolName}" in ${resolved}: ${err.message}`);
40638
+ }
40639
+ })
40640
+ );
40641
+ }
40642
+ }
40643
+ if (symbolPromises.length > 0) {
40644
+ await Promise.all(symbolPromises);
40645
+ }
40646
+ }
40647
+ /**
40648
+ * Track files discovered in probe search/extract output.
40649
+ * Parses "File: path" headers and "--- path ---" separators, marks each as "seen".
40650
+ * @param {string} output - Probe output text
40651
+ * @param {string} cwd - Working directory for resolving relative paths
40652
+ */
40653
+ async trackFilesFromOutput(output, cwd) {
40654
+ const paths = parseFilePathsFromOutput(output);
40655
+ for (const filePath of paths) {
40656
+ const resolved = (0, import_path7.isAbsolute)(filePath) ? filePath : (0, import_path7.resolve)(cwd, filePath);
40657
+ this.markFileSeen(resolved);
40658
+ }
40659
+ }
40660
+ /**
40661
+ * Check if a file is safe to edit (seen-check only).
40662
+ * Mode-specific content verification happens in edit handlers.
40663
+ * @param {string} resolvedPath - Absolute path to the file
40664
+ * @returns {{ok: boolean, reason?: string, message?: string}}
40665
+ */
40666
+ checkBeforeEdit(resolvedPath2) {
40667
+ if (!this._seenFiles.has(resolvedPath2)) {
40668
+ return {
40669
+ ok: false,
40670
+ reason: "untracked",
40671
+ message: "This file has not been read yet in this session. Use extract or search to read the file first."
40672
+ };
40673
+ }
40674
+ return { ok: true };
40675
+ }
40676
+ /**
40677
+ * Mark a file as seen after a successful write (backward compat).
40678
+ * Also invalidates content records for the file since its content changed.
40679
+ * @param {string} resolvedPath - Absolute path to the file
40680
+ */
40681
+ async trackFileAfterWrite(resolvedPath2) {
40682
+ this.markFileSeen(resolvedPath2);
40683
+ this.invalidateFileRecords(resolvedPath2);
40684
+ }
40685
+ /**
40686
+ * Update the stored hash for a symbol after a successful write.
40687
+ * Enables chained edits to the same symbol.
40688
+ * @param {string} resolvedPath - Absolute path to the file
40689
+ * @param {string} symbolName - Symbol name
40690
+ * @param {string} code - The symbol's new source code
40691
+ * @param {number} startLine - 1-indexed start line (new position)
40692
+ * @param {number} endLine - 1-indexed end line (new position)
40693
+ */
40694
+ trackSymbolAfterWrite(resolvedPath2, symbolName, code, startLine, endLine) {
40695
+ this.trackSymbolContent(resolvedPath2, symbolName, code, startLine, endLine, "edit");
40696
+ }
40697
+ /**
40698
+ * Remove all content records for a file.
40699
+ * Called after non-symbol edits (text/line mode) since those change content
40700
+ * without providing a symbol-level update.
40701
+ * @param {string} resolvedPath - Absolute path to the file
40702
+ */
40703
+ invalidateFileRecords(resolvedPath2) {
40704
+ const prefix = resolvedPath2 + "#";
40705
+ for (const key of this._contentRecords.keys()) {
40706
+ if (key.startsWith(prefix)) {
40707
+ this._contentRecords.delete(key);
40708
+ }
40709
+ }
40710
+ if (this.debug) {
40711
+ console.error(`[FileTracker] Invalidated content records for ${resolvedPath2}`);
40712
+ }
40713
+ }
40714
+ /**
40715
+ * Quick sync check if a file is being tracked (alias for isFileSeen).
40716
+ * @param {string} resolvedPath - Absolute path to the file
40717
+ * @returns {boolean}
40718
+ */
40719
+ isTracked(resolvedPath2) {
40720
+ return this.isFileSeen(resolvedPath2);
40721
+ }
40722
+ /**
40723
+ * Clear all tracking state.
40724
+ */
40725
+ clear() {
40726
+ this._seenFiles.clear();
40727
+ this._contentRecords.clear();
40728
+ }
40729
+ };
40730
+ }
40731
+ });
40732
+
40733
+ // node_modules/balanced-match/dist/esm/index.js
40734
+ var balanced, maybeMatch, range2;
40735
+ var init_esm = __esm({
40736
+ "node_modules/balanced-match/dist/esm/index.js"() {
40737
+ balanced = (a5, b5, str) => {
40738
+ const ma = a5 instanceof RegExp ? maybeMatch(a5, str) : a5;
40739
+ const mb = b5 instanceof RegExp ? maybeMatch(b5, str) : b5;
40740
+ const r5 = ma !== null && mb != null && range2(ma, mb, str);
39794
40741
  return r5 && {
39795
40742
  start: r5[0],
39796
40743
  end: r5[1],
39797
40744
  pre: str.slice(0, r5[0]),
39798
- body: str.slice(r5[0] + a5.length, r5[1]),
39799
- post: str.slice(r5[1] + b5.length)
40745
+ body: str.slice(r5[0] + ma.length, r5[1]),
40746
+ post: str.slice(r5[1] + mb.length)
39800
40747
  };
39801
- }
39802
- function maybeMatch(reg, str) {
39803
- var m5 = str.match(reg);
40748
+ };
40749
+ maybeMatch = (reg, str) => {
40750
+ const m5 = str.match(reg);
39804
40751
  return m5 ? m5[0] : null;
39805
- }
39806
- balanced.range = range2;
39807
- function range2(a5, b5, str) {
39808
- var begs, beg, left, right, result;
39809
- var ai = str.indexOf(a5);
39810
- var bi = str.indexOf(b5, ai + 1);
39811
- var i5 = ai;
40752
+ };
40753
+ range2 = (a5, b5, str) => {
40754
+ let begs, beg, left, right = void 0, result;
40755
+ let ai = str.indexOf(a5);
40756
+ let bi = str.indexOf(b5, ai + 1);
40757
+ let i5 = ai;
39812
40758
  if (ai >= 0 && bi > 0) {
39813
40759
  if (a5 === b5) {
39814
40760
  return [ai, bi];
@@ -39816,14 +40762,16 @@ var require_balanced_match = __commonJS({
39816
40762
  begs = [];
39817
40763
  left = str.length;
39818
40764
  while (i5 >= 0 && !result) {
39819
- if (i5 == ai) {
40765
+ if (i5 === ai) {
39820
40766
  begs.push(i5);
39821
40767
  ai = str.indexOf(a5, i5 + 1);
39822
- } else if (begs.length == 1) {
39823
- result = [begs.pop(), bi];
40768
+ } else if (begs.length === 1) {
40769
+ const r5 = begs.pop();
40770
+ if (r5 !== void 0)
40771
+ result = [r5, bi];
39824
40772
  } else {
39825
40773
  beg = begs.pop();
39826
- if (beg < left) {
40774
+ if (beg !== void 0 && beg < left) {
39827
40775
  left = beg;
39828
40776
  right = bi;
39829
40777
  }
@@ -39831,163 +40779,179 @@ var require_balanced_match = __commonJS({
39831
40779
  }
39832
40780
  i5 = ai < bi && ai >= 0 ? ai : bi;
39833
40781
  }
39834
- if (begs.length) {
40782
+ if (begs.length && right !== void 0) {
39835
40783
  result = [left, right];
39836
40784
  }
39837
40785
  }
39838
40786
  return result;
39839
- }
40787
+ };
39840
40788
  }
39841
40789
  });
39842
40790
 
39843
- // node_modules/brace-expansion/index.js
39844
- var require_brace_expansion = __commonJS({
39845
- "node_modules/brace-expansion/index.js"(exports2, module2) {
39846
- var balanced = require_balanced_match();
39847
- module2.exports = expandTop;
39848
- var escSlash = "\0SLASH" + Math.random() + "\0";
39849
- var escOpen = "\0OPEN" + Math.random() + "\0";
39850
- var escClose = "\0CLOSE" + Math.random() + "\0";
39851
- var escComma = "\0COMMA" + Math.random() + "\0";
39852
- var escPeriod = "\0PERIOD" + Math.random() + "\0";
39853
- function numeric(str) {
39854
- return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0);
39855
- }
39856
- function escapeBraces(str) {
39857
- return str.split("\\\\").join(escSlash).split("\\{").join(escOpen).split("\\}").join(escClose).split("\\,").join(escComma).split("\\.").join(escPeriod);
39858
- }
39859
- function unescapeBraces(str) {
39860
- return str.split(escSlash).join("\\").split(escOpen).join("{").split(escClose).join("}").split(escComma).join(",").split(escPeriod).join(".");
39861
- }
39862
- function parseCommaParts(str) {
39863
- if (!str)
39864
- return [""];
39865
- var parts = [];
39866
- var m5 = balanced("{", "}", str);
39867
- if (!m5)
39868
- return str.split(",");
39869
- var pre = m5.pre;
39870
- var body = m5.body;
39871
- var post = m5.post;
39872
- var p5 = pre.split(",");
39873
- p5[p5.length - 1] += "{" + body + "}";
39874
- var postParts = parseCommaParts(post);
39875
- if (post.length) {
39876
- p5[p5.length - 1] += postParts.shift();
39877
- p5.push.apply(p5, postParts);
39878
- }
39879
- parts.push.apply(parts, p5);
39880
- return parts;
39881
- }
39882
- function expandTop(str) {
39883
- if (!str)
39884
- return [];
39885
- if (str.substr(0, 2) === "{}") {
39886
- str = "\\{\\}" + str.substr(2);
39887
- }
39888
- return expand2(escapeBraces(str), true).map(unescapeBraces);
39889
- }
39890
- function embrace(str) {
39891
- return "{" + str + "}";
39892
- }
39893
- function isPadded(el) {
39894
- return /^-?0\d/.test(el);
39895
- }
39896
- function lte(i5, y2) {
39897
- return i5 <= y2;
39898
- }
39899
- function gte(i5, y2) {
39900
- return i5 >= y2;
40791
+ // node_modules/brace-expansion/dist/esm/index.js
40792
+ function numeric(str) {
40793
+ return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
40794
+ }
40795
+ function escapeBraces(str) {
40796
+ return str.replace(slashPattern, escSlash).replace(openPattern, escOpen).replace(closePattern, escClose).replace(commaPattern, escComma).replace(periodPattern, escPeriod);
40797
+ }
40798
+ function unescapeBraces(str) {
40799
+ return str.replace(escSlashPattern, "\\").replace(escOpenPattern, "{").replace(escClosePattern, "}").replace(escCommaPattern, ",").replace(escPeriodPattern, ".");
40800
+ }
40801
+ function parseCommaParts(str) {
40802
+ if (!str) {
40803
+ return [""];
40804
+ }
40805
+ const parts = [];
40806
+ const m5 = balanced("{", "}", str);
40807
+ if (!m5) {
40808
+ return str.split(",");
40809
+ }
40810
+ const { pre, body, post } = m5;
40811
+ const p5 = pre.split(",");
40812
+ p5[p5.length - 1] += "{" + body + "}";
40813
+ const postParts = parseCommaParts(post);
40814
+ if (post.length) {
40815
+ ;
40816
+ p5[p5.length - 1] += postParts.shift();
40817
+ p5.push.apply(p5, postParts);
40818
+ }
40819
+ parts.push.apply(parts, p5);
40820
+ return parts;
40821
+ }
40822
+ function expand(str, options = {}) {
40823
+ if (!str) {
40824
+ return [];
40825
+ }
40826
+ const { max = EXPANSION_MAX } = options;
40827
+ if (str.slice(0, 2) === "{}") {
40828
+ str = "\\{\\}" + str.slice(2);
40829
+ }
40830
+ return expand_(escapeBraces(str), max, true).map(unescapeBraces);
40831
+ }
40832
+ function embrace(str) {
40833
+ return "{" + str + "}";
40834
+ }
40835
+ function isPadded(el) {
40836
+ return /^-?0\d/.test(el);
40837
+ }
40838
+ function lte(i5, y2) {
40839
+ return i5 <= y2;
40840
+ }
40841
+ function gte(i5, y2) {
40842
+ return i5 >= y2;
40843
+ }
40844
+ function expand_(str, max, isTop) {
40845
+ const expansions = [];
40846
+ const m5 = balanced("{", "}", str);
40847
+ if (!m5)
40848
+ return [str];
40849
+ const pre = m5.pre;
40850
+ const post = m5.post.length ? expand_(m5.post, max, false) : [""];
40851
+ if (/\$$/.test(m5.pre)) {
40852
+ for (let k5 = 0; k5 < post.length && k5 < max; k5++) {
40853
+ const expansion = pre + "{" + m5.body + "}" + post[k5];
40854
+ expansions.push(expansion);
39901
40855
  }
39902
- function expand2(str, isTop) {
39903
- var expansions = [];
39904
- var m5 = balanced("{", "}", str);
39905
- if (!m5) return [str];
39906
- var pre = m5.pre;
39907
- var post = m5.post.length ? expand2(m5.post, false) : [""];
39908
- if (/\$$/.test(m5.pre)) {
39909
- for (var k5 = 0; k5 < post.length; k5++) {
39910
- var expansion = pre + "{" + m5.body + "}" + post[k5];
39911
- expansions.push(expansion);
39912
- }
39913
- } else {
39914
- var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m5.body);
39915
- var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m5.body);
39916
- var isSequence = isNumericSequence || isAlphaSequence;
39917
- var isOptions = m5.body.indexOf(",") >= 0;
39918
- if (!isSequence && !isOptions) {
39919
- if (m5.post.match(/,(?!,).*\}/)) {
39920
- str = m5.pre + "{" + m5.body + escClose + m5.post;
39921
- return expand2(str);
39922
- }
39923
- return [str];
39924
- }
39925
- var n5;
39926
- if (isSequence) {
39927
- n5 = m5.body.split(/\.\./);
39928
- } else {
39929
- n5 = parseCommaParts(m5.body);
39930
- if (n5.length === 1) {
39931
- n5 = expand2(n5[0], false).map(embrace);
39932
- if (n5.length === 1) {
39933
- return post.map(function(p5) {
39934
- return m5.pre + n5[0] + p5;
39935
- });
39936
- }
40856
+ } else {
40857
+ const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m5.body);
40858
+ const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m5.body);
40859
+ const isSequence = isNumericSequence || isAlphaSequence;
40860
+ const isOptions = m5.body.indexOf(",") >= 0;
40861
+ if (!isSequence && !isOptions) {
40862
+ if (m5.post.match(/,(?!,).*\}/)) {
40863
+ str = m5.pre + "{" + m5.body + escClose + m5.post;
40864
+ return expand_(str, max, true);
40865
+ }
40866
+ return [str];
40867
+ }
40868
+ let n5;
40869
+ if (isSequence) {
40870
+ n5 = m5.body.split(/\.\./);
40871
+ } else {
40872
+ n5 = parseCommaParts(m5.body);
40873
+ if (n5.length === 1 && n5[0] !== void 0) {
40874
+ n5 = expand_(n5[0], max, false).map(embrace);
40875
+ if (n5.length === 1) {
40876
+ return post.map((p5) => m5.pre + n5[0] + p5);
40877
+ }
40878
+ }
40879
+ }
40880
+ let N;
40881
+ if (isSequence && n5[0] !== void 0 && n5[1] !== void 0) {
40882
+ const x5 = numeric(n5[0]);
40883
+ const y2 = numeric(n5[1]);
40884
+ const width = Math.max(n5[0].length, n5[1].length);
40885
+ let incr = n5.length === 3 && n5[2] !== void 0 ? Math.abs(numeric(n5[2])) : 1;
40886
+ let test = lte;
40887
+ const reverse = y2 < x5;
40888
+ if (reverse) {
40889
+ incr *= -1;
40890
+ test = gte;
40891
+ }
40892
+ const pad = n5.some(isPadded);
40893
+ N = [];
40894
+ for (let i5 = x5; test(i5, y2); i5 += incr) {
40895
+ let c5;
40896
+ if (isAlphaSequence) {
40897
+ c5 = String.fromCharCode(i5);
40898
+ if (c5 === "\\") {
40899
+ c5 = "";
39937
40900
  }
39938
- }
39939
- var N;
39940
- if (isSequence) {
39941
- var x5 = numeric(n5[0]);
39942
- var y2 = numeric(n5[1]);
39943
- var width = Math.max(n5[0].length, n5[1].length);
39944
- var incr = n5.length == 3 ? Math.abs(numeric(n5[2])) : 1;
39945
- var test = lte;
39946
- var reverse = y2 < x5;
39947
- if (reverse) {
39948
- incr *= -1;
39949
- test = gte;
39950
- }
39951
- var pad = n5.some(isPadded);
39952
- N = [];
39953
- for (var i5 = x5; test(i5, y2); i5 += incr) {
39954
- var c5;
39955
- if (isAlphaSequence) {
39956
- c5 = String.fromCharCode(i5);
39957
- if (c5 === "\\")
39958
- c5 = "";
39959
- } else {
39960
- c5 = String(i5);
39961
- if (pad) {
39962
- var need = width - c5.length;
39963
- if (need > 0) {
39964
- var z2 = new Array(need + 1).join("0");
39965
- if (i5 < 0)
39966
- c5 = "-" + z2 + c5.slice(1);
39967
- else
39968
- c5 = z2 + c5;
39969
- }
40901
+ } else {
40902
+ c5 = String(i5);
40903
+ if (pad) {
40904
+ const need = width - c5.length;
40905
+ if (need > 0) {
40906
+ const z2 = new Array(need + 1).join("0");
40907
+ if (i5 < 0) {
40908
+ c5 = "-" + z2 + c5.slice(1);
40909
+ } else {
40910
+ c5 = z2 + c5;
39970
40911
  }
39971
40912
  }
39972
- N.push(c5);
39973
- }
39974
- } else {
39975
- N = [];
39976
- for (var j5 = 0; j5 < n5.length; j5++) {
39977
- N.push.apply(N, expand2(n5[j5], false));
39978
40913
  }
39979
40914
  }
39980
- for (var j5 = 0; j5 < N.length; j5++) {
39981
- for (var k5 = 0; k5 < post.length; k5++) {
39982
- var expansion = pre + N[j5] + post[k5];
39983
- if (!isTop || isSequence || expansion)
39984
- expansions.push(expansion);
39985
- }
40915
+ N.push(c5);
40916
+ }
40917
+ } else {
40918
+ N = [];
40919
+ for (let j5 = 0; j5 < n5.length; j5++) {
40920
+ N.push.apply(N, expand_(n5[j5], max, false));
40921
+ }
40922
+ }
40923
+ for (let j5 = 0; j5 < N.length; j5++) {
40924
+ for (let k5 = 0; k5 < post.length && expansions.length < max; k5++) {
40925
+ const expansion = pre + N[j5] + post[k5];
40926
+ if (!isTop || isSequence || expansion) {
40927
+ expansions.push(expansion);
39986
40928
  }
39987
40929
  }
39988
- return expansions;
39989
40930
  }
39990
40931
  }
40932
+ return expansions;
40933
+ }
40934
+ var escSlash, escOpen, escClose, escComma, escPeriod, escSlashPattern, escOpenPattern, escClosePattern, escCommaPattern, escPeriodPattern, slashPattern, openPattern, closePattern, commaPattern, periodPattern, EXPANSION_MAX;
40935
+ var init_esm2 = __esm({
40936
+ "node_modules/brace-expansion/dist/esm/index.js"() {
40937
+ init_esm();
40938
+ escSlash = "\0SLASH" + Math.random() + "\0";
40939
+ escOpen = "\0OPEN" + Math.random() + "\0";
40940
+ escClose = "\0CLOSE" + Math.random() + "\0";
40941
+ escComma = "\0COMMA" + Math.random() + "\0";
40942
+ escPeriod = "\0PERIOD" + Math.random() + "\0";
40943
+ escSlashPattern = new RegExp(escSlash, "g");
40944
+ escOpenPattern = new RegExp(escOpen, "g");
40945
+ escClosePattern = new RegExp(escClose, "g");
40946
+ escCommaPattern = new RegExp(escComma, "g");
40947
+ escPeriodPattern = new RegExp(escPeriod, "g");
40948
+ slashPattern = /\\\\/g;
40949
+ openPattern = /\\{/g;
40950
+ closePattern = /\\}/g;
40951
+ commaPattern = /\\,/g;
40952
+ periodPattern = /\\./g;
40953
+ EXPANSION_MAX = 1e5;
40954
+ }
39991
40955
  });
39992
40956
 
39993
40957
  // node_modules/minimatch/dist/esm/assert-valid-pattern.js
@@ -40570,11 +41534,13 @@ var init_ast = __esm({
40570
41534
  let escaping = false;
40571
41535
  let re = "";
40572
41536
  let uflag = false;
41537
+ let inStar = false;
40573
41538
  for (let i5 = 0; i5 < glob2.length; i5++) {
40574
41539
  const c5 = glob2.charAt(i5);
40575
41540
  if (escaping) {
40576
41541
  escaping = false;
40577
41542
  re += (reSpecials.has(c5) ? "\\" : "") + c5;
41543
+ inStar = false;
40578
41544
  continue;
40579
41545
  }
40580
41546
  if (c5 === "\\") {
@@ -40592,16 +41558,19 @@ var init_ast = __esm({
40592
41558
  uflag = uflag || needUflag;
40593
41559
  i5 += consumed - 1;
40594
41560
  hasMagic2 = hasMagic2 || magic;
41561
+ inStar = false;
40595
41562
  continue;
40596
41563
  }
40597
41564
  }
40598
41565
  if (c5 === "*") {
40599
- if (noEmpty && glob2 === "*")
40600
- re += starNoEmpty;
40601
- else
40602
- re += star;
41566
+ if (inStar)
41567
+ continue;
41568
+ inStar = true;
41569
+ re += noEmpty && /^[*]+$/.test(glob2) ? starNoEmpty : star;
40603
41570
  hasMagic2 = true;
40604
41571
  continue;
41572
+ } else {
41573
+ inStar = false;
40605
41574
  }
40606
41575
  if (c5 === "?") {
40607
41576
  re += qmark;
@@ -40627,10 +41596,10 @@ var init_escape = __esm({
40627
41596
  });
40628
41597
 
40629
41598
  // node_modules/minimatch/dist/esm/index.js
40630
- var import_brace_expansion, minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path5, sep2, GLOBSTAR, qmark2, star2, twoStarDot, twoStarNoDot, filter, ext, defaults, braceExpand, makeRe, match, globMagic, regExpEscape2, Minimatch;
40631
- var init_esm = __esm({
41599
+ var minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path5, sep2, GLOBSTAR, qmark2, star2, twoStarDot, twoStarNoDot, filter, ext, defaults, braceExpand, makeRe, match, globMagic, regExpEscape2, Minimatch;
41600
+ var init_esm3 = __esm({
40632
41601
  "node_modules/minimatch/dist/esm/index.js"() {
40633
- import_brace_expansion = __toESM(require_brace_expansion(), 1);
41602
+ init_esm2();
40634
41603
  init_assert_valid_pattern();
40635
41604
  init_ast();
40636
41605
  init_escape();
@@ -40753,7 +41722,7 @@ var init_esm = __esm({
40753
41722
  if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
40754
41723
  return [pattern];
40755
41724
  }
40756
- return (0, import_brace_expansion.default)(pattern);
41725
+ return expand(pattern);
40757
41726
  };
40758
41727
  minimatch.braceExpand = braceExpand;
40759
41728
  makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
@@ -41359,7 +42328,7 @@ var init_esm = __esm({
41359
42328
 
41360
42329
  // node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js
41361
42330
  var perf, warned, PROCESS, emitWarning, AC, AS, shouldWarn, TYPE, isPosInt, getUintArray, ZeroArray, Stack, LRUCache;
41362
- var init_esm2 = __esm({
42331
+ var init_esm4 = __esm({
41363
42332
  "node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js"() {
41364
42333
  perf = typeof performance === "object" && performance && typeof performance.now === "function" ? performance : Date;
41365
42334
  warned = /* @__PURE__ */ new Set();
@@ -42733,7 +43702,7 @@ var init_esm2 = __esm({
42733
43702
 
42734
43703
  // node_modules/minipass/dist/esm/index.js
42735
43704
  var import_node_events, import_node_stream, import_node_string_decoder, proc, isStream, isReadable, isWritable, EOF, MAYBE_EMIT_END, EMITTED_END, EMITTING_END, EMITTED_ERROR, CLOSED, READ, FLUSH, FLUSHCHUNK, ENCODING, DECODER, FLOWING, PAUSED, RESUME, BUFFER, PIPES, BUFFERLENGTH, BUFFERPUSH, BUFFERSHIFT, OBJECTMODE, DESTROYED, ERROR, EMITDATA, EMITEND, EMITEND2, ASYNC, ABORT, ABORTED, SIGNAL, DATALISTENERS, DISCARDED, defer, nodefer, isEndish, isArrayBufferLike, isArrayBufferView, Pipe, PipeProxyErrors, isObjectModeOptions, isEncodingOptions, Minipass;
42736
- var init_esm3 = __esm({
43705
+ var init_esm5 = __esm({
42737
43706
  "node_modules/minipass/dist/esm/index.js"() {
42738
43707
  import_node_events = require("node:events");
42739
43708
  import_node_stream = __toESM(require("node:stream"), 1);
@@ -43463,10 +44432,10 @@ var init_esm3 = __esm({
43463
44432
  * Return a void Promise that resolves once the stream ends.
43464
44433
  */
43465
44434
  async promise() {
43466
- return new Promise((resolve7, reject2) => {
44435
+ return new Promise((resolve8, reject2) => {
43467
44436
  this.on(DESTROYED, () => reject2(new Error("stream destroyed")));
43468
44437
  this.on("error", (er) => reject2(er));
43469
- this.on("end", () => resolve7());
44438
+ this.on("end", () => resolve8());
43470
44439
  });
43471
44440
  }
43472
44441
  /**
@@ -43490,7 +44459,7 @@ var init_esm3 = __esm({
43490
44459
  return Promise.resolve({ done: false, value: res });
43491
44460
  if (this[EOF])
43492
44461
  return stop();
43493
- let resolve7;
44462
+ let resolve8;
43494
44463
  let reject2;
43495
44464
  const onerr = (er) => {
43496
44465
  this.off("data", ondata);
@@ -43504,19 +44473,19 @@ var init_esm3 = __esm({
43504
44473
  this.off("end", onend);
43505
44474
  this.off(DESTROYED, ondestroy);
43506
44475
  this.pause();
43507
- resolve7({ value, done: !!this[EOF] });
44476
+ resolve8({ value, done: !!this[EOF] });
43508
44477
  };
43509
44478
  const onend = () => {
43510
44479
  this.off("error", onerr);
43511
44480
  this.off("data", ondata);
43512
44481
  this.off(DESTROYED, ondestroy);
43513
44482
  stop();
43514
- resolve7({ done: true, value: void 0 });
44483
+ resolve8({ done: true, value: void 0 });
43515
44484
  };
43516
44485
  const ondestroy = () => onerr(new Error("stream destroyed"));
43517
44486
  return new Promise((res2, rej) => {
43518
44487
  reject2 = rej;
43519
- resolve7 = res2;
44488
+ resolve8 = res2;
43520
44489
  this.once(DESTROYED, ondestroy);
43521
44490
  this.once("error", onerr);
43522
44491
  this.once("end", onend);
@@ -43620,15 +44589,15 @@ var init_esm3 = __esm({
43620
44589
 
43621
44590
  // node_modules/path-scurry/dist/esm/index.js
43622
44591
  var import_node_path, import_node_url, import_fs6, actualFS, import_promises, realpathSync2, defaultFS, fsFromOption, uncDriveRegexp, uncToDrive, eitherSep, UNKNOWN, IFIFO, IFCHR, IFDIR, IFBLK, IFREG, IFLNK, IFSOCK, IFMT, IFMT_UNKNOWN, READDIR_CALLED, LSTAT_CALLED, ENOTDIR, ENOENT, ENOREADLINK, ENOREALPATH, ENOCHILD, TYPEMASK, entToType, normalizeCache, normalize, normalizeNocaseCache, normalizeNocase, ResolveCache, ChildrenCache, setAsCwd, PathBase, PathWin32, PathPosix, PathScurryBase, PathScurryWin32, PathScurryPosix, PathScurryDarwin, Path, PathScurry;
43623
- var init_esm4 = __esm({
44592
+ var init_esm6 = __esm({
43624
44593
  "node_modules/path-scurry/dist/esm/index.js"() {
43625
- init_esm2();
44594
+ init_esm4();
43626
44595
  import_node_path = require("node:path");
43627
44596
  import_node_url = require("node:url");
43628
44597
  import_fs6 = require("fs");
43629
44598
  actualFS = __toESM(require("node:fs"), 1);
43630
44599
  import_promises = require("node:fs/promises");
43631
- init_esm3();
44600
+ init_esm5();
43632
44601
  realpathSync2 = import_fs6.realpathSync.native;
43633
44602
  defaultFS = {
43634
44603
  lstatSync: import_fs6.lstatSync,
@@ -44500,9 +45469,9 @@ var init_esm4 = __esm({
44500
45469
  if (this.#asyncReaddirInFlight) {
44501
45470
  await this.#asyncReaddirInFlight;
44502
45471
  } else {
44503
- let resolve7 = () => {
45472
+ let resolve8 = () => {
44504
45473
  };
44505
- this.#asyncReaddirInFlight = new Promise((res) => resolve7 = res);
45474
+ this.#asyncReaddirInFlight = new Promise((res) => resolve8 = res);
44506
45475
  try {
44507
45476
  for (const e5 of await this.#fs.promises.readdir(fullpath, {
44508
45477
  withFileTypes: true
@@ -44515,7 +45484,7 @@ var init_esm4 = __esm({
44515
45484
  children.provisional = 0;
44516
45485
  }
44517
45486
  this.#asyncReaddirInFlight = void 0;
44518
- resolve7();
45487
+ resolve8();
44519
45488
  }
44520
45489
  return children.slice(0, children.provisional);
44521
45490
  }
@@ -45358,7 +46327,7 @@ var init_esm4 = __esm({
45358
46327
  var isPatternList, isGlobList, Pattern;
45359
46328
  var init_pattern = __esm({
45360
46329
  "node_modules/glob/dist/esm/pattern.js"() {
45361
- init_esm();
46330
+ init_esm3();
45362
46331
  isPatternList = (pl) => pl.length >= 1;
45363
46332
  isGlobList = (gl) => gl.length >= 1;
45364
46333
  Pattern = class _Pattern {
@@ -45529,7 +46498,7 @@ var init_pattern = __esm({
45529
46498
  var defaultPlatform2, Ignore;
45530
46499
  var init_ignore = __esm({
45531
46500
  "node_modules/glob/dist/esm/ignore.js"() {
45532
- init_esm();
46501
+ init_esm3();
45533
46502
  init_pattern();
45534
46503
  defaultPlatform2 = typeof process === "object" && process && typeof process.platform === "string" ? process.platform : "linux";
45535
46504
  Ignore = class {
@@ -45623,7 +46592,7 @@ var init_ignore = __esm({
45623
46592
  var HasWalkedCache, MatchRecord, SubWalks, Processor;
45624
46593
  var init_processor = __esm({
45625
46594
  "node_modules/glob/dist/esm/processor.js"() {
45626
- init_esm();
46595
+ init_esm3();
45627
46596
  HasWalkedCache = class _HasWalkedCache {
45628
46597
  store;
45629
46598
  constructor(store = /* @__PURE__ */ new Map()) {
@@ -45850,7 +46819,7 @@ var init_processor = __esm({
45850
46819
  var makeIgnore, GlobUtil, GlobWalker, GlobStream;
45851
46820
  var init_walker = __esm({
45852
46821
  "node_modules/glob/dist/esm/walker.js"() {
45853
- init_esm3();
46822
+ init_esm5();
45854
46823
  init_ignore();
45855
46824
  init_processor();
45856
46825
  makeIgnore = (ignore2, opts) => typeof ignore2 === "string" ? new Ignore([ignore2], opts) : Array.isArray(ignore2) ? new Ignore(ignore2, opts) : ignore2;
@@ -46185,9 +47154,9 @@ var init_walker = __esm({
46185
47154
  var import_node_url2, defaultPlatform3, Glob;
46186
47155
  var init_glob = __esm({
46187
47156
  "node_modules/glob/dist/esm/glob.js"() {
46188
- init_esm();
47157
+ init_esm3();
46189
47158
  import_node_url2 = require("node:url");
46190
- init_esm4();
47159
+ init_esm6();
46191
47160
  init_pattern();
46192
47161
  init_walker();
46193
47162
  defaultPlatform3 = typeof process === "object" && process && typeof process.platform === "string" ? process.platform : "linux";
@@ -46395,7 +47364,7 @@ var init_glob = __esm({
46395
47364
  var hasMagic;
46396
47365
  var init_has_magic = __esm({
46397
47366
  "node_modules/glob/dist/esm/has-magic.js"() {
46398
- init_esm();
47367
+ init_esm3();
46399
47368
  hasMagic = (pattern, options = {}) => {
46400
47369
  if (!Array.isArray(pattern)) {
46401
47370
  pattern = [pattern];
@@ -46429,12 +47398,12 @@ function globIterate(pattern, options = {}) {
46429
47398
  return new Glob(pattern, options).iterate();
46430
47399
  }
46431
47400
  var streamSync, stream, iterateSync, iterate, sync, glob;
46432
- var init_esm5 = __esm({
47401
+ var init_esm7 = __esm({
46433
47402
  "node_modules/glob/dist/esm/index.js"() {
46434
- init_esm();
47403
+ init_esm3();
46435
47404
  init_glob();
46436
47405
  init_has_magic();
46437
- init_esm();
47406
+ init_esm3();
46438
47407
  init_glob();
46439
47408
  init_has_magic();
46440
47409
  init_ignore();
@@ -46564,19 +47533,19 @@ function createWrappedTools(baseTools) {
46564
47533
  }
46565
47534
  return wrappedTools;
46566
47535
  }
46567
- var import_child_process6, import_util11, import_crypto3, import_events, import_fs7, import_fs8, import_path7, toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
47536
+ var import_child_process6, import_util11, import_crypto4, import_events, import_fs7, import_fs8, import_path8, toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
46568
47537
  var init_probeTool = __esm({
46569
47538
  "src/agent/probeTool.js"() {
46570
47539
  "use strict";
46571
47540
  init_index();
46572
47541
  import_child_process6 = require("child_process");
46573
47542
  import_util11 = require("util");
46574
- import_crypto3 = require("crypto");
47543
+ import_crypto4 = require("crypto");
46575
47544
  import_events = require("events");
46576
47545
  import_fs7 = __toESM(require("fs"), 1);
46577
47546
  import_fs8 = require("fs");
46578
- import_path7 = __toESM(require("path"), 1);
46579
- init_esm5();
47547
+ import_path8 = __toESM(require("path"), 1);
47548
+ init_esm7();
46580
47549
  init_symlink_utils();
46581
47550
  toolCallEmitter = new import_events.EventEmitter();
46582
47551
  activeToolExecutions = /* @__PURE__ */ new Map();
@@ -46586,7 +47555,7 @@ var init_probeTool = __esm({
46586
47555
  // Spread schema, description etc.
46587
47556
  execute: async (params) => {
46588
47557
  const debug = process.env.DEBUG === "1";
46589
- const toolSessionId = params.sessionId || (0, import_crypto3.randomUUID)();
47558
+ const toolSessionId = params.sessionId || (0, import_crypto4.randomUUID)();
46590
47559
  if (debug) {
46591
47560
  console.log(`[DEBUG] probeTool: Executing ${toolName} for session ${toolSessionId}`);
46592
47561
  }
@@ -46664,17 +47633,17 @@ var init_probeTool = __esm({
46664
47633
  execute: async (params) => {
46665
47634
  const { directory = ".", workingDirectory } = params;
46666
47635
  const baseCwd = workingDirectory || process.cwd();
46667
- const secureBaseDir = import_path7.default.resolve(baseCwd);
47636
+ const secureBaseDir = import_path8.default.resolve(baseCwd);
46668
47637
  const isDependencyPath = directory.startsWith("/dep/") || directory.startsWith("go:") || directory.startsWith("js:") || directory.startsWith("rust:");
46669
47638
  let targetDir;
46670
- if (import_path7.default.isAbsolute(directory)) {
46671
- targetDir = import_path7.default.resolve(directory);
46672
- if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
47639
+ if (import_path8.default.isAbsolute(directory)) {
47640
+ targetDir = import_path8.default.resolve(directory);
47641
+ if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path8.default.sep) && targetDir !== secureBaseDir) {
46673
47642
  throw new Error(`Path traversal attempt detected. Cannot access directory outside workspace: ${directory}`);
46674
47643
  }
46675
47644
  } else {
46676
- targetDir = import_path7.default.resolve(secureBaseDir, directory);
46677
- if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
47645
+ targetDir = import_path8.default.resolve(secureBaseDir, directory);
47646
+ if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path8.default.sep) && targetDir !== secureBaseDir) {
46678
47647
  throw new Error(`Path traversal attempt detected. Access denied: ${directory}`);
46679
47648
  }
46680
47649
  }
@@ -46691,7 +47660,7 @@ var init_probeTool = __esm({
46691
47660
  return `${(size / (1024 * 1024 * 1024)).toFixed(1)}G`;
46692
47661
  };
46693
47662
  const entries = await Promise.all(files.map(async (file) => {
46694
- const fullPath = import_path7.default.join(targetDir, file.name);
47663
+ const fullPath = import_path8.default.join(targetDir, file.name);
46695
47664
  const entryType = await getEntryType(file, fullPath);
46696
47665
  return {
46697
47666
  name: file.name,
@@ -46728,17 +47697,17 @@ var init_probeTool = __esm({
46728
47697
  throw new Error("Pattern is required for file search");
46729
47698
  }
46730
47699
  const baseCwd = workingDirectory || process.cwd();
46731
- const secureBaseDir = import_path7.default.resolve(baseCwd);
47700
+ const secureBaseDir = import_path8.default.resolve(baseCwd);
46732
47701
  const isDependencyPath = directory.startsWith("/dep/") || directory.startsWith("go:") || directory.startsWith("js:") || directory.startsWith("rust:");
46733
47702
  let targetDir;
46734
- if (import_path7.default.isAbsolute(directory)) {
46735
- targetDir = import_path7.default.resolve(directory);
46736
- if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
47703
+ if (import_path8.default.isAbsolute(directory)) {
47704
+ targetDir = import_path8.default.resolve(directory);
47705
+ if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path8.default.sep) && targetDir !== secureBaseDir) {
46737
47706
  throw new Error(`Path traversal attempt detected. Cannot access directory outside workspace: ${directory}`);
46738
47707
  }
46739
47708
  } else {
46740
- targetDir = import_path7.default.resolve(secureBaseDir, directory);
46741
- if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
47709
+ targetDir = import_path8.default.resolve(secureBaseDir, directory);
47710
+ if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path8.default.sep) && targetDir !== secureBaseDir) {
46742
47711
  throw new Error(`Path traversal attempt detected. Access denied: ${directory}`);
46743
47712
  }
46744
47713
  }
@@ -46784,7 +47753,7 @@ function createMockProvider() {
46784
47753
  provider: "mock",
46785
47754
  // Mock the doGenerate method used by Vercel AI SDK
46786
47755
  doGenerate: async ({ messages, tools: tools2 }) => {
46787
- await new Promise((resolve7) => setTimeout(resolve7, 10));
47756
+ await new Promise((resolve8) => setTimeout(resolve8, 10));
46788
47757
  return {
46789
47758
  text: "This is a mock response for testing",
46790
47759
  toolCalls: [],
@@ -51987,23 +52956,23 @@ var init_regexp_parser = __esm({
51987
52956
  return ASSERT_NEVER_REACH_HERE();
51988
52957
  }
51989
52958
  quantifier(isBacktracking = false) {
51990
- let range2 = void 0;
52959
+ let range3 = void 0;
51991
52960
  const begin = this.idx;
51992
52961
  switch (this.popChar()) {
51993
52962
  case "*":
51994
- range2 = {
52963
+ range3 = {
51995
52964
  atLeast: 0,
51996
52965
  atMost: Infinity
51997
52966
  };
51998
52967
  break;
51999
52968
  case "+":
52000
- range2 = {
52969
+ range3 = {
52001
52970
  atLeast: 1,
52002
52971
  atMost: Infinity
52003
52972
  };
52004
52973
  break;
52005
52974
  case "?":
52006
- range2 = {
52975
+ range3 = {
52007
52976
  atLeast: 0,
52008
52977
  atMost: 1
52009
52978
  };
@@ -52012,7 +52981,7 @@ var init_regexp_parser = __esm({
52012
52981
  const atLeast = this.integerIncludingZero();
52013
52982
  switch (this.popChar()) {
52014
52983
  case "}":
52015
- range2 = {
52984
+ range3 = {
52016
52985
  atLeast,
52017
52986
  atMost: atLeast
52018
52987
  };
@@ -52021,12 +52990,12 @@ var init_regexp_parser = __esm({
52021
52990
  let atMost;
52022
52991
  if (this.isDigit()) {
52023
52992
  atMost = this.integerIncludingZero();
52024
- range2 = {
52993
+ range3 = {
52025
52994
  atLeast,
52026
52995
  atMost
52027
52996
  };
52028
52997
  } else {
52029
- range2 = {
52998
+ range3 = {
52030
52999
  atLeast,
52031
53000
  atMost: Infinity
52032
53001
  };
@@ -52034,25 +53003,25 @@ var init_regexp_parser = __esm({
52034
53003
  this.consumeChar("}");
52035
53004
  break;
52036
53005
  }
52037
- if (isBacktracking === true && range2 === void 0) {
53006
+ if (isBacktracking === true && range3 === void 0) {
52038
53007
  return void 0;
52039
53008
  }
52040
- ASSERT_EXISTS(range2);
53009
+ ASSERT_EXISTS(range3);
52041
53010
  break;
52042
53011
  }
52043
- if (isBacktracking === true && range2 === void 0) {
53012
+ if (isBacktracking === true && range3 === void 0) {
52044
53013
  return void 0;
52045
53014
  }
52046
- if (ASSERT_EXISTS(range2)) {
53015
+ if (ASSERT_EXISTS(range3)) {
52047
53016
  if (this.peekChar(0) === "?") {
52048
53017
  this.consumeChar("?");
52049
- range2.greedy = false;
53018
+ range3.greedy = false;
52050
53019
  } else {
52051
- range2.greedy = true;
53020
+ range3.greedy = true;
52052
53021
  }
52053
- range2.type = "Quantifier";
52054
- range2.loc = this.loc(begin);
52055
- return range2;
53022
+ range3.type = "Quantifier";
53023
+ range3.loc = this.loc(begin);
53024
+ return range3;
52056
53025
  }
52057
53026
  }
52058
53027
  atom() {
@@ -52754,18 +53723,18 @@ function firstCharOptimizedIndices(ast, result, ignoreCase) {
52754
53723
  if (typeof code === "number") {
52755
53724
  addOptimizedIdxToResult(code, result, ignoreCase);
52756
53725
  } else {
52757
- const range2 = code;
53726
+ const range3 = code;
52758
53727
  if (ignoreCase === true) {
52759
- for (let rangeCode = range2.from; rangeCode <= range2.to; rangeCode++) {
53728
+ for (let rangeCode = range3.from; rangeCode <= range3.to; rangeCode++) {
52760
53729
  addOptimizedIdxToResult(rangeCode, result, ignoreCase);
52761
53730
  }
52762
53731
  } else {
52763
- for (let rangeCode = range2.from; rangeCode <= range2.to && rangeCode < minOptimizationVal; rangeCode++) {
53732
+ for (let rangeCode = range3.from; rangeCode <= range3.to && rangeCode < minOptimizationVal; rangeCode++) {
52764
53733
  addOptimizedIdxToResult(rangeCode, result, ignoreCase);
52765
53734
  }
52766
- if (range2.to >= minOptimizationVal) {
52767
- const minUnOptVal = range2.from >= minOptimizationVal ? range2.from : minOptimizationVal;
52768
- const maxUnOptVal = range2.to;
53735
+ if (range3.to >= minOptimizationVal) {
53736
+ const minUnOptVal = range3.from >= minOptimizationVal ? range3.from : minOptimizationVal;
53737
+ const maxUnOptVal = range3.to;
52769
53738
  const minOptIdx = charCodeToOptimizedIndex(minUnOptVal);
52770
53739
  const maxOptIdx = charCodeToOptimizedIndex(maxUnOptVal);
52771
53740
  for (let currOptIdx = minOptIdx; currOptIdx <= maxOptIdx; currOptIdx++) {
@@ -52826,8 +53795,8 @@ function findCode(setNode, targetCharCodes) {
52826
53795
  if (typeof codeOrRange === "number") {
52827
53796
  return includes_default(targetCharCodes, codeOrRange);
52828
53797
  } else {
52829
- const range2 = codeOrRange;
52830
- return find_default(targetCharCodes, (targetCode) => range2.from <= targetCode && targetCode <= range2.to) !== void 0;
53798
+ const range3 = codeOrRange;
53799
+ return find_default(targetCharCodes, (targetCode) => range3.from <= targetCode && targetCode <= range3.to) !== void 0;
52831
53800
  }
52832
53801
  });
52833
53802
  }
@@ -70732,8 +71701,8 @@ var require_createRange = __commonJS({
70732
71701
  var require_range = __commonJS({
70733
71702
  "node_modules/lodash/range.js"(exports2, module2) {
70734
71703
  var createRange = require_createRange();
70735
- var range2 = createRange();
70736
- module2.exports = range2;
71704
+ var range3 = createRange();
71705
+ module2.exports = range3;
70737
71706
  }
70738
71707
  });
70739
71708
 
@@ -79974,7 +80943,7 @@ var require_compile = __commonJS({
79974
80943
  const schOrFunc = root2.refs[ref2];
79975
80944
  if (schOrFunc)
79976
80945
  return schOrFunc;
79977
- let _sch = resolve7.call(this, root2, ref2);
80946
+ let _sch = resolve8.call(this, root2, ref2);
79978
80947
  if (_sch === void 0) {
79979
80948
  const schema = (_a16 = root2.localRefs) === null || _a16 === void 0 ? void 0 : _a16[ref2];
79980
80949
  const { schemaId } = this.opts;
@@ -80001,7 +80970,7 @@ var require_compile = __commonJS({
80001
80970
  function sameSchemaEnv(s1, s22) {
80002
80971
  return s1.schema === s22.schema && s1.root === s22.root && s1.baseId === s22.baseId;
80003
80972
  }
80004
- function resolve7(root2, ref2) {
80973
+ function resolve8(root2, ref2) {
80005
80974
  let sch;
80006
80975
  while (typeof (sch = this.refs[ref2]) == "string")
80007
80976
  ref2 = sch;
@@ -80576,7 +81545,7 @@ var require_fast_uri = __commonJS({
80576
81545
  }
80577
81546
  return uri;
80578
81547
  }
80579
- function resolve7(baseURI, relativeURI, options) {
81548
+ function resolve8(baseURI, relativeURI, options) {
80580
81549
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
80581
81550
  const resolved = resolveComponent(parse9(baseURI, schemelessOptions), parse9(relativeURI, schemelessOptions), schemelessOptions, true);
80582
81551
  schemelessOptions.skipEscape = true;
@@ -80803,7 +81772,7 @@ var require_fast_uri = __commonJS({
80803
81772
  var fastUri = {
80804
81773
  SCHEMES,
80805
81774
  normalize: normalize3,
80806
- resolve: resolve7,
81775
+ resolve: resolve8,
80807
81776
  resolveComponent,
80808
81777
  equal,
80809
81778
  serialize,
@@ -85326,13 +86295,13 @@ function loadMCPConfiguration() {
85326
86295
  // Environment variable path
85327
86296
  process.env.MCP_CONFIG_PATH,
85328
86297
  // Local project paths
85329
- (0, import_path8.join)(process.cwd(), ".mcp", "config.json"),
85330
- (0, import_path8.join)(process.cwd(), "mcp.config.json"),
86298
+ (0, import_path9.join)(process.cwd(), ".mcp", "config.json"),
86299
+ (0, import_path9.join)(process.cwd(), "mcp.config.json"),
85331
86300
  // Home directory paths
85332
- (0, import_path8.join)((0, import_os3.homedir)(), ".config", "probe", "mcp.json"),
85333
- (0, import_path8.join)((0, import_os3.homedir)(), ".mcp", "config.json"),
86301
+ (0, import_path9.join)((0, import_os3.homedir)(), ".config", "probe", "mcp.json"),
86302
+ (0, import_path9.join)((0, import_os3.homedir)(), ".mcp", "config.json"),
85334
86303
  // Claude-style config location
85335
- (0, import_path8.join)((0, import_os3.homedir)(), "Library", "Application Support", "Claude", "mcp_config.json")
86304
+ (0, import_path9.join)((0, import_os3.homedir)(), "Library", "Application Support", "Claude", "mcp_config.json")
85336
86305
  ].filter(Boolean);
85337
86306
  let config = null;
85338
86307
  for (const configPath of configPaths) {
@@ -85459,16 +86428,16 @@ function parseEnabledServers(config) {
85459
86428
  }
85460
86429
  return servers;
85461
86430
  }
85462
- var import_fs9, import_path8, import_os3, import_url4, __filename4, __dirname4, DEFAULT_TIMEOUT, MAX_TIMEOUT, DEFAULT_CONFIG;
86431
+ var import_fs9, import_path9, import_os3, import_url4, __filename4, __dirname4, DEFAULT_TIMEOUT, MAX_TIMEOUT, DEFAULT_CONFIG;
85463
86432
  var init_config = __esm({
85464
86433
  "src/agent/mcp/config.js"() {
85465
86434
  "use strict";
85466
86435
  import_fs9 = require("fs");
85467
- import_path8 = require("path");
86436
+ import_path9 = require("path");
85468
86437
  import_os3 = require("os");
85469
86438
  import_url4 = require("url");
85470
86439
  __filename4 = (0, import_url4.fileURLToPath)("file:///");
85471
- __dirname4 = (0, import_path8.dirname)(__filename4);
86440
+ __dirname4 = (0, import_path9.dirname)(__filename4);
85472
86441
  DEFAULT_TIMEOUT = 3e4;
85473
86442
  MAX_TIMEOUT = (() => {
85474
86443
  if (process.env.MCP_MAX_TIMEOUT) {
@@ -85482,7 +86451,7 @@ var init_config = __esm({
85482
86451
  // Example probe server configuration
85483
86452
  "probe-local": {
85484
86453
  command: "node",
85485
- args: [(0, import_path8.join)(__dirname4, "../../../examples/chat/mcpServer.js")],
86454
+ args: [(0, import_path9.join)(__dirname4, "../../../examples/chat/mcpServer.js")],
85486
86455
  transport: "stdio",
85487
86456
  enabled: false
85488
86457
  },
@@ -91065,7 +92034,7 @@ var require_compose_scalar = __commonJS({
91065
92034
  var resolveBlockScalar = require_resolve_block_scalar();
91066
92035
  var resolveFlowScalar = require_resolve_flow_scalar();
91067
92036
  function composeScalar(ctx, token, tagToken, onError) {
91068
- const { value, type, comment, range: range2 } = token.type === "block-scalar" ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError) : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
92037
+ const { value, type, comment, range: range3 } = token.type === "block-scalar" ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError) : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
91069
92038
  const tagName = tagToken ? ctx.directives.tagName(tagToken.source, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg)) : null;
91070
92039
  let tag2;
91071
92040
  if (ctx.options.stringKeys && ctx.atKey) {
@@ -91085,7 +92054,7 @@ var require_compose_scalar = __commonJS({
91085
92054
  onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg);
91086
92055
  scalar = new Scalar.Scalar(value);
91087
92056
  }
91088
- scalar.range = range2;
92057
+ scalar.range = range3;
91089
92058
  scalar.source = value;
91090
92059
  if (type)
91091
92060
  scalar.type = type;
@@ -93676,17 +94645,17 @@ async function parseSkillFile(skillFilePath, directoryName) {
93676
94645
  description,
93677
94646
  skillFilePath,
93678
94647
  directoryName,
93679
- sourceDir: (0, import_path9.dirname)(skillFilePath)
94648
+ sourceDir: (0, import_path10.dirname)(skillFilePath)
93680
94649
  },
93681
94650
  error: null
93682
94651
  };
93683
94652
  }
93684
- var import_promises2, import_path9, import_yaml, SKILL_NAME_REGEX, MAX_SKILL_NAME_LENGTH, MAX_DESCRIPTION_CHARS;
94653
+ var import_promises2, import_path10, import_yaml, SKILL_NAME_REGEX, MAX_SKILL_NAME_LENGTH, MAX_DESCRIPTION_CHARS;
93685
94654
  var init_parser7 = __esm({
93686
94655
  "src/agent/skills/parser.js"() {
93687
94656
  "use strict";
93688
94657
  import_promises2 = require("fs/promises");
93689
- import_path9 = require("path");
94658
+ import_path10 = require("path");
93690
94659
  import_yaml = __toESM(require_dist(), 1);
93691
94660
  SKILL_NAME_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
93692
94661
  MAX_SKILL_NAME_LENGTH = 64;
@@ -93696,12 +94665,12 @@ var init_parser7 = __esm({
93696
94665
 
93697
94666
  // src/agent/skills/registry.js
93698
94667
  function isPathInside(basePath, targetPath) {
93699
- const base2 = (0, import_path10.resolve)(basePath);
93700
- const target = (0, import_path10.resolve)(targetPath);
93701
- const rel = (0, import_path10.relative)(base2, target);
94668
+ const base2 = (0, import_path11.resolve)(basePath);
94669
+ const target = (0, import_path11.resolve)(targetPath);
94670
+ const rel = (0, import_path11.relative)(base2, target);
93702
94671
  if (rel === "") return true;
93703
- if (rel === ".." || rel.startsWith(`..${import_path10.sep}`)) return false;
93704
- if ((0, import_path10.isAbsolute)(rel)) return false;
94672
+ if (rel === ".." || rel.startsWith(`..${import_path11.sep}`)) return false;
94673
+ if ((0, import_path11.isAbsolute)(rel)) return false;
93705
94674
  return true;
93706
94675
  }
93707
94676
  function isSafeEntryName(name14) {
@@ -93709,19 +94678,19 @@ function isSafeEntryName(name14) {
93709
94678
  if (name14.includes("\0")) return false;
93710
94679
  return !name14.includes("/") && !name14.includes("\\");
93711
94680
  }
93712
- var import_fs10, import_promises3, import_path10, DEFAULT_SKILL_DIRS, SKILL_FILE_NAME, SkillRegistry;
94681
+ var import_fs10, import_promises3, import_path11, DEFAULT_SKILL_DIRS, SKILL_FILE_NAME, SkillRegistry;
93713
94682
  var init_registry = __esm({
93714
94683
  "src/agent/skills/registry.js"() {
93715
94684
  "use strict";
93716
94685
  import_fs10 = require("fs");
93717
94686
  import_promises3 = require("fs/promises");
93718
- import_path10 = require("path");
94687
+ import_path11 = require("path");
93719
94688
  init_parser7();
93720
94689
  DEFAULT_SKILL_DIRS = [".claude/skills", ".codex/skills", "skills", ".skills"];
93721
94690
  SKILL_FILE_NAME = "SKILL.md";
93722
94691
  SkillRegistry = class {
93723
94692
  constructor({ repoRoot, skillDirs = DEFAULT_SKILL_DIRS, debug = false } = {}) {
93724
- this.repoRoot = repoRoot ? (0, import_path10.resolve)(repoRoot) : process.cwd();
94693
+ this.repoRoot = repoRoot ? (0, import_path11.resolve)(repoRoot) : process.cwd();
93725
94694
  this.repoRootReal = null;
93726
94695
  this.skillDirs = Array.isArray(skillDirs) && skillDirs.length > 0 ? skillDirs : DEFAULT_SKILL_DIRS;
93727
94696
  this.debug = debug;
@@ -93775,8 +94744,8 @@ var init_registry = __esm({
93775
94744
  }
93776
94745
  }
93777
94746
  async _resolveSkillDir(skillDir) {
93778
- const resolved = (0, import_path10.isAbsolute)(skillDir) ? (0, import_path10.resolve)(skillDir) : (0, import_path10.resolve)(this.repoRoot, skillDir);
93779
- const repoRoot = this.repoRootReal || (0, import_path10.resolve)(this.repoRoot);
94747
+ const resolved = (0, import_path11.isAbsolute)(skillDir) ? (0, import_path11.resolve)(skillDir) : (0, import_path11.resolve)(this.repoRoot, skillDir);
94748
+ const repoRoot = this.repoRootReal || (0, import_path11.resolve)(this.repoRoot);
93780
94749
  const resolvedReal = await this._resolveRealPath(resolved);
93781
94750
  if (!resolvedReal) return null;
93782
94751
  if (!isPathInside(repoRoot, resolvedReal)) {
@@ -93807,8 +94776,8 @@ var init_registry = __esm({
93807
94776
  }
93808
94777
  continue;
93809
94778
  }
93810
- const skillFolder = (0, import_path10.join)(dirPath, entry.name);
93811
- const skillFilePath = (0, import_path10.join)(skillFolder, SKILL_FILE_NAME);
94779
+ const skillFolder = (0, import_path11.join)(dirPath, entry.name);
94780
+ const skillFilePath = (0, import_path11.join)(skillFolder, SKILL_FILE_NAME);
93812
94781
  let skillStat;
93813
94782
  try {
93814
94783
  skillStat = await (0, import_promises3.lstat)(skillFilePath);
@@ -93966,7 +94935,7 @@ function extractErrorInfo(error2) {
93966
94935
  };
93967
94936
  }
93968
94937
  function sleep(ms) {
93969
- return new Promise((resolve7) => setTimeout(resolve7, ms));
94938
+ return new Promise((resolve8) => setTimeout(resolve8, ms));
93970
94939
  }
93971
94940
  var DEFAULT_RETRYABLE_ERRORS, RetryManager;
93972
94941
  var init_RetryManager = __esm({
@@ -94746,9 +95715,9 @@ async function truncateIfNeeded(content, tokenCounter, sessionId, maxTokens) {
94746
95715
  let tempFilePath = null;
94747
95716
  let fileError = null;
94748
95717
  try {
94749
- const tempDir = (0, import_path11.join)((0, import_os4.tmpdir)(), "probe-output");
95718
+ const tempDir = (0, import_path12.join)((0, import_os4.tmpdir)(), "probe-output");
94750
95719
  await (0, import_promises4.mkdir)(tempDir, { recursive: true });
94751
- tempFilePath = (0, import_path11.join)(tempDir, `tool-output-${sessionId || "unknown"}-${(0, import_crypto4.randomUUID)()}.txt`);
95720
+ tempFilePath = (0, import_path12.join)(tempDir, `tool-output-${sessionId || "unknown"}-${(0, import_crypto5.randomUUID)()}.txt`);
94752
95721
  await (0, import_promises4.writeFile)(tempFilePath, content, "utf8");
94753
95722
  } catch (err) {
94754
95723
  fileError = err.message || "Unknown file system error";
@@ -94796,14 +95765,14 @@ ${truncatedBody}
94796
95765
  error: fileError || void 0
94797
95766
  };
94798
95767
  }
94799
- var import_promises4, import_os4, import_path11, import_crypto4, DEFAULT_MAX_OUTPUT_TOKENS, CHARS_PER_TOKEN, TAIL_TOKENS, MIN_LIMIT_FOR_TAIL;
95768
+ var import_promises4, import_os4, import_path12, import_crypto5, DEFAULT_MAX_OUTPUT_TOKENS, CHARS_PER_TOKEN, TAIL_TOKENS, MIN_LIMIT_FOR_TAIL;
94800
95769
  var init_outputTruncator = __esm({
94801
95770
  "src/agent/outputTruncator.js"() {
94802
95771
  "use strict";
94803
95772
  import_promises4 = require("fs/promises");
94804
95773
  import_os4 = require("os");
94805
- import_path11 = require("path");
94806
- import_crypto4 = require("crypto");
95774
+ import_path12 = require("path");
95775
+ import_crypto5 = require("crypto");
94807
95776
  DEFAULT_MAX_OUTPUT_TOKENS = 2e4;
94808
95777
  CHARS_PER_TOKEN = 4;
94809
95778
  TAIL_TOKENS = 1e3;
@@ -95925,14 +96894,14 @@ var require_executor = __commonJS({
95925
96894
  function asyncDone(callback) {
95926
96895
  let isInstant = false;
95927
96896
  let instant;
95928
- const p5 = new Promise((resolve7, reject2) => {
96897
+ const p5 = new Promise((resolve8, reject2) => {
95929
96898
  callback((err, result) => {
95930
96899
  if (err)
95931
96900
  reject2(err);
95932
96901
  else {
95933
96902
  isInstant = true;
95934
96903
  instant = result;
95935
- resolve7({ result });
96904
+ resolve8({ result });
95936
96905
  }
95937
96906
  });
95938
96907
  });
@@ -95955,10 +96924,10 @@ var require_executor = __commonJS({
95955
96924
  }
95956
96925
  async function execAsync4(ticks, tree, scope, context, doneOriginal, inLoopOrSwitch) {
95957
96926
  let done = doneOriginal;
95958
- const p5 = new Promise((resolve7) => {
96927
+ const p5 = new Promise((resolve8) => {
95959
96928
  done = (e5, r5) => {
95960
96929
  doneOriginal(e5, r5);
95961
- resolve7();
96930
+ resolve8();
95962
96931
  };
95963
96932
  });
95964
96933
  if (!_execNoneRecurse(ticks, tree, scope, context, done, true, inLoopOrSwitch) && utils.isLisp(tree)) {
@@ -105922,7 +106891,7 @@ async function executeBashCommand(command, options = {}) {
105922
106891
  } = options;
105923
106892
  let cwd = workingDirectory;
105924
106893
  try {
105925
- cwd = (0, import_path12.resolve)(cwd);
106894
+ cwd = (0, import_path13.resolve)(cwd);
105926
106895
  if (!(0, import_fs11.existsSync)(cwd)) {
105927
106896
  throw new Error(`Working directory does not exist: ${cwd}`);
105928
106897
  }
@@ -105944,7 +106913,7 @@ async function executeBashCommand(command, options = {}) {
105944
106913
  console.log(`[BashExecutor] Working directory: "${cwd}"`);
105945
106914
  console.log(`[BashExecutor] Timeout: ${timeout}ms`);
105946
106915
  }
105947
- return new Promise((resolve7, reject2) => {
106916
+ return new Promise((resolve8, reject2) => {
105948
106917
  const processEnv = {
105949
106918
  ...process.env,
105950
106919
  ...env
@@ -105961,7 +106930,7 @@ async function executeBashCommand(command, options = {}) {
105961
106930
  } else {
105962
106931
  const args = parseCommandForExecution(command);
105963
106932
  if (!args || args.length === 0) {
105964
- resolve7({
106933
+ resolve8({
105965
106934
  success: false,
105966
106935
  error: "Failed to parse command",
105967
106936
  stdout: "",
@@ -106046,7 +107015,7 @@ async function executeBashCommand(command, options = {}) {
106046
107015
  success = false;
106047
107016
  error2 = `Command exited with code ${code}`;
106048
107017
  }
106049
- resolve7({
107018
+ resolve8({
106050
107019
  success,
106051
107020
  error: error2,
106052
107021
  stdout: stdout.trim(),
@@ -106066,7 +107035,7 @@ async function executeBashCommand(command, options = {}) {
106066
107035
  if (debug) {
106067
107036
  console.log(`[BashExecutor] Spawn error:`, error2);
106068
107037
  }
106069
- resolve7({
107038
+ resolve8({
106070
107039
  success: false,
106071
107040
  error: `Failed to execute command: ${error2.message}`,
106072
107041
  stdout: "",
@@ -106160,24 +107129,24 @@ function validateExecutionOptions(options = {}) {
106160
107129
  warnings
106161
107130
  };
106162
107131
  }
106163
- var import_child_process7, import_path12, import_fs11;
107132
+ var import_child_process7, import_path13, import_fs11;
106164
107133
  var init_bashExecutor = __esm({
106165
107134
  "src/agent/bashExecutor.js"() {
106166
107135
  "use strict";
106167
107136
  import_child_process7 = require("child_process");
106168
- import_path12 = require("path");
107137
+ import_path13 = require("path");
106169
107138
  import_fs11 = require("fs");
106170
107139
  init_bashCommandUtils();
106171
107140
  }
106172
107141
  });
106173
107142
 
106174
107143
  // src/tools/bash.js
106175
- var import_ai2, import_path13, bashTool;
107144
+ var import_ai2, import_path14, bashTool;
106176
107145
  var init_bash = __esm({
106177
107146
  "src/tools/bash.js"() {
106178
107147
  "use strict";
106179
107148
  import_ai2 = require("ai");
106180
- import_path13 = require("path");
107149
+ import_path14 = require("path");
106181
107150
  init_bashPermissions();
106182
107151
  init_bashExecutor();
106183
107152
  init_path_validation();
@@ -106294,12 +107263,12 @@ For code exploration, try these safe alternatives:
106294
107263
  - npm list, pip list for package information`;
106295
107264
  }
106296
107265
  const defaultDir = getDefaultWorkingDirectory();
106297
- const workingDir = workingDirectory ? (0, import_path13.isAbsolute)(workingDirectory) ? (0, import_path13.resolve)(workingDirectory) : (0, import_path13.resolve)(defaultDir, workingDirectory) : defaultDir;
107266
+ const workingDir = workingDirectory ? (0, import_path14.isAbsolute)(workingDirectory) ? (0, import_path14.resolve)(workingDirectory) : (0, import_path14.resolve)(defaultDir, workingDirectory) : defaultDir;
106298
107267
  if (allowedFolders && allowedFolders.length > 0) {
106299
107268
  const resolvedWorkingDir = safeRealpath(workingDir);
106300
107269
  const isAllowed = allowedFolders.some((folder) => {
106301
107270
  const resolvedFolder = safeRealpath(folder);
106302
- return resolvedWorkingDir === resolvedFolder || resolvedWorkingDir.startsWith(resolvedFolder + import_path13.sep);
107271
+ return resolvedWorkingDir === resolvedFolder || resolvedWorkingDir.startsWith(resolvedFolder + import_path14.sep);
106303
107272
  });
106304
107273
  if (!isAllowed) {
106305
107274
  const relativeDir = toRelativePath(workingDir, workspaceRoot);
@@ -107278,7 +108247,7 @@ var init_executePlan = __esm({
107278
108247
  init_query();
107279
108248
  init_extract();
107280
108249
  init_delegate();
107281
- init_esm5();
108250
+ init_esm7();
107282
108251
  init_bash();
107283
108252
  RAW_OUTPUT_START = "<<<RAW_OUTPUT>>>";
107284
108253
  RAW_OUTPUT_END = "<<<END_RAW_OUTPUT>>>";
@@ -107286,13 +108255,13 @@ var init_executePlan = __esm({
107286
108255
  });
107287
108256
 
107288
108257
  // src/agent/mcp/built-in-server.js
107289
- var import_http, import_events2, import_crypto5, import_server, import_sse2, import_streamableHttp, import_types3, InMemoryEventStore, BuiltInMCPServer;
108258
+ var import_http, import_events2, import_crypto6, import_server, import_sse2, import_streamableHttp, import_types3, InMemoryEventStore, BuiltInMCPServer;
107290
108259
  var init_built_in_server = __esm({
107291
108260
  "src/agent/mcp/built-in-server.js"() {
107292
108261
  "use strict";
107293
108262
  import_http = require("http");
107294
108263
  import_events2 = require("events");
107295
- import_crypto5 = require("crypto");
108264
+ import_crypto6 = require("crypto");
107296
108265
  import_server = require("@modelcontextprotocol/sdk/server/index.js");
107297
108266
  import_sse2 = require("@modelcontextprotocol/sdk/server/sse.js");
107298
108267
  import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
@@ -107368,7 +108337,7 @@ var init_built_in_server = __esm({
107368
108337
  }
107369
108338
  });
107370
108339
  this.registerHandlers();
107371
- return new Promise((resolve7, reject2) => {
108340
+ return new Promise((resolve8, reject2) => {
107372
108341
  this.httpServer.listen(this.port, this.host, async () => {
107373
108342
  const address = this.httpServer.address();
107374
108343
  this.port = address.port;
@@ -107378,7 +108347,7 @@ var init_built_in_server = __esm({
107378
108347
  console.log(`[MCP] Messages endpoint: http://${this.host}:${this.port}/messages`);
107379
108348
  }
107380
108349
  this.emit("ready", { host: this.host, port: this.port });
107381
- resolve7({ host: this.host, port: this.port });
108350
+ resolve8({ host: this.host, port: this.port });
107382
108351
  });
107383
108352
  this.httpServer.on("error", reject2);
107384
108353
  });
@@ -107536,7 +108505,7 @@ var init_built_in_server = __esm({
107536
108505
  }
107537
108506
  const eventStore = new InMemoryEventStore();
107538
108507
  transport = new import_streamableHttp.StreamableHTTPServerTransport({
107539
- sessionIdGenerator: () => (0, import_crypto5.randomUUID)(),
108508
+ sessionIdGenerator: () => (0, import_crypto6.randomUUID)(),
107540
108509
  eventStore,
107541
108510
  // Enable resumability
107542
108511
  onsessioninitialized: (newSessionId) => {
@@ -107597,7 +108566,7 @@ var init_built_in_server = __esm({
107597
108566
  * Parse request body as JSON
107598
108567
  */
107599
108568
  async parseRequestBody(req) {
107600
- return new Promise((resolve7, reject2) => {
108569
+ return new Promise((resolve8, reject2) => {
107601
108570
  let body = "";
107602
108571
  req.on("data", (chunk) => {
107603
108572
  body += chunk.toString();
@@ -107605,7 +108574,7 @@ var init_built_in_server = __esm({
107605
108574
  req.on("end", () => {
107606
108575
  try {
107607
108576
  const parsed = body ? JSON.parse(body) : null;
107608
- resolve7(parsed);
108577
+ resolve8(parsed);
107609
108578
  } catch (error2) {
107610
108579
  reject2(error2);
107611
108580
  }
@@ -107912,12 +108881,12 @@ data: ${JSON.stringify(data3)}
107912
108881
  }
107913
108882
  this.connections.clear();
107914
108883
  if (this.httpServer) {
107915
- return new Promise((resolve7) => {
108884
+ return new Promise((resolve8) => {
107916
108885
  this.httpServer.close(() => {
107917
108886
  if (this.debug) {
107918
108887
  console.log("[MCP] Built-in server stopped");
107919
108888
  }
107920
- resolve7();
108889
+ resolve8();
107921
108890
  });
107922
108891
  });
107923
108892
  }
@@ -107999,7 +108968,7 @@ __export(enhanced_claude_code_exports, {
107999
108968
  async function createEnhancedClaudeCLIEngine(options = {}) {
108000
108969
  const { agent, systemPrompt, customPrompt, debug, sessionId, allowedTools, timeout = 12e4 } = options;
108001
108970
  const session = new Session(
108002
- sessionId || (0, import_crypto6.randomBytes)(8).toString("hex"),
108971
+ sessionId || (0, import_crypto7.randomBytes)(8).toString("hex"),
108003
108972
  debug
108004
108973
  );
108005
108974
  let mcpServer = null;
@@ -108016,12 +108985,12 @@ async function createEnhancedClaudeCLIEngine(options = {}) {
108016
108985
  console.log("[DEBUG] Built-in MCP server started");
108017
108986
  console.log("[DEBUG] MCP URL:", `http://${host}:${port}/mcp`);
108018
108987
  }
108019
- mcpConfigPath = import_path14.default.join(import_os5.default.tmpdir(), `probe-mcp-${session.id}.json`);
108988
+ mcpConfigPath = import_path15.default.join(import_os5.default.tmpdir(), `probe-mcp-${session.id}.json`);
108020
108989
  const mcpConfig = {
108021
108990
  mcpServers: {
108022
108991
  probe: {
108023
108992
  command: "node",
108024
- args: [import_path14.default.join(process.cwd(), "mcp-probe-server.js")],
108993
+ args: [import_path15.default.join(process.cwd(), "mcp-probe-server.js")],
108025
108994
  env: {
108026
108995
  PROBE_WORKSPACE: process.cwd(),
108027
108996
  DEBUG: debug ? "true" : "false"
@@ -108246,8 +109215,8 @@ ${opts.schema}`;
108246
109215
  break;
108247
109216
  }
108248
109217
  } else if (!processEnded) {
108249
- await new Promise((resolve7) => {
108250
- resolver = resolve7;
109218
+ await new Promise((resolve8) => {
109219
+ resolver = resolve8;
108251
109220
  });
108252
109221
  }
108253
109222
  }
@@ -108446,14 +109415,14 @@ function combinePrompts(systemPrompt, customPrompt, agent) {
108446
109415
  }
108447
109416
  return systemPrompt || "";
108448
109417
  }
108449
- var import_child_process8, import_crypto6, import_promises5, import_path14, import_os5, import_events3;
109418
+ var import_child_process8, import_crypto7, import_promises5, import_path15, import_os5, import_events3;
108450
109419
  var init_enhanced_claude_code = __esm({
108451
109420
  "src/agent/engines/enhanced-claude-code.js"() {
108452
109421
  "use strict";
108453
109422
  import_child_process8 = require("child_process");
108454
- import_crypto6 = require("crypto");
109423
+ import_crypto7 = require("crypto");
108455
109424
  import_promises5 = __toESM(require("fs/promises"), 1);
108456
- import_path14 = __toESM(require("path"), 1);
109425
+ import_path15 = __toESM(require("path"), 1);
108457
109426
  import_os5 = __toESM(require("os"), 1);
108458
109427
  import_events3 = require("events");
108459
109428
  init_built_in_server();
@@ -108469,7 +109438,7 @@ __export(codex_exports, {
108469
109438
  async function createCodexEngine(options = {}) {
108470
109439
  const { agent, systemPrompt, customPrompt, debug, sessionId, allowedTools, model } = options;
108471
109440
  const session = new Session(
108472
- sessionId || (0, import_crypto7.randomBytes)(8).toString("hex"),
109441
+ sessionId || (0, import_crypto8.randomBytes)(8).toString("hex"),
108473
109442
  debug
108474
109443
  );
108475
109444
  let mcpServer = null;
@@ -108511,12 +109480,12 @@ async function createCodexEngine(options = {}) {
108511
109480
  }
108512
109481
  }
108513
109482
  if (message.id !== void 0 && pendingRequests.has(message.id)) {
108514
- const { resolve: resolve7, reject: reject2 } = pendingRequests.get(message.id);
109483
+ const { resolve: resolve8, reject: reject2 } = pendingRequests.get(message.id);
108515
109484
  pendingRequests.delete(message.id);
108516
109485
  if (message.error) {
108517
109486
  reject2(new Error(message.error.message || JSON.stringify(message.error)));
108518
109487
  } else {
108519
- resolve7(message.result);
109488
+ resolve8(message.result);
108520
109489
  }
108521
109490
  }
108522
109491
  if (message.method === "codex/event" && message.params) {
@@ -108537,7 +109506,7 @@ async function createCodexEngine(options = {}) {
108537
109506
  });
108538
109507
  }
108539
109508
  function sendRequest(method, params = {}) {
108540
- return new Promise((resolve7, reject2) => {
109509
+ return new Promise((resolve8, reject2) => {
108541
109510
  const id = ++requestId;
108542
109511
  const request = {
108543
109512
  jsonrpc: "2.0",
@@ -108545,7 +109514,7 @@ async function createCodexEngine(options = {}) {
108545
109514
  method,
108546
109515
  params
108547
109516
  };
108548
- pendingRequests.set(id, { resolve: resolve7, reject: reject2 });
109517
+ pendingRequests.set(id, { resolve: resolve8, reject: reject2 });
108549
109518
  setTimeout(() => {
108550
109519
  if (pendingRequests.has(id)) {
108551
109520
  pendingRequests.delete(id);
@@ -108608,7 +109577,7 @@ ${prompt}`;
108608
109577
  const reqId = requestId + 1;
108609
109578
  let fullResponse = "";
108610
109579
  let gotSessionId = false;
108611
- const eventPromise = new Promise((resolve7) => {
109580
+ const eventPromise = new Promise((resolve8) => {
108612
109581
  eventHandlers.set(reqId, (eventParams) => {
108613
109582
  const msg = eventParams.msg;
108614
109583
  if (msg.type === "session_configured" && msg.session_id && !gotSessionId) {
@@ -108628,7 +109597,7 @@ ${prompt}`;
108628
109597
  });
108629
109598
  setTimeout(() => {
108630
109599
  eventHandlers.delete(reqId);
108631
- resolve7();
109600
+ resolve8();
108632
109601
  }, 6e5);
108633
109602
  });
108634
109603
  const resultPromise = sendRequest("tools/call", {
@@ -108724,12 +109693,12 @@ function combinePrompts2(systemPrompt, customPrompt, agent) {
108724
109693
  }
108725
109694
  return systemPrompt || "";
108726
109695
  }
108727
- var import_child_process9, import_crypto7, import_readline;
109696
+ var import_child_process9, import_crypto8, import_readline;
108728
109697
  var init_codex = __esm({
108729
109698
  "src/agent/engines/codex.js"() {
108730
109699
  "use strict";
108731
109700
  import_child_process9 = require("child_process");
108732
- import_crypto7 = require("crypto");
109701
+ import_crypto8 = require("crypto");
108733
109702
  import_readline = require("readline");
108734
109703
  init_built_in_server();
108735
109704
  init_Session();
@@ -108834,7 +109803,7 @@ Your content here
108834
109803
 
108835
109804
  Do NOT wrap in other tags like <api_call>, <tool_name>, <function>, etc.`;
108836
109805
  }
108837
- var import_dotenv, import_anthropic2, import_openai2, import_google2, import_ai5, import_crypto8, import_events4, import_fs12, import_promises6, import_path15, ENGINE_ACTIVITY_TIMEOUT_DEFAULT, ENGINE_ACTIVITY_TIMEOUT_MIN, ENGINE_ACTIVITY_TIMEOUT_MAX, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, ProbeAgent;
109806
+ var import_dotenv, import_anthropic2, import_openai2, import_google2, import_ai5, import_crypto9, import_events4, import_fs12, import_promises6, import_path16, ENGINE_ACTIVITY_TIMEOUT_DEFAULT, ENGINE_ACTIVITY_TIMEOUT_MIN, ENGINE_ACTIVITY_TIMEOUT_MAX, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, ProbeAgent;
108838
109807
  var init_ProbeAgent = __esm({
108839
109808
  "src/agent/ProbeAgent.js"() {
108840
109809
  "use strict";
@@ -108844,17 +109813,18 @@ var init_ProbeAgent = __esm({
108844
109813
  import_google2 = require("@ai-sdk/google");
108845
109814
  init_dist3();
108846
109815
  import_ai5 = require("ai");
108847
- import_crypto8 = require("crypto");
109816
+ import_crypto9 = require("crypto");
108848
109817
  import_events4 = require("events");
108849
109818
  import_fs12 = require("fs");
108850
109819
  import_promises6 = require("fs/promises");
108851
- import_path15 = require("path");
109820
+ import_path16 = require("path");
108852
109821
  init_tokenCounter();
108853
109822
  init_InMemoryStorageAdapter();
108854
109823
  init_HookManager();
108855
109824
  init_imageConfig();
108856
109825
  init_tools();
108857
109826
  init_common2();
109827
+ init_fileTracker();
108858
109828
  init_probeTool();
108859
109829
  init_mockProvider();
108860
109830
  init_index();
@@ -108896,7 +109866,7 @@ var init_ProbeAgent = __esm({
108896
109866
  * @param {string} [options.customPrompt] - Custom prompt to replace the default system message
108897
109867
  * @param {string} [options.systemPrompt] - Alias for customPrompt; takes precedence when both are provided
108898
109868
  * @param {string} [options.promptType] - Predefined prompt type (code-explorer, code-searcher, architect, code-review, support)
108899
- * @param {boolean} [options.allowEdit=false] - Allow the use of the 'implement' tool
109869
+ * @param {boolean} [options.allowEdit=false] - Allow the use of the 'edit' and 'create' tools
108900
109870
  * @param {boolean} [options.enableDelegate=false] - Enable the delegate tool for task distribution to subagents
108901
109871
  * @param {boolean} [options.enableExecutePlan=false] - Enable the execute_plan DSL orchestration tool
108902
109872
  * @param {string} [options.architectureFileName] - Architecture context filename to embed from repo root (defaults to AGENTS.md with CLAUDE.md fallback; ARCHITECTURE.md is always included when present)
@@ -108941,10 +109911,11 @@ var init_ProbeAgent = __esm({
108941
109911
  * @param {number} [options.maxOperationTimeout] - Maximum timeout in ms for the entire operation including all retries and fallbacks (default: 300000 or MAX_OPERATION_TIMEOUT env var). This is the absolute maximum time for streamTextWithRetryAndFallback.
108942
109912
  */
108943
109913
  constructor(options = {}) {
108944
- this.sessionId = options.sessionId || (0, import_crypto8.randomUUID)();
109914
+ this.sessionId = options.sessionId || (0, import_crypto9.randomUUID)();
108945
109915
  this.customPrompt = options.systemPrompt || options.customPrompt || null;
108946
109916
  this.promptType = options.promptType || "code-explorer";
108947
109917
  this.allowEdit = !!options.allowEdit;
109918
+ this.hashLines = options.hashLines !== void 0 ? !!options.hashLines : this.allowEdit;
108948
109919
  this.enableDelegate = !!options.enableDelegate;
108949
109920
  this.enableExecutePlan = !!options.enableExecutePlan;
108950
109921
  this.debug = options.debug || process.env.DEBUG === "1";
@@ -109006,7 +109977,8 @@ var init_ProbeAgent = __esm({
109006
109977
  if (this.debug) {
109007
109978
  console.log(`[DEBUG] Generated session ID for agent: ${this.sessionId}`);
109008
109979
  console.log(`[DEBUG] Maximum tool iterations configured: ${MAX_TOOL_ITERATIONS}`);
109009
- console.log(`[DEBUG] Allow Edit (implement tool): ${this.allowEdit}`);
109980
+ console.log(`[DEBUG] Allow Edit: ${this.allowEdit}`);
109981
+ console.log(`[DEBUG] Hash Lines: ${this.hashLines}`);
109010
109982
  console.log(`[DEBUG] Search delegation enabled: ${this.searchDelegate}`);
109011
109983
  console.log(`[DEBUG] Workspace root: ${this.workspaceRoot}`);
109012
109984
  console.log(`[DEBUG] Working directory (cwd): ${this.cwd}`);
@@ -109391,9 +110363,12 @@ var init_ProbeAgent = __esm({
109391
110363
  cwd: this.cwd,
109392
110364
  workspaceRoot: this.workspaceRoot,
109393
110365
  allowedFolders: this.allowedFolders,
110366
+ // File state tracking for safe multi-edit workflows (only when editing is enabled)
110367
+ fileTracker: this.allowEdit ? new FileTracker({ debug: this.debug }) : null,
109394
110368
  outline: this.outline,
109395
110369
  searchDelegate: this.searchDelegate,
109396
110370
  allowEdit: this.allowEdit,
110371
+ hashLines: this.hashLines,
109397
110372
  enableDelegate: this.enableDelegate,
109398
110373
  enableExecutePlan: this.enableExecutePlan,
109399
110374
  enableBash: this.enableBash,
@@ -109464,7 +110439,7 @@ var init_ProbeAgent = __esm({
109464
110439
  if (!imagePath) {
109465
110440
  throw new Error("Image path is required");
109466
110441
  }
109467
- const filename = (0, import_path15.basename)(imagePath);
110442
+ const filename = (0, import_path16.basename)(imagePath);
109468
110443
  const extension = filename.toLowerCase().split(".").pop();
109469
110444
  if (!extension || !SUPPORTED_IMAGE_EXTENSIONS.includes(extension)) {
109470
110445
  throw new Error(`Invalid or unsupported image extension: ${extension}. Supported formats: ${SUPPORTED_IMAGE_EXTENSIONS.join(", ")}`);
@@ -110178,7 +111153,7 @@ var init_ProbeAgent = __esm({
110178
111153
  let resolvedPath2 = imagePath;
110179
111154
  if (!imagePath.includes("/") && !imagePath.includes("\\")) {
110180
111155
  for (const dir of listFilesDirectories) {
110181
- const potentialPath = (0, import_path15.resolve)(dir, imagePath);
111156
+ const potentialPath = (0, import_path16.resolve)(dir, imagePath);
110182
111157
  const loaded = await this.loadImageIfValid(potentialPath);
110183
111158
  if (loaded) {
110184
111159
  if (this.debug) {
@@ -110203,7 +111178,7 @@ var init_ProbeAgent = __esm({
110203
111178
  let match2;
110204
111179
  while ((match2 = fileHeaderPattern.exec(content)) !== null) {
110205
111180
  const filePath = match2[1].trim();
110206
- const dir = (0, import_path15.dirname)(filePath);
111181
+ const dir = (0, import_path16.dirname)(filePath);
110207
111182
  if (dir && dir !== ".") {
110208
111183
  directories.push(dir);
110209
111184
  if (this.debug) {
@@ -110248,17 +111223,17 @@ var init_ProbeAgent = __esm({
110248
111223
  const allowedDirs = this.allowedFolders && this.allowedFolders.length > 0 ? this.allowedFolders : [process.cwd()];
110249
111224
  let absolutePath;
110250
111225
  let isPathAllowed2 = false;
110251
- if ((0, import_path15.isAbsolute)(imagePath)) {
110252
- absolutePath = safeRealpath((0, import_path15.resolve)(imagePath));
111226
+ if ((0, import_path16.isAbsolute)(imagePath)) {
111227
+ absolutePath = safeRealpath((0, import_path16.resolve)(imagePath));
110253
111228
  isPathAllowed2 = allowedDirs.some((dir) => {
110254
111229
  const resolvedDir = safeRealpath(dir);
110255
- return absolutePath === resolvedDir || absolutePath.startsWith(resolvedDir + import_path15.sep);
111230
+ return absolutePath === resolvedDir || absolutePath.startsWith(resolvedDir + import_path16.sep);
110256
111231
  });
110257
111232
  } else {
110258
111233
  for (const dir of allowedDirs) {
110259
111234
  const resolvedDir = safeRealpath(dir);
110260
- const resolvedPath2 = safeRealpath((0, import_path15.resolve)(dir, imagePath));
110261
- if (resolvedPath2 === resolvedDir || resolvedPath2.startsWith(resolvedDir + import_path15.sep)) {
111235
+ const resolvedPath2 = safeRealpath((0, import_path16.resolve)(dir, imagePath));
111236
+ if (resolvedPath2 === resolvedDir || resolvedPath2.startsWith(resolvedDir + import_path16.sep)) {
110262
111237
  absolutePath = resolvedPath2;
110263
111238
  isPathAllowed2 = true;
110264
111239
  break;
@@ -110446,8 +111421,8 @@ var init_ProbeAgent = __esm({
110446
111421
  const hasConfiguredName = !!configuredName;
110447
111422
  let guidanceCandidates = [];
110448
111423
  if (hasConfiguredName) {
110449
- const targetName = (0, import_path15.basename)(configuredName);
110450
- if (configuredName !== targetName || configuredName.includes("/") || configuredName.includes("\\") || configuredName.includes("..") || (0, import_path15.isAbsolute)(configuredName)) {
111424
+ const targetName = (0, import_path16.basename)(configuredName);
111425
+ if (configuredName !== targetName || configuredName.includes("/") || configuredName.includes("\\") || configuredName.includes("..") || (0, import_path16.isAbsolute)(configuredName)) {
110451
111426
  console.warn(`[WARN] Invalid architectureFileName (must be a simple filename): ${configuredName}`);
110452
111427
  } else if (targetName) {
110453
111428
  const targetLower = targetName.toLowerCase();
@@ -110514,7 +111489,7 @@ var init_ProbeAgent = __esm({
110514
111489
  pushEntry(architectureMatch);
110515
111490
  const contexts = [];
110516
111491
  for (const entry of uniqueEntries) {
110517
- const filePath = (0, import_path15.resolve)(rootDirectory, entry.name);
111492
+ const filePath = (0, import_path16.resolve)(rootDirectory, entry.name);
110518
111493
  try {
110519
111494
  const content = await (0, import_promises6.readFile)(filePath, "utf8");
110520
111495
  let kind = "other";
@@ -110579,10 +111554,10 @@ ${this.architectureContext.content}
110579
111554
  }
110580
111555
  _getSkillsRepoRoot() {
110581
111556
  if (this.workspaceRoot) {
110582
- return (0, import_path15.resolve)(this.workspaceRoot);
111557
+ return (0, import_path16.resolve)(this.workspaceRoot);
110583
111558
  }
110584
111559
  if (this.allowedFolders && this.allowedFolders.length > 0) {
110585
- return (0, import_path15.resolve)(this.allowedFolders[0]);
111560
+ return (0, import_path16.resolve)(this.allowedFolders[0]);
110586
111561
  }
110587
111562
  return process.cwd();
110588
111563
  }
@@ -110771,10 +111746,6 @@ Workspace: ${this.allowedFolders.join(", ")}`;
110771
111746
  }
110772
111747
  if (isToolAllowed("readImage")) {
110773
111748
  toolDefinitions += `${readImageToolDefinition}
110774
- `;
110775
- }
110776
- if (this.allowEdit && isToolAllowed("implement")) {
110777
- toolDefinitions += `${implementToolDefinition}
110778
111749
  `;
110779
111750
  }
110780
111751
  if (this.allowEdit && isToolAllowed("edit")) {
@@ -110856,7 +111827,7 @@ The configuration is loaded from src/config.js lines 15-25 which contains the da
110856
111827
  availableToolsList += "- query: Search code using structural AST patterns.\n";
110857
111828
  }
110858
111829
  if (isToolAllowed("extract")) {
110859
- availableToolsList += "- extract: Extract specific code blocks or lines from files.\n";
111830
+ availableToolsList += '- extract: Extract specific code blocks or lines from files. Use with symbol targets (e.g. "file.js#funcName") to get line numbers for line-targeted editing.\n';
110860
111831
  }
110861
111832
  if (isToolAllowed("listFiles")) {
110862
111833
  availableToolsList += "- listFiles: List files and directories in a specified location.\n";
@@ -110873,11 +111844,8 @@ The configuration is loaded from src/config.js lines 15-25 which contains the da
110873
111844
  if (isToolAllowed("readImage")) {
110874
111845
  availableToolsList += "- readImage: Read and load an image file for AI analysis.\n";
110875
111846
  }
110876
- if (this.allowEdit && isToolAllowed("implement")) {
110877
- availableToolsList += "- implement: Implement a feature or fix a bug using aider.\n";
110878
- }
110879
111847
  if (this.allowEdit && isToolAllowed("edit")) {
110880
- availableToolsList += "- edit: Edit files using exact string replacement.\n";
111848
+ availableToolsList += "- edit: Edit files using text replacement, AST-aware symbol operations, or line-targeted editing.\n";
110881
111849
  }
110882
111850
  if (this.allowEdit && isToolAllowed("create")) {
110883
111851
  availableToolsList += "- create: Create new files with specified content.\n";
@@ -110965,8 +111933,14 @@ Follow these instructions carefully:
110965
111933
  8. Once the task is fully completed, use the '<attempt_completion>' tool to provide the final result. This is the ONLY way to signal completion.
110966
111934
  9. Prefer concise and focused search queries. Use specific keywords and phrases to narrow down results.${this.allowEdit ? `
110967
111935
  10. When modifying files, choose the appropriate tool:
110968
- - Use 'edit' for precise changes to existing files (requires exact string match)
110969
- - Use 'create' for new files or complete file rewrites` : ""}
111936
+ - Use 'edit' for all code modifications:
111937
+ * For small changes (a line or a few lines), use old_string + new_string \u2014 copy old_string verbatim from the file.
111938
+ * For rewriting entire functions/classes/methods, use the symbol parameter instead (no exact text matching needed).
111939
+ * For editing specific lines from search/extract output, use start_line (and optionally end_line) with the line numbers shown in the output.${this.hashLines ? ' Line references include content hashes (e.g. "42:ab") for integrity verification.' : ""}
111940
+ * For editing inside large functions: first use extract with the symbol target (e.g. "file.js#myFunction") to see the function with line numbers${this.hashLines ? " and hashes" : ""}, then use start_line/end_line to surgically edit specific lines within it.
111941
+ - Use 'create' for new files or complete file rewrites.
111942
+ - If an edit fails, read the error message \u2014 it tells you exactly how to fix the call and retry.
111943
+ - The system tracks which files you've seen via search/extract. If you try to edit a file you haven't read, or one that changed since you last read it, the edit will fail with instructions to re-read first. Always use extract before editing to ensure you have current file content.` : ""}
110970
111944
  </instructions>
110971
111945
  `;
110972
111946
  let systemMessage = "";
@@ -111466,8 +112440,11 @@ You are working with a workspace. Available paths: ${workspaceDesc}
111466
112440
  if (this.enableSkills && this.allowedTools.isEnabled("useSkill")) validTools.push("useSkill");
111467
112441
  if (this.allowedTools.isEnabled("readImage")) validTools.push("readImage");
111468
112442
  validTools.push("attempt_completion");
111469
- if (this.allowEdit && this.allowedTools.isEnabled("implement")) {
111470
- validTools.push("implement", "edit", "create");
112443
+ if (this.allowEdit && this.allowedTools.isEnabled("edit")) {
112444
+ validTools.push("edit");
112445
+ }
112446
+ if (this.allowEdit && this.allowedTools.isEnabled("create")) {
112447
+ validTools.push("create");
111471
112448
  }
111472
112449
  if (this.enableBash && this.allowedTools.isEnabled("bash")) {
111473
112450
  validTools.push("bash");
@@ -111689,10 +112666,10 @@ ${errorXml}
111689
112666
  try {
111690
112667
  let resolvedWorkingDirectory = this.workspaceRoot || this.cwd || this.allowedFolders && this.allowedFolders[0] || process.cwd();
111691
112668
  if (params.workingDirectory) {
111692
- const requestedDir = safeRealpath((0, import_path15.isAbsolute)(params.workingDirectory) ? (0, import_path15.resolve)(params.workingDirectory) : (0, import_path15.resolve)(resolvedWorkingDirectory, params.workingDirectory));
112669
+ const requestedDir = safeRealpath((0, import_path16.isAbsolute)(params.workingDirectory) ? (0, import_path16.resolve)(params.workingDirectory) : (0, import_path16.resolve)(resolvedWorkingDirectory, params.workingDirectory));
111693
112670
  const isWithinAllowed = !this.allowedFolders || this.allowedFolders.length === 0 || this.allowedFolders.some((folder) => {
111694
112671
  const resolvedFolder = safeRealpath(folder);
111695
- return requestedDir === resolvedFolder || requestedDir.startsWith(resolvedFolder + import_path15.sep);
112672
+ return requestedDir === resolvedFolder || requestedDir.startsWith(resolvedFolder + import_path16.sep);
111696
112673
  });
111697
112674
  if (isWithinAllowed) {
111698
112675
  resolvedWorkingDirectory = requestedDir;
@@ -111760,6 +112737,8 @@ ${errorXml}
111760
112737
  // Inherit bash enablement
111761
112738
  bashConfig: this.bashConfig,
111762
112739
  // Inherit bash configuration
112740
+ allowEdit: this.allowEdit,
112741
+ // Inherit edit/create permission
111763
112742
  allowedTools: allowedToolsForDelegate,
111764
112743
  // Inherit allowed tools from parent
111765
112744
  debug: this.debug,
@@ -111832,7 +112811,7 @@ ${errorXml}
111832
112811
  currentMessages.push({ role: "assistant", content: assistantResponseContent });
111833
112812
  let toolResultContent = typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult, null, 2);
111834
112813
  if (this.workspaceRoot && toolResultContent) {
111835
- const wsPrefix = this.workspaceRoot.endsWith(import_path15.sep) ? this.workspaceRoot : this.workspaceRoot + import_path15.sep;
112814
+ const wsPrefix = this.workspaceRoot.endsWith(import_path16.sep) ? this.workspaceRoot : this.workspaceRoot + import_path16.sep;
111836
112815
  toolResultContent = toolResultContent.split(wsPrefix).join("");
111837
112816
  }
111838
112817
  const { cleanedContent, extractedBlocks } = extractRawOutputBlocks(toolResultContent);
@@ -112682,7 +113661,7 @@ Convert your previous response content into actual JSON data that follows this s
112682
113661
  */
112683
113662
  clone(options = {}) {
112684
113663
  const {
112685
- sessionId = (0, import_crypto8.randomUUID)(),
113664
+ sessionId = (0, import_crypto9.randomUUID)(),
112686
113665
  stripInternalMessages = true,
112687
113666
  keepSystemMessage = true,
112688
113667
  deepCopy = true,
@@ -112915,6 +113894,7 @@ async function delegate({
112915
113894
  model = null,
112916
113895
  enableBash = false,
112917
113896
  bashConfig = null,
113897
+ allowEdit = false,
112918
113898
  architectureFileName = null,
112919
113899
  promptType = "code-researcher",
112920
113900
  allowedTools = null,
@@ -112947,7 +113927,7 @@ async function delegate({
112947
113927
  }
112948
113928
  }
112949
113929
  const manager = delegationManager || defaultDelegationManager;
112950
- const sessionId = (0, import_crypto9.randomUUID)();
113930
+ const sessionId = (0, import_crypto10.randomUUID)();
112951
113931
  const startTime = Date.now();
112952
113932
  const remainingIterations = Math.max(1, maxIterations - currentIteration);
112953
113933
  const delegationSpan = typeof tracer?.createDelegationSpan === "function" ? tracer.createDelegationSpan(sessionId, task) : null;
@@ -112994,6 +113974,8 @@ async function delegate({
112994
113974
  // Inherit from parent
112995
113975
  bashConfig,
112996
113976
  // Inherit from parent
113977
+ allowEdit,
113978
+ // Inherit from parent
112997
113979
  architectureFileName,
112998
113980
  allowedTools,
112999
113981
  disableTools,
@@ -113098,11 +114080,11 @@ async function delegate({
113098
114080
  throw new Error(`Delegation failed: ${error2.message}`);
113099
114081
  }
113100
114082
  }
113101
- var import_crypto9, DelegationManager, defaultDelegationManager, DEFAULT_DELEGATE_TIMEOUT;
114083
+ var import_crypto10, DelegationManager, defaultDelegationManager, DEFAULT_DELEGATE_TIMEOUT;
113102
114084
  var init_delegate = __esm({
113103
114085
  "src/delegate.js"() {
113104
114086
  "use strict";
113105
- import_crypto9 = require("crypto");
114087
+ import_crypto10 = require("crypto");
113106
114088
  init_ProbeAgent();
113107
114089
  DelegationManager = class {
113108
114090
  constructor(options = {}) {
@@ -113179,7 +114161,7 @@ var init_delegate = __esm({
113179
114161
  if (debug) {
113180
114162
  console.error(`[DelegationManager] Slot unavailable (${this.globalActive}/${this.maxConcurrent}), queuing... (queue size: ${this.waitQueue.length}, timeout: ${effectiveTimeout}ms)`);
113181
114163
  }
113182
- return new Promise((resolve7, reject2) => {
114164
+ return new Promise((resolve8, reject2) => {
113183
114165
  const entry = {
113184
114166
  resolve: null,
113185
114167
  // Will be wrapped below
@@ -113195,7 +114177,7 @@ var init_delegate = __esm({
113195
114177
  if (settled) return;
113196
114178
  settled = true;
113197
114179
  if (entry.timeoutId) clearTimeout(entry.timeoutId);
113198
- resolve7(value);
114180
+ resolve8(value);
113199
114181
  };
113200
114182
  entry.reject = (error2) => {
113201
114183
  if (settled) return;
@@ -113245,7 +114227,7 @@ var init_delegate = __esm({
113245
114227
  while (this.waitQueue.length > 0 && this.globalActive < this.maxConcurrent) {
113246
114228
  const next = this.waitQueue.shift();
113247
114229
  if (!next) break;
113248
- const { resolve: resolve7, reject: reject2, parentSessionId, queuedAt } = next;
114230
+ const { resolve: resolve8, reject: reject2, parentSessionId, queuedAt } = next;
113249
114231
  if (parentSessionId) {
113250
114232
  const sessionData = this.sessionDelegations.get(parentSessionId);
113251
114233
  const sessionCount = sessionData?.count || 0;
@@ -113262,12 +114244,12 @@ var init_delegate = __esm({
113262
114244
  const waitTime = Date.now() - queuedAt;
113263
114245
  console.error(`[DelegationManager] Granted slot from queue (waited ${waitTime}ms). Active: ${this.globalActive}/${this.maxConcurrent}`);
113264
114246
  }
113265
- toResolve.push(resolve7);
114247
+ toResolve.push(resolve8);
113266
114248
  }
113267
114249
  if (toResolve.length > 0 || toReject.length > 0) {
113268
114250
  setImmediate(() => {
113269
- for (const resolve7 of toResolve) {
113270
- resolve7(true);
114251
+ for (const resolve8 of toResolve) {
114252
+ resolve8(true);
113271
114253
  }
113272
114254
  for (const { reject: reject2, error: error2 } of toReject) {
113273
114255
  reject2(error2);
@@ -113913,6 +114895,7 @@ var init_vercel = __esm({
113913
114895
  init_analyzeAll();
113914
114896
  init_common2();
113915
114897
  init_error_types();
114898
+ init_hashline();
113916
114899
  CODE_SEARCH_SCHEMA = {
113917
114900
  type: "object",
113918
114901
  properties: {
@@ -113931,8 +114914,15 @@ var init_vercel = __esm({
113931
114914
  maxTokens = 2e4,
113932
114915
  debug = false,
113933
114916
  outline = false,
113934
- searchDelegate = false
114917
+ searchDelegate = false,
114918
+ hashLines = false
113935
114919
  } = options;
114920
+ const maybeAnnotate = (result) => {
114921
+ if (hashLines && typeof result === "string") {
114922
+ return annotateOutputWithHashes(result);
114923
+ }
114924
+ return result;
114925
+ };
113936
114926
  return (0, import_ai6.tool)({
113937
114927
  name: "search",
113938
114928
  description: searchDelegate ? `${searchDescription} (delegates code search to a subagent and returns extracted code blocks)` : searchDescription,
@@ -113974,7 +114964,12 @@ var init_vercel = __esm({
113974
114964
  };
113975
114965
  if (!searchDelegate) {
113976
114966
  try {
113977
- return await runRawSearch();
114967
+ const result = maybeAnnotate(await runRawSearch());
114968
+ if (options.fileTracker && typeof result === "string") {
114969
+ options.fileTracker.trackFilesFromOutput(result, options.cwd || ".").catch(() => {
114970
+ });
114971
+ }
114972
+ return result;
113978
114973
  } catch (error2) {
113979
114974
  console.error("Error executing search command:", error2);
113980
114975
  return formatErrorForAI(error2);
@@ -114017,7 +115012,12 @@ var init_vercel = __esm({
114017
115012
  if (debug) {
114018
115013
  console.error("Delegated search returned no targets; falling back to raw search");
114019
115014
  }
114020
- return await runRawSearch();
115015
+ const fallbackResult = maybeAnnotate(await runRawSearch());
115016
+ if (options.fileTracker && typeof fallbackResult === "string") {
115017
+ options.fileTracker.trackFilesFromOutput(fallbackResult, options.cwd || ".").catch(() => {
115018
+ });
115019
+ }
115020
+ return fallbackResult;
114021
115021
  }
114022
115022
  const resolutionBase = searchPaths[0] || options.cwd || ".";
114023
115023
  const resolvedTargets = targets.map((target) => resolveTargetPath(target, resolutionBase));
@@ -114032,13 +115032,18 @@ var init_vercel = __esm({
114032
115032
  const extractResult = await extract(extractOptions);
114033
115033
  if (resolutionBase && typeof extractResult === "string") {
114034
115034
  const wsPrefix = resolutionBase.endsWith("/") ? resolutionBase : resolutionBase + "/";
114035
- return extractResult.split(wsPrefix).join("");
115035
+ return maybeAnnotate(extractResult.split(wsPrefix).join(""));
114036
115036
  }
114037
- return extractResult;
115037
+ return maybeAnnotate(extractResult);
114038
115038
  } catch (error2) {
114039
115039
  console.error("Delegated search failed, falling back to raw search:", error2);
114040
115040
  try {
114041
- return await runRawSearch();
115041
+ const fallbackResult2 = maybeAnnotate(await runRawSearch());
115042
+ if (options.fileTracker && typeof fallbackResult2 === "string") {
115043
+ options.fileTracker.trackFilesFromOutput(fallbackResult2, options.cwd || ".").catch(() => {
115044
+ });
115045
+ }
115046
+ return fallbackResult2;
114042
115047
  } catch (fallbackError) {
114043
115048
  console.error("Error executing search command:", fallbackError);
114044
115049
  return formatErrorForAI(fallbackError);
@@ -114084,7 +115089,7 @@ var init_vercel = __esm({
114084
115089
  });
114085
115090
  };
114086
115091
  extractTool = (options = {}) => {
114087
- const { debug = false, outline = false } = options;
115092
+ const { debug = false, outline = false, hashLines = false } = options;
114088
115093
  return (0, import_ai6.tool)({
114089
115094
  name: "extract",
114090
115095
  description: extractDescription,
@@ -114101,6 +115106,7 @@ var init_vercel = __esm({
114101
115106
  }
114102
115107
  let tempFilePath = null;
114103
115108
  let extractOptions = { cwd: effectiveCwd };
115109
+ let extractFiles = null;
114104
115110
  if (input_content) {
114105
115111
  const { writeFileSync: writeFileSync2, unlinkSync } = await import("fs");
114106
115112
  const { join: join5 } = await import("path");
@@ -114124,13 +115130,13 @@ var init_vercel = __esm({
114124
115130
  };
114125
115131
  } else if (targets) {
114126
115132
  const parsedTargets = parseTargets(targets);
114127
- const files = parsedTargets.map((target) => resolveTargetPath(target, effectiveCwd));
115133
+ extractFiles = parsedTargets.map((target) => resolveTargetPath(target, effectiveCwd));
114128
115134
  let effectiveFormat = format2;
114129
115135
  if (outline && format2 === "outline-xml") {
114130
115136
  effectiveFormat = "xml";
114131
115137
  }
114132
115138
  extractOptions = {
114133
- files,
115139
+ files: extractFiles,
114134
115140
  cwd: effectiveCwd,
114135
115141
  allowTests: allow_tests ?? true,
114136
115142
  contextLines: context_lines,
@@ -114140,6 +115146,10 @@ var init_vercel = __esm({
114140
115146
  throw new Error("Either targets or input_content must be provided");
114141
115147
  }
114142
115148
  const results = await extract(extractOptions);
115149
+ if (options.fileTracker && extractFiles && extractFiles.length > 0) {
115150
+ options.fileTracker.trackFilesFromExtract(extractFiles, effectiveCwd).catch(() => {
115151
+ });
115152
+ }
114143
115153
  if (tempFilePath) {
114144
115154
  const { unlinkSync } = await import("fs");
114145
115155
  try {
@@ -114151,6 +115161,9 @@ var init_vercel = __esm({
114151
115161
  console.error(`Warning: Failed to remove temporary file: ${cleanupError.message}`);
114152
115162
  }
114153
115163
  }
115164
+ if (hashLines && typeof results === "string") {
115165
+ return annotateOutputWithHashes(results);
115166
+ }
114154
115167
  return results;
114155
115168
  } catch (error2) {
114156
115169
  console.error("Error executing extract command:", error2);
@@ -114577,7 +115590,7 @@ async function listFilesByLevel(options) {
114577
115590
  if (!import_fs13.default.existsSync(directory)) {
114578
115591
  throw new Error(`Directory does not exist: ${directory}`);
114579
115592
  }
114580
- const gitDirExists = import_fs13.default.existsSync(import_path16.default.join(directory, ".git"));
115593
+ const gitDirExists = import_fs13.default.existsSync(import_path17.default.join(directory, ".git"));
114581
115594
  if (gitDirExists && respectGitignore) {
114582
115595
  try {
114583
115596
  return await listFilesUsingGit(directory, maxFiles);
@@ -114592,8 +115605,8 @@ async function listFilesUsingGit(directory, maxFiles) {
114592
115605
  const { stdout } = await execAsync3("git ls-files", { cwd: directory });
114593
115606
  const files = stdout.split("\n").filter(Boolean);
114594
115607
  const sortedFiles = files.sort((a5, b5) => {
114595
- const depthA = a5.split(import_path16.default.sep).length;
114596
- const depthB = b5.split(import_path16.default.sep).length;
115608
+ const depthA = a5.split(import_path17.default.sep).length;
115609
+ const depthB = b5.split(import_path17.default.sep).length;
114597
115610
  return depthA - depthB;
114598
115611
  });
114599
115612
  return sortedFiles.slice(0, maxFiles);
@@ -114610,23 +115623,23 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
114610
115623
  try {
114611
115624
  const entries = import_fs13.default.readdirSync(dir, { withFileTypes: true });
114612
115625
  const files = entries.filter((entry) => {
114613
- const fullPath = import_path16.default.join(dir, entry.name);
115626
+ const fullPath = import_path17.default.join(dir, entry.name);
114614
115627
  return getEntryTypeSync(entry, fullPath).isFile;
114615
115628
  });
114616
115629
  for (const file of files) {
114617
115630
  if (result.length >= maxFiles) break;
114618
- const filePath = import_path16.default.join(dir, file.name);
114619
- const relativePath = import_path16.default.relative(directory, filePath);
115631
+ const filePath = import_path17.default.join(dir, file.name);
115632
+ const relativePath = import_path17.default.relative(directory, filePath);
114620
115633
  if (shouldIgnore(relativePath, ignorePatterns)) continue;
114621
115634
  result.push(relativePath);
114622
115635
  }
114623
115636
  const dirs = entries.filter((entry) => {
114624
- const fullPath = import_path16.default.join(dir, entry.name);
115637
+ const fullPath = import_path17.default.join(dir, entry.name);
114625
115638
  return getEntryTypeSync(entry, fullPath).isDirectory;
114626
115639
  });
114627
115640
  for (const subdir of dirs) {
114628
- const subdirPath = import_path16.default.join(dir, subdir.name);
114629
- const relativeSubdirPath = import_path16.default.relative(directory, subdirPath);
115641
+ const subdirPath = import_path17.default.join(dir, subdir.name);
115642
+ const relativeSubdirPath = import_path17.default.relative(directory, subdirPath);
114630
115643
  if (shouldIgnore(relativeSubdirPath, ignorePatterns)) continue;
114631
115644
  if (subdir.name === "node_modules" || subdir.name === ".git") continue;
114632
115645
  queue.push({ dir: subdirPath, level: level + 1 });
@@ -114638,7 +115651,7 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
114638
115651
  return result;
114639
115652
  }
114640
115653
  function loadGitignorePatterns(directory) {
114641
- const gitignorePath = import_path16.default.join(directory, ".gitignore");
115654
+ const gitignorePath = import_path17.default.join(directory, ".gitignore");
114642
115655
  if (!import_fs13.default.existsSync(gitignorePath)) {
114643
115656
  return [];
114644
115657
  }
@@ -114661,12 +115674,12 @@ function shouldIgnore(filePath, ignorePatterns) {
114661
115674
  }
114662
115675
  return false;
114663
115676
  }
114664
- var import_fs13, import_path16, import_util12, import_child_process10, execAsync3;
115677
+ var import_fs13, import_path17, import_util12, import_child_process10, execAsync3;
114665
115678
  var init_file_lister = __esm({
114666
115679
  "src/utils/file-lister.js"() {
114667
115680
  "use strict";
114668
115681
  import_fs13 = __toESM(require("fs"), 1);
114669
- import_path16 = __toESM(require("path"), 1);
115682
+ import_path17 = __toESM(require("path"), 1);
114670
115683
  import_util12 = require("util");
114671
115684
  import_child_process10 = require("child_process");
114672
115685
  init_symlink_utils();
@@ -114684,12 +115697,12 @@ function initializeSimpleTelemetryFromOptions(options) {
114684
115697
  });
114685
115698
  return telemetry;
114686
115699
  }
114687
- var import_fs14, import_path17, SimpleTelemetry, SimpleAppTracer;
115700
+ var import_fs14, import_path18, SimpleTelemetry, SimpleAppTracer;
114688
115701
  var init_simpleTelemetry = __esm({
114689
115702
  "src/agent/simpleTelemetry.js"() {
114690
115703
  "use strict";
114691
115704
  import_fs14 = require("fs");
114692
- import_path17 = require("path");
115705
+ import_path18 = require("path");
114693
115706
  SimpleTelemetry = class {
114694
115707
  constructor(options = {}) {
114695
115708
  this.serviceName = options.serviceName || "probe-agent";
@@ -114703,7 +115716,7 @@ var init_simpleTelemetry = __esm({
114703
115716
  }
114704
115717
  initializeFileExporter() {
114705
115718
  try {
114706
- const dir = (0, import_path17.dirname)(this.filePath);
115719
+ const dir = (0, import_path18.dirname)(this.filePath);
114707
115720
  if (!(0, import_fs14.existsSync)(dir)) {
114708
115721
  (0, import_fs14.mkdirSync)(dir, { recursive: true });
114709
115722
  }
@@ -114768,20 +115781,20 @@ var init_simpleTelemetry = __esm({
114768
115781
  }
114769
115782
  async flush() {
114770
115783
  if (this.stream) {
114771
- return new Promise((resolve7) => {
114772
- this.stream.once("drain", resolve7);
115784
+ return new Promise((resolve8) => {
115785
+ this.stream.once("drain", resolve8);
114773
115786
  if (!this.stream.writableNeedDrain) {
114774
- resolve7();
115787
+ resolve8();
114775
115788
  }
114776
115789
  });
114777
115790
  }
114778
115791
  }
114779
115792
  async shutdown() {
114780
115793
  if (this.stream) {
114781
- return new Promise((resolve7) => {
115794
+ return new Promise((resolve8) => {
114782
115795
  this.stream.end(() => {
114783
115796
  console.log(`[SimpleTelemetry] File stream closed: ${this.filePath}`);
114784
- resolve7();
115797
+ resolve8();
114785
115798
  });
114786
115799
  });
114787
115800
  }
@@ -115140,6 +116153,7 @@ var init_hooks = __esm({
115140
116153
  var index_exports = {};
115141
116154
  __export(index_exports, {
115142
116155
  DEFAULT_SYSTEM_MESSAGE: () => DEFAULT_SYSTEM_MESSAGE,
116156
+ FileTracker: () => FileTracker,
115143
116157
  HOOK_TYPES: () => HOOK_TYPES,
115144
116158
  HookManager: () => HookManager,
115145
116159
  InMemoryStorageAdapter: () => InMemoryStorageAdapter,
@@ -115220,6 +116234,7 @@ var init_index = __esm({
115220
116234
  init_executePlan();
115221
116235
  init_bash();
115222
116236
  init_edit();
116237
+ init_fileTracker();
115223
116238
  init_ProbeAgent();
115224
116239
  init_simpleTelemetry();
115225
116240
  init_probeTool();
@@ -115233,6 +116248,7 @@ init_index();
115233
116248
  // Annotate the CommonJS export names for ESM import in node:
115234
116249
  0 && (module.exports = {
115235
116250
  DEFAULT_SYSTEM_MESSAGE,
116251
+ FileTracker,
115236
116252
  HOOK_TYPES,
115237
116253
  HookManager,
115238
116254
  InMemoryStorageAdapter,