@probelabs/probe 0.6.0-rc253 → 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.
- package/README.md +166 -3
- package/bin/binaries/probe-v0.6.0-rc255-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc255-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc255-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc255-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc255-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/ProbeAgent.d.ts +1 -1
- package/build/agent/ProbeAgent.js +51 -16
- package/build/agent/acp/tools.js +2 -1
- package/build/agent/acp/tools.test.js +2 -1
- package/build/agent/dsl/environment.js +19 -0
- package/build/agent/index.js +1512 -413
- package/build/agent/schemaUtils.js +91 -2
- package/build/agent/tools.js +0 -28
- package/build/delegate.js +3 -0
- package/build/index.js +2 -0
- package/build/tools/common.js +6 -5
- package/build/tools/edit.js +457 -65
- package/build/tools/executePlan.js +3 -1
- package/build/tools/fileTracker.js +318 -0
- package/build/tools/fuzzyMatch.js +271 -0
- package/build/tools/hashline.js +131 -0
- package/build/tools/lineEditHeuristics.js +138 -0
- package/build/tools/symbolEdit.js +119 -0
- package/build/tools/vercel.js +40 -9
- package/cjs/agent/ProbeAgent.cjs +1615 -517
- package/cjs/index.cjs +1643 -543
- package/index.d.ts +189 -1
- package/package.json +1 -1
- package/src/agent/ProbeAgent.d.ts +1 -1
- package/src/agent/ProbeAgent.js +51 -16
- package/src/agent/acp/tools.js +2 -1
- package/src/agent/acp/tools.test.js +2 -1
- package/src/agent/dsl/environment.js +19 -0
- package/src/agent/index.js +14 -3
- package/src/agent/schemaUtils.js +91 -2
- package/src/agent/tools.js +0 -28
- package/src/delegate.js +3 -0
- package/src/index.js +2 -0
- package/src/tools/common.js +6 -5
- package/src/tools/edit.js +457 -65
- package/src/tools/executePlan.js +3 -1
- package/src/tools/fileTracker.js +318 -0
- package/src/tools/fuzzyMatch.js +271 -0
- package/src/tools/hashline.js +131 -0
- package/src/tools/lineEditHeuristics.js +138 -0
- package/src/tools/symbolEdit.js +119 -0
- package/src/tools/vercel.js +40 -9
- package/bin/binaries/probe-v0.6.0-rc253-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc253-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc253-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc253-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc253-x86_64-unknown-linux-musl.tar.gz +0 -0
package/cjs/agent/ProbeAgent.cjs
CHANGED
|
@@ -2329,7 +2329,7 @@ var require_headStream = __commonJS({
|
|
|
2329
2329
|
if ((0, stream_type_check_1.isReadableStream)(stream2)) {
|
|
2330
2330
|
return (0, headStream_browser_1.headStream)(stream2, bytes);
|
|
2331
2331
|
}
|
|
2332
|
-
return new Promise((
|
|
2332
|
+
return new Promise((resolve8, reject2) => {
|
|
2333
2333
|
const collector = new Collector();
|
|
2334
2334
|
collector.limit = bytes;
|
|
2335
2335
|
stream2.pipe(collector);
|
|
@@ -2340,7 +2340,7 @@ var require_headStream = __commonJS({
|
|
|
2340
2340
|
collector.on("error", reject2);
|
|
2341
2341
|
collector.on("finish", function() {
|
|
2342
2342
|
const bytes2 = new Uint8Array(Buffer.concat(this.buffers));
|
|
2343
|
-
|
|
2343
|
+
resolve8(bytes2);
|
|
2344
2344
|
});
|
|
2345
2345
|
});
|
|
2346
2346
|
};
|
|
@@ -2528,21 +2528,21 @@ var require_dist_cjs15 = __commonJS({
|
|
|
2528
2528
|
let sendBody = true;
|
|
2529
2529
|
if (!externalAgent && expect === "100-continue") {
|
|
2530
2530
|
sendBody = await Promise.race([
|
|
2531
|
-
new Promise((
|
|
2532
|
-
timeoutId = Number(timing.setTimeout(() =>
|
|
2531
|
+
new Promise((resolve8) => {
|
|
2532
|
+
timeoutId = Number(timing.setTimeout(() => resolve8(true), Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
|
|
2533
2533
|
}),
|
|
2534
|
-
new Promise((
|
|
2534
|
+
new Promise((resolve8) => {
|
|
2535
2535
|
httpRequest.on("continue", () => {
|
|
2536
2536
|
timing.clearTimeout(timeoutId);
|
|
2537
|
-
|
|
2537
|
+
resolve8(true);
|
|
2538
2538
|
});
|
|
2539
2539
|
httpRequest.on("response", () => {
|
|
2540
2540
|
timing.clearTimeout(timeoutId);
|
|
2541
|
-
|
|
2541
|
+
resolve8(false);
|
|
2542
2542
|
});
|
|
2543
2543
|
httpRequest.on("error", () => {
|
|
2544
2544
|
timing.clearTimeout(timeoutId);
|
|
2545
|
-
|
|
2545
|
+
resolve8(false);
|
|
2546
2546
|
});
|
|
2547
2547
|
})
|
|
2548
2548
|
]);
|
|
@@ -2614,13 +2614,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2614
2614
|
return socketWarningTimestamp;
|
|
2615
2615
|
}
|
|
2616
2616
|
constructor(options) {
|
|
2617
|
-
this.configProvider = new Promise((
|
|
2617
|
+
this.configProvider = new Promise((resolve8, reject2) => {
|
|
2618
2618
|
if (typeof options === "function") {
|
|
2619
2619
|
options().then((_options) => {
|
|
2620
|
-
|
|
2620
|
+
resolve8(this.resolveDefaultConfig(_options));
|
|
2621
2621
|
}).catch(reject2);
|
|
2622
2622
|
} else {
|
|
2623
|
-
|
|
2623
|
+
resolve8(this.resolveDefaultConfig(options));
|
|
2624
2624
|
}
|
|
2625
2625
|
});
|
|
2626
2626
|
}
|
|
@@ -2663,7 +2663,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2663
2663
|
const config = this.config;
|
|
2664
2664
|
let writeRequestBodyPromise = void 0;
|
|
2665
2665
|
const timeouts = [];
|
|
2666
|
-
const
|
|
2666
|
+
const resolve8 = async (arg) => {
|
|
2667
2667
|
await writeRequestBodyPromise;
|
|
2668
2668
|
timeouts.forEach(timing.clearTimeout);
|
|
2669
2669
|
_resolve(arg);
|
|
@@ -2729,7 +2729,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2729
2729
|
headers: getTransformedHeaders(res.headers),
|
|
2730
2730
|
body: res
|
|
2731
2731
|
});
|
|
2732
|
-
|
|
2732
|
+
resolve8({ response: httpResponse });
|
|
2733
2733
|
});
|
|
2734
2734
|
req.on("error", (err) => {
|
|
2735
2735
|
if (NODEJS_TIMEOUT_ERROR_CODES.includes(err.code)) {
|
|
@@ -2909,13 +2909,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2909
2909
|
return new _NodeHttp2Handler(instanceOrOptions);
|
|
2910
2910
|
}
|
|
2911
2911
|
constructor(options) {
|
|
2912
|
-
this.configProvider = new Promise((
|
|
2912
|
+
this.configProvider = new Promise((resolve8, reject2) => {
|
|
2913
2913
|
if (typeof options === "function") {
|
|
2914
2914
|
options().then((opts) => {
|
|
2915
|
-
|
|
2915
|
+
resolve8(opts || {});
|
|
2916
2916
|
}).catch(reject2);
|
|
2917
2917
|
} else {
|
|
2918
|
-
|
|
2918
|
+
resolve8(options || {});
|
|
2919
2919
|
}
|
|
2920
2920
|
});
|
|
2921
2921
|
}
|
|
@@ -2935,7 +2935,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2935
2935
|
return new Promise((_resolve, _reject) => {
|
|
2936
2936
|
let fulfilled = false;
|
|
2937
2937
|
let writeRequestBodyPromise = void 0;
|
|
2938
|
-
const
|
|
2938
|
+
const resolve8 = async (arg) => {
|
|
2939
2939
|
await writeRequestBodyPromise;
|
|
2940
2940
|
_resolve(arg);
|
|
2941
2941
|
};
|
|
@@ -2991,7 +2991,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2991
2991
|
body: req
|
|
2992
2992
|
});
|
|
2993
2993
|
fulfilled = true;
|
|
2994
|
-
|
|
2994
|
+
resolve8({ response: httpResponse });
|
|
2995
2995
|
if (disableConcurrentStreams) {
|
|
2996
2996
|
session.close();
|
|
2997
2997
|
this.connectionManager.deleteSession(authority, session);
|
|
@@ -3068,7 +3068,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
3068
3068
|
if (isReadableStreamInstance(stream3)) {
|
|
3069
3069
|
return collectReadableStream(stream3);
|
|
3070
3070
|
}
|
|
3071
|
-
return new Promise((
|
|
3071
|
+
return new Promise((resolve8, reject2) => {
|
|
3072
3072
|
const collector = new Collector();
|
|
3073
3073
|
stream3.pipe(collector);
|
|
3074
3074
|
stream3.on("error", (err) => {
|
|
@@ -3078,7 +3078,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
3078
3078
|
collector.on("error", reject2);
|
|
3079
3079
|
collector.on("finish", function() {
|
|
3080
3080
|
const bytes = new Uint8Array(Buffer.concat(this.bufferedBytes));
|
|
3081
|
-
|
|
3081
|
+
resolve8(bytes);
|
|
3082
3082
|
});
|
|
3083
3083
|
});
|
|
3084
3084
|
};
|
|
@@ -3122,7 +3122,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
3122
3122
|
return new Request(url, requestOptions);
|
|
3123
3123
|
}
|
|
3124
3124
|
function requestTimeout(timeoutInMs = 0) {
|
|
3125
|
-
return new Promise((
|
|
3125
|
+
return new Promise((resolve8, reject2) => {
|
|
3126
3126
|
if (timeoutInMs) {
|
|
3127
3127
|
setTimeout(() => {
|
|
3128
3128
|
const timeoutError = new Error(`Request did not complete within ${timeoutInMs} ms`);
|
|
@@ -3240,7 +3240,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
3240
3240
|
requestTimeout(requestTimeoutInMs)
|
|
3241
3241
|
];
|
|
3242
3242
|
if (abortSignal) {
|
|
3243
|
-
raceOfPromises.push(new Promise((
|
|
3243
|
+
raceOfPromises.push(new Promise((resolve8, reject2) => {
|
|
3244
3244
|
const onAbort = () => {
|
|
3245
3245
|
const abortError = new Error("Request aborted");
|
|
3246
3246
|
abortError.name = "AbortError";
|
|
@@ -3304,7 +3304,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
3304
3304
|
return collected;
|
|
3305
3305
|
}
|
|
3306
3306
|
function readToBase64(blob) {
|
|
3307
|
-
return new Promise((
|
|
3307
|
+
return new Promise((resolve8, reject2) => {
|
|
3308
3308
|
const reader = new FileReader();
|
|
3309
3309
|
reader.onloadend = () => {
|
|
3310
3310
|
if (reader.readyState !== 2) {
|
|
@@ -3313,7 +3313,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
3313
3313
|
const result = reader.result ?? "";
|
|
3314
3314
|
const commaIndex = result.indexOf(",");
|
|
3315
3315
|
const dataOffset = commaIndex > -1 ? commaIndex + 1 : result.length;
|
|
3316
|
-
|
|
3316
|
+
resolve8(result.substring(dataOffset));
|
|
3317
3317
|
};
|
|
3318
3318
|
reader.onabort = () => reject2(new Error("Read aborted"));
|
|
3319
3319
|
reader.onerror = () => reject2(reader.error);
|
|
@@ -4981,11 +4981,11 @@ function __metadata(metadataKey, metadataValue) {
|
|
|
4981
4981
|
}
|
|
4982
4982
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
4983
4983
|
function adopt(value) {
|
|
4984
|
-
return value instanceof P ? value : new P(function(
|
|
4985
|
-
|
|
4984
|
+
return value instanceof P ? value : new P(function(resolve8) {
|
|
4985
|
+
resolve8(value);
|
|
4986
4986
|
});
|
|
4987
4987
|
}
|
|
4988
|
-
return new (P || (P = Promise))(function(
|
|
4988
|
+
return new (P || (P = Promise))(function(resolve8, reject2) {
|
|
4989
4989
|
function fulfilled(value) {
|
|
4990
4990
|
try {
|
|
4991
4991
|
step(generator.next(value));
|
|
@@ -5001,7 +5001,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
5001
5001
|
}
|
|
5002
5002
|
}
|
|
5003
5003
|
function step(result) {
|
|
5004
|
-
result.done ?
|
|
5004
|
+
result.done ? resolve8(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
5005
5005
|
}
|
|
5006
5006
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
5007
5007
|
});
|
|
@@ -5192,14 +5192,14 @@ function __asyncValues(o5) {
|
|
|
5192
5192
|
}, i5);
|
|
5193
5193
|
function verb(n5) {
|
|
5194
5194
|
i5[n5] = o5[n5] && function(v5) {
|
|
5195
|
-
return new Promise(function(
|
|
5196
|
-
v5 = o5[n5](v5), settle(
|
|
5195
|
+
return new Promise(function(resolve8, reject2) {
|
|
5196
|
+
v5 = o5[n5](v5), settle(resolve8, reject2, v5.done, v5.value);
|
|
5197
5197
|
});
|
|
5198
5198
|
};
|
|
5199
5199
|
}
|
|
5200
|
-
function settle(
|
|
5200
|
+
function settle(resolve8, reject2, d5, v5) {
|
|
5201
5201
|
Promise.resolve(v5).then(function(v6) {
|
|
5202
|
-
|
|
5202
|
+
resolve8({ value: v6, done: d5 });
|
|
5203
5203
|
}, reject2);
|
|
5204
5204
|
}
|
|
5205
5205
|
}
|
|
@@ -15600,7 +15600,7 @@ var require_dist_cjs37 = __commonJS({
|
|
|
15600
15600
|
this.sockets[url] = (this.sockets[url] ?? []).filter((socket) => ![WebSocket.CLOSING, WebSocket.CLOSED].includes(socket.readyState));
|
|
15601
15601
|
}
|
|
15602
15602
|
waitForReady(socket, connectionTimeout) {
|
|
15603
|
-
return new Promise((
|
|
15603
|
+
return new Promise((resolve8, reject2) => {
|
|
15604
15604
|
const timeout = setTimeout(() => {
|
|
15605
15605
|
this.removeNotUsableSockets(socket.url);
|
|
15606
15606
|
reject2({
|
|
@@ -15612,7 +15612,7 @@ var require_dist_cjs37 = __commonJS({
|
|
|
15612
15612
|
}, connectionTimeout);
|
|
15613
15613
|
socket.onopen = () => {
|
|
15614
15614
|
clearTimeout(timeout);
|
|
15615
|
-
|
|
15615
|
+
resolve8();
|
|
15616
15616
|
};
|
|
15617
15617
|
});
|
|
15618
15618
|
}
|
|
@@ -15665,8 +15665,8 @@ var require_dist_cjs37 = __commonJS({
|
|
|
15665
15665
|
}
|
|
15666
15666
|
return { done: item.done, value: item.value };
|
|
15667
15667
|
}
|
|
15668
|
-
return new Promise((
|
|
15669
|
-
pendingResolve =
|
|
15668
|
+
return new Promise((resolve8, reject2) => {
|
|
15669
|
+
pendingResolve = resolve8;
|
|
15670
15670
|
pendingReject = reject2;
|
|
15671
15671
|
});
|
|
15672
15672
|
}
|
|
@@ -16879,7 +16879,7 @@ var require_dist_cjs46 = __commonJS({
|
|
|
16879
16879
|
this.refillTokenBucket();
|
|
16880
16880
|
if (amount > this.currentCapacity) {
|
|
16881
16881
|
const delay = (amount - this.currentCapacity) / this.fillRate * 1e3;
|
|
16882
|
-
await new Promise((
|
|
16882
|
+
await new Promise((resolve8) => _DefaultRateLimiter.setTimeoutFn(resolve8, delay));
|
|
16883
16883
|
}
|
|
16884
16884
|
this.currentCapacity = this.currentCapacity - amount;
|
|
16885
16885
|
}
|
|
@@ -17214,7 +17214,7 @@ var require_dist_cjs47 = __commonJS({
|
|
|
17214
17214
|
const delayFromResponse = getDelayFromRetryAfterHeader(err.$response);
|
|
17215
17215
|
const delay = Math.max(delayFromResponse || 0, delayFromDecider);
|
|
17216
17216
|
totalDelay += delay;
|
|
17217
|
-
await new Promise((
|
|
17217
|
+
await new Promise((resolve8) => setTimeout(resolve8, delay));
|
|
17218
17218
|
continue;
|
|
17219
17219
|
}
|
|
17220
17220
|
if (!err.$metadata) {
|
|
@@ -17372,7 +17372,7 @@ var require_dist_cjs47 = __commonJS({
|
|
|
17372
17372
|
attempts = retryToken.getRetryCount();
|
|
17373
17373
|
const delay = retryToken.getRetryDelay();
|
|
17374
17374
|
totalRetryDelay += delay;
|
|
17375
|
-
await new Promise((
|
|
17375
|
+
await new Promise((resolve8) => setTimeout(resolve8, delay));
|
|
17376
17376
|
}
|
|
17377
17377
|
}
|
|
17378
17378
|
} else {
|
|
@@ -17524,7 +17524,7 @@ var require_package2 = __commonJS({
|
|
|
17524
17524
|
module2.exports = {
|
|
17525
17525
|
name: "@aws-sdk/client-bedrock-runtime",
|
|
17526
17526
|
description: "AWS SDK for JavaScript Bedrock Runtime Client for Node.js, Browser and React Native",
|
|
17527
|
-
version: "3.
|
|
17527
|
+
version: "3.995.0",
|
|
17528
17528
|
scripts: {
|
|
17529
17529
|
build: "concurrently 'yarn:build:types' 'yarn:build:es' && yarn build:cjs",
|
|
17530
17530
|
"build:cjs": "node ../../scripts/compilation/inline client-bedrock-runtime",
|
|
@@ -17554,11 +17554,11 @@ var require_package2 = __commonJS({
|
|
|
17554
17554
|
"@aws-sdk/middleware-user-agent": "^3.972.11",
|
|
17555
17555
|
"@aws-sdk/middleware-websocket": "^3.972.6",
|
|
17556
17556
|
"@aws-sdk/region-config-resolver": "^3.972.3",
|
|
17557
|
-
"@aws-sdk/token-providers": "3.
|
|
17557
|
+
"@aws-sdk/token-providers": "3.995.0",
|
|
17558
17558
|
"@aws-sdk/types": "^3.973.1",
|
|
17559
|
-
"@aws-sdk/util-endpoints": "3.
|
|
17559
|
+
"@aws-sdk/util-endpoints": "3.995.0",
|
|
17560
17560
|
"@aws-sdk/util-user-agent-browser": "^3.972.3",
|
|
17561
|
-
"@aws-sdk/util-user-agent-node": "^3.972.
|
|
17561
|
+
"@aws-sdk/util-user-agent-node": "^3.972.10",
|
|
17562
17562
|
"@smithy/config-resolver": "^4.4.6",
|
|
17563
17563
|
"@smithy/core": "^3.23.2",
|
|
17564
17564
|
"@smithy/eventstream-serde-browser": "^4.2.8",
|
|
@@ -17687,7 +17687,7 @@ var require_dist_cjs49 = __commonJS({
|
|
|
17687
17687
|
var nodeConfigProvider = require_dist_cjs43();
|
|
17688
17688
|
var urlParser = require_dist_cjs22();
|
|
17689
17689
|
function httpRequest(options) {
|
|
17690
|
-
return new Promise((
|
|
17690
|
+
return new Promise((resolve8, reject2) => {
|
|
17691
17691
|
const req = http.request({
|
|
17692
17692
|
method: "GET",
|
|
17693
17693
|
...options,
|
|
@@ -17712,7 +17712,7 @@ var require_dist_cjs49 = __commonJS({
|
|
|
17712
17712
|
chunks.push(chunk);
|
|
17713
17713
|
});
|
|
17714
17714
|
res.on("end", () => {
|
|
17715
|
-
|
|
17715
|
+
resolve8(buffer.Buffer.concat(chunks));
|
|
17716
17716
|
req.destroy();
|
|
17717
17717
|
});
|
|
17718
17718
|
});
|
|
@@ -18132,7 +18132,7 @@ var require_retry_wrapper = __commonJS({
|
|
|
18132
18132
|
try {
|
|
18133
18133
|
return await toRetry();
|
|
18134
18134
|
} catch (e5) {
|
|
18135
|
-
await new Promise((
|
|
18135
|
+
await new Promise((resolve8) => setTimeout(resolve8, delayMs));
|
|
18136
18136
|
}
|
|
18137
18137
|
}
|
|
18138
18138
|
return await toRetry();
|
|
@@ -18440,6 +18440,15 @@ var require_dist_cjs51 = __commonJS({
|
|
|
18440
18440
|
var os4 = require("os");
|
|
18441
18441
|
var process2 = require("process");
|
|
18442
18442
|
var middlewareUserAgent = require_dist_cjs29();
|
|
18443
|
+
var getRuntimeUserAgentPair = () => {
|
|
18444
|
+
const runtimesToCheck = ["deno", "bun", "llrt"];
|
|
18445
|
+
for (const runtime of runtimesToCheck) {
|
|
18446
|
+
if (process2.versions[runtime]) {
|
|
18447
|
+
return [`md/${runtime}`, process2.versions[runtime]];
|
|
18448
|
+
}
|
|
18449
|
+
}
|
|
18450
|
+
return ["md/nodejs", process2.versions.node];
|
|
18451
|
+
};
|
|
18443
18452
|
var crtAvailability = {
|
|
18444
18453
|
isCrtAvailable: false
|
|
18445
18454
|
};
|
|
@@ -18450,13 +18459,14 @@ var require_dist_cjs51 = __commonJS({
|
|
|
18450
18459
|
return null;
|
|
18451
18460
|
};
|
|
18452
18461
|
var createDefaultUserAgentProvider5 = ({ serviceId, clientVersion }) => {
|
|
18462
|
+
const runtimeUserAgentPair = getRuntimeUserAgentPair();
|
|
18453
18463
|
return async (config) => {
|
|
18454
18464
|
const sections = [
|
|
18455
18465
|
["aws-sdk-js", clientVersion],
|
|
18456
18466
|
["ua", "2.1"],
|
|
18457
18467
|
[`os/${os4.platform()}`, os4.release()],
|
|
18458
18468
|
["lang/js"],
|
|
18459
|
-
|
|
18469
|
+
runtimeUserAgentPair
|
|
18460
18470
|
];
|
|
18461
18471
|
const crtAvailable = isCrtAvailable();
|
|
18462
18472
|
if (crtAvailable) {
|
|
@@ -24019,8 +24029,8 @@ var require_dist_cjs66 = __commonJS({
|
|
|
24019
24029
|
systemClockOffsetProvider: this.systemClockOffsetProvider
|
|
24020
24030
|
});
|
|
24021
24031
|
let resolvePipeline;
|
|
24022
|
-
const pipelineError = new Promise((
|
|
24023
|
-
resolvePipeline = () =>
|
|
24032
|
+
const pipelineError = new Promise((resolve8, reject2) => {
|
|
24033
|
+
resolvePipeline = () => resolve8(void 0);
|
|
24024
24034
|
node_stream.pipeline(payloadStream, signingStream, request.body, (err) => {
|
|
24025
24035
|
if (err) {
|
|
24026
24036
|
reject2(new Error(`Pipeline error in @aws-sdk/eventstream-handler-node: ${err.message}`, { cause: err }));
|
|
@@ -24126,7 +24136,7 @@ var init_package2 = __esm({
|
|
|
24126
24136
|
"node_modules/@aws-sdk/token-providers/node_modules/@aws-sdk/nested-clients/package.json"() {
|
|
24127
24137
|
package_default2 = {
|
|
24128
24138
|
name: "@aws-sdk/nested-clients",
|
|
24129
|
-
version: "3.
|
|
24139
|
+
version: "3.995.0",
|
|
24130
24140
|
description: "Nested clients for AWS SDK packages.",
|
|
24131
24141
|
main: "./dist-cjs/index.js",
|
|
24132
24142
|
module: "./dist-es/index.js",
|
|
@@ -24162,9 +24172,9 @@ var init_package2 = __esm({
|
|
|
24162
24172
|
"@aws-sdk/middleware-user-agent": "^3.972.11",
|
|
24163
24173
|
"@aws-sdk/region-config-resolver": "^3.972.3",
|
|
24164
24174
|
"@aws-sdk/types": "^3.973.1",
|
|
24165
|
-
"@aws-sdk/util-endpoints": "3.
|
|
24175
|
+
"@aws-sdk/util-endpoints": "3.995.0",
|
|
24166
24176
|
"@aws-sdk/util-user-agent-browser": "^3.972.3",
|
|
24167
|
-
"@aws-sdk/util-user-agent-node": "^3.972.
|
|
24177
|
+
"@aws-sdk/util-user-agent-node": "^3.972.10",
|
|
24168
24178
|
"@smithy/config-resolver": "^4.4.6",
|
|
24169
24179
|
"@smithy/core": "^3.23.2",
|
|
24170
24180
|
"@smithy/fetch-http-handler": "^5.3.9",
|
|
@@ -25574,7 +25584,7 @@ var require_dist_cjs69 = __commonJS({
|
|
|
25574
25584
|
streamEnded = true;
|
|
25575
25585
|
});
|
|
25576
25586
|
while (!generationEnded) {
|
|
25577
|
-
const value = await new Promise((
|
|
25587
|
+
const value = await new Promise((resolve8) => setTimeout(() => resolve8(records.shift()), 0));
|
|
25578
25588
|
if (value) {
|
|
25579
25589
|
yield value;
|
|
25580
25590
|
}
|
|
@@ -31837,7 +31847,7 @@ async function waitForFileLock(lockPath, binaryPath) {
|
|
|
31837
31847
|
}
|
|
31838
31848
|
} catch {
|
|
31839
31849
|
}
|
|
31840
|
-
await new Promise((
|
|
31850
|
+
await new Promise((resolve8) => setTimeout(resolve8, LOCK_POLL_INTERVAL_MS));
|
|
31841
31851
|
}
|
|
31842
31852
|
if (process.env.DEBUG === "1" || process.env.VERBOSE === "1") {
|
|
31843
31853
|
console.log(`Timeout waiting for file lock`);
|
|
@@ -33186,7 +33196,7 @@ Cwd: ${cwd}`;
|
|
|
33186
33196
|
}
|
|
33187
33197
|
}
|
|
33188
33198
|
function extractWithStdin(binaryPath, cliArgs, content, options, cwd) {
|
|
33189
|
-
return new Promise((
|
|
33199
|
+
return new Promise((resolve8, reject2) => {
|
|
33190
33200
|
const childProcess = (0, import_child_process4.spawn)(binaryPath, ["extract", ...cliArgs], {
|
|
33191
33201
|
stdio: ["pipe", "pipe", "pipe"],
|
|
33192
33202
|
cwd
|
|
@@ -33209,7 +33219,7 @@ function extractWithStdin(binaryPath, cliArgs, content, options, cwd) {
|
|
|
33209
33219
|
}
|
|
33210
33220
|
try {
|
|
33211
33221
|
const result = processExtractOutput(stdout, options);
|
|
33212
|
-
|
|
33222
|
+
resolve8(result);
|
|
33213
33223
|
} catch (error2) {
|
|
33214
33224
|
reject2(error2);
|
|
33215
33225
|
}
|
|
@@ -33318,6 +33328,7 @@ async function delegate({
|
|
|
33318
33328
|
model = null,
|
|
33319
33329
|
enableBash = false,
|
|
33320
33330
|
bashConfig = null,
|
|
33331
|
+
allowEdit = false,
|
|
33321
33332
|
architectureFileName = null,
|
|
33322
33333
|
promptType = "code-researcher",
|
|
33323
33334
|
allowedTools = null,
|
|
@@ -33397,6 +33408,8 @@ async function delegate({
|
|
|
33397
33408
|
// Inherit from parent
|
|
33398
33409
|
bashConfig,
|
|
33399
33410
|
// Inherit from parent
|
|
33411
|
+
allowEdit,
|
|
33412
|
+
// Inherit from parent
|
|
33400
33413
|
architectureFileName,
|
|
33401
33414
|
allowedTools,
|
|
33402
33415
|
disableTools,
|
|
@@ -33582,7 +33595,7 @@ var init_delegate = __esm({
|
|
|
33582
33595
|
if (debug) {
|
|
33583
33596
|
console.error(`[DelegationManager] Slot unavailable (${this.globalActive}/${this.maxConcurrent}), queuing... (queue size: ${this.waitQueue.length}, timeout: ${effectiveTimeout}ms)`);
|
|
33584
33597
|
}
|
|
33585
|
-
return new Promise((
|
|
33598
|
+
return new Promise((resolve8, reject2) => {
|
|
33586
33599
|
const entry = {
|
|
33587
33600
|
resolve: null,
|
|
33588
33601
|
// Will be wrapped below
|
|
@@ -33598,7 +33611,7 @@ var init_delegate = __esm({
|
|
|
33598
33611
|
if (settled) return;
|
|
33599
33612
|
settled = true;
|
|
33600
33613
|
if (entry.timeoutId) clearTimeout(entry.timeoutId);
|
|
33601
|
-
|
|
33614
|
+
resolve8(value);
|
|
33602
33615
|
};
|
|
33603
33616
|
entry.reject = (error2) => {
|
|
33604
33617
|
if (settled) return;
|
|
@@ -33648,7 +33661,7 @@ var init_delegate = __esm({
|
|
|
33648
33661
|
while (this.waitQueue.length > 0 && this.globalActive < this.maxConcurrent) {
|
|
33649
33662
|
const next = this.waitQueue.shift();
|
|
33650
33663
|
if (!next) break;
|
|
33651
|
-
const { resolve:
|
|
33664
|
+
const { resolve: resolve8, reject: reject2, parentSessionId, queuedAt } = next;
|
|
33652
33665
|
if (parentSessionId) {
|
|
33653
33666
|
const sessionData = this.sessionDelegations.get(parentSessionId);
|
|
33654
33667
|
const sessionCount = sessionData?.count || 0;
|
|
@@ -33665,12 +33678,12 @@ var init_delegate = __esm({
|
|
|
33665
33678
|
const waitTime = Date.now() - queuedAt;
|
|
33666
33679
|
console.error(`[DelegationManager] Granted slot from queue (waited ${waitTime}ms). Active: ${this.globalActive}/${this.maxConcurrent}`);
|
|
33667
33680
|
}
|
|
33668
|
-
toResolve.push(
|
|
33681
|
+
toResolve.push(resolve8);
|
|
33669
33682
|
}
|
|
33670
33683
|
if (toResolve.length > 0 || toReject.length > 0) {
|
|
33671
33684
|
setImmediate(() => {
|
|
33672
|
-
for (const
|
|
33673
|
-
|
|
33685
|
+
for (const resolve8 of toResolve) {
|
|
33686
|
+
resolve8(true);
|
|
33674
33687
|
}
|
|
33675
33688
|
for (const { reject: reject2, error: error2 } of toReject) {
|
|
33676
33689
|
reject2(error2);
|
|
@@ -38305,6 +38318,400 @@ var init_zod = __esm({
|
|
|
38305
38318
|
}
|
|
38306
38319
|
});
|
|
38307
38320
|
|
|
38321
|
+
// src/tools/fuzzyMatch.js
|
|
38322
|
+
function findFuzzyMatch(content, searchString) {
|
|
38323
|
+
if (!searchString || searchString.trim().length === 0) {
|
|
38324
|
+
return null;
|
|
38325
|
+
}
|
|
38326
|
+
const normalizedContent = content.replace(/\r\n/g, "\n");
|
|
38327
|
+
const normalizedSearch = searchString.replace(/\r\n/g, "\n");
|
|
38328
|
+
const contentLines = normalizedContent.split("\n");
|
|
38329
|
+
const searchLines = normalizedSearch.split("\n");
|
|
38330
|
+
const trimmed = lineTrimmedMatch(contentLines, searchLines);
|
|
38331
|
+
if (trimmed) return { ...trimmed, strategy: "line-trimmed" };
|
|
38332
|
+
const normalized = whitespaceNormalizedMatch(normalizedContent, normalizedSearch);
|
|
38333
|
+
if (normalized) return { ...normalized, strategy: "whitespace-normalized" };
|
|
38334
|
+
const indentFlex = indentFlexibleMatch(contentLines, searchLines);
|
|
38335
|
+
if (indentFlex) return { ...indentFlex, strategy: "indent-flexible" };
|
|
38336
|
+
return null;
|
|
38337
|
+
}
|
|
38338
|
+
function lineTrimmedMatch(contentLines, searchLines) {
|
|
38339
|
+
if (searchLines.length === 0) return null;
|
|
38340
|
+
const trimmedSearchLines = searchLines.map((line) => line.trim());
|
|
38341
|
+
if (trimmedSearchLines.every((line) => line === "")) return null;
|
|
38342
|
+
const windowSize = searchLines.length;
|
|
38343
|
+
const matches = [];
|
|
38344
|
+
for (let i5 = 0; i5 <= contentLines.length - windowSize; i5++) {
|
|
38345
|
+
let allMatch = true;
|
|
38346
|
+
for (let j5 = 0; j5 < windowSize; j5++) {
|
|
38347
|
+
if (contentLines[i5 + j5].trim() !== trimmedSearchLines[j5]) {
|
|
38348
|
+
allMatch = false;
|
|
38349
|
+
break;
|
|
38350
|
+
}
|
|
38351
|
+
}
|
|
38352
|
+
if (allMatch) {
|
|
38353
|
+
const matchedText = contentLines.slice(i5, i5 + windowSize).join("\n");
|
|
38354
|
+
matches.push(matchedText);
|
|
38355
|
+
}
|
|
38356
|
+
}
|
|
38357
|
+
if (matches.length === 0) return null;
|
|
38358
|
+
return {
|
|
38359
|
+
matchedText: matches[0],
|
|
38360
|
+
count: matches.length
|
|
38361
|
+
};
|
|
38362
|
+
}
|
|
38363
|
+
function whitespaceNormalizedMatch(content, search2) {
|
|
38364
|
+
if (!search2 || search2.trim().length === 0) return null;
|
|
38365
|
+
const { normalized: normContent, indexMap: contentMap } = buildNormalizedMap(content);
|
|
38366
|
+
const { normalized: normSearch } = buildNormalizedMap(search2);
|
|
38367
|
+
if (normSearch.length === 0) return null;
|
|
38368
|
+
const matches = [];
|
|
38369
|
+
let searchStart = 0;
|
|
38370
|
+
while (searchStart <= normContent.length - normSearch.length) {
|
|
38371
|
+
const idx = normContent.indexOf(normSearch, searchStart);
|
|
38372
|
+
if (idx === -1) break;
|
|
38373
|
+
const originalStart = contentMap[idx];
|
|
38374
|
+
const originalEnd = contentMap[idx + normSearch.length - 1];
|
|
38375
|
+
let actualEnd = originalEnd + 1;
|
|
38376
|
+
while (actualEnd < content.length && /[ \t]/.test(content[actualEnd]) && (actualEnd === originalEnd + 1 || /[ \t]/.test(content[actualEnd - 1]))) {
|
|
38377
|
+
if (contentMap.indexOf(actualEnd) > idx + normSearch.length - 1 || contentMap.indexOf(actualEnd) === -1) {
|
|
38378
|
+
break;
|
|
38379
|
+
}
|
|
38380
|
+
actualEnd++;
|
|
38381
|
+
}
|
|
38382
|
+
const matchedText = content.substring(originalStart, actualEnd);
|
|
38383
|
+
matches.push(matchedText);
|
|
38384
|
+
searchStart = idx + 1;
|
|
38385
|
+
}
|
|
38386
|
+
if (matches.length === 0) return null;
|
|
38387
|
+
return {
|
|
38388
|
+
matchedText: matches[0],
|
|
38389
|
+
count: matches.length
|
|
38390
|
+
};
|
|
38391
|
+
}
|
|
38392
|
+
function buildNormalizedMap(str) {
|
|
38393
|
+
const normalized = [];
|
|
38394
|
+
const indexMap = [];
|
|
38395
|
+
let i5 = 0;
|
|
38396
|
+
while (i5 < str.length) {
|
|
38397
|
+
const ch = str[i5];
|
|
38398
|
+
if (ch === " " || ch === " ") {
|
|
38399
|
+
normalized.push(" ");
|
|
38400
|
+
indexMap.push(i5);
|
|
38401
|
+
while (i5 < str.length && (str[i5] === " " || str[i5] === " ")) {
|
|
38402
|
+
i5++;
|
|
38403
|
+
}
|
|
38404
|
+
} else {
|
|
38405
|
+
normalized.push(ch);
|
|
38406
|
+
indexMap.push(i5);
|
|
38407
|
+
i5++;
|
|
38408
|
+
}
|
|
38409
|
+
}
|
|
38410
|
+
return {
|
|
38411
|
+
normalized: normalized.join(""),
|
|
38412
|
+
indexMap
|
|
38413
|
+
};
|
|
38414
|
+
}
|
|
38415
|
+
function indentFlexibleMatch(contentLines, searchLines) {
|
|
38416
|
+
if (searchLines.length === 0) return null;
|
|
38417
|
+
if (searchLines.every((line) => line.trim() === "")) return null;
|
|
38418
|
+
const searchMinIndent = getMinIndent(searchLines);
|
|
38419
|
+
const strippedSearch = searchLines.map((line) => stripIndent(line, searchMinIndent));
|
|
38420
|
+
const windowSize = searchLines.length;
|
|
38421
|
+
const matches = [];
|
|
38422
|
+
for (let i5 = 0; i5 <= contentLines.length - windowSize; i5++) {
|
|
38423
|
+
const windowLines = contentLines.slice(i5, i5 + windowSize);
|
|
38424
|
+
const windowMinIndent = getMinIndent(windowLines);
|
|
38425
|
+
const strippedWindow = windowLines.map((line) => stripIndent(line, windowMinIndent));
|
|
38426
|
+
let allMatch = true;
|
|
38427
|
+
for (let j5 = 0; j5 < windowSize; j5++) {
|
|
38428
|
+
if (strippedWindow[j5] !== strippedSearch[j5]) {
|
|
38429
|
+
allMatch = false;
|
|
38430
|
+
break;
|
|
38431
|
+
}
|
|
38432
|
+
}
|
|
38433
|
+
if (allMatch) {
|
|
38434
|
+
const matchedText = windowLines.join("\n");
|
|
38435
|
+
matches.push(matchedText);
|
|
38436
|
+
}
|
|
38437
|
+
}
|
|
38438
|
+
if (matches.length === 0) return null;
|
|
38439
|
+
return {
|
|
38440
|
+
matchedText: matches[0],
|
|
38441
|
+
count: matches.length
|
|
38442
|
+
};
|
|
38443
|
+
}
|
|
38444
|
+
function getMinIndent(lines) {
|
|
38445
|
+
let min = Infinity;
|
|
38446
|
+
for (const line of lines) {
|
|
38447
|
+
if (line.trim() === "") continue;
|
|
38448
|
+
const match2 = line.match(/^([ \t]*)/);
|
|
38449
|
+
if (match2) {
|
|
38450
|
+
min = Math.min(min, match2[1].length);
|
|
38451
|
+
}
|
|
38452
|
+
}
|
|
38453
|
+
return min === Infinity ? 0 : min;
|
|
38454
|
+
}
|
|
38455
|
+
function stripIndent(line, amount) {
|
|
38456
|
+
if (line.trim() === "") return "";
|
|
38457
|
+
if (amount <= 0) return line;
|
|
38458
|
+
return line.substring(Math.min(amount, line.length));
|
|
38459
|
+
}
|
|
38460
|
+
var init_fuzzyMatch = __esm({
|
|
38461
|
+
"src/tools/fuzzyMatch.js"() {
|
|
38462
|
+
"use strict";
|
|
38463
|
+
}
|
|
38464
|
+
});
|
|
38465
|
+
|
|
38466
|
+
// src/tools/symbolEdit.js
|
|
38467
|
+
async function findSymbol(filePath, symbolName, cwd) {
|
|
38468
|
+
try {
|
|
38469
|
+
const result = await extract({
|
|
38470
|
+
files: [`${filePath}#${symbolName}`],
|
|
38471
|
+
format: "json",
|
|
38472
|
+
json: true,
|
|
38473
|
+
cwd
|
|
38474
|
+
});
|
|
38475
|
+
if (!result || !result.results || result.results.length === 0) {
|
|
38476
|
+
return null;
|
|
38477
|
+
}
|
|
38478
|
+
const match2 = result.results[0];
|
|
38479
|
+
return {
|
|
38480
|
+
startLine: match2.lines[0],
|
|
38481
|
+
// 1-indexed
|
|
38482
|
+
endLine: match2.lines[1],
|
|
38483
|
+
// 1-indexed
|
|
38484
|
+
code: match2.code,
|
|
38485
|
+
nodeType: match2.node_type,
|
|
38486
|
+
file: match2.file
|
|
38487
|
+
};
|
|
38488
|
+
} catch (error2) {
|
|
38489
|
+
if (process.env.DEBUG === "1") {
|
|
38490
|
+
console.error(`[SymbolEdit] findSymbol error for "${symbolName}" in ${filePath}: ${error2.message}`);
|
|
38491
|
+
}
|
|
38492
|
+
return null;
|
|
38493
|
+
}
|
|
38494
|
+
}
|
|
38495
|
+
async function findAllSymbols(filePath, symbolName, cwd) {
|
|
38496
|
+
try {
|
|
38497
|
+
const result = await extract({
|
|
38498
|
+
files: [`${filePath}#${symbolName}`],
|
|
38499
|
+
format: "json",
|
|
38500
|
+
json: true,
|
|
38501
|
+
cwd
|
|
38502
|
+
});
|
|
38503
|
+
if (!result || !result.results || result.results.length === 0) {
|
|
38504
|
+
return [];
|
|
38505
|
+
}
|
|
38506
|
+
return result.results.map((match2) => ({
|
|
38507
|
+
startLine: match2.lines[0],
|
|
38508
|
+
endLine: match2.lines[1],
|
|
38509
|
+
code: match2.code,
|
|
38510
|
+
nodeType: match2.node_type,
|
|
38511
|
+
file: match2.file,
|
|
38512
|
+
qualifiedName: match2.symbol_signature || symbolName
|
|
38513
|
+
}));
|
|
38514
|
+
} catch (error2) {
|
|
38515
|
+
if (process.env.DEBUG === "1") {
|
|
38516
|
+
console.error(`[SymbolEdit] findAllSymbols error for "${symbolName}" in ${filePath}: ${error2.message}`);
|
|
38517
|
+
}
|
|
38518
|
+
return [];
|
|
38519
|
+
}
|
|
38520
|
+
}
|
|
38521
|
+
function detectBaseIndent(code) {
|
|
38522
|
+
const lines = code.split("\n");
|
|
38523
|
+
for (const line of lines) {
|
|
38524
|
+
if (line.trim().length > 0) {
|
|
38525
|
+
const match2 = line.match(/^(\s*)/);
|
|
38526
|
+
return match2 ? match2[1] : "";
|
|
38527
|
+
}
|
|
38528
|
+
}
|
|
38529
|
+
return "";
|
|
38530
|
+
}
|
|
38531
|
+
function reindent(newContent, targetIndent) {
|
|
38532
|
+
const lines = newContent.split("\n");
|
|
38533
|
+
const sourceIndent = detectBaseIndent(newContent);
|
|
38534
|
+
return lines.map((line) => {
|
|
38535
|
+
if (line.trim().length === 0) {
|
|
38536
|
+
return "";
|
|
38537
|
+
}
|
|
38538
|
+
if (line.startsWith(sourceIndent)) {
|
|
38539
|
+
return targetIndent + line.slice(sourceIndent.length);
|
|
38540
|
+
}
|
|
38541
|
+
return line;
|
|
38542
|
+
}).join("\n");
|
|
38543
|
+
}
|
|
38544
|
+
var init_symbolEdit = __esm({
|
|
38545
|
+
"src/tools/symbolEdit.js"() {
|
|
38546
|
+
"use strict";
|
|
38547
|
+
init_extract();
|
|
38548
|
+
}
|
|
38549
|
+
});
|
|
38550
|
+
|
|
38551
|
+
// src/tools/hashline.js
|
|
38552
|
+
function computeLineHash(line) {
|
|
38553
|
+
const stripped = (line || "").replace(/\s+/g, "");
|
|
38554
|
+
let h5 = 5381;
|
|
38555
|
+
for (let i5 = 0; i5 < stripped.length; i5++) {
|
|
38556
|
+
h5 = (h5 << 5) + h5 + stripped.charCodeAt(i5) & 4294967295;
|
|
38557
|
+
}
|
|
38558
|
+
return ((h5 >>> 0) % 256).toString(16).padStart(2, "0");
|
|
38559
|
+
}
|
|
38560
|
+
function parseLineRef(ref2) {
|
|
38561
|
+
if (ref2 === void 0 || ref2 === null) return null;
|
|
38562
|
+
const str = String(ref2).trim();
|
|
38563
|
+
if (!str) return null;
|
|
38564
|
+
const hashMatch = str.match(/^(\d+):([0-9a-fA-F]{2})$/);
|
|
38565
|
+
if (hashMatch) {
|
|
38566
|
+
const line = parseInt(hashMatch[1], 10);
|
|
38567
|
+
if (line < 1 || !isFinite(line)) return null;
|
|
38568
|
+
return { line, hash: hashMatch[2].toLowerCase() };
|
|
38569
|
+
}
|
|
38570
|
+
const lineMatch = str.match(/^(\d+)$/);
|
|
38571
|
+
if (lineMatch) {
|
|
38572
|
+
const line = parseInt(lineMatch[1], 10);
|
|
38573
|
+
if (line < 1 || !isFinite(line)) return null;
|
|
38574
|
+
return { line, hash: null };
|
|
38575
|
+
}
|
|
38576
|
+
return null;
|
|
38577
|
+
}
|
|
38578
|
+
function validateLineHash(lineNum, hash, fileLines) {
|
|
38579
|
+
const idx = lineNum - 1;
|
|
38580
|
+
if (idx < 0 || idx >= fileLines.length) {
|
|
38581
|
+
return { valid: false, actualHash: "", actualContent: "" };
|
|
38582
|
+
}
|
|
38583
|
+
const actualContent = fileLines[idx];
|
|
38584
|
+
const actualHash = computeLineHash(actualContent);
|
|
38585
|
+
return {
|
|
38586
|
+
valid: actualHash === hash.toLowerCase(),
|
|
38587
|
+
actualHash,
|
|
38588
|
+
actualContent
|
|
38589
|
+
};
|
|
38590
|
+
}
|
|
38591
|
+
function annotateOutputWithHashes(output) {
|
|
38592
|
+
if (!output || typeof output !== "string") return output;
|
|
38593
|
+
return output.split("\n").map((line) => {
|
|
38594
|
+
const cleanLine = line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
38595
|
+
const match2 = cleanLine.match(/^(\s*)(\d+)(\s*\|)(.*)$/);
|
|
38596
|
+
if (!match2) return line;
|
|
38597
|
+
const [, prefix, lineNum, pipeSection, content] = match2;
|
|
38598
|
+
const hash = computeLineHash(content);
|
|
38599
|
+
const cr = line.endsWith("\r") ? "\r" : "";
|
|
38600
|
+
return `${prefix}${lineNum}:${hash}${pipeSection}${content}${cr}`;
|
|
38601
|
+
}).join("\n");
|
|
38602
|
+
}
|
|
38603
|
+
function stripHashlinePrefixes(text) {
|
|
38604
|
+
if (!text || typeof text !== "string") return { cleaned: text || "", stripped: false };
|
|
38605
|
+
const lines = text.split("\n");
|
|
38606
|
+
if (lines.length === 0) return { cleaned: "", stripped: false };
|
|
38607
|
+
const nonEmptyLines = lines.filter((l5) => l5.trim().length > 0);
|
|
38608
|
+
if (nonEmptyLines.length === 0) return { cleaned: text, stripped: false };
|
|
38609
|
+
const prefixPattern = /^\s*\d+(?::[0-9a-fA-F]{2})?\s*\|\s?/;
|
|
38610
|
+
const matchCount = nonEmptyLines.filter((l5) => prefixPattern.test(l5)).length;
|
|
38611
|
+
if (matchCount / nonEmptyLines.length <= 0.5) {
|
|
38612
|
+
return { cleaned: text, stripped: false };
|
|
38613
|
+
}
|
|
38614
|
+
const cleaned = lines.map((line) => {
|
|
38615
|
+
if (line.trim().length === 0) return line;
|
|
38616
|
+
return line.replace(prefixPattern, "");
|
|
38617
|
+
}).join("\n");
|
|
38618
|
+
return { cleaned, stripped: true };
|
|
38619
|
+
}
|
|
38620
|
+
var init_hashline = __esm({
|
|
38621
|
+
"src/tools/hashline.js"() {
|
|
38622
|
+
"use strict";
|
|
38623
|
+
}
|
|
38624
|
+
});
|
|
38625
|
+
|
|
38626
|
+
// src/tools/lineEditHeuristics.js
|
|
38627
|
+
function stripEchoedBoundaries(newStr, fileLines, startLine, endLine, position) {
|
|
38628
|
+
const modifications = [];
|
|
38629
|
+
let lines = newStr.split("\n");
|
|
38630
|
+
if (lines.length === 0) return { result: newStr, modifications };
|
|
38631
|
+
if (position === "after") {
|
|
38632
|
+
const anchorIdx = startLine - 1;
|
|
38633
|
+
if (anchorIdx >= 0 && anchorIdx < fileLines.length) {
|
|
38634
|
+
const anchorTrimmed = fileLines[anchorIdx].trim();
|
|
38635
|
+
if (anchorTrimmed.length > 0 && lines.length > 0 && lines[0].trim() === anchorTrimmed) {
|
|
38636
|
+
lines = lines.slice(1);
|
|
38637
|
+
modifications.push("stripped echoed anchor line (insert-after)");
|
|
38638
|
+
}
|
|
38639
|
+
}
|
|
38640
|
+
} else if (position === "before") {
|
|
38641
|
+
const anchorIdx = startLine - 1;
|
|
38642
|
+
if (anchorIdx >= 0 && anchorIdx < fileLines.length) {
|
|
38643
|
+
const anchorTrimmed = fileLines[anchorIdx].trim();
|
|
38644
|
+
if (anchorTrimmed.length > 0 && lines.length > 0 && lines[lines.length - 1].trim() === anchorTrimmed) {
|
|
38645
|
+
lines = lines.slice(0, -1);
|
|
38646
|
+
modifications.push("stripped echoed anchor line (insert-before)");
|
|
38647
|
+
}
|
|
38648
|
+
}
|
|
38649
|
+
} else {
|
|
38650
|
+
const beforeIdx = startLine - 2;
|
|
38651
|
+
if (beforeIdx >= 0 && beforeIdx < fileLines.length) {
|
|
38652
|
+
const beforeTrimmed = fileLines[beforeIdx].trim();
|
|
38653
|
+
if (beforeTrimmed.length > 0 && lines.length > 0 && lines[0].trim() === beforeTrimmed) {
|
|
38654
|
+
lines = lines.slice(1);
|
|
38655
|
+
modifications.push("stripped echoed line before range");
|
|
38656
|
+
}
|
|
38657
|
+
}
|
|
38658
|
+
const afterIdx = endLine;
|
|
38659
|
+
if (afterIdx >= 0 && afterIdx < fileLines.length) {
|
|
38660
|
+
const afterTrimmed = fileLines[afterIdx].trim();
|
|
38661
|
+
if (afterTrimmed.length > 0 && lines.length > 0 && lines[lines.length - 1].trim() === afterTrimmed) {
|
|
38662
|
+
lines = lines.slice(0, -1);
|
|
38663
|
+
modifications.push("stripped echoed line after range");
|
|
38664
|
+
}
|
|
38665
|
+
}
|
|
38666
|
+
}
|
|
38667
|
+
return { result: lines.join("\n"), modifications };
|
|
38668
|
+
}
|
|
38669
|
+
function restoreIndentation(newStr, originalLines) {
|
|
38670
|
+
const modifications = [];
|
|
38671
|
+
if (!newStr || !originalLines || originalLines.length === 0) {
|
|
38672
|
+
return { result: newStr || "", modifications };
|
|
38673
|
+
}
|
|
38674
|
+
const originalCode = originalLines.join("\n");
|
|
38675
|
+
const targetIndent = detectBaseIndent(originalCode);
|
|
38676
|
+
const newIndent = detectBaseIndent(newStr);
|
|
38677
|
+
if (targetIndent !== newIndent) {
|
|
38678
|
+
const reindented = reindent(newStr, targetIndent);
|
|
38679
|
+
if (reindented !== newStr) {
|
|
38680
|
+
modifications.push(`reindented from "${newIndent}" to "${targetIndent}"`);
|
|
38681
|
+
return { result: reindented, modifications };
|
|
38682
|
+
}
|
|
38683
|
+
}
|
|
38684
|
+
return { result: newStr, modifications };
|
|
38685
|
+
}
|
|
38686
|
+
function cleanNewString(newStr, fileLines, startLine, endLine, position) {
|
|
38687
|
+
const modifications = [];
|
|
38688
|
+
if (!newStr && newStr !== "") return { cleaned: "", modifications };
|
|
38689
|
+
const { cleaned: afterPrefixes, stripped } = stripHashlinePrefixes(newStr);
|
|
38690
|
+
if (stripped) modifications.push("stripped line-number prefixes");
|
|
38691
|
+
const { result: afterEchoes, modifications: echoMods } = stripEchoedBoundaries(
|
|
38692
|
+
afterPrefixes,
|
|
38693
|
+
fileLines,
|
|
38694
|
+
startLine,
|
|
38695
|
+
endLine,
|
|
38696
|
+
position
|
|
38697
|
+
);
|
|
38698
|
+
modifications.push(...echoMods);
|
|
38699
|
+
if (!position) {
|
|
38700
|
+
const originalLines = fileLines.slice(startLine - 1, endLine);
|
|
38701
|
+
const { result: afterIndent, modifications: indentMods } = restoreIndentation(afterEchoes, originalLines);
|
|
38702
|
+
modifications.push(...indentMods);
|
|
38703
|
+
return { cleaned: afterIndent, modifications };
|
|
38704
|
+
}
|
|
38705
|
+
return { cleaned: afterEchoes, modifications };
|
|
38706
|
+
}
|
|
38707
|
+
var init_lineEditHeuristics = __esm({
|
|
38708
|
+
"src/tools/lineEditHeuristics.js"() {
|
|
38709
|
+
"use strict";
|
|
38710
|
+
init_symbolEdit();
|
|
38711
|
+
init_hashline();
|
|
38712
|
+
}
|
|
38713
|
+
});
|
|
38714
|
+
|
|
38308
38715
|
// src/tools/edit.js
|
|
38309
38716
|
function isPathAllowed(filePath, allowedFolders) {
|
|
38310
38717
|
if (!allowedFolders || allowedFolders.length === 0) {
|
|
@@ -38328,6 +38735,174 @@ function parseFileToolOptions(options = {}) {
|
|
|
38328
38735
|
workspaceRoot: options.workspaceRoot || options.cwd || allowedFolders.length > 0 && allowedFolders[0] || process.cwd()
|
|
38329
38736
|
};
|
|
38330
38737
|
}
|
|
38738
|
+
async function handleSymbolEdit({ resolvedPath: resolvedPath2, file_path, symbol: symbol15, new_string, position, debug, cwd, fileTracker }) {
|
|
38739
|
+
if (typeof symbol15 !== "string" || symbol15.trim() === "") {
|
|
38740
|
+
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.';
|
|
38741
|
+
}
|
|
38742
|
+
if (position !== void 0 && position !== null && position !== "before" && position !== "after") {
|
|
38743
|
+
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.';
|
|
38744
|
+
}
|
|
38745
|
+
const allMatches = await findAllSymbols(resolvedPath2, symbol15, cwd || process.cwd());
|
|
38746
|
+
if (allMatches.length === 0) {
|
|
38747
|
+
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.`;
|
|
38748
|
+
}
|
|
38749
|
+
if (allMatches.length > 1) {
|
|
38750
|
+
const suggestions = allMatches.map(
|
|
38751
|
+
(m5) => ` - ${m5.qualifiedName} (${m5.nodeType}, line ${m5.startLine})`
|
|
38752
|
+
).join("\n");
|
|
38753
|
+
return `Error editing ${file_path}: Found ${allMatches.length} symbols named "${symbol15}". Use a qualified name to specify which one:
|
|
38754
|
+
${suggestions}
|
|
38755
|
+
|
|
38756
|
+
Example: <edit><file_path>${file_path}</file_path><symbol>${allMatches[0].qualifiedName}</symbol><new_string>...</new_string></edit>`;
|
|
38757
|
+
}
|
|
38758
|
+
const symbolInfo = allMatches[0];
|
|
38759
|
+
if (fileTracker) {
|
|
38760
|
+
const check = fileTracker.checkSymbolContent(resolvedPath2, symbol15, symbolInfo.code);
|
|
38761
|
+
if (!check.ok && check.reason === "stale") {
|
|
38762
|
+
return `Error editing ${file_path}: Symbol "${symbol15}" has changed since you last read it. Use extract to re-read the current content, then retry.
|
|
38763
|
+
|
|
38764
|
+
Example: <extract><targets>${file_path}#${symbol15}</targets></extract>`;
|
|
38765
|
+
}
|
|
38766
|
+
}
|
|
38767
|
+
const content = await import_fs4.promises.readFile(resolvedPath2, "utf-8");
|
|
38768
|
+
const lines = content.split("\n");
|
|
38769
|
+
if (position) {
|
|
38770
|
+
const refIndent = detectBaseIndent(symbolInfo.code);
|
|
38771
|
+
const reindented = reindent(new_string, refIndent);
|
|
38772
|
+
const newLines = reindented.split("\n");
|
|
38773
|
+
if (position === "after") {
|
|
38774
|
+
lines.splice(symbolInfo.endLine, 0, "", ...newLines);
|
|
38775
|
+
} else {
|
|
38776
|
+
lines.splice(symbolInfo.startLine - 1, 0, ...newLines, "");
|
|
38777
|
+
}
|
|
38778
|
+
await import_fs4.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
|
|
38779
|
+
if (fileTracker) {
|
|
38780
|
+
const updated = await findSymbol(resolvedPath2, symbol15, cwd || process.cwd());
|
|
38781
|
+
if (updated) {
|
|
38782
|
+
fileTracker.trackSymbolAfterWrite(resolvedPath2, symbol15, updated.code, updated.startLine, updated.endLine);
|
|
38783
|
+
}
|
|
38784
|
+
fileTracker.markFileSeen(resolvedPath2);
|
|
38785
|
+
}
|
|
38786
|
+
const insertLine = position === "after" ? symbolInfo.endLine + 1 : symbolInfo.startLine;
|
|
38787
|
+
if (debug) {
|
|
38788
|
+
console.error(`[Edit] Successfully inserted ${newLines.length} lines ${position} "${symbol15}" at line ${insertLine} in ${resolvedPath2}`);
|
|
38789
|
+
}
|
|
38790
|
+
return `Successfully inserted ${newLines.length} lines ${position} symbol "${symbol15}" in ${file_path} (at line ${insertLine})`;
|
|
38791
|
+
} else {
|
|
38792
|
+
const originalIndent = detectBaseIndent(symbolInfo.code);
|
|
38793
|
+
const reindented = reindent(new_string, originalIndent);
|
|
38794
|
+
const newLines = reindented.split("\n");
|
|
38795
|
+
lines.splice(symbolInfo.startLine - 1, symbolInfo.endLine - symbolInfo.startLine + 1, ...newLines);
|
|
38796
|
+
await import_fs4.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
|
|
38797
|
+
if (fileTracker) {
|
|
38798
|
+
const updated = await findSymbol(resolvedPath2, symbol15, cwd || process.cwd());
|
|
38799
|
+
if (updated) {
|
|
38800
|
+
fileTracker.trackSymbolAfterWrite(resolvedPath2, symbol15, updated.code, updated.startLine, updated.endLine);
|
|
38801
|
+
}
|
|
38802
|
+
fileTracker.markFileSeen(resolvedPath2);
|
|
38803
|
+
}
|
|
38804
|
+
if (debug) {
|
|
38805
|
+
console.error(`[Edit] Successfully replaced symbol "${symbol15}" in ${resolvedPath2} (lines ${symbolInfo.startLine}-${symbolInfo.endLine})`);
|
|
38806
|
+
}
|
|
38807
|
+
return `Successfully replaced symbol "${symbol15}" in ${file_path} (was lines ${symbolInfo.startLine}-${symbolInfo.endLine}, now ${newLines.length} lines)`;
|
|
38808
|
+
}
|
|
38809
|
+
}
|
|
38810
|
+
function buildLineEditResponse(file_path, startLine, endLine, newLineCount, updatedLines, insertOffset, action, heuristicMods) {
|
|
38811
|
+
const contextBefore = 1;
|
|
38812
|
+
const contextAfter = 1;
|
|
38813
|
+
const contextStart = Math.max(0, insertOffset - contextBefore);
|
|
38814
|
+
const contextEnd = Math.min(updatedLines.length, insertOffset + newLineCount + contextAfter);
|
|
38815
|
+
let context = "Context:\n";
|
|
38816
|
+
for (let i5 = contextStart; i5 < contextEnd; i5++) {
|
|
38817
|
+
const lineNum = i5 + 1;
|
|
38818
|
+
const hash = computeLineHash(updatedLines[i5]);
|
|
38819
|
+
const isNew = i5 >= insertOffset && i5 < insertOffset + newLineCount;
|
|
38820
|
+
const marker15 = isNew ? ">" : " ";
|
|
38821
|
+
context += `${marker15} ${lineNum}:${hash} | ${updatedLines[i5]}
|
|
38822
|
+
`;
|
|
38823
|
+
}
|
|
38824
|
+
let msg = `Successfully edited ${file_path} (${action})`;
|
|
38825
|
+
if (heuristicMods.length > 0) {
|
|
38826
|
+
msg += ` [auto-corrected: ${heuristicMods.join(", ")}]`;
|
|
38827
|
+
}
|
|
38828
|
+
msg += "\n" + context;
|
|
38829
|
+
return msg;
|
|
38830
|
+
}
|
|
38831
|
+
async function handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_line, end_line, new_string, position, debug, fileTracker }) {
|
|
38832
|
+
const startRef = parseLineRef(start_line);
|
|
38833
|
+
if (!startRef) {
|
|
38834
|
+
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.`;
|
|
38835
|
+
}
|
|
38836
|
+
let endRef = null;
|
|
38837
|
+
if (end_line !== void 0 && end_line !== null) {
|
|
38838
|
+
endRef = parseLineRef(end_line);
|
|
38839
|
+
if (!endRef) {
|
|
38840
|
+
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.`;
|
|
38841
|
+
}
|
|
38842
|
+
}
|
|
38843
|
+
const startLine = startRef.line;
|
|
38844
|
+
const endLine = endRef ? endRef.line : startLine;
|
|
38845
|
+
if (endLine < startLine) {
|
|
38846
|
+
return `Error editing file: end_line (${endLine}) must be >= start_line (${startLine}).`;
|
|
38847
|
+
}
|
|
38848
|
+
if (position !== void 0 && position !== null && position !== "before" && position !== "after") {
|
|
38849
|
+
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.';
|
|
38850
|
+
}
|
|
38851
|
+
const content = await import_fs4.promises.readFile(resolvedPath2, "utf-8");
|
|
38852
|
+
const fileLines = content.split("\n");
|
|
38853
|
+
if (startLine > fileLines.length) {
|
|
38854
|
+
return `Error editing file: Line ${startLine} is beyond file length (${fileLines.length} lines). Use 'extract' to read the current file content.`;
|
|
38855
|
+
}
|
|
38856
|
+
if (endLine > fileLines.length) {
|
|
38857
|
+
return `Error editing file: Line ${endLine} is beyond file length (${fileLines.length} lines). Use 'extract' to read the current file content.`;
|
|
38858
|
+
}
|
|
38859
|
+
if (startRef.hash) {
|
|
38860
|
+
const validation = validateLineHash(startLine, startRef.hash, fileLines);
|
|
38861
|
+
if (!validation.valid) {
|
|
38862
|
+
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.`;
|
|
38863
|
+
}
|
|
38864
|
+
}
|
|
38865
|
+
if (endRef && endRef.hash) {
|
|
38866
|
+
const validation = validateLineHash(endLine, endRef.hash, fileLines);
|
|
38867
|
+
if (!validation.valid) {
|
|
38868
|
+
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.`;
|
|
38869
|
+
}
|
|
38870
|
+
}
|
|
38871
|
+
const { cleaned, modifications } = cleanNewString(new_string, fileLines, startLine, endLine, position);
|
|
38872
|
+
if (debug) {
|
|
38873
|
+
if (modifications.length > 0) {
|
|
38874
|
+
console.error(`[Edit] Heuristic corrections: ${modifications.join(", ")}`);
|
|
38875
|
+
}
|
|
38876
|
+
}
|
|
38877
|
+
const newLines = cleaned === "" ? [] : cleaned.split("\n");
|
|
38878
|
+
if (position === "after") {
|
|
38879
|
+
fileLines.splice(startLine, 0, ...newLines);
|
|
38880
|
+
await import_fs4.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
|
|
38881
|
+
if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
38882
|
+
const action = `${newLines.length} line${newLines.length !== 1 ? "s" : ""} inserted after line ${startLine}`;
|
|
38883
|
+
return buildLineEditResponse(file_path, startLine, startLine, newLines.length, fileLines, startLine, action, modifications);
|
|
38884
|
+
} else if (position === "before") {
|
|
38885
|
+
fileLines.splice(startLine - 1, 0, ...newLines);
|
|
38886
|
+
await import_fs4.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
|
|
38887
|
+
if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
38888
|
+
const action = `${newLines.length} line${newLines.length !== 1 ? "s" : ""} inserted before line ${startLine}`;
|
|
38889
|
+
return buildLineEditResponse(file_path, startLine, startLine, newLines.length, fileLines, startLine - 1, action, modifications);
|
|
38890
|
+
} else {
|
|
38891
|
+
const replacedCount = endLine - startLine + 1;
|
|
38892
|
+
fileLines.splice(startLine - 1, replacedCount, ...newLines);
|
|
38893
|
+
await import_fs4.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
|
|
38894
|
+
if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
38895
|
+
let action;
|
|
38896
|
+
if (newLines.length === 0) {
|
|
38897
|
+
action = `${replacedCount} line${replacedCount !== 1 ? "s" : ""} deleted (lines ${startLine}-${endLine})`;
|
|
38898
|
+
} else if (startLine === endLine) {
|
|
38899
|
+
action = `line ${startLine} replaced with ${newLines.length} line${newLines.length !== 1 ? "s" : ""}`;
|
|
38900
|
+
} else {
|
|
38901
|
+
action = `lines ${startLine}-${endLine} replaced with ${newLines.length} line${newLines.length !== 1 ? "s" : ""}`;
|
|
38902
|
+
}
|
|
38903
|
+
return buildLineEditResponse(file_path, startLine, endLine, newLines.length, fileLines, startLine - 1, action, modifications);
|
|
38904
|
+
}
|
|
38905
|
+
}
|
|
38331
38906
|
var import_ai, import_fs4, import_path5, import_fs5, editTool, createTool, editSchema, createSchema, editDescription, createDescription, editToolDefinition, createToolDefinition;
|
|
38332
38907
|
var init_edit = __esm({
|
|
38333
38908
|
"src/tools/edit.js"() {
|
|
@@ -38337,24 +38912,31 @@ var init_edit = __esm({
|
|
|
38337
38912
|
import_path5 = require("path");
|
|
38338
38913
|
import_fs5 = require("fs");
|
|
38339
38914
|
init_path_validation();
|
|
38915
|
+
init_fuzzyMatch();
|
|
38916
|
+
init_symbolEdit();
|
|
38917
|
+
init_hashline();
|
|
38918
|
+
init_lineEditHeuristics();
|
|
38340
38919
|
editTool = (options = {}) => {
|
|
38341
38920
|
const { debug, allowedFolders, cwd, workspaceRoot } = parseFileToolOptions(options);
|
|
38342
38921
|
return (0, import_ai.tool)({
|
|
38343
38922
|
name: "edit",
|
|
38344
|
-
description: `Edit files using
|
|
38923
|
+
description: `Edit files using text replacement, AST-aware symbol operations, or line-targeted editing.
|
|
38345
38924
|
|
|
38346
|
-
|
|
38925
|
+
Modes:
|
|
38926
|
+
1. Text edit: Provide old_string + new_string to find and replace text (with fuzzy matching fallback)
|
|
38927
|
+
2. Symbol replace: Provide symbol + new_string to replace an entire function/class/method by name
|
|
38928
|
+
3. Symbol insert: Provide symbol + new_string + position to insert code before/after a symbol
|
|
38929
|
+
4. Line-targeted edit: Provide start_line + new_string to edit by line number (from extract/search output)
|
|
38347
38930
|
|
|
38348
38931
|
Parameters:
|
|
38349
38932
|
- file_path: Path to the file to edit (absolute or relative)
|
|
38350
|
-
-
|
|
38351
|
-
-
|
|
38352
|
-
- replace_all: (optional) Replace all occurrences
|
|
38353
|
-
|
|
38354
|
-
|
|
38355
|
-
-
|
|
38356
|
-
-
|
|
38357
|
-
- Use larger context around the string to ensure uniqueness when needed`,
|
|
38933
|
+
- new_string: Replacement text or new code content
|
|
38934
|
+
- old_string: (optional) Text to find and replace. If omitted, symbol or start_line must be provided.
|
|
38935
|
+
- replace_all: (optional) Replace all occurrences (text mode only)
|
|
38936
|
+
- symbol: (optional) Symbol name for AST-aware editing (e.g. "myFunction", "MyClass.myMethod")
|
|
38937
|
+
- position: (optional) "before" or "after" \u2014 insert code near a symbol or line instead of replacing it
|
|
38938
|
+
- start_line: (optional) Line reference (e.g. "42" or "42:ab") for line-targeted editing
|
|
38939
|
+
- end_line: (optional) End of line range, inclusive (e.g. "55" or "55:cd")`,
|
|
38358
38940
|
inputSchema: {
|
|
38359
38941
|
type: "object",
|
|
38360
38942
|
properties: {
|
|
@@ -38364,30 +38946,44 @@ Important:
|
|
|
38364
38946
|
},
|
|
38365
38947
|
old_string: {
|
|
38366
38948
|
type: "string",
|
|
38367
|
-
description: "
|
|
38949
|
+
description: "Text to find and replace (for text-based editing)"
|
|
38368
38950
|
},
|
|
38369
38951
|
new_string: {
|
|
38370
38952
|
type: "string",
|
|
38371
|
-
description: "
|
|
38953
|
+
description: "Replacement text or new code content"
|
|
38372
38954
|
},
|
|
38373
38955
|
replace_all: {
|
|
38374
38956
|
type: "boolean",
|
|
38375
|
-
description: "Replace all occurrences (default: false)",
|
|
38957
|
+
description: "Replace all occurrences (default: false, text mode only)",
|
|
38376
38958
|
default: false
|
|
38959
|
+
},
|
|
38960
|
+
symbol: {
|
|
38961
|
+
type: "string",
|
|
38962
|
+
description: 'Symbol name for AST-aware editing (e.g. "myFunction", "MyClass.myMethod")'
|
|
38963
|
+
},
|
|
38964
|
+
position: {
|
|
38965
|
+
type: "string",
|
|
38966
|
+
enum: ["before", "after"],
|
|
38967
|
+
description: "Insert before/after symbol or line (requires symbol or start_line, omit to replace)"
|
|
38968
|
+
},
|
|
38969
|
+
start_line: {
|
|
38970
|
+
type: "string",
|
|
38971
|
+
description: 'Line reference for line-targeted editing (e.g. "42" or "42:ab" with hash)'
|
|
38972
|
+
},
|
|
38973
|
+
end_line: {
|
|
38974
|
+
type: "string",
|
|
38975
|
+
description: 'End of line range, inclusive (e.g. "55" or "55:cd"). Defaults to start_line.'
|
|
38377
38976
|
}
|
|
38378
38977
|
},
|
|
38379
|
-
required: ["file_path", "
|
|
38978
|
+
required: ["file_path", "new_string"]
|
|
38380
38979
|
},
|
|
38381
|
-
execute: async ({ file_path, old_string, new_string, replace_all = false }) => {
|
|
38980
|
+
execute: async ({ file_path, old_string, new_string, replace_all = false, symbol: symbol15, position, start_line, end_line }) => {
|
|
38382
38981
|
try {
|
|
38383
38982
|
if (!file_path || typeof file_path !== "string" || file_path.trim() === "") {
|
|
38384
|
-
return `Error editing file: Invalid file_path - must be a non-empty string
|
|
38385
|
-
}
|
|
38386
|
-
if (old_string === void 0 || old_string === null || typeof old_string !== "string") {
|
|
38387
|
-
return `Error editing file: Invalid old_string - must be a string`;
|
|
38983
|
+
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").`;
|
|
38388
38984
|
}
|
|
38389
38985
|
if (new_string === void 0 || new_string === null || typeof new_string !== "string") {
|
|
38390
|
-
return `Error editing file: Invalid new_string - must be a string
|
|
38986
|
+
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).`;
|
|
38391
38987
|
}
|
|
38392
38988
|
const resolvedPath2 = (0, import_path5.isAbsolute)(file_path) ? file_path : (0, import_path5.resolve)(cwd || process.cwd(), file_path);
|
|
38393
38989
|
if (debug) {
|
|
@@ -38395,34 +38991,64 @@ Important:
|
|
|
38395
38991
|
}
|
|
38396
38992
|
if (!isPathAllowed(resolvedPath2, allowedFolders)) {
|
|
38397
38993
|
const relativePath = toRelativePath(resolvedPath2, workspaceRoot);
|
|
38398
|
-
return `Error editing file: Permission denied - ${relativePath} is outside allowed directories
|
|
38994
|
+
return `Error editing file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
|
|
38399
38995
|
}
|
|
38400
38996
|
if (!(0, import_fs5.existsSync)(resolvedPath2)) {
|
|
38401
|
-
return `Error editing file: File not found - ${file_path}
|
|
38997
|
+
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.`;
|
|
38998
|
+
}
|
|
38999
|
+
if (options.fileTracker && !options.fileTracker.isFileSeen(resolvedPath2)) {
|
|
39000
|
+
const displayPath = toRelativePath(resolvedPath2, workspaceRoot);
|
|
39001
|
+
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.
|
|
39002
|
+
|
|
39003
|
+
Example: <extract><targets>${displayPath}</targets></extract>`;
|
|
39004
|
+
}
|
|
39005
|
+
if (symbol15 !== void 0 && symbol15 !== null) {
|
|
39006
|
+
return await handleSymbolEdit({ resolvedPath: resolvedPath2, file_path, symbol: symbol15, new_string, position, debug, cwd, fileTracker: options.fileTracker });
|
|
39007
|
+
}
|
|
39008
|
+
if (start_line !== void 0 && start_line !== null) {
|
|
39009
|
+
return await handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_line, end_line, new_string, position, debug, fileTracker: options.fileTracker });
|
|
39010
|
+
}
|
|
39011
|
+
if (old_string === void 0 || old_string === null) {
|
|
39012
|
+
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").';
|
|
39013
|
+
}
|
|
39014
|
+
if (typeof old_string !== "string") {
|
|
39015
|
+
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.`;
|
|
38402
39016
|
}
|
|
38403
39017
|
const content = await import_fs4.promises.readFile(resolvedPath2, "utf-8");
|
|
39018
|
+
let matchTarget = old_string;
|
|
39019
|
+
let matchStrategy = "exact";
|
|
38404
39020
|
if (!content.includes(old_string)) {
|
|
38405
|
-
|
|
39021
|
+
const fuzzy = findFuzzyMatch(content, old_string);
|
|
39022
|
+
if (!fuzzy) {
|
|
39023
|
+
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.`;
|
|
39024
|
+
}
|
|
39025
|
+
matchTarget = fuzzy.matchedText;
|
|
39026
|
+
matchStrategy = fuzzy.strategy;
|
|
39027
|
+
if (debug) {
|
|
39028
|
+
console.error(`[Edit] Exact match failed, used ${matchStrategy} matching`);
|
|
39029
|
+
}
|
|
38406
39030
|
}
|
|
38407
|
-
const occurrences = content.split(
|
|
39031
|
+
const occurrences = content.split(matchTarget).length - 1;
|
|
38408
39032
|
if (!replace_all && occurrences > 1) {
|
|
38409
|
-
return `Error editing file: Multiple occurrences found - the old_string appears ${occurrences} times.
|
|
39033
|
+
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).`;
|
|
38410
39034
|
}
|
|
38411
39035
|
let newContent;
|
|
38412
39036
|
if (replace_all) {
|
|
38413
|
-
newContent = content.replaceAll(
|
|
39037
|
+
newContent = content.replaceAll(matchTarget, new_string);
|
|
38414
39038
|
} else {
|
|
38415
|
-
newContent = content.replace(
|
|
39039
|
+
newContent = content.replace(matchTarget, new_string);
|
|
38416
39040
|
}
|
|
38417
39041
|
if (newContent === content) {
|
|
38418
|
-
return `Error editing file: No changes made - old_string and new_string
|
|
39042
|
+
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.`;
|
|
38419
39043
|
}
|
|
38420
39044
|
await import_fs4.promises.writeFile(resolvedPath2, newContent, "utf-8");
|
|
39045
|
+
if (options.fileTracker) await options.fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
38421
39046
|
const replacedCount = replace_all ? occurrences : 1;
|
|
38422
39047
|
if (debug) {
|
|
38423
39048
|
console.error(`[Edit] Successfully edited ${resolvedPath2}, replaced ${replacedCount} occurrence(s)`);
|
|
38424
39049
|
}
|
|
38425
|
-
|
|
39050
|
+
const strategyNote = matchStrategy !== "exact" ? `, matched via ${matchStrategy}` : "";
|
|
39051
|
+
return `Successfully edited ${file_path} (${replacedCount} replacement${replacedCount !== 1 ? "s" : ""}${strategyNote})`;
|
|
38426
39052
|
} catch (error2) {
|
|
38427
39053
|
console.error("[Edit] Error:", error2);
|
|
38428
39054
|
return `Error editing file: ${error2.message}`;
|
|
@@ -38469,10 +39095,10 @@ Important:
|
|
|
38469
39095
|
execute: async ({ file_path, content, overwrite = false }) => {
|
|
38470
39096
|
try {
|
|
38471
39097
|
if (!file_path || typeof file_path !== "string" || file_path.trim() === "") {
|
|
38472
|
-
return `Error creating file: Invalid file_path - must be a non-empty string
|
|
39098
|
+
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").`;
|
|
38473
39099
|
}
|
|
38474
39100
|
if (content === void 0 || content === null || typeof content !== "string") {
|
|
38475
|
-
return `Error creating file: Invalid content - must be a string
|
|
39101
|
+
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).`;
|
|
38476
39102
|
}
|
|
38477
39103
|
const resolvedPath2 = (0, import_path5.isAbsolute)(file_path) ? file_path : (0, import_path5.resolve)(cwd || process.cwd(), file_path);
|
|
38478
39104
|
if (debug) {
|
|
@@ -38480,15 +39106,17 @@ Important:
|
|
|
38480
39106
|
}
|
|
38481
39107
|
if (!isPathAllowed(resolvedPath2, allowedFolders)) {
|
|
38482
39108
|
const relativePath = toRelativePath(resolvedPath2, workspaceRoot);
|
|
38483
|
-
return `Error creating file: Permission denied - ${relativePath} is outside allowed directories
|
|
39109
|
+
return `Error creating file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
|
|
38484
39110
|
}
|
|
38485
39111
|
if ((0, import_fs5.existsSync)(resolvedPath2) && !overwrite) {
|
|
38486
39112
|
return `Error creating file: File already exists - ${file_path}. Use overwrite: true to replace it.`;
|
|
38487
39113
|
}
|
|
39114
|
+
const existed = (0, import_fs5.existsSync)(resolvedPath2);
|
|
38488
39115
|
const dir = (0, import_path5.dirname)(resolvedPath2);
|
|
38489
39116
|
await import_fs4.promises.mkdir(dir, { recursive: true });
|
|
38490
39117
|
await import_fs4.promises.writeFile(resolvedPath2, content, "utf-8");
|
|
38491
|
-
|
|
39118
|
+
if (options.fileTracker) await options.fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
39119
|
+
const action = existed && overwrite ? "overwrote" : "created";
|
|
38492
39120
|
const bytes = Buffer.byteLength(content, "utf-8");
|
|
38493
39121
|
if (debug) {
|
|
38494
39122
|
console.error(`[Create] Successfully ${action} ${resolvedPath2}`);
|
|
@@ -38510,18 +39138,35 @@ Important:
|
|
|
38510
39138
|
},
|
|
38511
39139
|
old_string: {
|
|
38512
39140
|
type: "string",
|
|
38513
|
-
description: "
|
|
39141
|
+
description: "Text to find and replace (for text-based editing)"
|
|
38514
39142
|
},
|
|
38515
39143
|
new_string: {
|
|
38516
39144
|
type: "string",
|
|
38517
|
-
description: "
|
|
39145
|
+
description: "Replacement text or new code content"
|
|
38518
39146
|
},
|
|
38519
39147
|
replace_all: {
|
|
38520
39148
|
type: "boolean",
|
|
38521
|
-
description: "Replace all occurrences (default: false)"
|
|
39149
|
+
description: "Replace all occurrences (default: false, text mode only)"
|
|
39150
|
+
},
|
|
39151
|
+
symbol: {
|
|
39152
|
+
type: "string",
|
|
39153
|
+
description: 'Symbol name for AST-aware editing (e.g. "myFunction", "MyClass.myMethod")'
|
|
39154
|
+
},
|
|
39155
|
+
position: {
|
|
39156
|
+
type: "string",
|
|
39157
|
+
enum: ["before", "after"],
|
|
39158
|
+
description: "Insert before/after symbol or line (requires symbol or start_line, omit to replace)"
|
|
39159
|
+
},
|
|
39160
|
+
start_line: {
|
|
39161
|
+
type: "string",
|
|
39162
|
+
description: 'Line reference for line-targeted editing (e.g. "42" or "42:ab" with hash)'
|
|
39163
|
+
},
|
|
39164
|
+
end_line: {
|
|
39165
|
+
type: "string",
|
|
39166
|
+
description: 'End of line range, inclusive (e.g. "55" or "55:cd"). Defaults to start_line.'
|
|
38522
39167
|
}
|
|
38523
39168
|
},
|
|
38524
|
-
required: ["file_path", "
|
|
39169
|
+
required: ["file_path", "new_string"]
|
|
38525
39170
|
};
|
|
38526
39171
|
createSchema = {
|
|
38527
39172
|
type: "object",
|
|
@@ -38541,50 +39186,123 @@ Important:
|
|
|
38541
39186
|
},
|
|
38542
39187
|
required: ["file_path", "content"]
|
|
38543
39188
|
};
|
|
38544
|
-
editDescription = "Edit files using
|
|
39189
|
+
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.";
|
|
38545
39190
|
createDescription = "Create new files with specified content. Will create parent directories if needed.";
|
|
38546
39191
|
editToolDefinition = `
|
|
38547
39192
|
## edit
|
|
38548
39193
|
Description: ${editDescription}
|
|
38549
39194
|
|
|
38550
|
-
|
|
38551
|
-
- For precise, surgical edits to existing files
|
|
38552
|
-
- When you need to change specific lines or blocks of code
|
|
38553
|
-
- For renaming functions, variables, or updating configuration values
|
|
38554
|
-
- When the exact text to replace is known and unique (or use replace_all for multiple occurrences)
|
|
39195
|
+
Four editing modes \u2014 choose based on the scope of your change:
|
|
38555
39196
|
|
|
38556
|
-
|
|
38557
|
-
|
|
38558
|
-
|
|
38559
|
-
|
|
39197
|
+
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.
|
|
39198
|
+
|
|
39199
|
+
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.
|
|
39200
|
+
|
|
39201
|
+
3. **Symbol insert** (symbol + new_string + position): For adding new code before or after an existing symbol. Set position to "before" or "after".
|
|
39202
|
+
|
|
39203
|
+
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.
|
|
38560
39204
|
|
|
38561
39205
|
Parameters:
|
|
38562
39206
|
- file_path: (required) Path to the file to edit
|
|
38563
|
-
-
|
|
38564
|
-
-
|
|
38565
|
-
- replace_all: (optional, default: false) Replace all occurrences
|
|
38566
|
-
|
|
38567
|
-
|
|
38568
|
-
-
|
|
38569
|
-
-
|
|
38570
|
-
|
|
39207
|
+
- new_string: (required) Replacement text or new code content
|
|
39208
|
+
- old_string: (optional) Text to find and replace \u2014 copy verbatim from the file, do not paraphrase or reformat
|
|
39209
|
+
- replace_all: (optional, default: false) Replace all occurrences of old_string (text mode only)
|
|
39210
|
+
- symbol: (optional) Name of a code symbol (e.g. "myFunction", "MyClass.myMethod") \u2014 must match a function, class, or method definition
|
|
39211
|
+
- position: (optional) "before" or "after" \u2014 insert new_string near the symbol or line instead of replacing it
|
|
39212
|
+
- start_line: (optional) Line reference for line-targeted editing (e.g. "42" or "42:ab")
|
|
39213
|
+
- end_line: (optional) End of line range, inclusive (e.g. "55" or "55:cd"). Defaults to start_line.
|
|
39214
|
+
|
|
39215
|
+
Mode selection rules (priority order):
|
|
39216
|
+
- If symbol is provided, symbol mode is used (old_string and start_line are ignored)
|
|
39217
|
+
- If start_line is provided (without symbol), line-targeted mode is used
|
|
39218
|
+
- If old_string is provided (without symbol or start_line), text mode is used
|
|
39219
|
+
- If none are provided, the tool returns an error with guidance
|
|
39220
|
+
|
|
39221
|
+
When to use each mode:
|
|
39222
|
+
- Small edits (a line or a few lines): use text mode with old_string
|
|
39223
|
+
- Replacing entire functions/classes/methods: use symbol mode \u2014 no exact text matching needed
|
|
39224
|
+
- Editing specific lines from extract/search output: use line-targeted mode with start_line
|
|
39225
|
+
- 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
|
|
39226
|
+
|
|
39227
|
+
Error handling:
|
|
39228
|
+
- If an edit fails, read the error message carefully \u2014 it contains specific instructions for how to fix the call and retry
|
|
39229
|
+
- Common fixes: use 'search'/'extract' to get exact file content, add more context to old_string, switch between text and symbol modes
|
|
39230
|
+
- Line-targeted hash mismatch: the file changed since last read; the error provides updated line:hash references
|
|
38571
39231
|
|
|
38572
39232
|
Examples:
|
|
39233
|
+
|
|
39234
|
+
Text edit (find and replace):
|
|
38573
39235
|
<edit>
|
|
38574
39236
|
<file_path>src/main.js</file_path>
|
|
38575
|
-
<old_string>
|
|
38576
|
-
|
|
38577
|
-
}</old_string>
|
|
38578
|
-
<new_string>function newName() {
|
|
38579
|
-
return 42;
|
|
38580
|
-
}</new_string>
|
|
39237
|
+
<old_string>return false;</old_string>
|
|
39238
|
+
<new_string>return true;</new_string>
|
|
38581
39239
|
</edit>
|
|
38582
39240
|
|
|
39241
|
+
Text edit with replace_all:
|
|
38583
39242
|
<edit>
|
|
38584
39243
|
<file_path>config.json</file_path>
|
|
38585
39244
|
<old_string>"debug": false</old_string>
|
|
38586
39245
|
<new_string>"debug": true</new_string>
|
|
38587
39246
|
<replace_all>true</replace_all>
|
|
39247
|
+
</edit>
|
|
39248
|
+
|
|
39249
|
+
Symbol replace (rewrite entire function by name):
|
|
39250
|
+
<edit>
|
|
39251
|
+
<file_path>src/utils.js</file_path>
|
|
39252
|
+
<symbol>calculateTotal</symbol>
|
|
39253
|
+
<new_string>function calculateTotal(items) {
|
|
39254
|
+
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
|
39255
|
+
}</new_string>
|
|
39256
|
+
</edit>
|
|
39257
|
+
|
|
39258
|
+
Symbol insert (add new function after existing one):
|
|
39259
|
+
<edit>
|
|
39260
|
+
<file_path>src/utils.js</file_path>
|
|
39261
|
+
<symbol>calculateTotal</symbol>
|
|
39262
|
+
<position>after</position>
|
|
39263
|
+
<new_string>function calculateTax(total, rate) {
|
|
39264
|
+
return total * rate;
|
|
39265
|
+
}</new_string>
|
|
39266
|
+
</edit>
|
|
39267
|
+
|
|
39268
|
+
Line-targeted edit (replace a line):
|
|
39269
|
+
<edit>
|
|
39270
|
+
<file_path>src/main.js</file_path>
|
|
39271
|
+
<start_line>42</start_line>
|
|
39272
|
+
<new_string> return processItems(order.items);</new_string>
|
|
39273
|
+
</edit>
|
|
39274
|
+
|
|
39275
|
+
Line-targeted edit (replace a range of lines):
|
|
39276
|
+
<edit>
|
|
39277
|
+
<file_path>src/main.js</file_path>
|
|
39278
|
+
<start_line>42</start_line>
|
|
39279
|
+
<end_line>55</end_line>
|
|
39280
|
+
<new_string> // simplified implementation
|
|
39281
|
+
return processItems(order.items);</new_string>
|
|
39282
|
+
</edit>
|
|
39283
|
+
|
|
39284
|
+
Line-targeted edit with hash verification:
|
|
39285
|
+
<edit>
|
|
39286
|
+
<file_path>src/main.js</file_path>
|
|
39287
|
+
<start_line>42:ab</start_line>
|
|
39288
|
+
<end_line>55:cd</end_line>
|
|
39289
|
+
<new_string> return processItems(order.items);</new_string>
|
|
39290
|
+
</edit>
|
|
39291
|
+
|
|
39292
|
+
Line-targeted insert (add code after a line):
|
|
39293
|
+
<edit>
|
|
39294
|
+
<file_path>src/main.js</file_path>
|
|
39295
|
+
<start_line>42</start_line>
|
|
39296
|
+
<position>after</position>
|
|
39297
|
+
<new_string> const validated = validate(input);</new_string>
|
|
39298
|
+
</edit>
|
|
39299
|
+
|
|
39300
|
+
Line-targeted delete (remove lines):
|
|
39301
|
+
<edit>
|
|
39302
|
+
<file_path>src/main.js</file_path>
|
|
39303
|
+
<start_line>42</start_line>
|
|
39304
|
+
<end_line>45</end_line>
|
|
39305
|
+
<new_string></new_string>
|
|
38588
39306
|
</edit>`;
|
|
38589
39307
|
createToolDefinition = `
|
|
38590
39308
|
## create
|
|
@@ -39121,7 +39839,7 @@ function getValidParamsForTool(toolName) {
|
|
|
39121
39839
|
};
|
|
39122
39840
|
const schema = schemaMap[toolName];
|
|
39123
39841
|
if (!schema) {
|
|
39124
|
-
return ["path", "directory", "pattern", "recursive", "includeHidden", "task", "files", "
|
|
39842
|
+
return ["path", "directory", "pattern", "recursive", "includeHidden", "task", "files", "result"];
|
|
39125
39843
|
}
|
|
39126
39844
|
if (toolName === "attempt_completion") {
|
|
39127
39845
|
return ["result"];
|
|
@@ -39242,7 +39960,6 @@ function detectUnrecognizedToolCall(xmlString, validTools) {
|
|
|
39242
39960
|
"listSkills",
|
|
39243
39961
|
"useSkill",
|
|
39244
39962
|
"readImage",
|
|
39245
|
-
"implement",
|
|
39246
39963
|
"edit",
|
|
39247
39964
|
"create",
|
|
39248
39965
|
"delegate",
|
|
@@ -39617,6 +40334,8 @@ User: Read file inside the dependency
|
|
|
39617
40334
|
</extract>
|
|
39618
40335
|
|
|
39619
40336
|
</examples>
|
|
40337
|
+
|
|
40338
|
+
**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.
|
|
39620
40339
|
`;
|
|
39621
40340
|
delegateToolDefinition = `
|
|
39622
40341
|
## delegate
|
|
@@ -39772,7 +40491,7 @@ Capabilities:
|
|
|
39772
40491
|
`;
|
|
39773
40492
|
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.";
|
|
39774
40493
|
queryDescription = "Search code using ast-grep structural pattern matching. Use this tool to find specific code structures like functions, classes, or methods.";
|
|
39775
|
-
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.";
|
|
40494
|
+
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.";
|
|
39776
40495
|
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.";
|
|
39777
40496
|
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.';
|
|
39778
40497
|
DEFAULT_VALID_TOOLS = [
|
|
@@ -39787,7 +40506,6 @@ Capabilities:
|
|
|
39787
40506
|
"useSkill",
|
|
39788
40507
|
"listFiles",
|
|
39789
40508
|
"searchFiles",
|
|
39790
|
-
"implement",
|
|
39791
40509
|
"bash",
|
|
39792
40510
|
"task",
|
|
39793
40511
|
"attempt_completion"
|
|
@@ -39912,6 +40630,7 @@ var init_vercel = __esm({
|
|
|
39912
40630
|
init_analyzeAll();
|
|
39913
40631
|
init_common2();
|
|
39914
40632
|
init_error_types();
|
|
40633
|
+
init_hashline();
|
|
39915
40634
|
CODE_SEARCH_SCHEMA = {
|
|
39916
40635
|
type: "object",
|
|
39917
40636
|
properties: {
|
|
@@ -39930,8 +40649,15 @@ var init_vercel = __esm({
|
|
|
39930
40649
|
maxTokens = 2e4,
|
|
39931
40650
|
debug = false,
|
|
39932
40651
|
outline = false,
|
|
39933
|
-
searchDelegate = false
|
|
40652
|
+
searchDelegate = false,
|
|
40653
|
+
hashLines = false
|
|
39934
40654
|
} = options;
|
|
40655
|
+
const maybeAnnotate = (result) => {
|
|
40656
|
+
if (hashLines && typeof result === "string") {
|
|
40657
|
+
return annotateOutputWithHashes(result);
|
|
40658
|
+
}
|
|
40659
|
+
return result;
|
|
40660
|
+
};
|
|
39935
40661
|
return (0, import_ai2.tool)({
|
|
39936
40662
|
name: "search",
|
|
39937
40663
|
description: searchDelegate ? `${searchDescription} (delegates code search to a subagent and returns extracted code blocks)` : searchDescription,
|
|
@@ -39973,7 +40699,12 @@ var init_vercel = __esm({
|
|
|
39973
40699
|
};
|
|
39974
40700
|
if (!searchDelegate) {
|
|
39975
40701
|
try {
|
|
39976
|
-
|
|
40702
|
+
const result = maybeAnnotate(await runRawSearch());
|
|
40703
|
+
if (options.fileTracker && typeof result === "string") {
|
|
40704
|
+
options.fileTracker.trackFilesFromOutput(result, options.cwd || ".").catch(() => {
|
|
40705
|
+
});
|
|
40706
|
+
}
|
|
40707
|
+
return result;
|
|
39977
40708
|
} catch (error2) {
|
|
39978
40709
|
console.error("Error executing search command:", error2);
|
|
39979
40710
|
return formatErrorForAI(error2);
|
|
@@ -40016,7 +40747,12 @@ var init_vercel = __esm({
|
|
|
40016
40747
|
if (debug) {
|
|
40017
40748
|
console.error("Delegated search returned no targets; falling back to raw search");
|
|
40018
40749
|
}
|
|
40019
|
-
|
|
40750
|
+
const fallbackResult = maybeAnnotate(await runRawSearch());
|
|
40751
|
+
if (options.fileTracker && typeof fallbackResult === "string") {
|
|
40752
|
+
options.fileTracker.trackFilesFromOutput(fallbackResult, options.cwd || ".").catch(() => {
|
|
40753
|
+
});
|
|
40754
|
+
}
|
|
40755
|
+
return fallbackResult;
|
|
40020
40756
|
}
|
|
40021
40757
|
const resolutionBase = searchPaths[0] || options.cwd || ".";
|
|
40022
40758
|
const resolvedTargets = targets.map((target) => resolveTargetPath(target, resolutionBase));
|
|
@@ -40031,13 +40767,18 @@ var init_vercel = __esm({
|
|
|
40031
40767
|
const extractResult = await extract(extractOptions);
|
|
40032
40768
|
if (resolutionBase && typeof extractResult === "string") {
|
|
40033
40769
|
const wsPrefix = resolutionBase.endsWith("/") ? resolutionBase : resolutionBase + "/";
|
|
40034
|
-
return extractResult.split(wsPrefix).join("");
|
|
40770
|
+
return maybeAnnotate(extractResult.split(wsPrefix).join(""));
|
|
40035
40771
|
}
|
|
40036
|
-
return extractResult;
|
|
40772
|
+
return maybeAnnotate(extractResult);
|
|
40037
40773
|
} catch (error2) {
|
|
40038
40774
|
console.error("Delegated search failed, falling back to raw search:", error2);
|
|
40039
40775
|
try {
|
|
40040
|
-
|
|
40776
|
+
const fallbackResult2 = maybeAnnotate(await runRawSearch());
|
|
40777
|
+
if (options.fileTracker && typeof fallbackResult2 === "string") {
|
|
40778
|
+
options.fileTracker.trackFilesFromOutput(fallbackResult2, options.cwd || ".").catch(() => {
|
|
40779
|
+
});
|
|
40780
|
+
}
|
|
40781
|
+
return fallbackResult2;
|
|
40041
40782
|
} catch (fallbackError) {
|
|
40042
40783
|
console.error("Error executing search command:", fallbackError);
|
|
40043
40784
|
return formatErrorForAI(fallbackError);
|
|
@@ -40083,7 +40824,7 @@ var init_vercel = __esm({
|
|
|
40083
40824
|
});
|
|
40084
40825
|
};
|
|
40085
40826
|
extractTool = (options = {}) => {
|
|
40086
|
-
const { debug = false, outline = false } = options;
|
|
40827
|
+
const { debug = false, outline = false, hashLines = false } = options;
|
|
40087
40828
|
return (0, import_ai2.tool)({
|
|
40088
40829
|
name: "extract",
|
|
40089
40830
|
description: extractDescription,
|
|
@@ -40100,6 +40841,7 @@ var init_vercel = __esm({
|
|
|
40100
40841
|
}
|
|
40101
40842
|
let tempFilePath = null;
|
|
40102
40843
|
let extractOptions = { cwd: effectiveCwd };
|
|
40844
|
+
let extractFiles = null;
|
|
40103
40845
|
if (input_content) {
|
|
40104
40846
|
const { writeFileSync: writeFileSync2, unlinkSync } = await import("fs");
|
|
40105
40847
|
const { join: join5 } = await import("path");
|
|
@@ -40123,13 +40865,13 @@ var init_vercel = __esm({
|
|
|
40123
40865
|
};
|
|
40124
40866
|
} else if (targets) {
|
|
40125
40867
|
const parsedTargets = parseTargets(targets);
|
|
40126
|
-
|
|
40868
|
+
extractFiles = parsedTargets.map((target) => resolveTargetPath(target, effectiveCwd));
|
|
40127
40869
|
let effectiveFormat = format2;
|
|
40128
40870
|
if (outline && format2 === "outline-xml") {
|
|
40129
40871
|
effectiveFormat = "xml";
|
|
40130
40872
|
}
|
|
40131
40873
|
extractOptions = {
|
|
40132
|
-
files,
|
|
40874
|
+
files: extractFiles,
|
|
40133
40875
|
cwd: effectiveCwd,
|
|
40134
40876
|
allowTests: allow_tests ?? true,
|
|
40135
40877
|
contextLines: context_lines,
|
|
@@ -40139,6 +40881,10 @@ var init_vercel = __esm({
|
|
|
40139
40881
|
throw new Error("Either targets or input_content must be provided");
|
|
40140
40882
|
}
|
|
40141
40883
|
const results = await extract(extractOptions);
|
|
40884
|
+
if (options.fileTracker && extractFiles && extractFiles.length > 0) {
|
|
40885
|
+
options.fileTracker.trackFilesFromExtract(extractFiles, effectiveCwd).catch(() => {
|
|
40886
|
+
});
|
|
40887
|
+
}
|
|
40142
40888
|
if (tempFilePath) {
|
|
40143
40889
|
const { unlinkSync } = await import("fs");
|
|
40144
40890
|
try {
|
|
@@ -40150,6 +40896,9 @@ var init_vercel = __esm({
|
|
|
40150
40896
|
console.error(`Warning: Failed to remove temporary file: ${cleanupError.message}`);
|
|
40151
40897
|
}
|
|
40152
40898
|
}
|
|
40899
|
+
if (hashLines && typeof results === "string") {
|
|
40900
|
+
return annotateOutputWithHashes(results);
|
|
40901
|
+
}
|
|
40153
40902
|
return results;
|
|
40154
40903
|
} catch (error2) {
|
|
40155
40904
|
console.error("Error executing extract command:", error2);
|
|
@@ -41497,7 +42246,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
41497
42246
|
console.log(`[BashExecutor] Working directory: "${cwd}"`);
|
|
41498
42247
|
console.log(`[BashExecutor] Timeout: ${timeout}ms`);
|
|
41499
42248
|
}
|
|
41500
|
-
return new Promise((
|
|
42249
|
+
return new Promise((resolve8, reject2) => {
|
|
41501
42250
|
const processEnv = {
|
|
41502
42251
|
...process.env,
|
|
41503
42252
|
...env
|
|
@@ -41514,7 +42263,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
41514
42263
|
} else {
|
|
41515
42264
|
const args = parseCommandForExecution(command);
|
|
41516
42265
|
if (!args || args.length === 0) {
|
|
41517
|
-
|
|
42266
|
+
resolve8({
|
|
41518
42267
|
success: false,
|
|
41519
42268
|
error: "Failed to parse command",
|
|
41520
42269
|
stdout: "",
|
|
@@ -41599,7 +42348,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
41599
42348
|
success = false;
|
|
41600
42349
|
error2 = `Command exited with code ${code}`;
|
|
41601
42350
|
}
|
|
41602
|
-
|
|
42351
|
+
resolve8({
|
|
41603
42352
|
success,
|
|
41604
42353
|
error: error2,
|
|
41605
42354
|
stdout: stdout.trim(),
|
|
@@ -41619,7 +42368,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
41619
42368
|
if (debug) {
|
|
41620
42369
|
console.log(`[BashExecutor] Spawn error:`, error2);
|
|
41621
42370
|
}
|
|
41622
|
-
|
|
42371
|
+
resolve8({
|
|
41623
42372
|
success: false,
|
|
41624
42373
|
error: `Failed to execute command: ${error2.message}`,
|
|
41625
42374
|
stdout: "",
|
|
@@ -43031,14 +43780,14 @@ var require_executor = __commonJS({
|
|
|
43031
43780
|
function asyncDone(callback) {
|
|
43032
43781
|
let isInstant = false;
|
|
43033
43782
|
let instant;
|
|
43034
|
-
const p5 = new Promise((
|
|
43783
|
+
const p5 = new Promise((resolve8, reject2) => {
|
|
43035
43784
|
callback((err, result) => {
|
|
43036
43785
|
if (err)
|
|
43037
43786
|
reject2(err);
|
|
43038
43787
|
else {
|
|
43039
43788
|
isInstant = true;
|
|
43040
43789
|
instant = result;
|
|
43041
|
-
|
|
43790
|
+
resolve8({ result });
|
|
43042
43791
|
}
|
|
43043
43792
|
});
|
|
43044
43793
|
});
|
|
@@ -43061,10 +43810,10 @@ var require_executor = __commonJS({
|
|
|
43061
43810
|
}
|
|
43062
43811
|
async function execAsync4(ticks, tree, scope, context, doneOriginal, inLoopOrSwitch) {
|
|
43063
43812
|
let done = doneOriginal;
|
|
43064
|
-
const p5 = new Promise((
|
|
43813
|
+
const p5 = new Promise((resolve8) => {
|
|
43065
43814
|
done = (e5, r5) => {
|
|
43066
43815
|
doneOriginal(e5, r5);
|
|
43067
|
-
|
|
43816
|
+
resolve8();
|
|
43068
43817
|
};
|
|
43069
43818
|
});
|
|
43070
43819
|
if (!_execNoneRecurse(ticks, tree, scope, context, done, true, inLoopOrSwitch) && utils.isLisp(tree)) {
|
|
@@ -51415,6 +52164,13 @@ function generateSandboxGlobals(options) {
|
|
|
51415
52164
|
if (i5 < keys2.length) params[keys2[i5]] = arg;
|
|
51416
52165
|
});
|
|
51417
52166
|
}
|
|
52167
|
+
if (params.path && typeof params.path === "object") {
|
|
52168
|
+
const coercedPath = params.path.file_path || params.path.path || params.path.directory || params.path.filename;
|
|
52169
|
+
if (coercedPath && typeof coercedPath === "string") {
|
|
52170
|
+
logFn?.(`[${name14}] Warning: Coerced object path to string "${coercedPath}" (issue #444)`);
|
|
52171
|
+
params.path = coercedPath;
|
|
52172
|
+
}
|
|
52173
|
+
}
|
|
51418
52174
|
const validated = schema.safeParse(params);
|
|
51419
52175
|
if (!validated.success) {
|
|
51420
52176
|
throw new Error(`Invalid parameters for ${name14}: ${validated.error.message}`);
|
|
@@ -51451,6 +52207,11 @@ function generateSandboxGlobals(options) {
|
|
|
51451
52207
|
}
|
|
51452
52208
|
if (llmCall) {
|
|
51453
52209
|
const rawLLM = async (instruction, data3, opts = {}) => {
|
|
52210
|
+
const dataStr = typeof data3 === "string" ? data3 : JSON.stringify(data3);
|
|
52211
|
+
if (dataStr && dataStr.startsWith("ERROR:")) {
|
|
52212
|
+
logFn?.("[LLM] Blocked: data contains error from previous tool call");
|
|
52213
|
+
return "ERROR: Previous tool call failed - " + dataStr.substring(0, 200);
|
|
52214
|
+
}
|
|
51454
52215
|
const result = await llmCall(instruction, data3, opts);
|
|
51455
52216
|
if (opts.schema && typeof result === "string") {
|
|
51456
52217
|
try {
|
|
@@ -51816,33 +52577,31 @@ var init_runtime = __esm({
|
|
|
51816
52577
|
}
|
|
51817
52578
|
});
|
|
51818
52579
|
|
|
51819
|
-
// node_modules/balanced-match/index.js
|
|
51820
|
-
var
|
|
51821
|
-
|
|
51822
|
-
|
|
51823
|
-
|
|
51824
|
-
|
|
51825
|
-
|
|
51826
|
-
|
|
51827
|
-
var r5 = range2(a5, b5, str);
|
|
52580
|
+
// node_modules/balanced-match/dist/esm/index.js
|
|
52581
|
+
var balanced, maybeMatch, range2;
|
|
52582
|
+
var init_esm = __esm({
|
|
52583
|
+
"node_modules/balanced-match/dist/esm/index.js"() {
|
|
52584
|
+
balanced = (a5, b5, str) => {
|
|
52585
|
+
const ma = a5 instanceof RegExp ? maybeMatch(a5, str) : a5;
|
|
52586
|
+
const mb = b5 instanceof RegExp ? maybeMatch(b5, str) : b5;
|
|
52587
|
+
const r5 = ma !== null && mb != null && range2(ma, mb, str);
|
|
51828
52588
|
return r5 && {
|
|
51829
52589
|
start: r5[0],
|
|
51830
52590
|
end: r5[1],
|
|
51831
52591
|
pre: str.slice(0, r5[0]),
|
|
51832
|
-
body: str.slice(r5[0] +
|
|
51833
|
-
post: str.slice(r5[1] +
|
|
52592
|
+
body: str.slice(r5[0] + ma.length, r5[1]),
|
|
52593
|
+
post: str.slice(r5[1] + mb.length)
|
|
51834
52594
|
};
|
|
51835
|
-
}
|
|
51836
|
-
|
|
51837
|
-
|
|
52595
|
+
};
|
|
52596
|
+
maybeMatch = (reg, str) => {
|
|
52597
|
+
const m5 = str.match(reg);
|
|
51838
52598
|
return m5 ? m5[0] : null;
|
|
51839
|
-
}
|
|
51840
|
-
|
|
51841
|
-
|
|
51842
|
-
|
|
51843
|
-
|
|
51844
|
-
|
|
51845
|
-
var i5 = ai;
|
|
52599
|
+
};
|
|
52600
|
+
range2 = (a5, b5, str) => {
|
|
52601
|
+
let begs, beg, left, right = void 0, result;
|
|
52602
|
+
let ai = str.indexOf(a5);
|
|
52603
|
+
let bi = str.indexOf(b5, ai + 1);
|
|
52604
|
+
let i5 = ai;
|
|
51846
52605
|
if (ai >= 0 && bi > 0) {
|
|
51847
52606
|
if (a5 === b5) {
|
|
51848
52607
|
return [ai, bi];
|
|
@@ -51850,14 +52609,16 @@ var require_balanced_match = __commonJS({
|
|
|
51850
52609
|
begs = [];
|
|
51851
52610
|
left = str.length;
|
|
51852
52611
|
while (i5 >= 0 && !result) {
|
|
51853
|
-
if (i5
|
|
52612
|
+
if (i5 === ai) {
|
|
51854
52613
|
begs.push(i5);
|
|
51855
52614
|
ai = str.indexOf(a5, i5 + 1);
|
|
51856
|
-
} else if (begs.length
|
|
51857
|
-
|
|
52615
|
+
} else if (begs.length === 1) {
|
|
52616
|
+
const r5 = begs.pop();
|
|
52617
|
+
if (r5 !== void 0)
|
|
52618
|
+
result = [r5, bi];
|
|
51858
52619
|
} else {
|
|
51859
52620
|
beg = begs.pop();
|
|
51860
|
-
if (beg < left) {
|
|
52621
|
+
if (beg !== void 0 && beg < left) {
|
|
51861
52622
|
left = beg;
|
|
51862
52623
|
right = bi;
|
|
51863
52624
|
}
|
|
@@ -51865,163 +52626,179 @@ var require_balanced_match = __commonJS({
|
|
|
51865
52626
|
}
|
|
51866
52627
|
i5 = ai < bi && ai >= 0 ? ai : bi;
|
|
51867
52628
|
}
|
|
51868
|
-
if (begs.length) {
|
|
52629
|
+
if (begs.length && right !== void 0) {
|
|
51869
52630
|
result = [left, right];
|
|
51870
52631
|
}
|
|
51871
52632
|
}
|
|
51872
52633
|
return result;
|
|
51873
|
-
}
|
|
52634
|
+
};
|
|
51874
52635
|
}
|
|
51875
52636
|
});
|
|
51876
52637
|
|
|
51877
|
-
// node_modules/brace-expansion/index.js
|
|
51878
|
-
|
|
51879
|
-
|
|
51880
|
-
|
|
51881
|
-
|
|
51882
|
-
|
|
51883
|
-
|
|
51884
|
-
|
|
51885
|
-
|
|
51886
|
-
|
|
51887
|
-
|
|
51888
|
-
|
|
51889
|
-
|
|
51890
|
-
|
|
51891
|
-
|
|
51892
|
-
|
|
51893
|
-
|
|
51894
|
-
|
|
51895
|
-
|
|
51896
|
-
|
|
51897
|
-
|
|
51898
|
-
|
|
51899
|
-
|
|
51900
|
-
|
|
51901
|
-
|
|
51902
|
-
|
|
51903
|
-
|
|
51904
|
-
|
|
51905
|
-
|
|
51906
|
-
|
|
51907
|
-
|
|
51908
|
-
|
|
51909
|
-
|
|
51910
|
-
|
|
51911
|
-
|
|
51912
|
-
|
|
51913
|
-
|
|
51914
|
-
|
|
51915
|
-
|
|
51916
|
-
|
|
51917
|
-
|
|
51918
|
-
|
|
51919
|
-
|
|
51920
|
-
|
|
51921
|
-
|
|
51922
|
-
|
|
51923
|
-
|
|
51924
|
-
|
|
51925
|
-
|
|
51926
|
-
|
|
51927
|
-
|
|
51928
|
-
|
|
51929
|
-
|
|
51930
|
-
|
|
51931
|
-
|
|
51932
|
-
|
|
51933
|
-
|
|
51934
|
-
|
|
52638
|
+
// node_modules/brace-expansion/dist/esm/index.js
|
|
52639
|
+
function numeric(str) {
|
|
52640
|
+
return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
|
|
52641
|
+
}
|
|
52642
|
+
function escapeBraces(str) {
|
|
52643
|
+
return str.replace(slashPattern, escSlash).replace(openPattern, escOpen).replace(closePattern, escClose).replace(commaPattern, escComma).replace(periodPattern, escPeriod);
|
|
52644
|
+
}
|
|
52645
|
+
function unescapeBraces(str) {
|
|
52646
|
+
return str.replace(escSlashPattern, "\\").replace(escOpenPattern, "{").replace(escClosePattern, "}").replace(escCommaPattern, ",").replace(escPeriodPattern, ".");
|
|
52647
|
+
}
|
|
52648
|
+
function parseCommaParts(str) {
|
|
52649
|
+
if (!str) {
|
|
52650
|
+
return [""];
|
|
52651
|
+
}
|
|
52652
|
+
const parts = [];
|
|
52653
|
+
const m5 = balanced("{", "}", str);
|
|
52654
|
+
if (!m5) {
|
|
52655
|
+
return str.split(",");
|
|
52656
|
+
}
|
|
52657
|
+
const { pre, body, post } = m5;
|
|
52658
|
+
const p5 = pre.split(",");
|
|
52659
|
+
p5[p5.length - 1] += "{" + body + "}";
|
|
52660
|
+
const postParts = parseCommaParts(post);
|
|
52661
|
+
if (post.length) {
|
|
52662
|
+
;
|
|
52663
|
+
p5[p5.length - 1] += postParts.shift();
|
|
52664
|
+
p5.push.apply(p5, postParts);
|
|
52665
|
+
}
|
|
52666
|
+
parts.push.apply(parts, p5);
|
|
52667
|
+
return parts;
|
|
52668
|
+
}
|
|
52669
|
+
function expand(str, options = {}) {
|
|
52670
|
+
if (!str) {
|
|
52671
|
+
return [];
|
|
52672
|
+
}
|
|
52673
|
+
const { max = EXPANSION_MAX } = options;
|
|
52674
|
+
if (str.slice(0, 2) === "{}") {
|
|
52675
|
+
str = "\\{\\}" + str.slice(2);
|
|
52676
|
+
}
|
|
52677
|
+
return expand_(escapeBraces(str), max, true).map(unescapeBraces);
|
|
52678
|
+
}
|
|
52679
|
+
function embrace(str) {
|
|
52680
|
+
return "{" + str + "}";
|
|
52681
|
+
}
|
|
52682
|
+
function isPadded(el) {
|
|
52683
|
+
return /^-?0\d/.test(el);
|
|
52684
|
+
}
|
|
52685
|
+
function lte(i5, y2) {
|
|
52686
|
+
return i5 <= y2;
|
|
52687
|
+
}
|
|
52688
|
+
function gte(i5, y2) {
|
|
52689
|
+
return i5 >= y2;
|
|
52690
|
+
}
|
|
52691
|
+
function expand_(str, max, isTop) {
|
|
52692
|
+
const expansions = [];
|
|
52693
|
+
const m5 = balanced("{", "}", str);
|
|
52694
|
+
if (!m5)
|
|
52695
|
+
return [str];
|
|
52696
|
+
const pre = m5.pre;
|
|
52697
|
+
const post = m5.post.length ? expand_(m5.post, max, false) : [""];
|
|
52698
|
+
if (/\$$/.test(m5.pre)) {
|
|
52699
|
+
for (let k5 = 0; k5 < post.length && k5 < max; k5++) {
|
|
52700
|
+
const expansion = pre + "{" + m5.body + "}" + post[k5];
|
|
52701
|
+
expansions.push(expansion);
|
|
51935
52702
|
}
|
|
51936
|
-
|
|
51937
|
-
|
|
51938
|
-
|
|
51939
|
-
|
|
51940
|
-
|
|
51941
|
-
|
|
51942
|
-
if (
|
|
51943
|
-
|
|
51944
|
-
|
|
51945
|
-
|
|
51946
|
-
|
|
51947
|
-
|
|
51948
|
-
|
|
51949
|
-
|
|
51950
|
-
|
|
51951
|
-
|
|
51952
|
-
|
|
51953
|
-
|
|
51954
|
-
|
|
51955
|
-
|
|
51956
|
-
|
|
51957
|
-
|
|
51958
|
-
|
|
51959
|
-
|
|
51960
|
-
|
|
51961
|
-
|
|
51962
|
-
|
|
51963
|
-
|
|
51964
|
-
|
|
51965
|
-
|
|
51966
|
-
|
|
51967
|
-
|
|
51968
|
-
|
|
51969
|
-
|
|
51970
|
-
|
|
52703
|
+
} else {
|
|
52704
|
+
const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m5.body);
|
|
52705
|
+
const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m5.body);
|
|
52706
|
+
const isSequence = isNumericSequence || isAlphaSequence;
|
|
52707
|
+
const isOptions = m5.body.indexOf(",") >= 0;
|
|
52708
|
+
if (!isSequence && !isOptions) {
|
|
52709
|
+
if (m5.post.match(/,(?!,).*\}/)) {
|
|
52710
|
+
str = m5.pre + "{" + m5.body + escClose + m5.post;
|
|
52711
|
+
return expand_(str, max, true);
|
|
52712
|
+
}
|
|
52713
|
+
return [str];
|
|
52714
|
+
}
|
|
52715
|
+
let n5;
|
|
52716
|
+
if (isSequence) {
|
|
52717
|
+
n5 = m5.body.split(/\.\./);
|
|
52718
|
+
} else {
|
|
52719
|
+
n5 = parseCommaParts(m5.body);
|
|
52720
|
+
if (n5.length === 1 && n5[0] !== void 0) {
|
|
52721
|
+
n5 = expand_(n5[0], max, false).map(embrace);
|
|
52722
|
+
if (n5.length === 1) {
|
|
52723
|
+
return post.map((p5) => m5.pre + n5[0] + p5);
|
|
52724
|
+
}
|
|
52725
|
+
}
|
|
52726
|
+
}
|
|
52727
|
+
let N;
|
|
52728
|
+
if (isSequence && n5[0] !== void 0 && n5[1] !== void 0) {
|
|
52729
|
+
const x5 = numeric(n5[0]);
|
|
52730
|
+
const y2 = numeric(n5[1]);
|
|
52731
|
+
const width = Math.max(n5[0].length, n5[1].length);
|
|
52732
|
+
let incr = n5.length === 3 && n5[2] !== void 0 ? Math.abs(numeric(n5[2])) : 1;
|
|
52733
|
+
let test = lte;
|
|
52734
|
+
const reverse = y2 < x5;
|
|
52735
|
+
if (reverse) {
|
|
52736
|
+
incr *= -1;
|
|
52737
|
+
test = gte;
|
|
52738
|
+
}
|
|
52739
|
+
const pad = n5.some(isPadded);
|
|
52740
|
+
N = [];
|
|
52741
|
+
for (let i5 = x5; test(i5, y2); i5 += incr) {
|
|
52742
|
+
let c5;
|
|
52743
|
+
if (isAlphaSequence) {
|
|
52744
|
+
c5 = String.fromCharCode(i5);
|
|
52745
|
+
if (c5 === "\\") {
|
|
52746
|
+
c5 = "";
|
|
51971
52747
|
}
|
|
51972
|
-
}
|
|
51973
|
-
|
|
51974
|
-
|
|
51975
|
-
|
|
51976
|
-
|
|
51977
|
-
|
|
51978
|
-
|
|
51979
|
-
|
|
51980
|
-
|
|
51981
|
-
|
|
51982
|
-
incr *= -1;
|
|
51983
|
-
test = gte;
|
|
51984
|
-
}
|
|
51985
|
-
var pad = n5.some(isPadded);
|
|
51986
|
-
N = [];
|
|
51987
|
-
for (var i5 = x5; test(i5, y2); i5 += incr) {
|
|
51988
|
-
var c5;
|
|
51989
|
-
if (isAlphaSequence) {
|
|
51990
|
-
c5 = String.fromCharCode(i5);
|
|
51991
|
-
if (c5 === "\\")
|
|
51992
|
-
c5 = "";
|
|
51993
|
-
} else {
|
|
51994
|
-
c5 = String(i5);
|
|
51995
|
-
if (pad) {
|
|
51996
|
-
var need = width - c5.length;
|
|
51997
|
-
if (need > 0) {
|
|
51998
|
-
var z2 = new Array(need + 1).join("0");
|
|
51999
|
-
if (i5 < 0)
|
|
52000
|
-
c5 = "-" + z2 + c5.slice(1);
|
|
52001
|
-
else
|
|
52002
|
-
c5 = z2 + c5;
|
|
52003
|
-
}
|
|
52748
|
+
} else {
|
|
52749
|
+
c5 = String(i5);
|
|
52750
|
+
if (pad) {
|
|
52751
|
+
const need = width - c5.length;
|
|
52752
|
+
if (need > 0) {
|
|
52753
|
+
const z2 = new Array(need + 1).join("0");
|
|
52754
|
+
if (i5 < 0) {
|
|
52755
|
+
c5 = "-" + z2 + c5.slice(1);
|
|
52756
|
+
} else {
|
|
52757
|
+
c5 = z2 + c5;
|
|
52004
52758
|
}
|
|
52005
52759
|
}
|
|
52006
|
-
N.push(c5);
|
|
52007
|
-
}
|
|
52008
|
-
} else {
|
|
52009
|
-
N = [];
|
|
52010
|
-
for (var j5 = 0; j5 < n5.length; j5++) {
|
|
52011
|
-
N.push.apply(N, expand2(n5[j5], false));
|
|
52012
52760
|
}
|
|
52013
52761
|
}
|
|
52014
|
-
|
|
52015
|
-
|
|
52016
|
-
|
|
52017
|
-
|
|
52018
|
-
|
|
52019
|
-
|
|
52762
|
+
N.push(c5);
|
|
52763
|
+
}
|
|
52764
|
+
} else {
|
|
52765
|
+
N = [];
|
|
52766
|
+
for (let j5 = 0; j5 < n5.length; j5++) {
|
|
52767
|
+
N.push.apply(N, expand_(n5[j5], max, false));
|
|
52768
|
+
}
|
|
52769
|
+
}
|
|
52770
|
+
for (let j5 = 0; j5 < N.length; j5++) {
|
|
52771
|
+
for (let k5 = 0; k5 < post.length && expansions.length < max; k5++) {
|
|
52772
|
+
const expansion = pre + N[j5] + post[k5];
|
|
52773
|
+
if (!isTop || isSequence || expansion) {
|
|
52774
|
+
expansions.push(expansion);
|
|
52020
52775
|
}
|
|
52021
52776
|
}
|
|
52022
|
-
return expansions;
|
|
52023
52777
|
}
|
|
52024
52778
|
}
|
|
52779
|
+
return expansions;
|
|
52780
|
+
}
|
|
52781
|
+
var escSlash, escOpen, escClose, escComma, escPeriod, escSlashPattern, escOpenPattern, escClosePattern, escCommaPattern, escPeriodPattern, slashPattern, openPattern, closePattern, commaPattern, periodPattern, EXPANSION_MAX;
|
|
52782
|
+
var init_esm2 = __esm({
|
|
52783
|
+
"node_modules/brace-expansion/dist/esm/index.js"() {
|
|
52784
|
+
init_esm();
|
|
52785
|
+
escSlash = "\0SLASH" + Math.random() + "\0";
|
|
52786
|
+
escOpen = "\0OPEN" + Math.random() + "\0";
|
|
52787
|
+
escClose = "\0CLOSE" + Math.random() + "\0";
|
|
52788
|
+
escComma = "\0COMMA" + Math.random() + "\0";
|
|
52789
|
+
escPeriod = "\0PERIOD" + Math.random() + "\0";
|
|
52790
|
+
escSlashPattern = new RegExp(escSlash, "g");
|
|
52791
|
+
escOpenPattern = new RegExp(escOpen, "g");
|
|
52792
|
+
escClosePattern = new RegExp(escClose, "g");
|
|
52793
|
+
escCommaPattern = new RegExp(escComma, "g");
|
|
52794
|
+
escPeriodPattern = new RegExp(escPeriod, "g");
|
|
52795
|
+
slashPattern = /\\\\/g;
|
|
52796
|
+
openPattern = /\\{/g;
|
|
52797
|
+
closePattern = /\\}/g;
|
|
52798
|
+
commaPattern = /\\,/g;
|
|
52799
|
+
periodPattern = /\\./g;
|
|
52800
|
+
EXPANSION_MAX = 1e5;
|
|
52801
|
+
}
|
|
52025
52802
|
});
|
|
52026
52803
|
|
|
52027
52804
|
// node_modules/minimatch/dist/esm/assert-valid-pattern.js
|
|
@@ -52604,11 +53381,13 @@ var init_ast = __esm({
|
|
|
52604
53381
|
let escaping = false;
|
|
52605
53382
|
let re = "";
|
|
52606
53383
|
let uflag = false;
|
|
53384
|
+
let inStar = false;
|
|
52607
53385
|
for (let i5 = 0; i5 < glob2.length; i5++) {
|
|
52608
53386
|
const c5 = glob2.charAt(i5);
|
|
52609
53387
|
if (escaping) {
|
|
52610
53388
|
escaping = false;
|
|
52611
53389
|
re += (reSpecials.has(c5) ? "\\" : "") + c5;
|
|
53390
|
+
inStar = false;
|
|
52612
53391
|
continue;
|
|
52613
53392
|
}
|
|
52614
53393
|
if (c5 === "\\") {
|
|
@@ -52626,16 +53405,19 @@ var init_ast = __esm({
|
|
|
52626
53405
|
uflag = uflag || needUflag;
|
|
52627
53406
|
i5 += consumed - 1;
|
|
52628
53407
|
hasMagic2 = hasMagic2 || magic;
|
|
53408
|
+
inStar = false;
|
|
52629
53409
|
continue;
|
|
52630
53410
|
}
|
|
52631
53411
|
}
|
|
52632
53412
|
if (c5 === "*") {
|
|
52633
|
-
if (
|
|
52634
|
-
|
|
52635
|
-
|
|
52636
|
-
|
|
53413
|
+
if (inStar)
|
|
53414
|
+
continue;
|
|
53415
|
+
inStar = true;
|
|
53416
|
+
re += noEmpty && /^[*]+$/.test(glob2) ? starNoEmpty : star;
|
|
52637
53417
|
hasMagic2 = true;
|
|
52638
53418
|
continue;
|
|
53419
|
+
} else {
|
|
53420
|
+
inStar = false;
|
|
52639
53421
|
}
|
|
52640
53422
|
if (c5 === "?") {
|
|
52641
53423
|
re += qmark;
|
|
@@ -52661,10 +53443,10 @@ var init_escape = __esm({
|
|
|
52661
53443
|
});
|
|
52662
53444
|
|
|
52663
53445
|
// node_modules/minimatch/dist/esm/index.js
|
|
52664
|
-
var
|
|
52665
|
-
var
|
|
53446
|
+
var minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path5, sep3, GLOBSTAR, qmark2, star2, twoStarDot, twoStarNoDot, filter, ext, defaults, braceExpand, makeRe, match, globMagic, regExpEscape2, Minimatch;
|
|
53447
|
+
var init_esm3 = __esm({
|
|
52666
53448
|
"node_modules/minimatch/dist/esm/index.js"() {
|
|
52667
|
-
|
|
53449
|
+
init_esm2();
|
|
52668
53450
|
init_assert_valid_pattern();
|
|
52669
53451
|
init_ast();
|
|
52670
53452
|
init_escape();
|
|
@@ -52787,7 +53569,7 @@ var init_esm = __esm({
|
|
|
52787
53569
|
if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
|
|
52788
53570
|
return [pattern];
|
|
52789
53571
|
}
|
|
52790
|
-
return (
|
|
53572
|
+
return expand(pattern);
|
|
52791
53573
|
};
|
|
52792
53574
|
minimatch.braceExpand = braceExpand;
|
|
52793
53575
|
makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
|
|
@@ -53393,7 +54175,7 @@ var init_esm = __esm({
|
|
|
53393
54175
|
|
|
53394
54176
|
// node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js
|
|
53395
54177
|
var perf, warned, PROCESS, emitWarning, AC, AS, shouldWarn, TYPE, isPosInt, getUintArray, ZeroArray, Stack, LRUCache;
|
|
53396
|
-
var
|
|
54178
|
+
var init_esm4 = __esm({
|
|
53397
54179
|
"node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js"() {
|
|
53398
54180
|
perf = typeof performance === "object" && performance && typeof performance.now === "function" ? performance : Date;
|
|
53399
54181
|
warned = /* @__PURE__ */ new Set();
|
|
@@ -54767,7 +55549,7 @@ var init_esm2 = __esm({
|
|
|
54767
55549
|
|
|
54768
55550
|
// node_modules/minipass/dist/esm/index.js
|
|
54769
55551
|
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;
|
|
54770
|
-
var
|
|
55552
|
+
var init_esm5 = __esm({
|
|
54771
55553
|
"node_modules/minipass/dist/esm/index.js"() {
|
|
54772
55554
|
import_node_events = require("node:events");
|
|
54773
55555
|
import_node_stream = __toESM(require("node:stream"), 1);
|
|
@@ -55497,10 +56279,10 @@ var init_esm3 = __esm({
|
|
|
55497
56279
|
* Return a void Promise that resolves once the stream ends.
|
|
55498
56280
|
*/
|
|
55499
56281
|
async promise() {
|
|
55500
|
-
return new Promise((
|
|
56282
|
+
return new Promise((resolve8, reject2) => {
|
|
55501
56283
|
this.on(DESTROYED, () => reject2(new Error("stream destroyed")));
|
|
55502
56284
|
this.on("error", (er) => reject2(er));
|
|
55503
|
-
this.on("end", () =>
|
|
56285
|
+
this.on("end", () => resolve8());
|
|
55504
56286
|
});
|
|
55505
56287
|
}
|
|
55506
56288
|
/**
|
|
@@ -55524,7 +56306,7 @@ var init_esm3 = __esm({
|
|
|
55524
56306
|
return Promise.resolve({ done: false, value: res });
|
|
55525
56307
|
if (this[EOF])
|
|
55526
56308
|
return stop();
|
|
55527
|
-
let
|
|
56309
|
+
let resolve8;
|
|
55528
56310
|
let reject2;
|
|
55529
56311
|
const onerr = (er) => {
|
|
55530
56312
|
this.off("data", ondata);
|
|
@@ -55538,19 +56320,19 @@ var init_esm3 = __esm({
|
|
|
55538
56320
|
this.off("end", onend);
|
|
55539
56321
|
this.off(DESTROYED, ondestroy);
|
|
55540
56322
|
this.pause();
|
|
55541
|
-
|
|
56323
|
+
resolve8({ value, done: !!this[EOF] });
|
|
55542
56324
|
};
|
|
55543
56325
|
const onend = () => {
|
|
55544
56326
|
this.off("error", onerr);
|
|
55545
56327
|
this.off("data", ondata);
|
|
55546
56328
|
this.off(DESTROYED, ondestroy);
|
|
55547
56329
|
stop();
|
|
55548
|
-
|
|
56330
|
+
resolve8({ done: true, value: void 0 });
|
|
55549
56331
|
};
|
|
55550
56332
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
55551
56333
|
return new Promise((res2, rej) => {
|
|
55552
56334
|
reject2 = rej;
|
|
55553
|
-
|
|
56335
|
+
resolve8 = res2;
|
|
55554
56336
|
this.once(DESTROYED, ondestroy);
|
|
55555
56337
|
this.once("error", onerr);
|
|
55556
56338
|
this.once("end", onend);
|
|
@@ -55654,15 +56436,15 @@ var init_esm3 = __esm({
|
|
|
55654
56436
|
|
|
55655
56437
|
// node_modules/path-scurry/dist/esm/index.js
|
|
55656
56438
|
var import_node_path, import_node_url, import_fs7, 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;
|
|
55657
|
-
var
|
|
56439
|
+
var init_esm6 = __esm({
|
|
55658
56440
|
"node_modules/path-scurry/dist/esm/index.js"() {
|
|
55659
|
-
|
|
56441
|
+
init_esm4();
|
|
55660
56442
|
import_node_path = require("node:path");
|
|
55661
56443
|
import_node_url = require("node:url");
|
|
55662
56444
|
import_fs7 = require("fs");
|
|
55663
56445
|
actualFS = __toESM(require("node:fs"), 1);
|
|
55664
56446
|
import_promises = require("node:fs/promises");
|
|
55665
|
-
|
|
56447
|
+
init_esm5();
|
|
55666
56448
|
realpathSync2 = import_fs7.realpathSync.native;
|
|
55667
56449
|
defaultFS = {
|
|
55668
56450
|
lstatSync: import_fs7.lstatSync,
|
|
@@ -56534,9 +57316,9 @@ var init_esm4 = __esm({
|
|
|
56534
57316
|
if (this.#asyncReaddirInFlight) {
|
|
56535
57317
|
await this.#asyncReaddirInFlight;
|
|
56536
57318
|
} else {
|
|
56537
|
-
let
|
|
57319
|
+
let resolve8 = () => {
|
|
56538
57320
|
};
|
|
56539
|
-
this.#asyncReaddirInFlight = new Promise((res) =>
|
|
57321
|
+
this.#asyncReaddirInFlight = new Promise((res) => resolve8 = res);
|
|
56540
57322
|
try {
|
|
56541
57323
|
for (const e5 of await this.#fs.promises.readdir(fullpath, {
|
|
56542
57324
|
withFileTypes: true
|
|
@@ -56549,7 +57331,7 @@ var init_esm4 = __esm({
|
|
|
56549
57331
|
children.provisional = 0;
|
|
56550
57332
|
}
|
|
56551
57333
|
this.#asyncReaddirInFlight = void 0;
|
|
56552
|
-
|
|
57334
|
+
resolve8();
|
|
56553
57335
|
}
|
|
56554
57336
|
return children.slice(0, children.provisional);
|
|
56555
57337
|
}
|
|
@@ -57392,7 +58174,7 @@ var init_esm4 = __esm({
|
|
|
57392
58174
|
var isPatternList, isGlobList, Pattern;
|
|
57393
58175
|
var init_pattern = __esm({
|
|
57394
58176
|
"node_modules/glob/dist/esm/pattern.js"() {
|
|
57395
|
-
|
|
58177
|
+
init_esm3();
|
|
57396
58178
|
isPatternList = (pl) => pl.length >= 1;
|
|
57397
58179
|
isGlobList = (gl) => gl.length >= 1;
|
|
57398
58180
|
Pattern = class _Pattern {
|
|
@@ -57563,7 +58345,7 @@ var init_pattern = __esm({
|
|
|
57563
58345
|
var defaultPlatform2, Ignore;
|
|
57564
58346
|
var init_ignore = __esm({
|
|
57565
58347
|
"node_modules/glob/dist/esm/ignore.js"() {
|
|
57566
|
-
|
|
58348
|
+
init_esm3();
|
|
57567
58349
|
init_pattern();
|
|
57568
58350
|
defaultPlatform2 = typeof process === "object" && process && typeof process.platform === "string" ? process.platform : "linux";
|
|
57569
58351
|
Ignore = class {
|
|
@@ -57657,7 +58439,7 @@ var init_ignore = __esm({
|
|
|
57657
58439
|
var HasWalkedCache, MatchRecord, SubWalks, Processor;
|
|
57658
58440
|
var init_processor = __esm({
|
|
57659
58441
|
"node_modules/glob/dist/esm/processor.js"() {
|
|
57660
|
-
|
|
58442
|
+
init_esm3();
|
|
57661
58443
|
HasWalkedCache = class _HasWalkedCache {
|
|
57662
58444
|
store;
|
|
57663
58445
|
constructor(store = /* @__PURE__ */ new Map()) {
|
|
@@ -57884,7 +58666,7 @@ var init_processor = __esm({
|
|
|
57884
58666
|
var makeIgnore, GlobUtil, GlobWalker, GlobStream;
|
|
57885
58667
|
var init_walker = __esm({
|
|
57886
58668
|
"node_modules/glob/dist/esm/walker.js"() {
|
|
57887
|
-
|
|
58669
|
+
init_esm5();
|
|
57888
58670
|
init_ignore();
|
|
57889
58671
|
init_processor();
|
|
57890
58672
|
makeIgnore = (ignore2, opts) => typeof ignore2 === "string" ? new Ignore([ignore2], opts) : Array.isArray(ignore2) ? new Ignore(ignore2, opts) : ignore2;
|
|
@@ -58219,9 +59001,9 @@ var init_walker = __esm({
|
|
|
58219
59001
|
var import_node_url2, defaultPlatform3, Glob;
|
|
58220
59002
|
var init_glob = __esm({
|
|
58221
59003
|
"node_modules/glob/dist/esm/glob.js"() {
|
|
58222
|
-
|
|
59004
|
+
init_esm3();
|
|
58223
59005
|
import_node_url2 = require("node:url");
|
|
58224
|
-
|
|
59006
|
+
init_esm6();
|
|
58225
59007
|
init_pattern();
|
|
58226
59008
|
init_walker();
|
|
58227
59009
|
defaultPlatform3 = typeof process === "object" && process && typeof process.platform === "string" ? process.platform : "linux";
|
|
@@ -58429,7 +59211,7 @@ var init_glob = __esm({
|
|
|
58429
59211
|
var hasMagic;
|
|
58430
59212
|
var init_has_magic = __esm({
|
|
58431
59213
|
"node_modules/glob/dist/esm/has-magic.js"() {
|
|
58432
|
-
|
|
59214
|
+
init_esm3();
|
|
58433
59215
|
hasMagic = (pattern, options = {}) => {
|
|
58434
59216
|
if (!Array.isArray(pattern)) {
|
|
58435
59217
|
pattern = [pattern];
|
|
@@ -58463,12 +59245,12 @@ function globIterate(pattern, options = {}) {
|
|
|
58463
59245
|
return new Glob(pattern, options).iterate();
|
|
58464
59246
|
}
|
|
58465
59247
|
var streamSync, stream, iterateSync, iterate, sync, glob;
|
|
58466
|
-
var
|
|
59248
|
+
var init_esm7 = __esm({
|
|
58467
59249
|
"node_modules/glob/dist/esm/index.js"() {
|
|
58468
|
-
|
|
59250
|
+
init_esm3();
|
|
58469
59251
|
init_glob();
|
|
58470
59252
|
init_has_magic();
|
|
58471
|
-
|
|
59253
|
+
init_esm3();
|
|
58472
59254
|
init_glob();
|
|
58473
59255
|
init_has_magic();
|
|
58474
59256
|
init_ignore();
|
|
@@ -58804,6 +59586,7 @@ ${lastError}
|
|
|
58804
59586
|
|
|
58805
59587
|
RULES REMINDER:
|
|
58806
59588
|
- search(query) is KEYWORD SEARCH \u2014 pass a search query, NOT a filename. Use extract(filepath) to read file contents.
|
|
59589
|
+
- search(query, path) \u2014 the path argument must be a STRING, not an object. Use field.file_path, not field.
|
|
58807
59590
|
- search() returns up to 20K tokens by default. Use search(query, path, {maxTokens: null}) for unlimited, or searchAll(query) to auto-paginate ALL results.
|
|
58808
59591
|
- search(), searchAll(), query(), extract(), listFiles(), bash() all return STRINGS, not arrays.
|
|
58809
59592
|
- Use chunk(stringData) to split a string into an array of chunks.
|
|
@@ -58812,7 +59595,8 @@ RULES REMINDER:
|
|
|
58812
59595
|
- Do NOT define helper functions that call tools \u2014 write logic inline.
|
|
58813
59596
|
- Do NOT use async/await, template literals, or shorthand properties.
|
|
58814
59597
|
- Do NOT use regex literals (/pattern/) \u2014 use String methods like indexOf, includes, startsWith instead.
|
|
58815
|
-
- String concatenation with +, not template literals
|
|
59598
|
+
- String concatenation with +, not template literals.
|
|
59599
|
+
- IMPORTANT: If a tool returns "ERROR: ...", do NOT pass that error string to LLM() \u2014 handle or skip it.`;
|
|
58816
59600
|
const fixedCode = await llmCallFn(fixPrompt, "", { maxTokens: 4e3, temperature: 0.2 });
|
|
58817
59601
|
currentCode = stripCodeWrapping(fixedCode);
|
|
58818
59602
|
planSpan?.addEvent?.("dsl.self_heal_complete", {
|
|
@@ -59426,7 +60210,7 @@ var init_executePlan = __esm({
|
|
|
59426
60210
|
init_query();
|
|
59427
60211
|
init_extract();
|
|
59428
60212
|
init_delegate();
|
|
59429
|
-
|
|
60213
|
+
init_esm7();
|
|
59430
60214
|
init_bash();
|
|
59431
60215
|
RAW_OUTPUT_START = "<<<RAW_OUTPUT>>>";
|
|
59432
60216
|
RAW_OUTPUT_END = "<<<END_RAW_OUTPUT>>>";
|
|
@@ -59698,13 +60482,271 @@ var init_file_lister = __esm({
|
|
|
59698
60482
|
}
|
|
59699
60483
|
});
|
|
59700
60484
|
|
|
60485
|
+
// src/tools/fileTracker.js
|
|
60486
|
+
function computeContentHash(content) {
|
|
60487
|
+
const normalized = (content || "").split("\n").map((l5) => l5.trimEnd()).join("\n");
|
|
60488
|
+
return (0, import_crypto3.createHash)("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
60489
|
+
}
|
|
60490
|
+
function extractFilePath(target) {
|
|
60491
|
+
const hashIdx = target.indexOf("#");
|
|
60492
|
+
if (hashIdx !== -1) {
|
|
60493
|
+
return target.slice(0, hashIdx);
|
|
60494
|
+
}
|
|
60495
|
+
const colonIdx = target.lastIndexOf(":");
|
|
60496
|
+
if (colonIdx !== -1) {
|
|
60497
|
+
const after = target.slice(colonIdx + 1);
|
|
60498
|
+
if (/^\d+(-\d+)?$/.test(after)) {
|
|
60499
|
+
return target.slice(0, colonIdx);
|
|
60500
|
+
}
|
|
60501
|
+
}
|
|
60502
|
+
return target;
|
|
60503
|
+
}
|
|
60504
|
+
function extractSymbolName(target) {
|
|
60505
|
+
const hashIdx = target.indexOf("#");
|
|
60506
|
+
if (hashIdx !== -1) {
|
|
60507
|
+
const symbol15 = target.slice(hashIdx + 1);
|
|
60508
|
+
return symbol15 || null;
|
|
60509
|
+
}
|
|
60510
|
+
return null;
|
|
60511
|
+
}
|
|
60512
|
+
function parseFilePathsFromOutput(output) {
|
|
60513
|
+
const paths = [];
|
|
60514
|
+
const regex = /^(?:File:\s+|---\s+)([^\s].*?)(?:\s+---)?$/gm;
|
|
60515
|
+
let match2;
|
|
60516
|
+
while ((match2 = regex.exec(output)) !== null) {
|
|
60517
|
+
const path9 = match2[1].trim();
|
|
60518
|
+
if (path9 && !path9.startsWith("Results") && !path9.startsWith("Page") && (path9.includes("/") || path9.includes(".") || path9.includes("\\"))) {
|
|
60519
|
+
paths.push(path9);
|
|
60520
|
+
}
|
|
60521
|
+
}
|
|
60522
|
+
return paths;
|
|
60523
|
+
}
|
|
60524
|
+
var import_crypto3, import_path10, FileTracker;
|
|
60525
|
+
var init_fileTracker = __esm({
|
|
60526
|
+
"src/tools/fileTracker.js"() {
|
|
60527
|
+
"use strict";
|
|
60528
|
+
import_crypto3 = require("crypto");
|
|
60529
|
+
import_path10 = require("path");
|
|
60530
|
+
init_symbolEdit();
|
|
60531
|
+
FileTracker = class {
|
|
60532
|
+
/**
|
|
60533
|
+
* @param {Object} [options]
|
|
60534
|
+
* @param {boolean} [options.debug=false] - Enable debug logging
|
|
60535
|
+
*/
|
|
60536
|
+
constructor(options = {}) {
|
|
60537
|
+
this.debug = options.debug || false;
|
|
60538
|
+
this._seenFiles = /* @__PURE__ */ new Set();
|
|
60539
|
+
this._contentRecords = /* @__PURE__ */ new Map();
|
|
60540
|
+
}
|
|
60541
|
+
/**
|
|
60542
|
+
* Mark a file as "seen" — the LLM has read its content.
|
|
60543
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60544
|
+
*/
|
|
60545
|
+
markFileSeen(resolvedPath2) {
|
|
60546
|
+
this._seenFiles.add(resolvedPath2);
|
|
60547
|
+
if (this.debug) {
|
|
60548
|
+
console.error(`[FileTracker] Marked as seen: ${resolvedPath2}`);
|
|
60549
|
+
}
|
|
60550
|
+
}
|
|
60551
|
+
/**
|
|
60552
|
+
* Check if a file has been seen in this session.
|
|
60553
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60554
|
+
* @returns {boolean}
|
|
60555
|
+
*/
|
|
60556
|
+
isFileSeen(resolvedPath2) {
|
|
60557
|
+
return this._seenFiles.has(resolvedPath2);
|
|
60558
|
+
}
|
|
60559
|
+
/**
|
|
60560
|
+
* Store a content hash for a symbol in a file.
|
|
60561
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60562
|
+
* @param {string} symbolName - Symbol name (e.g. "calculateTotal")
|
|
60563
|
+
* @param {string} code - The symbol's source code
|
|
60564
|
+
* @param {number} startLine - 1-indexed start line
|
|
60565
|
+
* @param {number} endLine - 1-indexed end line
|
|
60566
|
+
* @param {string} [source='extract'] - How the content was obtained
|
|
60567
|
+
*/
|
|
60568
|
+
trackSymbolContent(resolvedPath2, symbolName, code, startLine, endLine, source = "extract") {
|
|
60569
|
+
const key = `${resolvedPath2}#${symbolName}`;
|
|
60570
|
+
const contentHash = computeContentHash(code);
|
|
60571
|
+
this._contentRecords.set(key, {
|
|
60572
|
+
contentHash,
|
|
60573
|
+
startLine,
|
|
60574
|
+
endLine,
|
|
60575
|
+
symbolName,
|
|
60576
|
+
source,
|
|
60577
|
+
timestamp: Date.now()
|
|
60578
|
+
});
|
|
60579
|
+
if (this.debug) {
|
|
60580
|
+
console.error(`[FileTracker] Tracked symbol ${key} (hash: ${contentHash}, lines ${startLine}-${endLine})`);
|
|
60581
|
+
}
|
|
60582
|
+
}
|
|
60583
|
+
/**
|
|
60584
|
+
* Look up a stored content record for a symbol.
|
|
60585
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60586
|
+
* @param {string} symbolName - Symbol name
|
|
60587
|
+
* @returns {Object|null} The stored record or null
|
|
60588
|
+
*/
|
|
60589
|
+
getSymbolRecord(resolvedPath2, symbolName) {
|
|
60590
|
+
return this._contentRecords.get(`${resolvedPath2}#${symbolName}`) || null;
|
|
60591
|
+
}
|
|
60592
|
+
/**
|
|
60593
|
+
* Check if a symbol's current content matches what was stored.
|
|
60594
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60595
|
+
* @param {string} symbolName - Symbol name
|
|
60596
|
+
* @param {string} currentCode - The symbol's current source code (from findSymbol)
|
|
60597
|
+
* @returns {{ok: boolean, reason?: string, message?: string}}
|
|
60598
|
+
*/
|
|
60599
|
+
checkSymbolContent(resolvedPath2, symbolName, currentCode) {
|
|
60600
|
+
const key = `${resolvedPath2}#${symbolName}`;
|
|
60601
|
+
const record = this._contentRecords.get(key);
|
|
60602
|
+
if (!record) {
|
|
60603
|
+
return { ok: true };
|
|
60604
|
+
}
|
|
60605
|
+
const currentHash = computeContentHash(currentCode);
|
|
60606
|
+
if (currentHash === record.contentHash) {
|
|
60607
|
+
return { ok: true };
|
|
60608
|
+
}
|
|
60609
|
+
return {
|
|
60610
|
+
ok: false,
|
|
60611
|
+
reason: "stale",
|
|
60612
|
+
message: `Symbol "${symbolName}" has changed since you last read it (hash: ${record.contentHash} \u2192 ${currentHash}).`
|
|
60613
|
+
};
|
|
60614
|
+
}
|
|
60615
|
+
/**
|
|
60616
|
+
* Track files from extract target strings.
|
|
60617
|
+
* Marks each file as seen. For #symbol targets, calls findSymbol to get and hash the code.
|
|
60618
|
+
* @param {string[]} targets - Array of extract targets (e.g. ["file.js#fn", "file.js:10-20"])
|
|
60619
|
+
* @param {string} cwd - Working directory for resolving relative paths
|
|
60620
|
+
*/
|
|
60621
|
+
async trackFilesFromExtract(targets, cwd) {
|
|
60622
|
+
const seenPaths = /* @__PURE__ */ new Set();
|
|
60623
|
+
const symbolPromises = [];
|
|
60624
|
+
for (const target of targets) {
|
|
60625
|
+
const filePath = extractFilePath(target);
|
|
60626
|
+
const resolved = (0, import_path10.isAbsolute)(filePath) ? filePath : (0, import_path10.resolve)(cwd, filePath);
|
|
60627
|
+
if (!seenPaths.has(resolved)) {
|
|
60628
|
+
seenPaths.add(resolved);
|
|
60629
|
+
this.markFileSeen(resolved);
|
|
60630
|
+
}
|
|
60631
|
+
const symbolName = extractSymbolName(target);
|
|
60632
|
+
if (symbolName) {
|
|
60633
|
+
symbolPromises.push(
|
|
60634
|
+
findSymbol(resolved, symbolName, cwd).then((symbolInfo) => {
|
|
60635
|
+
if (symbolInfo) {
|
|
60636
|
+
this.trackSymbolContent(
|
|
60637
|
+
resolved,
|
|
60638
|
+
symbolName,
|
|
60639
|
+
symbolInfo.code,
|
|
60640
|
+
symbolInfo.startLine,
|
|
60641
|
+
symbolInfo.endLine,
|
|
60642
|
+
"extract"
|
|
60643
|
+
);
|
|
60644
|
+
}
|
|
60645
|
+
}).catch((err) => {
|
|
60646
|
+
if (this.debug) {
|
|
60647
|
+
console.error(`[FileTracker] Failed to track symbol "${symbolName}" in ${resolved}: ${err.message}`);
|
|
60648
|
+
}
|
|
60649
|
+
})
|
|
60650
|
+
);
|
|
60651
|
+
}
|
|
60652
|
+
}
|
|
60653
|
+
if (symbolPromises.length > 0) {
|
|
60654
|
+
await Promise.all(symbolPromises);
|
|
60655
|
+
}
|
|
60656
|
+
}
|
|
60657
|
+
/**
|
|
60658
|
+
* Track files discovered in probe search/extract output.
|
|
60659
|
+
* Parses "File: path" headers and "--- path ---" separators, marks each as "seen".
|
|
60660
|
+
* @param {string} output - Probe output text
|
|
60661
|
+
* @param {string} cwd - Working directory for resolving relative paths
|
|
60662
|
+
*/
|
|
60663
|
+
async trackFilesFromOutput(output, cwd) {
|
|
60664
|
+
const paths = parseFilePathsFromOutput(output);
|
|
60665
|
+
for (const filePath of paths) {
|
|
60666
|
+
const resolved = (0, import_path10.isAbsolute)(filePath) ? filePath : (0, import_path10.resolve)(cwd, filePath);
|
|
60667
|
+
this.markFileSeen(resolved);
|
|
60668
|
+
}
|
|
60669
|
+
}
|
|
60670
|
+
/**
|
|
60671
|
+
* Check if a file is safe to edit (seen-check only).
|
|
60672
|
+
* Mode-specific content verification happens in edit handlers.
|
|
60673
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60674
|
+
* @returns {{ok: boolean, reason?: string, message?: string}}
|
|
60675
|
+
*/
|
|
60676
|
+
checkBeforeEdit(resolvedPath2) {
|
|
60677
|
+
if (!this._seenFiles.has(resolvedPath2)) {
|
|
60678
|
+
return {
|
|
60679
|
+
ok: false,
|
|
60680
|
+
reason: "untracked",
|
|
60681
|
+
message: "This file has not been read yet in this session. Use extract or search to read the file first."
|
|
60682
|
+
};
|
|
60683
|
+
}
|
|
60684
|
+
return { ok: true };
|
|
60685
|
+
}
|
|
60686
|
+
/**
|
|
60687
|
+
* Mark a file as seen after a successful write (backward compat).
|
|
60688
|
+
* Also invalidates content records for the file since its content changed.
|
|
60689
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60690
|
+
*/
|
|
60691
|
+
async trackFileAfterWrite(resolvedPath2) {
|
|
60692
|
+
this.markFileSeen(resolvedPath2);
|
|
60693
|
+
this.invalidateFileRecords(resolvedPath2);
|
|
60694
|
+
}
|
|
60695
|
+
/**
|
|
60696
|
+
* Update the stored hash for a symbol after a successful write.
|
|
60697
|
+
* Enables chained edits to the same symbol.
|
|
60698
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60699
|
+
* @param {string} symbolName - Symbol name
|
|
60700
|
+
* @param {string} code - The symbol's new source code
|
|
60701
|
+
* @param {number} startLine - 1-indexed start line (new position)
|
|
60702
|
+
* @param {number} endLine - 1-indexed end line (new position)
|
|
60703
|
+
*/
|
|
60704
|
+
trackSymbolAfterWrite(resolvedPath2, symbolName, code, startLine, endLine) {
|
|
60705
|
+
this.trackSymbolContent(resolvedPath2, symbolName, code, startLine, endLine, "edit");
|
|
60706
|
+
}
|
|
60707
|
+
/**
|
|
60708
|
+
* Remove all content records for a file.
|
|
60709
|
+
* Called after non-symbol edits (text/line mode) since those change content
|
|
60710
|
+
* without providing a symbol-level update.
|
|
60711
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60712
|
+
*/
|
|
60713
|
+
invalidateFileRecords(resolvedPath2) {
|
|
60714
|
+
const prefix = resolvedPath2 + "#";
|
|
60715
|
+
for (const key of this._contentRecords.keys()) {
|
|
60716
|
+
if (key.startsWith(prefix)) {
|
|
60717
|
+
this._contentRecords.delete(key);
|
|
60718
|
+
}
|
|
60719
|
+
}
|
|
60720
|
+
if (this.debug) {
|
|
60721
|
+
console.error(`[FileTracker] Invalidated content records for ${resolvedPath2}`);
|
|
60722
|
+
}
|
|
60723
|
+
}
|
|
60724
|
+
/**
|
|
60725
|
+
* Quick sync check if a file is being tracked (alias for isFileSeen).
|
|
60726
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60727
|
+
* @returns {boolean}
|
|
60728
|
+
*/
|
|
60729
|
+
isTracked(resolvedPath2) {
|
|
60730
|
+
return this.isFileSeen(resolvedPath2);
|
|
60731
|
+
}
|
|
60732
|
+
/**
|
|
60733
|
+
* Clear all tracking state.
|
|
60734
|
+
*/
|
|
60735
|
+
clear() {
|
|
60736
|
+
this._seenFiles.clear();
|
|
60737
|
+
this._contentRecords.clear();
|
|
60738
|
+
}
|
|
60739
|
+
};
|
|
60740
|
+
}
|
|
60741
|
+
});
|
|
60742
|
+
|
|
59701
60743
|
// src/agent/simpleTelemetry.js
|
|
59702
|
-
var import_fs9,
|
|
60744
|
+
var import_fs9, import_path11;
|
|
59703
60745
|
var init_simpleTelemetry = __esm({
|
|
59704
60746
|
"src/agent/simpleTelemetry.js"() {
|
|
59705
60747
|
"use strict";
|
|
59706
60748
|
import_fs9 = require("fs");
|
|
59707
|
-
|
|
60749
|
+
import_path11 = require("path");
|
|
59708
60750
|
}
|
|
59709
60751
|
});
|
|
59710
60752
|
|
|
@@ -59803,19 +60845,19 @@ function createWrappedTools(baseTools) {
|
|
|
59803
60845
|
}
|
|
59804
60846
|
return wrappedTools;
|
|
59805
60847
|
}
|
|
59806
|
-
var import_child_process8, import_util12,
|
|
60848
|
+
var import_child_process8, import_util12, import_crypto4, import_events, import_fs10, import_fs11, import_path12, toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
|
|
59807
60849
|
var init_probeTool = __esm({
|
|
59808
60850
|
"src/agent/probeTool.js"() {
|
|
59809
60851
|
"use strict";
|
|
59810
60852
|
init_index();
|
|
59811
60853
|
import_child_process8 = require("child_process");
|
|
59812
60854
|
import_util12 = require("util");
|
|
59813
|
-
|
|
60855
|
+
import_crypto4 = require("crypto");
|
|
59814
60856
|
import_events = require("events");
|
|
59815
60857
|
import_fs10 = __toESM(require("fs"), 1);
|
|
59816
60858
|
import_fs11 = require("fs");
|
|
59817
|
-
|
|
59818
|
-
|
|
60859
|
+
import_path12 = __toESM(require("path"), 1);
|
|
60860
|
+
init_esm7();
|
|
59819
60861
|
init_symlink_utils();
|
|
59820
60862
|
toolCallEmitter = new import_events.EventEmitter();
|
|
59821
60863
|
activeToolExecutions = /* @__PURE__ */ new Map();
|
|
@@ -59825,7 +60867,7 @@ var init_probeTool = __esm({
|
|
|
59825
60867
|
// Spread schema, description etc.
|
|
59826
60868
|
execute: async (params) => {
|
|
59827
60869
|
const debug = process.env.DEBUG === "1";
|
|
59828
|
-
const toolSessionId = params.sessionId || (0,
|
|
60870
|
+
const toolSessionId = params.sessionId || (0, import_crypto4.randomUUID)();
|
|
59829
60871
|
if (debug) {
|
|
59830
60872
|
console.log(`[DEBUG] probeTool: Executing ${toolName} for session ${toolSessionId}`);
|
|
59831
60873
|
}
|
|
@@ -59903,17 +60945,17 @@ var init_probeTool = __esm({
|
|
|
59903
60945
|
execute: async (params) => {
|
|
59904
60946
|
const { directory = ".", workingDirectory } = params;
|
|
59905
60947
|
const baseCwd = workingDirectory || process.cwd();
|
|
59906
|
-
const secureBaseDir =
|
|
60948
|
+
const secureBaseDir = import_path12.default.resolve(baseCwd);
|
|
59907
60949
|
const isDependencyPath = directory.startsWith("/dep/") || directory.startsWith("go:") || directory.startsWith("js:") || directory.startsWith("rust:");
|
|
59908
60950
|
let targetDir;
|
|
59909
|
-
if (
|
|
59910
|
-
targetDir =
|
|
59911
|
-
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir +
|
|
60951
|
+
if (import_path12.default.isAbsolute(directory)) {
|
|
60952
|
+
targetDir = import_path12.default.resolve(directory);
|
|
60953
|
+
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path12.default.sep) && targetDir !== secureBaseDir) {
|
|
59912
60954
|
throw new Error(`Path traversal attempt detected. Cannot access directory outside workspace: ${directory}`);
|
|
59913
60955
|
}
|
|
59914
60956
|
} else {
|
|
59915
|
-
targetDir =
|
|
59916
|
-
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir +
|
|
60957
|
+
targetDir = import_path12.default.resolve(secureBaseDir, directory);
|
|
60958
|
+
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path12.default.sep) && targetDir !== secureBaseDir) {
|
|
59917
60959
|
throw new Error(`Path traversal attempt detected. Access denied: ${directory}`);
|
|
59918
60960
|
}
|
|
59919
60961
|
}
|
|
@@ -59930,7 +60972,7 @@ var init_probeTool = __esm({
|
|
|
59930
60972
|
return `${(size / (1024 * 1024 * 1024)).toFixed(1)}G`;
|
|
59931
60973
|
};
|
|
59932
60974
|
const entries = await Promise.all(files.map(async (file) => {
|
|
59933
|
-
const fullPath =
|
|
60975
|
+
const fullPath = import_path12.default.join(targetDir, file.name);
|
|
59934
60976
|
const entryType = await getEntryType(file, fullPath);
|
|
59935
60977
|
return {
|
|
59936
60978
|
name: file.name,
|
|
@@ -59967,17 +61009,17 @@ var init_probeTool = __esm({
|
|
|
59967
61009
|
throw new Error("Pattern is required for file search");
|
|
59968
61010
|
}
|
|
59969
61011
|
const baseCwd = workingDirectory || process.cwd();
|
|
59970
|
-
const secureBaseDir =
|
|
61012
|
+
const secureBaseDir = import_path12.default.resolve(baseCwd);
|
|
59971
61013
|
const isDependencyPath = directory.startsWith("/dep/") || directory.startsWith("go:") || directory.startsWith("js:") || directory.startsWith("rust:");
|
|
59972
61014
|
let targetDir;
|
|
59973
|
-
if (
|
|
59974
|
-
targetDir =
|
|
59975
|
-
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir +
|
|
61015
|
+
if (import_path12.default.isAbsolute(directory)) {
|
|
61016
|
+
targetDir = import_path12.default.resolve(directory);
|
|
61017
|
+
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path12.default.sep) && targetDir !== secureBaseDir) {
|
|
59976
61018
|
throw new Error(`Path traversal attempt detected. Cannot access directory outside workspace: ${directory}`);
|
|
59977
61019
|
}
|
|
59978
61020
|
} else {
|
|
59979
|
-
targetDir =
|
|
59980
|
-
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir +
|
|
61021
|
+
targetDir = import_path12.default.resolve(secureBaseDir, directory);
|
|
61022
|
+
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path12.default.sep) && targetDir !== secureBaseDir) {
|
|
59981
61023
|
throw new Error(`Path traversal attempt detected. Access denied: ${directory}`);
|
|
59982
61024
|
}
|
|
59983
61025
|
}
|
|
@@ -60554,6 +61596,7 @@ var init_index = __esm({
|
|
|
60554
61596
|
init_executePlan();
|
|
60555
61597
|
init_bash();
|
|
60556
61598
|
init_edit();
|
|
61599
|
+
init_fileTracker();
|
|
60557
61600
|
init_ProbeAgent();
|
|
60558
61601
|
init_simpleTelemetry();
|
|
60559
61602
|
init_probeTool();
|
|
@@ -60735,39 +61778,14 @@ function parseXmlToolCallWithThinking(xmlString, validTools) {
|
|
|
60735
61778
|
const toolCall = parseXmlToolCall(cleanedXmlString, validTools);
|
|
60736
61779
|
return toolCall ? { ...toolCall, thinkingContent } : null;
|
|
60737
61780
|
}
|
|
60738
|
-
var
|
|
61781
|
+
var import_crypto5, listFilesToolDefinition, searchFilesToolDefinition, listSkillsToolDefinition, useSkillToolDefinition, readImageToolDefinition;
|
|
60739
61782
|
var init_tools2 = __esm({
|
|
60740
61783
|
"src/agent/tools.js"() {
|
|
60741
61784
|
"use strict";
|
|
60742
61785
|
init_index();
|
|
60743
|
-
|
|
61786
|
+
import_crypto5 = require("crypto");
|
|
60744
61787
|
init_xmlParsingUtils();
|
|
60745
61788
|
init_tasks();
|
|
60746
|
-
implementToolDefinition = `
|
|
60747
|
-
## implement
|
|
60748
|
-
Description: Implement a given task. Can modify files. Can be used ONLY if task explicitly stated that something requires modification or implementation.
|
|
60749
|
-
|
|
60750
|
-
Parameters:
|
|
60751
|
-
- task: (required) The task description. Should be as detailed as possible, ideally pointing to exact files which needs be modified or created.
|
|
60752
|
-
- autoCommits: (optional) Whether to enable auto-commits in aider. Default is false.
|
|
60753
|
-
|
|
60754
|
-
Usage Example:
|
|
60755
|
-
|
|
60756
|
-
<examples>
|
|
60757
|
-
|
|
60758
|
-
User: Can you implement a function to calculate Fibonacci numbers in main.js?
|
|
60759
|
-
<implement>
|
|
60760
|
-
<task>Implement a recursive function to calculate the nth Fibonacci number in main.js</task>
|
|
60761
|
-
</implement>
|
|
60762
|
-
|
|
60763
|
-
User: Can you implement a function to calculate Fibonacci numbers in main.js with auto-commits?
|
|
60764
|
-
<implement>
|
|
60765
|
-
<task>Implement a recursive function to calculate the nth Fibonacci number in main.js</task>
|
|
60766
|
-
<autoCommits>true</autoCommits>
|
|
60767
|
-
</implement>
|
|
60768
|
-
|
|
60769
|
-
</examples>
|
|
60770
|
-
`;
|
|
60771
61789
|
listFilesToolDefinition = `
|
|
60772
61790
|
## listFiles
|
|
60773
61791
|
Description: List files and directories in a specified location.
|
|
@@ -60891,7 +61909,7 @@ function createMockProvider() {
|
|
|
60891
61909
|
provider: "mock",
|
|
60892
61910
|
// Mock the doGenerate method used by Vercel AI SDK
|
|
60893
61911
|
doGenerate: async ({ messages, tools: tools2 }) => {
|
|
60894
|
-
await new Promise((
|
|
61912
|
+
await new Promise((resolve8) => setTimeout(resolve8, 10));
|
|
60895
61913
|
return {
|
|
60896
61914
|
text: "This is a mock response for testing",
|
|
60897
61915
|
toolCalls: [],
|
|
@@ -66094,23 +67112,23 @@ var init_regexp_parser = __esm({
|
|
|
66094
67112
|
return ASSERT_NEVER_REACH_HERE();
|
|
66095
67113
|
}
|
|
66096
67114
|
quantifier(isBacktracking = false) {
|
|
66097
|
-
let
|
|
67115
|
+
let range3 = void 0;
|
|
66098
67116
|
const begin = this.idx;
|
|
66099
67117
|
switch (this.popChar()) {
|
|
66100
67118
|
case "*":
|
|
66101
|
-
|
|
67119
|
+
range3 = {
|
|
66102
67120
|
atLeast: 0,
|
|
66103
67121
|
atMost: Infinity
|
|
66104
67122
|
};
|
|
66105
67123
|
break;
|
|
66106
67124
|
case "+":
|
|
66107
|
-
|
|
67125
|
+
range3 = {
|
|
66108
67126
|
atLeast: 1,
|
|
66109
67127
|
atMost: Infinity
|
|
66110
67128
|
};
|
|
66111
67129
|
break;
|
|
66112
67130
|
case "?":
|
|
66113
|
-
|
|
67131
|
+
range3 = {
|
|
66114
67132
|
atLeast: 0,
|
|
66115
67133
|
atMost: 1
|
|
66116
67134
|
};
|
|
@@ -66119,7 +67137,7 @@ var init_regexp_parser = __esm({
|
|
|
66119
67137
|
const atLeast = this.integerIncludingZero();
|
|
66120
67138
|
switch (this.popChar()) {
|
|
66121
67139
|
case "}":
|
|
66122
|
-
|
|
67140
|
+
range3 = {
|
|
66123
67141
|
atLeast,
|
|
66124
67142
|
atMost: atLeast
|
|
66125
67143
|
};
|
|
@@ -66128,12 +67146,12 @@ var init_regexp_parser = __esm({
|
|
|
66128
67146
|
let atMost;
|
|
66129
67147
|
if (this.isDigit()) {
|
|
66130
67148
|
atMost = this.integerIncludingZero();
|
|
66131
|
-
|
|
67149
|
+
range3 = {
|
|
66132
67150
|
atLeast,
|
|
66133
67151
|
atMost
|
|
66134
67152
|
};
|
|
66135
67153
|
} else {
|
|
66136
|
-
|
|
67154
|
+
range3 = {
|
|
66137
67155
|
atLeast,
|
|
66138
67156
|
atMost: Infinity
|
|
66139
67157
|
};
|
|
@@ -66141,25 +67159,25 @@ var init_regexp_parser = __esm({
|
|
|
66141
67159
|
this.consumeChar("}");
|
|
66142
67160
|
break;
|
|
66143
67161
|
}
|
|
66144
|
-
if (isBacktracking === true &&
|
|
67162
|
+
if (isBacktracking === true && range3 === void 0) {
|
|
66145
67163
|
return void 0;
|
|
66146
67164
|
}
|
|
66147
|
-
ASSERT_EXISTS(
|
|
67165
|
+
ASSERT_EXISTS(range3);
|
|
66148
67166
|
break;
|
|
66149
67167
|
}
|
|
66150
|
-
if (isBacktracking === true &&
|
|
67168
|
+
if (isBacktracking === true && range3 === void 0) {
|
|
66151
67169
|
return void 0;
|
|
66152
67170
|
}
|
|
66153
|
-
if (ASSERT_EXISTS(
|
|
67171
|
+
if (ASSERT_EXISTS(range3)) {
|
|
66154
67172
|
if (this.peekChar(0) === "?") {
|
|
66155
67173
|
this.consumeChar("?");
|
|
66156
|
-
|
|
67174
|
+
range3.greedy = false;
|
|
66157
67175
|
} else {
|
|
66158
|
-
|
|
67176
|
+
range3.greedy = true;
|
|
66159
67177
|
}
|
|
66160
|
-
|
|
66161
|
-
|
|
66162
|
-
return
|
|
67178
|
+
range3.type = "Quantifier";
|
|
67179
|
+
range3.loc = this.loc(begin);
|
|
67180
|
+
return range3;
|
|
66163
67181
|
}
|
|
66164
67182
|
}
|
|
66165
67183
|
atom() {
|
|
@@ -66861,18 +67879,18 @@ function firstCharOptimizedIndices(ast, result, ignoreCase) {
|
|
|
66861
67879
|
if (typeof code === "number") {
|
|
66862
67880
|
addOptimizedIdxToResult(code, result, ignoreCase);
|
|
66863
67881
|
} else {
|
|
66864
|
-
const
|
|
67882
|
+
const range3 = code;
|
|
66865
67883
|
if (ignoreCase === true) {
|
|
66866
|
-
for (let rangeCode =
|
|
67884
|
+
for (let rangeCode = range3.from; rangeCode <= range3.to; rangeCode++) {
|
|
66867
67885
|
addOptimizedIdxToResult(rangeCode, result, ignoreCase);
|
|
66868
67886
|
}
|
|
66869
67887
|
} else {
|
|
66870
|
-
for (let rangeCode =
|
|
67888
|
+
for (let rangeCode = range3.from; rangeCode <= range3.to && rangeCode < minOptimizationVal; rangeCode++) {
|
|
66871
67889
|
addOptimizedIdxToResult(rangeCode, result, ignoreCase);
|
|
66872
67890
|
}
|
|
66873
|
-
if (
|
|
66874
|
-
const minUnOptVal =
|
|
66875
|
-
const maxUnOptVal =
|
|
67891
|
+
if (range3.to >= minOptimizationVal) {
|
|
67892
|
+
const minUnOptVal = range3.from >= minOptimizationVal ? range3.from : minOptimizationVal;
|
|
67893
|
+
const maxUnOptVal = range3.to;
|
|
66876
67894
|
const minOptIdx = charCodeToOptimizedIndex(minUnOptVal);
|
|
66877
67895
|
const maxOptIdx = charCodeToOptimizedIndex(maxUnOptVal);
|
|
66878
67896
|
for (let currOptIdx = minOptIdx; currOptIdx <= maxOptIdx; currOptIdx++) {
|
|
@@ -66933,8 +67951,8 @@ function findCode(setNode, targetCharCodes) {
|
|
|
66933
67951
|
if (typeof codeOrRange === "number") {
|
|
66934
67952
|
return includes_default(targetCharCodes, codeOrRange);
|
|
66935
67953
|
} else {
|
|
66936
|
-
const
|
|
66937
|
-
return find_default(targetCharCodes, (targetCode) =>
|
|
67954
|
+
const range3 = codeOrRange;
|
|
67955
|
+
return find_default(targetCharCodes, (targetCode) => range3.from <= targetCode && targetCode <= range3.to) !== void 0;
|
|
66938
67956
|
}
|
|
66939
67957
|
});
|
|
66940
67958
|
}
|
|
@@ -84839,8 +85857,8 @@ var require_createRange = __commonJS({
|
|
|
84839
85857
|
var require_range = __commonJS({
|
|
84840
85858
|
"node_modules/lodash/range.js"(exports2, module2) {
|
|
84841
85859
|
var createRange = require_createRange();
|
|
84842
|
-
var
|
|
84843
|
-
module2.exports =
|
|
85860
|
+
var range3 = createRange();
|
|
85861
|
+
module2.exports = range3;
|
|
84844
85862
|
}
|
|
84845
85863
|
});
|
|
84846
85864
|
|
|
@@ -94081,7 +95099,7 @@ var require_compile = __commonJS({
|
|
|
94081
95099
|
const schOrFunc = root2.refs[ref2];
|
|
94082
95100
|
if (schOrFunc)
|
|
94083
95101
|
return schOrFunc;
|
|
94084
|
-
let _sch =
|
|
95102
|
+
let _sch = resolve8.call(this, root2, ref2);
|
|
94085
95103
|
if (_sch === void 0) {
|
|
94086
95104
|
const schema = (_a16 = root2.localRefs) === null || _a16 === void 0 ? void 0 : _a16[ref2];
|
|
94087
95105
|
const { schemaId } = this.opts;
|
|
@@ -94108,7 +95126,7 @@ var require_compile = __commonJS({
|
|
|
94108
95126
|
function sameSchemaEnv(s1, s22) {
|
|
94109
95127
|
return s1.schema === s22.schema && s1.root === s22.root && s1.baseId === s22.baseId;
|
|
94110
95128
|
}
|
|
94111
|
-
function
|
|
95129
|
+
function resolve8(root2, ref2) {
|
|
94112
95130
|
let sch;
|
|
94113
95131
|
while (typeof (sch = this.refs[ref2]) == "string")
|
|
94114
95132
|
ref2 = sch;
|
|
@@ -94683,7 +95701,7 @@ var require_fast_uri = __commonJS({
|
|
|
94683
95701
|
}
|
|
94684
95702
|
return uri;
|
|
94685
95703
|
}
|
|
94686
|
-
function
|
|
95704
|
+
function resolve8(baseURI, relativeURI, options) {
|
|
94687
95705
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
94688
95706
|
const resolved = resolveComponent(parse9(baseURI, schemelessOptions), parse9(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
94689
95707
|
schemelessOptions.skipEscape = true;
|
|
@@ -94910,7 +95928,7 @@ var require_fast_uri = __commonJS({
|
|
|
94910
95928
|
var fastUri = {
|
|
94911
95929
|
SCHEMES,
|
|
94912
95930
|
normalize: normalize3,
|
|
94913
|
-
resolve:
|
|
95931
|
+
resolve: resolve8,
|
|
94914
95932
|
resolveComponent,
|
|
94915
95933
|
equal,
|
|
94916
95934
|
serialize,
|
|
@@ -97603,6 +98621,7 @@ __export(schemaUtils_exports, {
|
|
|
97603
98621
|
processSchemaResponse: () => processSchemaResponse,
|
|
97604
98622
|
replaceMermaidDiagramsInJson: () => replaceMermaidDiagramsInJson,
|
|
97605
98623
|
replaceMermaidDiagramsInMarkdown: () => replaceMermaidDiagramsInMarkdown,
|
|
98624
|
+
sanitizeMarkdownEscapesInJson: () => sanitizeMarkdownEscapesInJson,
|
|
97606
98625
|
tryAutoWrapForSimpleSchema: () => tryAutoWrapForSimpleSchema,
|
|
97607
98626
|
tryMaidAutoFix: () => tryMaidAutoFix,
|
|
97608
98627
|
validateAndFixMermaidResponse: () => validateAndFixMermaidResponse,
|
|
@@ -97706,6 +98725,17 @@ function decodeHtmlEntities2(text) {
|
|
|
97706
98725
|
}
|
|
97707
98726
|
return decoded;
|
|
97708
98727
|
}
|
|
98728
|
+
function sanitizeMarkdownEscapesInJson(jsonString) {
|
|
98729
|
+
if (!jsonString || typeof jsonString !== "string") {
|
|
98730
|
+
return jsonString;
|
|
98731
|
+
}
|
|
98732
|
+
return jsonString.replace(/\\\\|\\([^"\\\/bfnrtu])/g, (match2, captured) => {
|
|
98733
|
+
if (match2 === "\\\\") {
|
|
98734
|
+
return "\\\\";
|
|
98735
|
+
}
|
|
98736
|
+
return captured;
|
|
98737
|
+
});
|
|
98738
|
+
}
|
|
97709
98739
|
function normalizeJsonQuotes(str) {
|
|
97710
98740
|
if (!str || typeof str !== "string") {
|
|
97711
98741
|
return str;
|
|
@@ -97758,6 +98788,15 @@ function cleanSchemaResponse(response) {
|
|
|
97758
98788
|
if (resultWrapperMatch) {
|
|
97759
98789
|
return cleanSchemaResponse(resultWrapperMatch[1]);
|
|
97760
98790
|
}
|
|
98791
|
+
const toolCodeMatch = trimmed.match(/<tool_code>\s*([\s\S]*?)\s*<\/tool_code>/);
|
|
98792
|
+
if (toolCodeMatch) {
|
|
98793
|
+
let innerContent = toolCodeMatch[1].trim();
|
|
98794
|
+
const funcCallMatch = innerContent.match(/(?:print|attempt_completion)\s*\(\s*([{\[][\s\S]*[}\]])\s*\)/);
|
|
98795
|
+
if (funcCallMatch) {
|
|
98796
|
+
return cleanSchemaResponse(funcCallMatch[1]);
|
|
98797
|
+
}
|
|
98798
|
+
return cleanSchemaResponse(innerContent);
|
|
98799
|
+
}
|
|
97761
98800
|
const jsonBlockMatch = trimmed.match(/```json\s*\n([\s\S]*?)\n```/);
|
|
97762
98801
|
if (jsonBlockMatch) {
|
|
97763
98802
|
return normalizeJsonQuotes(jsonBlockMatch[1].trim());
|
|
@@ -97825,9 +98864,25 @@ function validateJsonResponse(response, options = {}) {
|
|
|
97825
98864
|
console.log(`[DEBUG] JSON validation: Schema validation enabled`);
|
|
97826
98865
|
}
|
|
97827
98866
|
}
|
|
98867
|
+
let responseToValidate = response;
|
|
98868
|
+
try {
|
|
98869
|
+
JSON.parse(response);
|
|
98870
|
+
} catch (initialError) {
|
|
98871
|
+
if (initialError.message && initialError.message.includes("escape")) {
|
|
98872
|
+
const sanitized = sanitizeMarkdownEscapesInJson(response);
|
|
98873
|
+
try {
|
|
98874
|
+
JSON.parse(sanitized);
|
|
98875
|
+
responseToValidate = sanitized;
|
|
98876
|
+
if (debug) {
|
|
98877
|
+
console.log(`[DEBUG] JSON validation: Fixed Markdown escapes in JSON (issue #441)`);
|
|
98878
|
+
}
|
|
98879
|
+
} catch {
|
|
98880
|
+
}
|
|
98881
|
+
}
|
|
98882
|
+
}
|
|
97828
98883
|
try {
|
|
97829
98884
|
const parseStart = Date.now();
|
|
97830
|
-
const parsed = JSON.parse(
|
|
98885
|
+
const parsed = JSON.parse(responseToValidate);
|
|
97831
98886
|
const parseTime = Date.now() - parseStart;
|
|
97832
98887
|
if (debug) {
|
|
97833
98888
|
console.log(`[DEBUG] JSON validation: Successfully parsed in ${parseTime}ms`);
|
|
@@ -98169,7 +99224,21 @@ function tryAutoWrapForSimpleSchema(response, schema, options = {}) {
|
|
|
98169
99224
|
console.log(`[DEBUG] Auto-wrap: Response is already valid JSON, skipping`);
|
|
98170
99225
|
}
|
|
98171
99226
|
return null;
|
|
98172
|
-
} catch {
|
|
99227
|
+
} catch (initialError) {
|
|
99228
|
+
if (initialError.message && initialError.message.includes("escape")) {
|
|
99229
|
+
try {
|
|
99230
|
+
const sanitized = sanitizeMarkdownEscapesInJson(response);
|
|
99231
|
+
JSON.parse(sanitized);
|
|
99232
|
+
if (debug) {
|
|
99233
|
+
console.log(`[DEBUG] Auto-wrap: Fixed Markdown escapes in JSON (issue #441), returning sanitized JSON`);
|
|
99234
|
+
}
|
|
99235
|
+
return sanitized;
|
|
99236
|
+
} catch {
|
|
99237
|
+
if (debug) {
|
|
99238
|
+
console.log(`[DEBUG] Auto-wrap: Markdown escape sanitization didn't fix JSON, proceeding with wrapping`);
|
|
99239
|
+
}
|
|
99240
|
+
}
|
|
99241
|
+
}
|
|
98173
99242
|
}
|
|
98174
99243
|
const wrapped = JSON.stringify({ [wrapperInfo.fieldName]: response });
|
|
98175
99244
|
if (debug) {
|
|
@@ -99382,13 +100451,13 @@ function loadMCPConfiguration() {
|
|
|
99382
100451
|
// Environment variable path
|
|
99383
100452
|
process.env.MCP_CONFIG_PATH,
|
|
99384
100453
|
// Local project paths
|
|
99385
|
-
(0,
|
|
99386
|
-
(0,
|
|
100454
|
+
(0, import_path13.join)(process.cwd(), ".mcp", "config.json"),
|
|
100455
|
+
(0, import_path13.join)(process.cwd(), "mcp.config.json"),
|
|
99387
100456
|
// Home directory paths
|
|
99388
|
-
(0,
|
|
99389
|
-
(0,
|
|
100457
|
+
(0, import_path13.join)((0, import_os3.homedir)(), ".config", "probe", "mcp.json"),
|
|
100458
|
+
(0, import_path13.join)((0, import_os3.homedir)(), ".mcp", "config.json"),
|
|
99390
100459
|
// Claude-style config location
|
|
99391
|
-
(0,
|
|
100460
|
+
(0, import_path13.join)((0, import_os3.homedir)(), "Library", "Application Support", "Claude", "mcp_config.json")
|
|
99392
100461
|
].filter(Boolean);
|
|
99393
100462
|
let config = null;
|
|
99394
100463
|
for (const configPath of configPaths) {
|
|
@@ -99515,16 +100584,16 @@ function parseEnabledServers(config) {
|
|
|
99515
100584
|
}
|
|
99516
100585
|
return servers;
|
|
99517
100586
|
}
|
|
99518
|
-
var import_fs12,
|
|
100587
|
+
var import_fs12, import_path13, import_os3, import_url4, __filename4, __dirname4, DEFAULT_TIMEOUT, MAX_TIMEOUT, DEFAULT_CONFIG;
|
|
99519
100588
|
var init_config = __esm({
|
|
99520
100589
|
"src/agent/mcp/config.js"() {
|
|
99521
100590
|
"use strict";
|
|
99522
100591
|
import_fs12 = require("fs");
|
|
99523
|
-
|
|
100592
|
+
import_path13 = require("path");
|
|
99524
100593
|
import_os3 = require("os");
|
|
99525
100594
|
import_url4 = require("url");
|
|
99526
100595
|
__filename4 = (0, import_url4.fileURLToPath)("file:///");
|
|
99527
|
-
__dirname4 = (0,
|
|
100596
|
+
__dirname4 = (0, import_path13.dirname)(__filename4);
|
|
99528
100597
|
DEFAULT_TIMEOUT = 3e4;
|
|
99529
100598
|
MAX_TIMEOUT = (() => {
|
|
99530
100599
|
if (process.env.MCP_MAX_TIMEOUT) {
|
|
@@ -99538,7 +100607,7 @@ var init_config = __esm({
|
|
|
99538
100607
|
// Example probe server configuration
|
|
99539
100608
|
"probe-local": {
|
|
99540
100609
|
command: "node",
|
|
99541
|
-
args: [(0,
|
|
100610
|
+
args: [(0, import_path13.join)(__dirname4, "../../../examples/chat/mcpServer.js")],
|
|
99542
100611
|
transport: "stdio",
|
|
99543
100612
|
enabled: false
|
|
99544
100613
|
},
|
|
@@ -105121,7 +106190,7 @@ var require_compose_scalar = __commonJS({
|
|
|
105121
106190
|
var resolveBlockScalar = require_resolve_block_scalar();
|
|
105122
106191
|
var resolveFlowScalar = require_resolve_flow_scalar();
|
|
105123
106192
|
function composeScalar(ctx, token, tagToken, onError) {
|
|
105124
|
-
const { value, type, comment, range:
|
|
106193
|
+
const { value, type, comment, range: range3 } = token.type === "block-scalar" ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError) : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
|
|
105125
106194
|
const tagName = tagToken ? ctx.directives.tagName(tagToken.source, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg)) : null;
|
|
105126
106195
|
let tag2;
|
|
105127
106196
|
if (ctx.options.stringKeys && ctx.atKey) {
|
|
@@ -105141,7 +106210,7 @@ var require_compose_scalar = __commonJS({
|
|
|
105141
106210
|
onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg);
|
|
105142
106211
|
scalar = new Scalar.Scalar(value);
|
|
105143
106212
|
}
|
|
105144
|
-
scalar.range =
|
|
106213
|
+
scalar.range = range3;
|
|
105145
106214
|
scalar.source = value;
|
|
105146
106215
|
if (type)
|
|
105147
106216
|
scalar.type = type;
|
|
@@ -107732,17 +108801,17 @@ async function parseSkillFile(skillFilePath, directoryName) {
|
|
|
107732
108801
|
description,
|
|
107733
108802
|
skillFilePath,
|
|
107734
108803
|
directoryName,
|
|
107735
|
-
sourceDir: (0,
|
|
108804
|
+
sourceDir: (0, import_path14.dirname)(skillFilePath)
|
|
107736
108805
|
},
|
|
107737
108806
|
error: null
|
|
107738
108807
|
};
|
|
107739
108808
|
}
|
|
107740
|
-
var import_promises2,
|
|
108809
|
+
var import_promises2, import_path14, import_yaml, SKILL_NAME_REGEX, MAX_SKILL_NAME_LENGTH, MAX_DESCRIPTION_CHARS;
|
|
107741
108810
|
var init_parser7 = __esm({
|
|
107742
108811
|
"src/agent/skills/parser.js"() {
|
|
107743
108812
|
"use strict";
|
|
107744
108813
|
import_promises2 = require("fs/promises");
|
|
107745
|
-
|
|
108814
|
+
import_path14 = require("path");
|
|
107746
108815
|
import_yaml = __toESM(require_dist(), 1);
|
|
107747
108816
|
SKILL_NAME_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
107748
108817
|
MAX_SKILL_NAME_LENGTH = 64;
|
|
@@ -107752,12 +108821,12 @@ var init_parser7 = __esm({
|
|
|
107752
108821
|
|
|
107753
108822
|
// src/agent/skills/registry.js
|
|
107754
108823
|
function isPathInside(basePath, targetPath) {
|
|
107755
|
-
const base2 = (0,
|
|
107756
|
-
const target = (0,
|
|
107757
|
-
const rel = (0,
|
|
108824
|
+
const base2 = (0, import_path15.resolve)(basePath);
|
|
108825
|
+
const target = (0, import_path15.resolve)(targetPath);
|
|
108826
|
+
const rel = (0, import_path15.relative)(base2, target);
|
|
107758
108827
|
if (rel === "") return true;
|
|
107759
|
-
if (rel === ".." || rel.startsWith(`..${
|
|
107760
|
-
if ((0,
|
|
108828
|
+
if (rel === ".." || rel.startsWith(`..${import_path15.sep}`)) return false;
|
|
108829
|
+
if ((0, import_path15.isAbsolute)(rel)) return false;
|
|
107761
108830
|
return true;
|
|
107762
108831
|
}
|
|
107763
108832
|
function isSafeEntryName(name14) {
|
|
@@ -107765,19 +108834,19 @@ function isSafeEntryName(name14) {
|
|
|
107765
108834
|
if (name14.includes("\0")) return false;
|
|
107766
108835
|
return !name14.includes("/") && !name14.includes("\\");
|
|
107767
108836
|
}
|
|
107768
|
-
var import_fs13, import_promises3,
|
|
108837
|
+
var import_fs13, import_promises3, import_path15, DEFAULT_SKILL_DIRS, SKILL_FILE_NAME, SkillRegistry;
|
|
107769
108838
|
var init_registry = __esm({
|
|
107770
108839
|
"src/agent/skills/registry.js"() {
|
|
107771
108840
|
"use strict";
|
|
107772
108841
|
import_fs13 = require("fs");
|
|
107773
108842
|
import_promises3 = require("fs/promises");
|
|
107774
|
-
|
|
108843
|
+
import_path15 = require("path");
|
|
107775
108844
|
init_parser7();
|
|
107776
108845
|
DEFAULT_SKILL_DIRS = [".claude/skills", ".codex/skills", "skills", ".skills"];
|
|
107777
108846
|
SKILL_FILE_NAME = "SKILL.md";
|
|
107778
108847
|
SkillRegistry = class {
|
|
107779
108848
|
constructor({ repoRoot, skillDirs = DEFAULT_SKILL_DIRS, debug = false } = {}) {
|
|
107780
|
-
this.repoRoot = repoRoot ? (0,
|
|
108849
|
+
this.repoRoot = repoRoot ? (0, import_path15.resolve)(repoRoot) : process.cwd();
|
|
107781
108850
|
this.repoRootReal = null;
|
|
107782
108851
|
this.skillDirs = Array.isArray(skillDirs) && skillDirs.length > 0 ? skillDirs : DEFAULT_SKILL_DIRS;
|
|
107783
108852
|
this.debug = debug;
|
|
@@ -107831,8 +108900,8 @@ var init_registry = __esm({
|
|
|
107831
108900
|
}
|
|
107832
108901
|
}
|
|
107833
108902
|
async _resolveSkillDir(skillDir) {
|
|
107834
|
-
const resolved = (0,
|
|
107835
|
-
const repoRoot = this.repoRootReal || (0,
|
|
108903
|
+
const resolved = (0, import_path15.isAbsolute)(skillDir) ? (0, import_path15.resolve)(skillDir) : (0, import_path15.resolve)(this.repoRoot, skillDir);
|
|
108904
|
+
const repoRoot = this.repoRootReal || (0, import_path15.resolve)(this.repoRoot);
|
|
107836
108905
|
const resolvedReal = await this._resolveRealPath(resolved);
|
|
107837
108906
|
if (!resolvedReal) return null;
|
|
107838
108907
|
if (!isPathInside(repoRoot, resolvedReal)) {
|
|
@@ -107863,8 +108932,8 @@ var init_registry = __esm({
|
|
|
107863
108932
|
}
|
|
107864
108933
|
continue;
|
|
107865
108934
|
}
|
|
107866
|
-
const skillFolder = (0,
|
|
107867
|
-
const skillFilePath = (0,
|
|
108935
|
+
const skillFolder = (0, import_path15.join)(dirPath, entry.name);
|
|
108936
|
+
const skillFilePath = (0, import_path15.join)(skillFolder, SKILL_FILE_NAME);
|
|
107868
108937
|
let skillStat;
|
|
107869
108938
|
try {
|
|
107870
108939
|
skillStat = await (0, import_promises3.lstat)(skillFilePath);
|
|
@@ -108022,7 +109091,7 @@ function extractErrorInfo(error2) {
|
|
|
108022
109091
|
};
|
|
108023
109092
|
}
|
|
108024
109093
|
function sleep(ms) {
|
|
108025
|
-
return new Promise((
|
|
109094
|
+
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
108026
109095
|
}
|
|
108027
109096
|
var DEFAULT_RETRYABLE_ERRORS, RetryManager;
|
|
108028
109097
|
var init_RetryManager = __esm({
|
|
@@ -108802,9 +109871,9 @@ async function truncateIfNeeded(content, tokenCounter, sessionId, maxTokens) {
|
|
|
108802
109871
|
let tempFilePath = null;
|
|
108803
109872
|
let fileError = null;
|
|
108804
109873
|
try {
|
|
108805
|
-
const tempDir = (0,
|
|
109874
|
+
const tempDir = (0, import_path16.join)((0, import_os4.tmpdir)(), "probe-output");
|
|
108806
109875
|
await (0, import_promises4.mkdir)(tempDir, { recursive: true });
|
|
108807
|
-
tempFilePath = (0,
|
|
109876
|
+
tempFilePath = (0, import_path16.join)(tempDir, `tool-output-${sessionId || "unknown"}-${(0, import_crypto6.randomUUID)()}.txt`);
|
|
108808
109877
|
await (0, import_promises4.writeFile)(tempFilePath, content, "utf8");
|
|
108809
109878
|
} catch (err) {
|
|
108810
109879
|
fileError = err.message || "Unknown file system error";
|
|
@@ -108852,14 +109921,14 @@ ${truncatedBody}
|
|
|
108852
109921
|
error: fileError || void 0
|
|
108853
109922
|
};
|
|
108854
109923
|
}
|
|
108855
|
-
var import_promises4, import_os4,
|
|
109924
|
+
var import_promises4, import_os4, import_path16, import_crypto6, DEFAULT_MAX_OUTPUT_TOKENS, CHARS_PER_TOKEN2, TAIL_TOKENS, MIN_LIMIT_FOR_TAIL;
|
|
108856
109925
|
var init_outputTruncator = __esm({
|
|
108857
109926
|
"src/agent/outputTruncator.js"() {
|
|
108858
109927
|
"use strict";
|
|
108859
109928
|
import_promises4 = require("fs/promises");
|
|
108860
109929
|
import_os4 = require("os");
|
|
108861
|
-
|
|
108862
|
-
|
|
109930
|
+
import_path16 = require("path");
|
|
109931
|
+
import_crypto6 = require("crypto");
|
|
108863
109932
|
DEFAULT_MAX_OUTPUT_TOKENS = 2e4;
|
|
108864
109933
|
CHARS_PER_TOKEN2 = 4;
|
|
108865
109934
|
TAIL_TOKENS = 1e3;
|
|
@@ -108868,13 +109937,13 @@ var init_outputTruncator = __esm({
|
|
|
108868
109937
|
});
|
|
108869
109938
|
|
|
108870
109939
|
// src/agent/mcp/built-in-server.js
|
|
108871
|
-
var import_http, import_events2,
|
|
109940
|
+
var import_http, import_events2, import_crypto7, import_server, import_sse2, import_streamableHttp, import_types3, InMemoryEventStore, BuiltInMCPServer;
|
|
108872
109941
|
var init_built_in_server = __esm({
|
|
108873
109942
|
"src/agent/mcp/built-in-server.js"() {
|
|
108874
109943
|
"use strict";
|
|
108875
109944
|
import_http = require("http");
|
|
108876
109945
|
import_events2 = require("events");
|
|
108877
|
-
|
|
109946
|
+
import_crypto7 = require("crypto");
|
|
108878
109947
|
import_server = require("@modelcontextprotocol/sdk/server/index.js");
|
|
108879
109948
|
import_sse2 = require("@modelcontextprotocol/sdk/server/sse.js");
|
|
108880
109949
|
import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
@@ -108950,7 +110019,7 @@ var init_built_in_server = __esm({
|
|
|
108950
110019
|
}
|
|
108951
110020
|
});
|
|
108952
110021
|
this.registerHandlers();
|
|
108953
|
-
return new Promise((
|
|
110022
|
+
return new Promise((resolve8, reject2) => {
|
|
108954
110023
|
this.httpServer.listen(this.port, this.host, async () => {
|
|
108955
110024
|
const address = this.httpServer.address();
|
|
108956
110025
|
this.port = address.port;
|
|
@@ -108960,7 +110029,7 @@ var init_built_in_server = __esm({
|
|
|
108960
110029
|
console.log(`[MCP] Messages endpoint: http://${this.host}:${this.port}/messages`);
|
|
108961
110030
|
}
|
|
108962
110031
|
this.emit("ready", { host: this.host, port: this.port });
|
|
108963
|
-
|
|
110032
|
+
resolve8({ host: this.host, port: this.port });
|
|
108964
110033
|
});
|
|
108965
110034
|
this.httpServer.on("error", reject2);
|
|
108966
110035
|
});
|
|
@@ -109118,7 +110187,7 @@ var init_built_in_server = __esm({
|
|
|
109118
110187
|
}
|
|
109119
110188
|
const eventStore = new InMemoryEventStore();
|
|
109120
110189
|
transport = new import_streamableHttp.StreamableHTTPServerTransport({
|
|
109121
|
-
sessionIdGenerator: () => (0,
|
|
110190
|
+
sessionIdGenerator: () => (0, import_crypto7.randomUUID)(),
|
|
109122
110191
|
eventStore,
|
|
109123
110192
|
// Enable resumability
|
|
109124
110193
|
onsessioninitialized: (newSessionId) => {
|
|
@@ -109179,7 +110248,7 @@ var init_built_in_server = __esm({
|
|
|
109179
110248
|
* Parse request body as JSON
|
|
109180
110249
|
*/
|
|
109181
110250
|
async parseRequestBody(req) {
|
|
109182
|
-
return new Promise((
|
|
110251
|
+
return new Promise((resolve8, reject2) => {
|
|
109183
110252
|
let body = "";
|
|
109184
110253
|
req.on("data", (chunk) => {
|
|
109185
110254
|
body += chunk.toString();
|
|
@@ -109187,7 +110256,7 @@ var init_built_in_server = __esm({
|
|
|
109187
110256
|
req.on("end", () => {
|
|
109188
110257
|
try {
|
|
109189
110258
|
const parsed = body ? JSON.parse(body) : null;
|
|
109190
|
-
|
|
110259
|
+
resolve8(parsed);
|
|
109191
110260
|
} catch (error2) {
|
|
109192
110261
|
reject2(error2);
|
|
109193
110262
|
}
|
|
@@ -109494,12 +110563,12 @@ data: ${JSON.stringify(data3)}
|
|
|
109494
110563
|
}
|
|
109495
110564
|
this.connections.clear();
|
|
109496
110565
|
if (this.httpServer) {
|
|
109497
|
-
return new Promise((
|
|
110566
|
+
return new Promise((resolve8) => {
|
|
109498
110567
|
this.httpServer.close(() => {
|
|
109499
110568
|
if (this.debug) {
|
|
109500
110569
|
console.log("[MCP] Built-in server stopped");
|
|
109501
110570
|
}
|
|
109502
|
-
|
|
110571
|
+
resolve8();
|
|
109503
110572
|
});
|
|
109504
110573
|
});
|
|
109505
110574
|
}
|
|
@@ -109581,7 +110650,7 @@ __export(enhanced_claude_code_exports, {
|
|
|
109581
110650
|
async function createEnhancedClaudeCLIEngine(options = {}) {
|
|
109582
110651
|
const { agent, systemPrompt, customPrompt, debug, sessionId, allowedTools, timeout = 12e4 } = options;
|
|
109583
110652
|
const session = new Session(
|
|
109584
|
-
sessionId || (0,
|
|
110653
|
+
sessionId || (0, import_crypto8.randomBytes)(8).toString("hex"),
|
|
109585
110654
|
debug
|
|
109586
110655
|
);
|
|
109587
110656
|
let mcpServer = null;
|
|
@@ -109598,12 +110667,12 @@ async function createEnhancedClaudeCLIEngine(options = {}) {
|
|
|
109598
110667
|
console.log("[DEBUG] Built-in MCP server started");
|
|
109599
110668
|
console.log("[DEBUG] MCP URL:", `http://${host}:${port}/mcp`);
|
|
109600
110669
|
}
|
|
109601
|
-
mcpConfigPath =
|
|
110670
|
+
mcpConfigPath = import_path17.default.join(import_os5.default.tmpdir(), `probe-mcp-${session.id}.json`);
|
|
109602
110671
|
const mcpConfig = {
|
|
109603
110672
|
mcpServers: {
|
|
109604
110673
|
probe: {
|
|
109605
110674
|
command: "node",
|
|
109606
|
-
args: [
|
|
110675
|
+
args: [import_path17.default.join(process.cwd(), "mcp-probe-server.js")],
|
|
109607
110676
|
env: {
|
|
109608
110677
|
PROBE_WORKSPACE: process.cwd(),
|
|
109609
110678
|
DEBUG: debug ? "true" : "false"
|
|
@@ -109828,8 +110897,8 @@ ${opts.schema}`;
|
|
|
109828
110897
|
break;
|
|
109829
110898
|
}
|
|
109830
110899
|
} else if (!processEnded) {
|
|
109831
|
-
await new Promise((
|
|
109832
|
-
resolver =
|
|
110900
|
+
await new Promise((resolve8) => {
|
|
110901
|
+
resolver = resolve8;
|
|
109833
110902
|
});
|
|
109834
110903
|
}
|
|
109835
110904
|
}
|
|
@@ -110028,14 +111097,14 @@ function combinePrompts(systemPrompt, customPrompt, agent) {
|
|
|
110028
111097
|
}
|
|
110029
111098
|
return systemPrompt || "";
|
|
110030
111099
|
}
|
|
110031
|
-
var import_child_process9,
|
|
111100
|
+
var import_child_process9, import_crypto8, import_promises5, import_path17, import_os5, import_events3;
|
|
110032
111101
|
var init_enhanced_claude_code = __esm({
|
|
110033
111102
|
"src/agent/engines/enhanced-claude-code.js"() {
|
|
110034
111103
|
"use strict";
|
|
110035
111104
|
import_child_process9 = require("child_process");
|
|
110036
|
-
|
|
111105
|
+
import_crypto8 = require("crypto");
|
|
110037
111106
|
import_promises5 = __toESM(require("fs/promises"), 1);
|
|
110038
|
-
|
|
111107
|
+
import_path17 = __toESM(require("path"), 1);
|
|
110039
111108
|
import_os5 = __toESM(require("os"), 1);
|
|
110040
111109
|
import_events3 = require("events");
|
|
110041
111110
|
init_built_in_server();
|
|
@@ -110051,7 +111120,7 @@ __export(codex_exports, {
|
|
|
110051
111120
|
async function createCodexEngine(options = {}) {
|
|
110052
111121
|
const { agent, systemPrompt, customPrompt, debug, sessionId, allowedTools, model } = options;
|
|
110053
111122
|
const session = new Session(
|
|
110054
|
-
sessionId || (0,
|
|
111123
|
+
sessionId || (0, import_crypto9.randomBytes)(8).toString("hex"),
|
|
110055
111124
|
debug
|
|
110056
111125
|
);
|
|
110057
111126
|
let mcpServer = null;
|
|
@@ -110093,12 +111162,12 @@ async function createCodexEngine(options = {}) {
|
|
|
110093
111162
|
}
|
|
110094
111163
|
}
|
|
110095
111164
|
if (message.id !== void 0 && pendingRequests.has(message.id)) {
|
|
110096
|
-
const { resolve:
|
|
111165
|
+
const { resolve: resolve8, reject: reject2 } = pendingRequests.get(message.id);
|
|
110097
111166
|
pendingRequests.delete(message.id);
|
|
110098
111167
|
if (message.error) {
|
|
110099
111168
|
reject2(new Error(message.error.message || JSON.stringify(message.error)));
|
|
110100
111169
|
} else {
|
|
110101
|
-
|
|
111170
|
+
resolve8(message.result);
|
|
110102
111171
|
}
|
|
110103
111172
|
}
|
|
110104
111173
|
if (message.method === "codex/event" && message.params) {
|
|
@@ -110119,7 +111188,7 @@ async function createCodexEngine(options = {}) {
|
|
|
110119
111188
|
});
|
|
110120
111189
|
}
|
|
110121
111190
|
function sendRequest(method, params = {}) {
|
|
110122
|
-
return new Promise((
|
|
111191
|
+
return new Promise((resolve8, reject2) => {
|
|
110123
111192
|
const id = ++requestId;
|
|
110124
111193
|
const request = {
|
|
110125
111194
|
jsonrpc: "2.0",
|
|
@@ -110127,7 +111196,7 @@ async function createCodexEngine(options = {}) {
|
|
|
110127
111196
|
method,
|
|
110128
111197
|
params
|
|
110129
111198
|
};
|
|
110130
|
-
pendingRequests.set(id, { resolve:
|
|
111199
|
+
pendingRequests.set(id, { resolve: resolve8, reject: reject2 });
|
|
110131
111200
|
setTimeout(() => {
|
|
110132
111201
|
if (pendingRequests.has(id)) {
|
|
110133
111202
|
pendingRequests.delete(id);
|
|
@@ -110190,7 +111259,7 @@ ${prompt}`;
|
|
|
110190
111259
|
const reqId = requestId + 1;
|
|
110191
111260
|
let fullResponse = "";
|
|
110192
111261
|
let gotSessionId = false;
|
|
110193
|
-
const eventPromise = new Promise((
|
|
111262
|
+
const eventPromise = new Promise((resolve8) => {
|
|
110194
111263
|
eventHandlers.set(reqId, (eventParams) => {
|
|
110195
111264
|
const msg = eventParams.msg;
|
|
110196
111265
|
if (msg.type === "session_configured" && msg.session_id && !gotSessionId) {
|
|
@@ -110210,7 +111279,7 @@ ${prompt}`;
|
|
|
110210
111279
|
});
|
|
110211
111280
|
setTimeout(() => {
|
|
110212
111281
|
eventHandlers.delete(reqId);
|
|
110213
|
-
|
|
111282
|
+
resolve8();
|
|
110214
111283
|
}, 6e5);
|
|
110215
111284
|
});
|
|
110216
111285
|
const resultPromise = sendRequest("tools/call", {
|
|
@@ -110306,12 +111375,12 @@ function combinePrompts2(systemPrompt, customPrompt, agent) {
|
|
|
110306
111375
|
}
|
|
110307
111376
|
return systemPrompt || "";
|
|
110308
111377
|
}
|
|
110309
|
-
var import_child_process10,
|
|
111378
|
+
var import_child_process10, import_crypto9, import_readline;
|
|
110310
111379
|
var init_codex = __esm({
|
|
110311
111380
|
"src/agent/engines/codex.js"() {
|
|
110312
111381
|
"use strict";
|
|
110313
111382
|
import_child_process10 = require("child_process");
|
|
110314
|
-
|
|
111383
|
+
import_crypto9 = require("crypto");
|
|
110315
111384
|
import_readline = require("readline");
|
|
110316
111385
|
init_built_in_server();
|
|
110317
111386
|
init_Session();
|
|
@@ -110417,7 +111486,7 @@ Your content here
|
|
|
110417
111486
|
|
|
110418
111487
|
Do NOT wrap in other tags like <api_call>, <tool_name>, <function>, etc.`;
|
|
110419
111488
|
}
|
|
110420
|
-
var import_dotenv2, import_anthropic2, import_openai2, import_google2, import_ai6,
|
|
111489
|
+
var import_dotenv2, import_anthropic2, import_openai2, import_google2, import_ai6, import_crypto10, import_events4, import_fs14, import_promises6, import_path18, ENGINE_ACTIVITY_TIMEOUT_DEFAULT, ENGINE_ACTIVITY_TIMEOUT_MIN, ENGINE_ACTIVITY_TIMEOUT_MAX, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, ProbeAgent;
|
|
110421
111490
|
var init_ProbeAgent = __esm({
|
|
110422
111491
|
"src/agent/ProbeAgent.js"() {
|
|
110423
111492
|
import_dotenv2 = __toESM(require_main(), 1);
|
|
@@ -110426,17 +111495,18 @@ var init_ProbeAgent = __esm({
|
|
|
110426
111495
|
import_google2 = require("@ai-sdk/google");
|
|
110427
111496
|
init_dist3();
|
|
110428
111497
|
import_ai6 = require("ai");
|
|
110429
|
-
|
|
111498
|
+
import_crypto10 = require("crypto");
|
|
110430
111499
|
import_events4 = require("events");
|
|
110431
111500
|
import_fs14 = require("fs");
|
|
110432
111501
|
import_promises6 = require("fs/promises");
|
|
110433
|
-
|
|
111502
|
+
import_path18 = require("path");
|
|
110434
111503
|
init_tokenCounter();
|
|
110435
111504
|
init_InMemoryStorageAdapter();
|
|
110436
111505
|
init_HookManager();
|
|
110437
111506
|
init_imageConfig();
|
|
110438
111507
|
init_tools2();
|
|
110439
111508
|
init_common2();
|
|
111509
|
+
init_fileTracker();
|
|
110440
111510
|
init_probeTool();
|
|
110441
111511
|
init_mockProvider();
|
|
110442
111512
|
init_index();
|
|
@@ -110478,7 +111548,7 @@ var init_ProbeAgent = __esm({
|
|
|
110478
111548
|
* @param {string} [options.customPrompt] - Custom prompt to replace the default system message
|
|
110479
111549
|
* @param {string} [options.systemPrompt] - Alias for customPrompt; takes precedence when both are provided
|
|
110480
111550
|
* @param {string} [options.promptType] - Predefined prompt type (code-explorer, code-searcher, architect, code-review, support)
|
|
110481
|
-
* @param {boolean} [options.allowEdit=false] - Allow the use of the '
|
|
111551
|
+
* @param {boolean} [options.allowEdit=false] - Allow the use of the 'edit' and 'create' tools
|
|
110482
111552
|
* @param {boolean} [options.enableDelegate=false] - Enable the delegate tool for task distribution to subagents
|
|
110483
111553
|
* @param {boolean} [options.enableExecutePlan=false] - Enable the execute_plan DSL orchestration tool
|
|
110484
111554
|
* @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)
|
|
@@ -110523,10 +111593,11 @@ var init_ProbeAgent = __esm({
|
|
|
110523
111593
|
* @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.
|
|
110524
111594
|
*/
|
|
110525
111595
|
constructor(options = {}) {
|
|
110526
|
-
this.sessionId = options.sessionId || (0,
|
|
111596
|
+
this.sessionId = options.sessionId || (0, import_crypto10.randomUUID)();
|
|
110527
111597
|
this.customPrompt = options.systemPrompt || options.customPrompt || null;
|
|
110528
111598
|
this.promptType = options.promptType || "code-explorer";
|
|
110529
111599
|
this.allowEdit = !!options.allowEdit;
|
|
111600
|
+
this.hashLines = options.hashLines !== void 0 ? !!options.hashLines : this.allowEdit;
|
|
110530
111601
|
this.enableDelegate = !!options.enableDelegate;
|
|
110531
111602
|
this.enableExecutePlan = !!options.enableExecutePlan;
|
|
110532
111603
|
this.debug = options.debug || process.env.DEBUG === "1";
|
|
@@ -110588,7 +111659,8 @@ var init_ProbeAgent = __esm({
|
|
|
110588
111659
|
if (this.debug) {
|
|
110589
111660
|
console.log(`[DEBUG] Generated session ID for agent: ${this.sessionId}`);
|
|
110590
111661
|
console.log(`[DEBUG] Maximum tool iterations configured: ${MAX_TOOL_ITERATIONS}`);
|
|
110591
|
-
console.log(`[DEBUG] Allow Edit
|
|
111662
|
+
console.log(`[DEBUG] Allow Edit: ${this.allowEdit}`);
|
|
111663
|
+
console.log(`[DEBUG] Hash Lines: ${this.hashLines}`);
|
|
110592
111664
|
console.log(`[DEBUG] Search delegation enabled: ${this.searchDelegate}`);
|
|
110593
111665
|
console.log(`[DEBUG] Workspace root: ${this.workspaceRoot}`);
|
|
110594
111666
|
console.log(`[DEBUG] Working directory (cwd): ${this.cwd}`);
|
|
@@ -110973,9 +112045,12 @@ var init_ProbeAgent = __esm({
|
|
|
110973
112045
|
cwd: this.cwd,
|
|
110974
112046
|
workspaceRoot: this.workspaceRoot,
|
|
110975
112047
|
allowedFolders: this.allowedFolders,
|
|
112048
|
+
// File state tracking for safe multi-edit workflows (only when editing is enabled)
|
|
112049
|
+
fileTracker: this.allowEdit ? new FileTracker({ debug: this.debug }) : null,
|
|
110976
112050
|
outline: this.outline,
|
|
110977
112051
|
searchDelegate: this.searchDelegate,
|
|
110978
112052
|
allowEdit: this.allowEdit,
|
|
112053
|
+
hashLines: this.hashLines,
|
|
110979
112054
|
enableDelegate: this.enableDelegate,
|
|
110980
112055
|
enableExecutePlan: this.enableExecutePlan,
|
|
110981
112056
|
enableBash: this.enableBash,
|
|
@@ -111046,7 +112121,7 @@ var init_ProbeAgent = __esm({
|
|
|
111046
112121
|
if (!imagePath) {
|
|
111047
112122
|
throw new Error("Image path is required");
|
|
111048
112123
|
}
|
|
111049
|
-
const filename = (0,
|
|
112124
|
+
const filename = (0, import_path18.basename)(imagePath);
|
|
111050
112125
|
const extension = filename.toLowerCase().split(".").pop();
|
|
111051
112126
|
if (!extension || !SUPPORTED_IMAGE_EXTENSIONS.includes(extension)) {
|
|
111052
112127
|
throw new Error(`Invalid or unsupported image extension: ${extension}. Supported formats: ${SUPPORTED_IMAGE_EXTENSIONS.join(", ")}`);
|
|
@@ -111760,7 +112835,7 @@ var init_ProbeAgent = __esm({
|
|
|
111760
112835
|
let resolvedPath2 = imagePath;
|
|
111761
112836
|
if (!imagePath.includes("/") && !imagePath.includes("\\")) {
|
|
111762
112837
|
for (const dir of listFilesDirectories) {
|
|
111763
|
-
const potentialPath = (0,
|
|
112838
|
+
const potentialPath = (0, import_path18.resolve)(dir, imagePath);
|
|
111764
112839
|
const loaded = await this.loadImageIfValid(potentialPath);
|
|
111765
112840
|
if (loaded) {
|
|
111766
112841
|
if (this.debug) {
|
|
@@ -111785,7 +112860,7 @@ var init_ProbeAgent = __esm({
|
|
|
111785
112860
|
let match2;
|
|
111786
112861
|
while ((match2 = fileHeaderPattern.exec(content)) !== null) {
|
|
111787
112862
|
const filePath = match2[1].trim();
|
|
111788
|
-
const dir = (0,
|
|
112863
|
+
const dir = (0, import_path18.dirname)(filePath);
|
|
111789
112864
|
if (dir && dir !== ".") {
|
|
111790
112865
|
directories.push(dir);
|
|
111791
112866
|
if (this.debug) {
|
|
@@ -111830,17 +112905,17 @@ var init_ProbeAgent = __esm({
|
|
|
111830
112905
|
const allowedDirs = this.allowedFolders && this.allowedFolders.length > 0 ? this.allowedFolders : [process.cwd()];
|
|
111831
112906
|
let absolutePath;
|
|
111832
112907
|
let isPathAllowed2 = false;
|
|
111833
|
-
if ((0,
|
|
111834
|
-
absolutePath = safeRealpath((0,
|
|
112908
|
+
if ((0, import_path18.isAbsolute)(imagePath)) {
|
|
112909
|
+
absolutePath = safeRealpath((0, import_path18.resolve)(imagePath));
|
|
111835
112910
|
isPathAllowed2 = allowedDirs.some((dir) => {
|
|
111836
112911
|
const resolvedDir = safeRealpath(dir);
|
|
111837
|
-
return absolutePath === resolvedDir || absolutePath.startsWith(resolvedDir +
|
|
112912
|
+
return absolutePath === resolvedDir || absolutePath.startsWith(resolvedDir + import_path18.sep);
|
|
111838
112913
|
});
|
|
111839
112914
|
} else {
|
|
111840
112915
|
for (const dir of allowedDirs) {
|
|
111841
112916
|
const resolvedDir = safeRealpath(dir);
|
|
111842
|
-
const resolvedPath2 = safeRealpath((0,
|
|
111843
|
-
if (resolvedPath2 === resolvedDir || resolvedPath2.startsWith(resolvedDir +
|
|
112917
|
+
const resolvedPath2 = safeRealpath((0, import_path18.resolve)(dir, imagePath));
|
|
112918
|
+
if (resolvedPath2 === resolvedDir || resolvedPath2.startsWith(resolvedDir + import_path18.sep)) {
|
|
111844
112919
|
absolutePath = resolvedPath2;
|
|
111845
112920
|
isPathAllowed2 = true;
|
|
111846
112921
|
break;
|
|
@@ -112028,8 +113103,8 @@ var init_ProbeAgent = __esm({
|
|
|
112028
113103
|
const hasConfiguredName = !!configuredName;
|
|
112029
113104
|
let guidanceCandidates = [];
|
|
112030
113105
|
if (hasConfiguredName) {
|
|
112031
|
-
const targetName = (0,
|
|
112032
|
-
if (configuredName !== targetName || configuredName.includes("/") || configuredName.includes("\\") || configuredName.includes("..") || (0,
|
|
113106
|
+
const targetName = (0, import_path18.basename)(configuredName);
|
|
113107
|
+
if (configuredName !== targetName || configuredName.includes("/") || configuredName.includes("\\") || configuredName.includes("..") || (0, import_path18.isAbsolute)(configuredName)) {
|
|
112033
113108
|
console.warn(`[WARN] Invalid architectureFileName (must be a simple filename): ${configuredName}`);
|
|
112034
113109
|
} else if (targetName) {
|
|
112035
113110
|
const targetLower = targetName.toLowerCase();
|
|
@@ -112096,7 +113171,7 @@ var init_ProbeAgent = __esm({
|
|
|
112096
113171
|
pushEntry(architectureMatch);
|
|
112097
113172
|
const contexts = [];
|
|
112098
113173
|
for (const entry of uniqueEntries) {
|
|
112099
|
-
const filePath = (0,
|
|
113174
|
+
const filePath = (0, import_path18.resolve)(rootDirectory, entry.name);
|
|
112100
113175
|
try {
|
|
112101
113176
|
const content = await (0, import_promises6.readFile)(filePath, "utf8");
|
|
112102
113177
|
let kind = "other";
|
|
@@ -112161,10 +113236,10 @@ ${this.architectureContext.content}
|
|
|
112161
113236
|
}
|
|
112162
113237
|
_getSkillsRepoRoot() {
|
|
112163
113238
|
if (this.workspaceRoot) {
|
|
112164
|
-
return (0,
|
|
113239
|
+
return (0, import_path18.resolve)(this.workspaceRoot);
|
|
112165
113240
|
}
|
|
112166
113241
|
if (this.allowedFolders && this.allowedFolders.length > 0) {
|
|
112167
|
-
return (0,
|
|
113242
|
+
return (0, import_path18.resolve)(this.allowedFolders[0]);
|
|
112168
113243
|
}
|
|
112169
113244
|
return process.cwd();
|
|
112170
113245
|
}
|
|
@@ -112353,10 +113428,6 @@ Workspace: ${this.allowedFolders.join(", ")}`;
|
|
|
112353
113428
|
}
|
|
112354
113429
|
if (isToolAllowed("readImage")) {
|
|
112355
113430
|
toolDefinitions += `${readImageToolDefinition}
|
|
112356
|
-
`;
|
|
112357
|
-
}
|
|
112358
|
-
if (this.allowEdit && isToolAllowed("implement")) {
|
|
112359
|
-
toolDefinitions += `${implementToolDefinition}
|
|
112360
113431
|
`;
|
|
112361
113432
|
}
|
|
112362
113433
|
if (this.allowEdit && isToolAllowed("edit")) {
|
|
@@ -112438,7 +113509,7 @@ The configuration is loaded from src/config.js lines 15-25 which contains the da
|
|
|
112438
113509
|
availableToolsList += "- query: Search code using structural AST patterns.\n";
|
|
112439
113510
|
}
|
|
112440
113511
|
if (isToolAllowed("extract")) {
|
|
112441
|
-
availableToolsList +=
|
|
113512
|
+
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';
|
|
112442
113513
|
}
|
|
112443
113514
|
if (isToolAllowed("listFiles")) {
|
|
112444
113515
|
availableToolsList += "- listFiles: List files and directories in a specified location.\n";
|
|
@@ -112455,11 +113526,8 @@ The configuration is loaded from src/config.js lines 15-25 which contains the da
|
|
|
112455
113526
|
if (isToolAllowed("readImage")) {
|
|
112456
113527
|
availableToolsList += "- readImage: Read and load an image file for AI analysis.\n";
|
|
112457
113528
|
}
|
|
112458
|
-
if (this.allowEdit && isToolAllowed("implement")) {
|
|
112459
|
-
availableToolsList += "- implement: Implement a feature or fix a bug using aider.\n";
|
|
112460
|
-
}
|
|
112461
113529
|
if (this.allowEdit && isToolAllowed("edit")) {
|
|
112462
|
-
availableToolsList += "- edit: Edit files using
|
|
113530
|
+
availableToolsList += "- edit: Edit files using text replacement, AST-aware symbol operations, or line-targeted editing.\n";
|
|
112463
113531
|
}
|
|
112464
113532
|
if (this.allowEdit && isToolAllowed("create")) {
|
|
112465
113533
|
availableToolsList += "- create: Create new files with specified content.\n";
|
|
@@ -112547,8 +113615,14 @@ Follow these instructions carefully:
|
|
|
112547
113615
|
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.
|
|
112548
113616
|
9. Prefer concise and focused search queries. Use specific keywords and phrases to narrow down results.${this.allowEdit ? `
|
|
112549
113617
|
10. When modifying files, choose the appropriate tool:
|
|
112550
|
-
- Use 'edit' for
|
|
112551
|
-
|
|
113618
|
+
- Use 'edit' for all code modifications:
|
|
113619
|
+
* For small changes (a line or a few lines), use old_string + new_string \u2014 copy old_string verbatim from the file.
|
|
113620
|
+
* For rewriting entire functions/classes/methods, use the symbol parameter instead (no exact text matching needed).
|
|
113621
|
+
* 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.' : ""}
|
|
113622
|
+
* 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.
|
|
113623
|
+
- Use 'create' for new files or complete file rewrites.
|
|
113624
|
+
- If an edit fails, read the error message \u2014 it tells you exactly how to fix the call and retry.
|
|
113625
|
+
- 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.` : ""}
|
|
112552
113626
|
</instructions>
|
|
112553
113627
|
`;
|
|
112554
113628
|
let systemMessage = "";
|
|
@@ -113048,8 +114122,11 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
113048
114122
|
if (this.enableSkills && this.allowedTools.isEnabled("useSkill")) validTools.push("useSkill");
|
|
113049
114123
|
if (this.allowedTools.isEnabled("readImage")) validTools.push("readImage");
|
|
113050
114124
|
validTools.push("attempt_completion");
|
|
113051
|
-
if (this.allowEdit && this.allowedTools.isEnabled("
|
|
113052
|
-
validTools.push("
|
|
114125
|
+
if (this.allowEdit && this.allowedTools.isEnabled("edit")) {
|
|
114126
|
+
validTools.push("edit");
|
|
114127
|
+
}
|
|
114128
|
+
if (this.allowEdit && this.allowedTools.isEnabled("create")) {
|
|
114129
|
+
validTools.push("create");
|
|
113053
114130
|
}
|
|
113054
114131
|
if (this.enableBash && this.allowedTools.isEnabled("bash")) {
|
|
113055
114132
|
validTools.push("bash");
|
|
@@ -113271,10 +114348,10 @@ ${errorXml}
|
|
|
113271
114348
|
try {
|
|
113272
114349
|
let resolvedWorkingDirectory = this.workspaceRoot || this.cwd || this.allowedFolders && this.allowedFolders[0] || process.cwd();
|
|
113273
114350
|
if (params.workingDirectory) {
|
|
113274
|
-
const requestedDir = safeRealpath((0,
|
|
114351
|
+
const requestedDir = safeRealpath((0, import_path18.isAbsolute)(params.workingDirectory) ? (0, import_path18.resolve)(params.workingDirectory) : (0, import_path18.resolve)(resolvedWorkingDirectory, params.workingDirectory));
|
|
113275
114352
|
const isWithinAllowed = !this.allowedFolders || this.allowedFolders.length === 0 || this.allowedFolders.some((folder) => {
|
|
113276
114353
|
const resolvedFolder = safeRealpath(folder);
|
|
113277
|
-
return requestedDir === resolvedFolder || requestedDir.startsWith(resolvedFolder +
|
|
114354
|
+
return requestedDir === resolvedFolder || requestedDir.startsWith(resolvedFolder + import_path18.sep);
|
|
113278
114355
|
});
|
|
113279
114356
|
if (isWithinAllowed) {
|
|
113280
114357
|
resolvedWorkingDirectory = requestedDir;
|
|
@@ -113342,6 +114419,8 @@ ${errorXml}
|
|
|
113342
114419
|
// Inherit bash enablement
|
|
113343
114420
|
bashConfig: this.bashConfig,
|
|
113344
114421
|
// Inherit bash configuration
|
|
114422
|
+
allowEdit: this.allowEdit,
|
|
114423
|
+
// Inherit edit/create permission
|
|
113345
114424
|
allowedTools: allowedToolsForDelegate,
|
|
113346
114425
|
// Inherit allowed tools from parent
|
|
113347
114426
|
debug: this.debug,
|
|
@@ -113414,7 +114493,7 @@ ${errorXml}
|
|
|
113414
114493
|
currentMessages.push({ role: "assistant", content: assistantResponseContent });
|
|
113415
114494
|
let toolResultContent = typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult, null, 2);
|
|
113416
114495
|
if (this.workspaceRoot && toolResultContent) {
|
|
113417
|
-
const wsPrefix = this.workspaceRoot.endsWith(
|
|
114496
|
+
const wsPrefix = this.workspaceRoot.endsWith(import_path18.sep) ? this.workspaceRoot : this.workspaceRoot + import_path18.sep;
|
|
113418
114497
|
toolResultContent = toolResultContent.split(wsPrefix).join("");
|
|
113419
114498
|
}
|
|
113420
114499
|
const { cleanedContent, extractedBlocks } = extractRawOutputBlocks(toolResultContent);
|
|
@@ -113502,6 +114581,25 @@ ${errorXml}
|
|
|
113502
114581
|
}
|
|
113503
114582
|
break;
|
|
113504
114583
|
}
|
|
114584
|
+
if (options.schema) {
|
|
114585
|
+
let contentToCheck = assistantResponseContent;
|
|
114586
|
+
contentToCheck = contentToCheck.replace(/<thinking>[\s\S]*?<\/thinking>/gi, "").trim();
|
|
114587
|
+
contentToCheck = contentToCheck.replace(/<thinking>[\s\S]*$/gi, "").trim();
|
|
114588
|
+
const cleanedJson = cleanSchemaResponse(contentToCheck);
|
|
114589
|
+
try {
|
|
114590
|
+
JSON.parse(cleanedJson);
|
|
114591
|
+
const validation = validateJsonResponse(cleanedJson, { debug: this.debug, schema: options.schema });
|
|
114592
|
+
if (validation.isValid) {
|
|
114593
|
+
if (this.debug) {
|
|
114594
|
+
console.log(`[DEBUG] Issue #443: Accepting valid JSON response without attempt_completion (${cleanedJson.length} chars)`);
|
|
114595
|
+
}
|
|
114596
|
+
finalResult = cleanedJson;
|
|
114597
|
+
completionAttempted = true;
|
|
114598
|
+
break;
|
|
114599
|
+
}
|
|
114600
|
+
} catch {
|
|
114601
|
+
}
|
|
114602
|
+
}
|
|
113505
114603
|
consecutiveNoToolCount++;
|
|
113506
114604
|
const isIdentical = lastNoToolResponse !== null && assistantResponseContent === lastNoToolResponse;
|
|
113507
114605
|
const isSemanticallyStuck = lastNoToolResponse !== null && areBothStuckResponses(lastNoToolResponse, assistantResponseContent);
|
|
@@ -114245,7 +115343,7 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
114245
115343
|
*/
|
|
114246
115344
|
clone(options = {}) {
|
|
114247
115345
|
const {
|
|
114248
|
-
sessionId = (0,
|
|
115346
|
+
sessionId = (0, import_crypto10.randomUUID)(),
|
|
114249
115347
|
stripInternalMessages = true,
|
|
114250
115348
|
keepSystemMessage = true,
|
|
114251
115349
|
deepCopy = true,
|