@probelabs/probe 0.6.0-rc254 → 0.6.0-rc256
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-rc256-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc256-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc256-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc256-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc256-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/ProbeAgent.d.ts +1 -1
- package/build/agent/ProbeAgent.js +39 -23
- package/build/agent/acp/tools.js +2 -1
- package/build/agent/acp/tools.test.js +2 -1
- package/build/agent/bashDefaults.js +75 -6
- package/build/agent/index.js +1752 -426
- package/build/agent/mcp/xmlBridge.js +3 -2
- package/build/agent/schemaUtils.js +127 -0
- package/build/agent/tools.js +0 -28
- package/build/delegate.js +3 -0
- package/build/index.js +2 -0
- package/build/tools/common.js +26 -8
- package/build/tools/edit.js +457 -65
- 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 +1863 -528
- package/cjs/index.cjs +1891 -554
- package/index.d.ts +189 -1
- package/package.json +1 -1
- package/src/agent/ProbeAgent.d.ts +1 -1
- package/src/agent/ProbeAgent.js +39 -23
- package/src/agent/acp/tools.js +2 -1
- package/src/agent/acp/tools.test.js +2 -1
- package/src/agent/bashDefaults.js +75 -6
- package/src/agent/index.js +18 -7
- package/src/agent/mcp/xmlBridge.js +3 -2
- package/src/agent/schemaUtils.js +127 -0
- package/src/agent/tools.js +0 -28
- package/src/delegate.js +3 -0
- package/src/index.js +2 -0
- package/src/tools/common.js +26 -8
- package/src/tools/edit.js +457 -65
- 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-rc254-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc254-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc254-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc254-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc254-x86_64-unknown-linux-musl.tar.gz +0 -0
package/cjs/agent/ProbeAgent.cjs
CHANGED
|
@@ -1844,6 +1844,7 @@ var require_ChecksumStream = __commonJS({
|
|
|
1844
1844
|
checksum;
|
|
1845
1845
|
source;
|
|
1846
1846
|
base64Encoder;
|
|
1847
|
+
pendingCallback = null;
|
|
1847
1848
|
constructor({ expectedChecksum, checksum, source, checksumSourceLocation, base64Encoder }) {
|
|
1848
1849
|
super();
|
|
1849
1850
|
if (typeof source.pipe === "function") {
|
|
@@ -1858,11 +1859,20 @@ var require_ChecksumStream = __commonJS({
|
|
|
1858
1859
|
this.source.pipe(this);
|
|
1859
1860
|
}
|
|
1860
1861
|
_read(size) {
|
|
1862
|
+
if (this.pendingCallback) {
|
|
1863
|
+
const callback = this.pendingCallback;
|
|
1864
|
+
this.pendingCallback = null;
|
|
1865
|
+
callback();
|
|
1866
|
+
}
|
|
1861
1867
|
}
|
|
1862
1868
|
_write(chunk, encoding, callback) {
|
|
1863
1869
|
try {
|
|
1864
1870
|
this.checksum.update(chunk);
|
|
1865
|
-
this.push(chunk);
|
|
1871
|
+
const canPushMore = this.push(chunk);
|
|
1872
|
+
if (!canPushMore) {
|
|
1873
|
+
this.pendingCallback = callback;
|
|
1874
|
+
return;
|
|
1875
|
+
}
|
|
1866
1876
|
} catch (e5) {
|
|
1867
1877
|
return callback(e5);
|
|
1868
1878
|
}
|
|
@@ -2329,7 +2339,7 @@ var require_headStream = __commonJS({
|
|
|
2329
2339
|
if ((0, stream_type_check_1.isReadableStream)(stream2)) {
|
|
2330
2340
|
return (0, headStream_browser_1.headStream)(stream2, bytes);
|
|
2331
2341
|
}
|
|
2332
|
-
return new Promise((
|
|
2342
|
+
return new Promise((resolve8, reject2) => {
|
|
2333
2343
|
const collector = new Collector();
|
|
2334
2344
|
collector.limit = bytes;
|
|
2335
2345
|
stream2.pipe(collector);
|
|
@@ -2340,7 +2350,7 @@ var require_headStream = __commonJS({
|
|
|
2340
2350
|
collector.on("error", reject2);
|
|
2341
2351
|
collector.on("finish", function() {
|
|
2342
2352
|
const bytes2 = new Uint8Array(Buffer.concat(this.buffers));
|
|
2343
|
-
|
|
2353
|
+
resolve8(bytes2);
|
|
2344
2354
|
});
|
|
2345
2355
|
});
|
|
2346
2356
|
};
|
|
@@ -2528,21 +2538,21 @@ var require_dist_cjs15 = __commonJS({
|
|
|
2528
2538
|
let sendBody = true;
|
|
2529
2539
|
if (!externalAgent && expect === "100-continue") {
|
|
2530
2540
|
sendBody = await Promise.race([
|
|
2531
|
-
new Promise((
|
|
2532
|
-
timeoutId = Number(timing.setTimeout(() =>
|
|
2541
|
+
new Promise((resolve8) => {
|
|
2542
|
+
timeoutId = Number(timing.setTimeout(() => resolve8(true), Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
|
|
2533
2543
|
}),
|
|
2534
|
-
new Promise((
|
|
2544
|
+
new Promise((resolve8) => {
|
|
2535
2545
|
httpRequest.on("continue", () => {
|
|
2536
2546
|
timing.clearTimeout(timeoutId);
|
|
2537
|
-
|
|
2547
|
+
resolve8(true);
|
|
2538
2548
|
});
|
|
2539
2549
|
httpRequest.on("response", () => {
|
|
2540
2550
|
timing.clearTimeout(timeoutId);
|
|
2541
|
-
|
|
2551
|
+
resolve8(false);
|
|
2542
2552
|
});
|
|
2543
2553
|
httpRequest.on("error", () => {
|
|
2544
2554
|
timing.clearTimeout(timeoutId);
|
|
2545
|
-
|
|
2555
|
+
resolve8(false);
|
|
2546
2556
|
});
|
|
2547
2557
|
})
|
|
2548
2558
|
]);
|
|
@@ -2614,13 +2624,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2614
2624
|
return socketWarningTimestamp;
|
|
2615
2625
|
}
|
|
2616
2626
|
constructor(options) {
|
|
2617
|
-
this.configProvider = new Promise((
|
|
2627
|
+
this.configProvider = new Promise((resolve8, reject2) => {
|
|
2618
2628
|
if (typeof options === "function") {
|
|
2619
2629
|
options().then((_options) => {
|
|
2620
|
-
|
|
2630
|
+
resolve8(this.resolveDefaultConfig(_options));
|
|
2621
2631
|
}).catch(reject2);
|
|
2622
2632
|
} else {
|
|
2623
|
-
|
|
2633
|
+
resolve8(this.resolveDefaultConfig(options));
|
|
2624
2634
|
}
|
|
2625
2635
|
});
|
|
2626
2636
|
}
|
|
@@ -2663,7 +2673,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2663
2673
|
const config = this.config;
|
|
2664
2674
|
let writeRequestBodyPromise = void 0;
|
|
2665
2675
|
const timeouts = [];
|
|
2666
|
-
const
|
|
2676
|
+
const resolve8 = async (arg) => {
|
|
2667
2677
|
await writeRequestBodyPromise;
|
|
2668
2678
|
timeouts.forEach(timing.clearTimeout);
|
|
2669
2679
|
_resolve(arg);
|
|
@@ -2729,7 +2739,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2729
2739
|
headers: getTransformedHeaders(res.headers),
|
|
2730
2740
|
body: res
|
|
2731
2741
|
});
|
|
2732
|
-
|
|
2742
|
+
resolve8({ response: httpResponse });
|
|
2733
2743
|
});
|
|
2734
2744
|
req.on("error", (err) => {
|
|
2735
2745
|
if (NODEJS_TIMEOUT_ERROR_CODES.includes(err.code)) {
|
|
@@ -2909,13 +2919,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2909
2919
|
return new _NodeHttp2Handler(instanceOrOptions);
|
|
2910
2920
|
}
|
|
2911
2921
|
constructor(options) {
|
|
2912
|
-
this.configProvider = new Promise((
|
|
2922
|
+
this.configProvider = new Promise((resolve8, reject2) => {
|
|
2913
2923
|
if (typeof options === "function") {
|
|
2914
2924
|
options().then((opts) => {
|
|
2915
|
-
|
|
2925
|
+
resolve8(opts || {});
|
|
2916
2926
|
}).catch(reject2);
|
|
2917
2927
|
} else {
|
|
2918
|
-
|
|
2928
|
+
resolve8(options || {});
|
|
2919
2929
|
}
|
|
2920
2930
|
});
|
|
2921
2931
|
}
|
|
@@ -2935,7 +2945,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2935
2945
|
return new Promise((_resolve, _reject) => {
|
|
2936
2946
|
let fulfilled = false;
|
|
2937
2947
|
let writeRequestBodyPromise = void 0;
|
|
2938
|
-
const
|
|
2948
|
+
const resolve8 = async (arg) => {
|
|
2939
2949
|
await writeRequestBodyPromise;
|
|
2940
2950
|
_resolve(arg);
|
|
2941
2951
|
};
|
|
@@ -2991,7 +3001,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2991
3001
|
body: req
|
|
2992
3002
|
});
|
|
2993
3003
|
fulfilled = true;
|
|
2994
|
-
|
|
3004
|
+
resolve8({ response: httpResponse });
|
|
2995
3005
|
if (disableConcurrentStreams) {
|
|
2996
3006
|
session.close();
|
|
2997
3007
|
this.connectionManager.deleteSession(authority, session);
|
|
@@ -3068,7 +3078,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
3068
3078
|
if (isReadableStreamInstance(stream3)) {
|
|
3069
3079
|
return collectReadableStream(stream3);
|
|
3070
3080
|
}
|
|
3071
|
-
return new Promise((
|
|
3081
|
+
return new Promise((resolve8, reject2) => {
|
|
3072
3082
|
const collector = new Collector();
|
|
3073
3083
|
stream3.pipe(collector);
|
|
3074
3084
|
stream3.on("error", (err) => {
|
|
@@ -3078,7 +3088,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
3078
3088
|
collector.on("error", reject2);
|
|
3079
3089
|
collector.on("finish", function() {
|
|
3080
3090
|
const bytes = new Uint8Array(Buffer.concat(this.bufferedBytes));
|
|
3081
|
-
|
|
3091
|
+
resolve8(bytes);
|
|
3082
3092
|
});
|
|
3083
3093
|
});
|
|
3084
3094
|
};
|
|
@@ -3122,7 +3132,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
3122
3132
|
return new Request(url, requestOptions);
|
|
3123
3133
|
}
|
|
3124
3134
|
function requestTimeout(timeoutInMs = 0) {
|
|
3125
|
-
return new Promise((
|
|
3135
|
+
return new Promise((resolve8, reject2) => {
|
|
3126
3136
|
if (timeoutInMs) {
|
|
3127
3137
|
setTimeout(() => {
|
|
3128
3138
|
const timeoutError = new Error(`Request did not complete within ${timeoutInMs} ms`);
|
|
@@ -3240,7 +3250,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
3240
3250
|
requestTimeout(requestTimeoutInMs)
|
|
3241
3251
|
];
|
|
3242
3252
|
if (abortSignal) {
|
|
3243
|
-
raceOfPromises.push(new Promise((
|
|
3253
|
+
raceOfPromises.push(new Promise((resolve8, reject2) => {
|
|
3244
3254
|
const onAbort = () => {
|
|
3245
3255
|
const abortError = new Error("Request aborted");
|
|
3246
3256
|
abortError.name = "AbortError";
|
|
@@ -3304,7 +3314,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
3304
3314
|
return collected;
|
|
3305
3315
|
}
|
|
3306
3316
|
function readToBase64(blob) {
|
|
3307
|
-
return new Promise((
|
|
3317
|
+
return new Promise((resolve8, reject2) => {
|
|
3308
3318
|
const reader = new FileReader();
|
|
3309
3319
|
reader.onloadend = () => {
|
|
3310
3320
|
if (reader.readyState !== 2) {
|
|
@@ -3313,7 +3323,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
3313
3323
|
const result = reader.result ?? "";
|
|
3314
3324
|
const commaIndex = result.indexOf(",");
|
|
3315
3325
|
const dataOffset = commaIndex > -1 ? commaIndex + 1 : result.length;
|
|
3316
|
-
|
|
3326
|
+
resolve8(result.substring(dataOffset));
|
|
3317
3327
|
};
|
|
3318
3328
|
reader.onabort = () => reject2(new Error("Read aborted"));
|
|
3319
3329
|
reader.onerror = () => reject2(reader.error);
|
|
@@ -4981,11 +4991,11 @@ function __metadata(metadataKey, metadataValue) {
|
|
|
4981
4991
|
}
|
|
4982
4992
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
4983
4993
|
function adopt(value) {
|
|
4984
|
-
return value instanceof P ? value : new P(function(
|
|
4985
|
-
|
|
4994
|
+
return value instanceof P ? value : new P(function(resolve8) {
|
|
4995
|
+
resolve8(value);
|
|
4986
4996
|
});
|
|
4987
4997
|
}
|
|
4988
|
-
return new (P || (P = Promise))(function(
|
|
4998
|
+
return new (P || (P = Promise))(function(resolve8, reject2) {
|
|
4989
4999
|
function fulfilled(value) {
|
|
4990
5000
|
try {
|
|
4991
5001
|
step(generator.next(value));
|
|
@@ -5001,7 +5011,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
5001
5011
|
}
|
|
5002
5012
|
}
|
|
5003
5013
|
function step(result) {
|
|
5004
|
-
result.done ?
|
|
5014
|
+
result.done ? resolve8(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
5005
5015
|
}
|
|
5006
5016
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
5007
5017
|
});
|
|
@@ -5192,14 +5202,14 @@ function __asyncValues(o5) {
|
|
|
5192
5202
|
}, i5);
|
|
5193
5203
|
function verb(n5) {
|
|
5194
5204
|
i5[n5] = o5[n5] && function(v5) {
|
|
5195
|
-
return new Promise(function(
|
|
5196
|
-
v5 = o5[n5](v5), settle(
|
|
5205
|
+
return new Promise(function(resolve8, reject2) {
|
|
5206
|
+
v5 = o5[n5](v5), settle(resolve8, reject2, v5.done, v5.value);
|
|
5197
5207
|
});
|
|
5198
5208
|
};
|
|
5199
5209
|
}
|
|
5200
|
-
function settle(
|
|
5210
|
+
function settle(resolve8, reject2, d5, v5) {
|
|
5201
5211
|
Promise.resolve(v5).then(function(v6) {
|
|
5202
|
-
|
|
5212
|
+
resolve8({ value: v6, done: d5 });
|
|
5203
5213
|
}, reject2);
|
|
5204
5214
|
}
|
|
5205
5215
|
}
|
|
@@ -15600,7 +15610,7 @@ var require_dist_cjs37 = __commonJS({
|
|
|
15600
15610
|
this.sockets[url] = (this.sockets[url] ?? []).filter((socket) => ![WebSocket.CLOSING, WebSocket.CLOSED].includes(socket.readyState));
|
|
15601
15611
|
}
|
|
15602
15612
|
waitForReady(socket, connectionTimeout) {
|
|
15603
|
-
return new Promise((
|
|
15613
|
+
return new Promise((resolve8, reject2) => {
|
|
15604
15614
|
const timeout = setTimeout(() => {
|
|
15605
15615
|
this.removeNotUsableSockets(socket.url);
|
|
15606
15616
|
reject2({
|
|
@@ -15612,7 +15622,7 @@ var require_dist_cjs37 = __commonJS({
|
|
|
15612
15622
|
}, connectionTimeout);
|
|
15613
15623
|
socket.onopen = () => {
|
|
15614
15624
|
clearTimeout(timeout);
|
|
15615
|
-
|
|
15625
|
+
resolve8();
|
|
15616
15626
|
};
|
|
15617
15627
|
});
|
|
15618
15628
|
}
|
|
@@ -15665,8 +15675,8 @@ var require_dist_cjs37 = __commonJS({
|
|
|
15665
15675
|
}
|
|
15666
15676
|
return { done: item.done, value: item.value };
|
|
15667
15677
|
}
|
|
15668
|
-
return new Promise((
|
|
15669
|
-
pendingResolve =
|
|
15678
|
+
return new Promise((resolve8, reject2) => {
|
|
15679
|
+
pendingResolve = resolve8;
|
|
15670
15680
|
pendingReject = reject2;
|
|
15671
15681
|
});
|
|
15672
15682
|
}
|
|
@@ -16879,7 +16889,7 @@ var require_dist_cjs46 = __commonJS({
|
|
|
16879
16889
|
this.refillTokenBucket();
|
|
16880
16890
|
if (amount > this.currentCapacity) {
|
|
16881
16891
|
const delay = (amount - this.currentCapacity) / this.fillRate * 1e3;
|
|
16882
|
-
await new Promise((
|
|
16892
|
+
await new Promise((resolve8) => _DefaultRateLimiter.setTimeoutFn(resolve8, delay));
|
|
16883
16893
|
}
|
|
16884
16894
|
this.currentCapacity = this.currentCapacity - amount;
|
|
16885
16895
|
}
|
|
@@ -17214,7 +17224,7 @@ var require_dist_cjs47 = __commonJS({
|
|
|
17214
17224
|
const delayFromResponse = getDelayFromRetryAfterHeader(err.$response);
|
|
17215
17225
|
const delay = Math.max(delayFromResponse || 0, delayFromDecider);
|
|
17216
17226
|
totalDelay += delay;
|
|
17217
|
-
await new Promise((
|
|
17227
|
+
await new Promise((resolve8) => setTimeout(resolve8, delay));
|
|
17218
17228
|
continue;
|
|
17219
17229
|
}
|
|
17220
17230
|
if (!err.$metadata) {
|
|
@@ -17372,7 +17382,7 @@ var require_dist_cjs47 = __commonJS({
|
|
|
17372
17382
|
attempts = retryToken.getRetryCount();
|
|
17373
17383
|
const delay = retryToken.getRetryDelay();
|
|
17374
17384
|
totalRetryDelay += delay;
|
|
17375
|
-
await new Promise((
|
|
17385
|
+
await new Promise((resolve8) => setTimeout(resolve8, delay));
|
|
17376
17386
|
}
|
|
17377
17387
|
}
|
|
17378
17388
|
} else {
|
|
@@ -17524,7 +17534,7 @@ var require_package2 = __commonJS({
|
|
|
17524
17534
|
module2.exports = {
|
|
17525
17535
|
name: "@aws-sdk/client-bedrock-runtime",
|
|
17526
17536
|
description: "AWS SDK for JavaScript Bedrock Runtime Client for Node.js, Browser and React Native",
|
|
17527
|
-
version: "3.
|
|
17537
|
+
version: "3.995.0",
|
|
17528
17538
|
scripts: {
|
|
17529
17539
|
build: "concurrently 'yarn:build:types' 'yarn:build:es' && yarn build:cjs",
|
|
17530
17540
|
"build:cjs": "node ../../scripts/compilation/inline client-bedrock-runtime",
|
|
@@ -17554,11 +17564,11 @@ var require_package2 = __commonJS({
|
|
|
17554
17564
|
"@aws-sdk/middleware-user-agent": "^3.972.11",
|
|
17555
17565
|
"@aws-sdk/middleware-websocket": "^3.972.6",
|
|
17556
17566
|
"@aws-sdk/region-config-resolver": "^3.972.3",
|
|
17557
|
-
"@aws-sdk/token-providers": "3.
|
|
17567
|
+
"@aws-sdk/token-providers": "3.995.0",
|
|
17558
17568
|
"@aws-sdk/types": "^3.973.1",
|
|
17559
|
-
"@aws-sdk/util-endpoints": "3.
|
|
17569
|
+
"@aws-sdk/util-endpoints": "3.995.0",
|
|
17560
17570
|
"@aws-sdk/util-user-agent-browser": "^3.972.3",
|
|
17561
|
-
"@aws-sdk/util-user-agent-node": "^3.972.
|
|
17571
|
+
"@aws-sdk/util-user-agent-node": "^3.972.10",
|
|
17562
17572
|
"@smithy/config-resolver": "^4.4.6",
|
|
17563
17573
|
"@smithy/core": "^3.23.2",
|
|
17564
17574
|
"@smithy/eventstream-serde-browser": "^4.2.8",
|
|
@@ -17687,7 +17697,7 @@ var require_dist_cjs49 = __commonJS({
|
|
|
17687
17697
|
var nodeConfigProvider = require_dist_cjs43();
|
|
17688
17698
|
var urlParser = require_dist_cjs22();
|
|
17689
17699
|
function httpRequest(options) {
|
|
17690
|
-
return new Promise((
|
|
17700
|
+
return new Promise((resolve8, reject2) => {
|
|
17691
17701
|
const req = http.request({
|
|
17692
17702
|
method: "GET",
|
|
17693
17703
|
...options,
|
|
@@ -17712,7 +17722,7 @@ var require_dist_cjs49 = __commonJS({
|
|
|
17712
17722
|
chunks.push(chunk);
|
|
17713
17723
|
});
|
|
17714
17724
|
res.on("end", () => {
|
|
17715
|
-
|
|
17725
|
+
resolve8(buffer.Buffer.concat(chunks));
|
|
17716
17726
|
req.destroy();
|
|
17717
17727
|
});
|
|
17718
17728
|
});
|
|
@@ -18132,7 +18142,7 @@ var require_retry_wrapper = __commonJS({
|
|
|
18132
18142
|
try {
|
|
18133
18143
|
return await toRetry();
|
|
18134
18144
|
} catch (e5) {
|
|
18135
|
-
await new Promise((
|
|
18145
|
+
await new Promise((resolve8) => setTimeout(resolve8, delayMs));
|
|
18136
18146
|
}
|
|
18137
18147
|
}
|
|
18138
18148
|
return await toRetry();
|
|
@@ -18440,6 +18450,15 @@ var require_dist_cjs51 = __commonJS({
|
|
|
18440
18450
|
var os4 = require("os");
|
|
18441
18451
|
var process2 = require("process");
|
|
18442
18452
|
var middlewareUserAgent = require_dist_cjs29();
|
|
18453
|
+
var getRuntimeUserAgentPair = () => {
|
|
18454
|
+
const runtimesToCheck = ["deno", "bun", "llrt"];
|
|
18455
|
+
for (const runtime of runtimesToCheck) {
|
|
18456
|
+
if (process2.versions[runtime]) {
|
|
18457
|
+
return [`md/${runtime}`, process2.versions[runtime]];
|
|
18458
|
+
}
|
|
18459
|
+
}
|
|
18460
|
+
return ["md/nodejs", process2.versions.node];
|
|
18461
|
+
};
|
|
18443
18462
|
var crtAvailability = {
|
|
18444
18463
|
isCrtAvailable: false
|
|
18445
18464
|
};
|
|
@@ -18450,13 +18469,14 @@ var require_dist_cjs51 = __commonJS({
|
|
|
18450
18469
|
return null;
|
|
18451
18470
|
};
|
|
18452
18471
|
var createDefaultUserAgentProvider5 = ({ serviceId, clientVersion }) => {
|
|
18472
|
+
const runtimeUserAgentPair = getRuntimeUserAgentPair();
|
|
18453
18473
|
return async (config) => {
|
|
18454
18474
|
const sections = [
|
|
18455
18475
|
["aws-sdk-js", clientVersion],
|
|
18456
18476
|
["ua", "2.1"],
|
|
18457
18477
|
[`os/${os4.platform()}`, os4.release()],
|
|
18458
18478
|
["lang/js"],
|
|
18459
|
-
|
|
18479
|
+
runtimeUserAgentPair
|
|
18460
18480
|
];
|
|
18461
18481
|
const crtAvailable = isCrtAvailable();
|
|
18462
18482
|
if (crtAvailable) {
|
|
@@ -24019,8 +24039,8 @@ var require_dist_cjs66 = __commonJS({
|
|
|
24019
24039
|
systemClockOffsetProvider: this.systemClockOffsetProvider
|
|
24020
24040
|
});
|
|
24021
24041
|
let resolvePipeline;
|
|
24022
|
-
const pipelineError = new Promise((
|
|
24023
|
-
resolvePipeline = () =>
|
|
24042
|
+
const pipelineError = new Promise((resolve8, reject2) => {
|
|
24043
|
+
resolvePipeline = () => resolve8(void 0);
|
|
24024
24044
|
node_stream.pipeline(payloadStream, signingStream, request.body, (err) => {
|
|
24025
24045
|
if (err) {
|
|
24026
24046
|
reject2(new Error(`Pipeline error in @aws-sdk/eventstream-handler-node: ${err.message}`, { cause: err }));
|
|
@@ -24126,7 +24146,7 @@ var init_package2 = __esm({
|
|
|
24126
24146
|
"node_modules/@aws-sdk/token-providers/node_modules/@aws-sdk/nested-clients/package.json"() {
|
|
24127
24147
|
package_default2 = {
|
|
24128
24148
|
name: "@aws-sdk/nested-clients",
|
|
24129
|
-
version: "3.
|
|
24149
|
+
version: "3.995.0",
|
|
24130
24150
|
description: "Nested clients for AWS SDK packages.",
|
|
24131
24151
|
main: "./dist-cjs/index.js",
|
|
24132
24152
|
module: "./dist-es/index.js",
|
|
@@ -24162,9 +24182,9 @@ var init_package2 = __esm({
|
|
|
24162
24182
|
"@aws-sdk/middleware-user-agent": "^3.972.11",
|
|
24163
24183
|
"@aws-sdk/region-config-resolver": "^3.972.3",
|
|
24164
24184
|
"@aws-sdk/types": "^3.973.1",
|
|
24165
|
-
"@aws-sdk/util-endpoints": "3.
|
|
24185
|
+
"@aws-sdk/util-endpoints": "3.995.0",
|
|
24166
24186
|
"@aws-sdk/util-user-agent-browser": "^3.972.3",
|
|
24167
|
-
"@aws-sdk/util-user-agent-node": "^3.972.
|
|
24187
|
+
"@aws-sdk/util-user-agent-node": "^3.972.10",
|
|
24168
24188
|
"@smithy/config-resolver": "^4.4.6",
|
|
24169
24189
|
"@smithy/core": "^3.23.2",
|
|
24170
24190
|
"@smithy/fetch-http-handler": "^5.3.9",
|
|
@@ -25574,7 +25594,7 @@ var require_dist_cjs69 = __commonJS({
|
|
|
25574
25594
|
streamEnded = true;
|
|
25575
25595
|
});
|
|
25576
25596
|
while (!generationEnded) {
|
|
25577
|
-
const value = await new Promise((
|
|
25597
|
+
const value = await new Promise((resolve8) => setTimeout(() => resolve8(records.shift()), 0));
|
|
25578
25598
|
if (value) {
|
|
25579
25599
|
yield value;
|
|
25580
25600
|
}
|
|
@@ -31837,7 +31857,7 @@ async function waitForFileLock(lockPath, binaryPath) {
|
|
|
31837
31857
|
}
|
|
31838
31858
|
} catch {
|
|
31839
31859
|
}
|
|
31840
|
-
await new Promise((
|
|
31860
|
+
await new Promise((resolve8) => setTimeout(resolve8, LOCK_POLL_INTERVAL_MS));
|
|
31841
31861
|
}
|
|
31842
31862
|
if (process.env.DEBUG === "1" || process.env.VERBOSE === "1") {
|
|
31843
31863
|
console.log(`Timeout waiting for file lock`);
|
|
@@ -33186,7 +33206,7 @@ Cwd: ${cwd}`;
|
|
|
33186
33206
|
}
|
|
33187
33207
|
}
|
|
33188
33208
|
function extractWithStdin(binaryPath, cliArgs, content, options, cwd) {
|
|
33189
|
-
return new Promise((
|
|
33209
|
+
return new Promise((resolve8, reject2) => {
|
|
33190
33210
|
const childProcess = (0, import_child_process4.spawn)(binaryPath, ["extract", ...cliArgs], {
|
|
33191
33211
|
stdio: ["pipe", "pipe", "pipe"],
|
|
33192
33212
|
cwd
|
|
@@ -33209,7 +33229,7 @@ function extractWithStdin(binaryPath, cliArgs, content, options, cwd) {
|
|
|
33209
33229
|
}
|
|
33210
33230
|
try {
|
|
33211
33231
|
const result = processExtractOutput(stdout, options);
|
|
33212
|
-
|
|
33232
|
+
resolve8(result);
|
|
33213
33233
|
} catch (error2) {
|
|
33214
33234
|
reject2(error2);
|
|
33215
33235
|
}
|
|
@@ -33318,6 +33338,7 @@ async function delegate({
|
|
|
33318
33338
|
model = null,
|
|
33319
33339
|
enableBash = false,
|
|
33320
33340
|
bashConfig = null,
|
|
33341
|
+
allowEdit = false,
|
|
33321
33342
|
architectureFileName = null,
|
|
33322
33343
|
promptType = "code-researcher",
|
|
33323
33344
|
allowedTools = null,
|
|
@@ -33397,6 +33418,8 @@ async function delegate({
|
|
|
33397
33418
|
// Inherit from parent
|
|
33398
33419
|
bashConfig,
|
|
33399
33420
|
// Inherit from parent
|
|
33421
|
+
allowEdit,
|
|
33422
|
+
// Inherit from parent
|
|
33400
33423
|
architectureFileName,
|
|
33401
33424
|
allowedTools,
|
|
33402
33425
|
disableTools,
|
|
@@ -33582,7 +33605,7 @@ var init_delegate = __esm({
|
|
|
33582
33605
|
if (debug) {
|
|
33583
33606
|
console.error(`[DelegationManager] Slot unavailable (${this.globalActive}/${this.maxConcurrent}), queuing... (queue size: ${this.waitQueue.length}, timeout: ${effectiveTimeout}ms)`);
|
|
33584
33607
|
}
|
|
33585
|
-
return new Promise((
|
|
33608
|
+
return new Promise((resolve8, reject2) => {
|
|
33586
33609
|
const entry = {
|
|
33587
33610
|
resolve: null,
|
|
33588
33611
|
// Will be wrapped below
|
|
@@ -33598,7 +33621,7 @@ var init_delegate = __esm({
|
|
|
33598
33621
|
if (settled) return;
|
|
33599
33622
|
settled = true;
|
|
33600
33623
|
if (entry.timeoutId) clearTimeout(entry.timeoutId);
|
|
33601
|
-
|
|
33624
|
+
resolve8(value);
|
|
33602
33625
|
};
|
|
33603
33626
|
entry.reject = (error2) => {
|
|
33604
33627
|
if (settled) return;
|
|
@@ -33648,7 +33671,7 @@ var init_delegate = __esm({
|
|
|
33648
33671
|
while (this.waitQueue.length > 0 && this.globalActive < this.maxConcurrent) {
|
|
33649
33672
|
const next = this.waitQueue.shift();
|
|
33650
33673
|
if (!next) break;
|
|
33651
|
-
const { resolve:
|
|
33674
|
+
const { resolve: resolve8, reject: reject2, parentSessionId, queuedAt } = next;
|
|
33652
33675
|
if (parentSessionId) {
|
|
33653
33676
|
const sessionData = this.sessionDelegations.get(parentSessionId);
|
|
33654
33677
|
const sessionCount = sessionData?.count || 0;
|
|
@@ -33665,12 +33688,12 @@ var init_delegate = __esm({
|
|
|
33665
33688
|
const waitTime = Date.now() - queuedAt;
|
|
33666
33689
|
console.error(`[DelegationManager] Granted slot from queue (waited ${waitTime}ms). Active: ${this.globalActive}/${this.maxConcurrent}`);
|
|
33667
33690
|
}
|
|
33668
|
-
toResolve.push(
|
|
33691
|
+
toResolve.push(resolve8);
|
|
33669
33692
|
}
|
|
33670
33693
|
if (toResolve.length > 0 || toReject.length > 0) {
|
|
33671
33694
|
setImmediate(() => {
|
|
33672
|
-
for (const
|
|
33673
|
-
|
|
33695
|
+
for (const resolve8 of toResolve) {
|
|
33696
|
+
resolve8(true);
|
|
33674
33697
|
}
|
|
33675
33698
|
for (const { reject: reject2, error: error2 } of toReject) {
|
|
33676
33699
|
reject2(error2);
|
|
@@ -38305,6 +38328,400 @@ var init_zod = __esm({
|
|
|
38305
38328
|
}
|
|
38306
38329
|
});
|
|
38307
38330
|
|
|
38331
|
+
// src/tools/fuzzyMatch.js
|
|
38332
|
+
function findFuzzyMatch(content, searchString) {
|
|
38333
|
+
if (!searchString || searchString.trim().length === 0) {
|
|
38334
|
+
return null;
|
|
38335
|
+
}
|
|
38336
|
+
const normalizedContent = content.replace(/\r\n/g, "\n");
|
|
38337
|
+
const normalizedSearch = searchString.replace(/\r\n/g, "\n");
|
|
38338
|
+
const contentLines = normalizedContent.split("\n");
|
|
38339
|
+
const searchLines = normalizedSearch.split("\n");
|
|
38340
|
+
const trimmed = lineTrimmedMatch(contentLines, searchLines);
|
|
38341
|
+
if (trimmed) return { ...trimmed, strategy: "line-trimmed" };
|
|
38342
|
+
const normalized = whitespaceNormalizedMatch(normalizedContent, normalizedSearch);
|
|
38343
|
+
if (normalized) return { ...normalized, strategy: "whitespace-normalized" };
|
|
38344
|
+
const indentFlex = indentFlexibleMatch(contentLines, searchLines);
|
|
38345
|
+
if (indentFlex) return { ...indentFlex, strategy: "indent-flexible" };
|
|
38346
|
+
return null;
|
|
38347
|
+
}
|
|
38348
|
+
function lineTrimmedMatch(contentLines, searchLines) {
|
|
38349
|
+
if (searchLines.length === 0) return null;
|
|
38350
|
+
const trimmedSearchLines = searchLines.map((line) => line.trim());
|
|
38351
|
+
if (trimmedSearchLines.every((line) => line === "")) return null;
|
|
38352
|
+
const windowSize = searchLines.length;
|
|
38353
|
+
const matches = [];
|
|
38354
|
+
for (let i5 = 0; i5 <= contentLines.length - windowSize; i5++) {
|
|
38355
|
+
let allMatch = true;
|
|
38356
|
+
for (let j5 = 0; j5 < windowSize; j5++) {
|
|
38357
|
+
if (contentLines[i5 + j5].trim() !== trimmedSearchLines[j5]) {
|
|
38358
|
+
allMatch = false;
|
|
38359
|
+
break;
|
|
38360
|
+
}
|
|
38361
|
+
}
|
|
38362
|
+
if (allMatch) {
|
|
38363
|
+
const matchedText = contentLines.slice(i5, i5 + windowSize).join("\n");
|
|
38364
|
+
matches.push(matchedText);
|
|
38365
|
+
}
|
|
38366
|
+
}
|
|
38367
|
+
if (matches.length === 0) return null;
|
|
38368
|
+
return {
|
|
38369
|
+
matchedText: matches[0],
|
|
38370
|
+
count: matches.length
|
|
38371
|
+
};
|
|
38372
|
+
}
|
|
38373
|
+
function whitespaceNormalizedMatch(content, search2) {
|
|
38374
|
+
if (!search2 || search2.trim().length === 0) return null;
|
|
38375
|
+
const { normalized: normContent, indexMap: contentMap } = buildNormalizedMap(content);
|
|
38376
|
+
const { normalized: normSearch } = buildNormalizedMap(search2);
|
|
38377
|
+
if (normSearch.length === 0) return null;
|
|
38378
|
+
const matches = [];
|
|
38379
|
+
let searchStart = 0;
|
|
38380
|
+
while (searchStart <= normContent.length - normSearch.length) {
|
|
38381
|
+
const idx = normContent.indexOf(normSearch, searchStart);
|
|
38382
|
+
if (idx === -1) break;
|
|
38383
|
+
const originalStart = contentMap[idx];
|
|
38384
|
+
const originalEnd = contentMap[idx + normSearch.length - 1];
|
|
38385
|
+
let actualEnd = originalEnd + 1;
|
|
38386
|
+
while (actualEnd < content.length && /[ \t]/.test(content[actualEnd]) && (actualEnd === originalEnd + 1 || /[ \t]/.test(content[actualEnd - 1]))) {
|
|
38387
|
+
if (contentMap.indexOf(actualEnd) > idx + normSearch.length - 1 || contentMap.indexOf(actualEnd) === -1) {
|
|
38388
|
+
break;
|
|
38389
|
+
}
|
|
38390
|
+
actualEnd++;
|
|
38391
|
+
}
|
|
38392
|
+
const matchedText = content.substring(originalStart, actualEnd);
|
|
38393
|
+
matches.push(matchedText);
|
|
38394
|
+
searchStart = idx + 1;
|
|
38395
|
+
}
|
|
38396
|
+
if (matches.length === 0) return null;
|
|
38397
|
+
return {
|
|
38398
|
+
matchedText: matches[0],
|
|
38399
|
+
count: matches.length
|
|
38400
|
+
};
|
|
38401
|
+
}
|
|
38402
|
+
function buildNormalizedMap(str) {
|
|
38403
|
+
const normalized = [];
|
|
38404
|
+
const indexMap = [];
|
|
38405
|
+
let i5 = 0;
|
|
38406
|
+
while (i5 < str.length) {
|
|
38407
|
+
const ch = str[i5];
|
|
38408
|
+
if (ch === " " || ch === " ") {
|
|
38409
|
+
normalized.push(" ");
|
|
38410
|
+
indexMap.push(i5);
|
|
38411
|
+
while (i5 < str.length && (str[i5] === " " || str[i5] === " ")) {
|
|
38412
|
+
i5++;
|
|
38413
|
+
}
|
|
38414
|
+
} else {
|
|
38415
|
+
normalized.push(ch);
|
|
38416
|
+
indexMap.push(i5);
|
|
38417
|
+
i5++;
|
|
38418
|
+
}
|
|
38419
|
+
}
|
|
38420
|
+
return {
|
|
38421
|
+
normalized: normalized.join(""),
|
|
38422
|
+
indexMap
|
|
38423
|
+
};
|
|
38424
|
+
}
|
|
38425
|
+
function indentFlexibleMatch(contentLines, searchLines) {
|
|
38426
|
+
if (searchLines.length === 0) return null;
|
|
38427
|
+
if (searchLines.every((line) => line.trim() === "")) return null;
|
|
38428
|
+
const searchMinIndent = getMinIndent(searchLines);
|
|
38429
|
+
const strippedSearch = searchLines.map((line) => stripIndent(line, searchMinIndent));
|
|
38430
|
+
const windowSize = searchLines.length;
|
|
38431
|
+
const matches = [];
|
|
38432
|
+
for (let i5 = 0; i5 <= contentLines.length - windowSize; i5++) {
|
|
38433
|
+
const windowLines = contentLines.slice(i5, i5 + windowSize);
|
|
38434
|
+
const windowMinIndent = getMinIndent(windowLines);
|
|
38435
|
+
const strippedWindow = windowLines.map((line) => stripIndent(line, windowMinIndent));
|
|
38436
|
+
let allMatch = true;
|
|
38437
|
+
for (let j5 = 0; j5 < windowSize; j5++) {
|
|
38438
|
+
if (strippedWindow[j5] !== strippedSearch[j5]) {
|
|
38439
|
+
allMatch = false;
|
|
38440
|
+
break;
|
|
38441
|
+
}
|
|
38442
|
+
}
|
|
38443
|
+
if (allMatch) {
|
|
38444
|
+
const matchedText = windowLines.join("\n");
|
|
38445
|
+
matches.push(matchedText);
|
|
38446
|
+
}
|
|
38447
|
+
}
|
|
38448
|
+
if (matches.length === 0) return null;
|
|
38449
|
+
return {
|
|
38450
|
+
matchedText: matches[0],
|
|
38451
|
+
count: matches.length
|
|
38452
|
+
};
|
|
38453
|
+
}
|
|
38454
|
+
function getMinIndent(lines) {
|
|
38455
|
+
let min = Infinity;
|
|
38456
|
+
for (const line of lines) {
|
|
38457
|
+
if (line.trim() === "") continue;
|
|
38458
|
+
const match2 = line.match(/^([ \t]*)/);
|
|
38459
|
+
if (match2) {
|
|
38460
|
+
min = Math.min(min, match2[1].length);
|
|
38461
|
+
}
|
|
38462
|
+
}
|
|
38463
|
+
return min === Infinity ? 0 : min;
|
|
38464
|
+
}
|
|
38465
|
+
function stripIndent(line, amount) {
|
|
38466
|
+
if (line.trim() === "") return "";
|
|
38467
|
+
if (amount <= 0) return line;
|
|
38468
|
+
return line.substring(Math.min(amount, line.length));
|
|
38469
|
+
}
|
|
38470
|
+
var init_fuzzyMatch = __esm({
|
|
38471
|
+
"src/tools/fuzzyMatch.js"() {
|
|
38472
|
+
"use strict";
|
|
38473
|
+
}
|
|
38474
|
+
});
|
|
38475
|
+
|
|
38476
|
+
// src/tools/symbolEdit.js
|
|
38477
|
+
async function findSymbol(filePath, symbolName, cwd) {
|
|
38478
|
+
try {
|
|
38479
|
+
const result = await extract({
|
|
38480
|
+
files: [`${filePath}#${symbolName}`],
|
|
38481
|
+
format: "json",
|
|
38482
|
+
json: true,
|
|
38483
|
+
cwd
|
|
38484
|
+
});
|
|
38485
|
+
if (!result || !result.results || result.results.length === 0) {
|
|
38486
|
+
return null;
|
|
38487
|
+
}
|
|
38488
|
+
const match2 = result.results[0];
|
|
38489
|
+
return {
|
|
38490
|
+
startLine: match2.lines[0],
|
|
38491
|
+
// 1-indexed
|
|
38492
|
+
endLine: match2.lines[1],
|
|
38493
|
+
// 1-indexed
|
|
38494
|
+
code: match2.code,
|
|
38495
|
+
nodeType: match2.node_type,
|
|
38496
|
+
file: match2.file
|
|
38497
|
+
};
|
|
38498
|
+
} catch (error2) {
|
|
38499
|
+
if (process.env.DEBUG === "1") {
|
|
38500
|
+
console.error(`[SymbolEdit] findSymbol error for "${symbolName}" in ${filePath}: ${error2.message}`);
|
|
38501
|
+
}
|
|
38502
|
+
return null;
|
|
38503
|
+
}
|
|
38504
|
+
}
|
|
38505
|
+
async function findAllSymbols(filePath, symbolName, cwd) {
|
|
38506
|
+
try {
|
|
38507
|
+
const result = await extract({
|
|
38508
|
+
files: [`${filePath}#${symbolName}`],
|
|
38509
|
+
format: "json",
|
|
38510
|
+
json: true,
|
|
38511
|
+
cwd
|
|
38512
|
+
});
|
|
38513
|
+
if (!result || !result.results || result.results.length === 0) {
|
|
38514
|
+
return [];
|
|
38515
|
+
}
|
|
38516
|
+
return result.results.map((match2) => ({
|
|
38517
|
+
startLine: match2.lines[0],
|
|
38518
|
+
endLine: match2.lines[1],
|
|
38519
|
+
code: match2.code,
|
|
38520
|
+
nodeType: match2.node_type,
|
|
38521
|
+
file: match2.file,
|
|
38522
|
+
qualifiedName: match2.symbol_signature || symbolName
|
|
38523
|
+
}));
|
|
38524
|
+
} catch (error2) {
|
|
38525
|
+
if (process.env.DEBUG === "1") {
|
|
38526
|
+
console.error(`[SymbolEdit] findAllSymbols error for "${symbolName}" in ${filePath}: ${error2.message}`);
|
|
38527
|
+
}
|
|
38528
|
+
return [];
|
|
38529
|
+
}
|
|
38530
|
+
}
|
|
38531
|
+
function detectBaseIndent(code) {
|
|
38532
|
+
const lines = code.split("\n");
|
|
38533
|
+
for (const line of lines) {
|
|
38534
|
+
if (line.trim().length > 0) {
|
|
38535
|
+
const match2 = line.match(/^(\s*)/);
|
|
38536
|
+
return match2 ? match2[1] : "";
|
|
38537
|
+
}
|
|
38538
|
+
}
|
|
38539
|
+
return "";
|
|
38540
|
+
}
|
|
38541
|
+
function reindent(newContent, targetIndent) {
|
|
38542
|
+
const lines = newContent.split("\n");
|
|
38543
|
+
const sourceIndent = detectBaseIndent(newContent);
|
|
38544
|
+
return lines.map((line) => {
|
|
38545
|
+
if (line.trim().length === 0) {
|
|
38546
|
+
return "";
|
|
38547
|
+
}
|
|
38548
|
+
if (line.startsWith(sourceIndent)) {
|
|
38549
|
+
return targetIndent + line.slice(sourceIndent.length);
|
|
38550
|
+
}
|
|
38551
|
+
return line;
|
|
38552
|
+
}).join("\n");
|
|
38553
|
+
}
|
|
38554
|
+
var init_symbolEdit = __esm({
|
|
38555
|
+
"src/tools/symbolEdit.js"() {
|
|
38556
|
+
"use strict";
|
|
38557
|
+
init_extract();
|
|
38558
|
+
}
|
|
38559
|
+
});
|
|
38560
|
+
|
|
38561
|
+
// src/tools/hashline.js
|
|
38562
|
+
function computeLineHash(line) {
|
|
38563
|
+
const stripped = (line || "").replace(/\s+/g, "");
|
|
38564
|
+
let h5 = 5381;
|
|
38565
|
+
for (let i5 = 0; i5 < stripped.length; i5++) {
|
|
38566
|
+
h5 = (h5 << 5) + h5 + stripped.charCodeAt(i5) & 4294967295;
|
|
38567
|
+
}
|
|
38568
|
+
return ((h5 >>> 0) % 256).toString(16).padStart(2, "0");
|
|
38569
|
+
}
|
|
38570
|
+
function parseLineRef(ref2) {
|
|
38571
|
+
if (ref2 === void 0 || ref2 === null) return null;
|
|
38572
|
+
const str = String(ref2).trim();
|
|
38573
|
+
if (!str) return null;
|
|
38574
|
+
const hashMatch = str.match(/^(\d+):([0-9a-fA-F]{2})$/);
|
|
38575
|
+
if (hashMatch) {
|
|
38576
|
+
const line = parseInt(hashMatch[1], 10);
|
|
38577
|
+
if (line < 1 || !isFinite(line)) return null;
|
|
38578
|
+
return { line, hash: hashMatch[2].toLowerCase() };
|
|
38579
|
+
}
|
|
38580
|
+
const lineMatch = str.match(/^(\d+)$/);
|
|
38581
|
+
if (lineMatch) {
|
|
38582
|
+
const line = parseInt(lineMatch[1], 10);
|
|
38583
|
+
if (line < 1 || !isFinite(line)) return null;
|
|
38584
|
+
return { line, hash: null };
|
|
38585
|
+
}
|
|
38586
|
+
return null;
|
|
38587
|
+
}
|
|
38588
|
+
function validateLineHash(lineNum, hash, fileLines) {
|
|
38589
|
+
const idx = lineNum - 1;
|
|
38590
|
+
if (idx < 0 || idx >= fileLines.length) {
|
|
38591
|
+
return { valid: false, actualHash: "", actualContent: "" };
|
|
38592
|
+
}
|
|
38593
|
+
const actualContent = fileLines[idx];
|
|
38594
|
+
const actualHash = computeLineHash(actualContent);
|
|
38595
|
+
return {
|
|
38596
|
+
valid: actualHash === hash.toLowerCase(),
|
|
38597
|
+
actualHash,
|
|
38598
|
+
actualContent
|
|
38599
|
+
};
|
|
38600
|
+
}
|
|
38601
|
+
function annotateOutputWithHashes(output) {
|
|
38602
|
+
if (!output || typeof output !== "string") return output;
|
|
38603
|
+
return output.split("\n").map((line) => {
|
|
38604
|
+
const cleanLine = line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
38605
|
+
const match2 = cleanLine.match(/^(\s*)(\d+)(\s*\|)(.*)$/);
|
|
38606
|
+
if (!match2) return line;
|
|
38607
|
+
const [, prefix, lineNum, pipeSection, content] = match2;
|
|
38608
|
+
const hash = computeLineHash(content);
|
|
38609
|
+
const cr = line.endsWith("\r") ? "\r" : "";
|
|
38610
|
+
return `${prefix}${lineNum}:${hash}${pipeSection}${content}${cr}`;
|
|
38611
|
+
}).join("\n");
|
|
38612
|
+
}
|
|
38613
|
+
function stripHashlinePrefixes(text) {
|
|
38614
|
+
if (!text || typeof text !== "string") return { cleaned: text || "", stripped: false };
|
|
38615
|
+
const lines = text.split("\n");
|
|
38616
|
+
if (lines.length === 0) return { cleaned: "", stripped: false };
|
|
38617
|
+
const nonEmptyLines = lines.filter((l5) => l5.trim().length > 0);
|
|
38618
|
+
if (nonEmptyLines.length === 0) return { cleaned: text, stripped: false };
|
|
38619
|
+
const prefixPattern = /^\s*\d+(?::[0-9a-fA-F]{2})?\s*\|\s?/;
|
|
38620
|
+
const matchCount = nonEmptyLines.filter((l5) => prefixPattern.test(l5)).length;
|
|
38621
|
+
if (matchCount / nonEmptyLines.length <= 0.5) {
|
|
38622
|
+
return { cleaned: text, stripped: false };
|
|
38623
|
+
}
|
|
38624
|
+
const cleaned = lines.map((line) => {
|
|
38625
|
+
if (line.trim().length === 0) return line;
|
|
38626
|
+
return line.replace(prefixPattern, "");
|
|
38627
|
+
}).join("\n");
|
|
38628
|
+
return { cleaned, stripped: true };
|
|
38629
|
+
}
|
|
38630
|
+
var init_hashline = __esm({
|
|
38631
|
+
"src/tools/hashline.js"() {
|
|
38632
|
+
"use strict";
|
|
38633
|
+
}
|
|
38634
|
+
});
|
|
38635
|
+
|
|
38636
|
+
// src/tools/lineEditHeuristics.js
|
|
38637
|
+
function stripEchoedBoundaries(newStr, fileLines, startLine, endLine, position) {
|
|
38638
|
+
const modifications = [];
|
|
38639
|
+
let lines = newStr.split("\n");
|
|
38640
|
+
if (lines.length === 0) return { result: newStr, modifications };
|
|
38641
|
+
if (position === "after") {
|
|
38642
|
+
const anchorIdx = startLine - 1;
|
|
38643
|
+
if (anchorIdx >= 0 && anchorIdx < fileLines.length) {
|
|
38644
|
+
const anchorTrimmed = fileLines[anchorIdx].trim();
|
|
38645
|
+
if (anchorTrimmed.length > 0 && lines.length > 0 && lines[0].trim() === anchorTrimmed) {
|
|
38646
|
+
lines = lines.slice(1);
|
|
38647
|
+
modifications.push("stripped echoed anchor line (insert-after)");
|
|
38648
|
+
}
|
|
38649
|
+
}
|
|
38650
|
+
} else if (position === "before") {
|
|
38651
|
+
const anchorIdx = startLine - 1;
|
|
38652
|
+
if (anchorIdx >= 0 && anchorIdx < fileLines.length) {
|
|
38653
|
+
const anchorTrimmed = fileLines[anchorIdx].trim();
|
|
38654
|
+
if (anchorTrimmed.length > 0 && lines.length > 0 && lines[lines.length - 1].trim() === anchorTrimmed) {
|
|
38655
|
+
lines = lines.slice(0, -1);
|
|
38656
|
+
modifications.push("stripped echoed anchor line (insert-before)");
|
|
38657
|
+
}
|
|
38658
|
+
}
|
|
38659
|
+
} else {
|
|
38660
|
+
const beforeIdx = startLine - 2;
|
|
38661
|
+
if (beforeIdx >= 0 && beforeIdx < fileLines.length) {
|
|
38662
|
+
const beforeTrimmed = fileLines[beforeIdx].trim();
|
|
38663
|
+
if (beforeTrimmed.length > 0 && lines.length > 0 && lines[0].trim() === beforeTrimmed) {
|
|
38664
|
+
lines = lines.slice(1);
|
|
38665
|
+
modifications.push("stripped echoed line before range");
|
|
38666
|
+
}
|
|
38667
|
+
}
|
|
38668
|
+
const afterIdx = endLine;
|
|
38669
|
+
if (afterIdx >= 0 && afterIdx < fileLines.length) {
|
|
38670
|
+
const afterTrimmed = fileLines[afterIdx].trim();
|
|
38671
|
+
if (afterTrimmed.length > 0 && lines.length > 0 && lines[lines.length - 1].trim() === afterTrimmed) {
|
|
38672
|
+
lines = lines.slice(0, -1);
|
|
38673
|
+
modifications.push("stripped echoed line after range");
|
|
38674
|
+
}
|
|
38675
|
+
}
|
|
38676
|
+
}
|
|
38677
|
+
return { result: lines.join("\n"), modifications };
|
|
38678
|
+
}
|
|
38679
|
+
function restoreIndentation(newStr, originalLines) {
|
|
38680
|
+
const modifications = [];
|
|
38681
|
+
if (!newStr || !originalLines || originalLines.length === 0) {
|
|
38682
|
+
return { result: newStr || "", modifications };
|
|
38683
|
+
}
|
|
38684
|
+
const originalCode = originalLines.join("\n");
|
|
38685
|
+
const targetIndent = detectBaseIndent(originalCode);
|
|
38686
|
+
const newIndent = detectBaseIndent(newStr);
|
|
38687
|
+
if (targetIndent !== newIndent) {
|
|
38688
|
+
const reindented = reindent(newStr, targetIndent);
|
|
38689
|
+
if (reindented !== newStr) {
|
|
38690
|
+
modifications.push(`reindented from "${newIndent}" to "${targetIndent}"`);
|
|
38691
|
+
return { result: reindented, modifications };
|
|
38692
|
+
}
|
|
38693
|
+
}
|
|
38694
|
+
return { result: newStr, modifications };
|
|
38695
|
+
}
|
|
38696
|
+
function cleanNewString(newStr, fileLines, startLine, endLine, position) {
|
|
38697
|
+
const modifications = [];
|
|
38698
|
+
if (!newStr && newStr !== "") return { cleaned: "", modifications };
|
|
38699
|
+
const { cleaned: afterPrefixes, stripped } = stripHashlinePrefixes(newStr);
|
|
38700
|
+
if (stripped) modifications.push("stripped line-number prefixes");
|
|
38701
|
+
const { result: afterEchoes, modifications: echoMods } = stripEchoedBoundaries(
|
|
38702
|
+
afterPrefixes,
|
|
38703
|
+
fileLines,
|
|
38704
|
+
startLine,
|
|
38705
|
+
endLine,
|
|
38706
|
+
position
|
|
38707
|
+
);
|
|
38708
|
+
modifications.push(...echoMods);
|
|
38709
|
+
if (!position) {
|
|
38710
|
+
const originalLines = fileLines.slice(startLine - 1, endLine);
|
|
38711
|
+
const { result: afterIndent, modifications: indentMods } = restoreIndentation(afterEchoes, originalLines);
|
|
38712
|
+
modifications.push(...indentMods);
|
|
38713
|
+
return { cleaned: afterIndent, modifications };
|
|
38714
|
+
}
|
|
38715
|
+
return { cleaned: afterEchoes, modifications };
|
|
38716
|
+
}
|
|
38717
|
+
var init_lineEditHeuristics = __esm({
|
|
38718
|
+
"src/tools/lineEditHeuristics.js"() {
|
|
38719
|
+
"use strict";
|
|
38720
|
+
init_symbolEdit();
|
|
38721
|
+
init_hashline();
|
|
38722
|
+
}
|
|
38723
|
+
});
|
|
38724
|
+
|
|
38308
38725
|
// src/tools/edit.js
|
|
38309
38726
|
function isPathAllowed(filePath, allowedFolders) {
|
|
38310
38727
|
if (!allowedFolders || allowedFolders.length === 0) {
|
|
@@ -38328,6 +38745,174 @@ function parseFileToolOptions(options = {}) {
|
|
|
38328
38745
|
workspaceRoot: options.workspaceRoot || options.cwd || allowedFolders.length > 0 && allowedFolders[0] || process.cwd()
|
|
38329
38746
|
};
|
|
38330
38747
|
}
|
|
38748
|
+
async function handleSymbolEdit({ resolvedPath: resolvedPath2, file_path, symbol: symbol15, new_string, position, debug, cwd, fileTracker }) {
|
|
38749
|
+
if (typeof symbol15 !== "string" || symbol15.trim() === "") {
|
|
38750
|
+
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.';
|
|
38751
|
+
}
|
|
38752
|
+
if (position !== void 0 && position !== null && position !== "before" && position !== "after") {
|
|
38753
|
+
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.';
|
|
38754
|
+
}
|
|
38755
|
+
const allMatches = await findAllSymbols(resolvedPath2, symbol15, cwd || process.cwd());
|
|
38756
|
+
if (allMatches.length === 0) {
|
|
38757
|
+
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.`;
|
|
38758
|
+
}
|
|
38759
|
+
if (allMatches.length > 1) {
|
|
38760
|
+
const suggestions = allMatches.map(
|
|
38761
|
+
(m5) => ` - ${m5.qualifiedName} (${m5.nodeType}, line ${m5.startLine})`
|
|
38762
|
+
).join("\n");
|
|
38763
|
+
return `Error editing ${file_path}: Found ${allMatches.length} symbols named "${symbol15}". Use a qualified name to specify which one:
|
|
38764
|
+
${suggestions}
|
|
38765
|
+
|
|
38766
|
+
Example: <edit><file_path>${file_path}</file_path><symbol>${allMatches[0].qualifiedName}</symbol><new_string>...</new_string></edit>`;
|
|
38767
|
+
}
|
|
38768
|
+
const symbolInfo = allMatches[0];
|
|
38769
|
+
if (fileTracker) {
|
|
38770
|
+
const check = fileTracker.checkSymbolContent(resolvedPath2, symbol15, symbolInfo.code);
|
|
38771
|
+
if (!check.ok && check.reason === "stale") {
|
|
38772
|
+
return `Error editing ${file_path}: Symbol "${symbol15}" has changed since you last read it. Use extract to re-read the current content, then retry.
|
|
38773
|
+
|
|
38774
|
+
Example: <extract><targets>${file_path}#${symbol15}</targets></extract>`;
|
|
38775
|
+
}
|
|
38776
|
+
}
|
|
38777
|
+
const content = await import_fs4.promises.readFile(resolvedPath2, "utf-8");
|
|
38778
|
+
const lines = content.split("\n");
|
|
38779
|
+
if (position) {
|
|
38780
|
+
const refIndent = detectBaseIndent(symbolInfo.code);
|
|
38781
|
+
const reindented = reindent(new_string, refIndent);
|
|
38782
|
+
const newLines = reindented.split("\n");
|
|
38783
|
+
if (position === "after") {
|
|
38784
|
+
lines.splice(symbolInfo.endLine, 0, "", ...newLines);
|
|
38785
|
+
} else {
|
|
38786
|
+
lines.splice(symbolInfo.startLine - 1, 0, ...newLines, "");
|
|
38787
|
+
}
|
|
38788
|
+
await import_fs4.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
|
|
38789
|
+
if (fileTracker) {
|
|
38790
|
+
const updated = await findSymbol(resolvedPath2, symbol15, cwd || process.cwd());
|
|
38791
|
+
if (updated) {
|
|
38792
|
+
fileTracker.trackSymbolAfterWrite(resolvedPath2, symbol15, updated.code, updated.startLine, updated.endLine);
|
|
38793
|
+
}
|
|
38794
|
+
fileTracker.markFileSeen(resolvedPath2);
|
|
38795
|
+
}
|
|
38796
|
+
const insertLine = position === "after" ? symbolInfo.endLine + 1 : symbolInfo.startLine;
|
|
38797
|
+
if (debug) {
|
|
38798
|
+
console.error(`[Edit] Successfully inserted ${newLines.length} lines ${position} "${symbol15}" at line ${insertLine} in ${resolvedPath2}`);
|
|
38799
|
+
}
|
|
38800
|
+
return `Successfully inserted ${newLines.length} lines ${position} symbol "${symbol15}" in ${file_path} (at line ${insertLine})`;
|
|
38801
|
+
} else {
|
|
38802
|
+
const originalIndent = detectBaseIndent(symbolInfo.code);
|
|
38803
|
+
const reindented = reindent(new_string, originalIndent);
|
|
38804
|
+
const newLines = reindented.split("\n");
|
|
38805
|
+
lines.splice(symbolInfo.startLine - 1, symbolInfo.endLine - symbolInfo.startLine + 1, ...newLines);
|
|
38806
|
+
await import_fs4.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
|
|
38807
|
+
if (fileTracker) {
|
|
38808
|
+
const updated = await findSymbol(resolvedPath2, symbol15, cwd || process.cwd());
|
|
38809
|
+
if (updated) {
|
|
38810
|
+
fileTracker.trackSymbolAfterWrite(resolvedPath2, symbol15, updated.code, updated.startLine, updated.endLine);
|
|
38811
|
+
}
|
|
38812
|
+
fileTracker.markFileSeen(resolvedPath2);
|
|
38813
|
+
}
|
|
38814
|
+
if (debug) {
|
|
38815
|
+
console.error(`[Edit] Successfully replaced symbol "${symbol15}" in ${resolvedPath2} (lines ${symbolInfo.startLine}-${symbolInfo.endLine})`);
|
|
38816
|
+
}
|
|
38817
|
+
return `Successfully replaced symbol "${symbol15}" in ${file_path} (was lines ${symbolInfo.startLine}-${symbolInfo.endLine}, now ${newLines.length} lines)`;
|
|
38818
|
+
}
|
|
38819
|
+
}
|
|
38820
|
+
function buildLineEditResponse(file_path, startLine, endLine, newLineCount, updatedLines, insertOffset, action, heuristicMods) {
|
|
38821
|
+
const contextBefore = 1;
|
|
38822
|
+
const contextAfter = 1;
|
|
38823
|
+
const contextStart = Math.max(0, insertOffset - contextBefore);
|
|
38824
|
+
const contextEnd = Math.min(updatedLines.length, insertOffset + newLineCount + contextAfter);
|
|
38825
|
+
let context = "Context:\n";
|
|
38826
|
+
for (let i5 = contextStart; i5 < contextEnd; i5++) {
|
|
38827
|
+
const lineNum = i5 + 1;
|
|
38828
|
+
const hash = computeLineHash(updatedLines[i5]);
|
|
38829
|
+
const isNew = i5 >= insertOffset && i5 < insertOffset + newLineCount;
|
|
38830
|
+
const marker15 = isNew ? ">" : " ";
|
|
38831
|
+
context += `${marker15} ${lineNum}:${hash} | ${updatedLines[i5]}
|
|
38832
|
+
`;
|
|
38833
|
+
}
|
|
38834
|
+
let msg = `Successfully edited ${file_path} (${action})`;
|
|
38835
|
+
if (heuristicMods.length > 0) {
|
|
38836
|
+
msg += ` [auto-corrected: ${heuristicMods.join(", ")}]`;
|
|
38837
|
+
}
|
|
38838
|
+
msg += "\n" + context;
|
|
38839
|
+
return msg;
|
|
38840
|
+
}
|
|
38841
|
+
async function handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_line, end_line, new_string, position, debug, fileTracker }) {
|
|
38842
|
+
const startRef = parseLineRef(start_line);
|
|
38843
|
+
if (!startRef) {
|
|
38844
|
+
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.`;
|
|
38845
|
+
}
|
|
38846
|
+
let endRef = null;
|
|
38847
|
+
if (end_line !== void 0 && end_line !== null) {
|
|
38848
|
+
endRef = parseLineRef(end_line);
|
|
38849
|
+
if (!endRef) {
|
|
38850
|
+
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.`;
|
|
38851
|
+
}
|
|
38852
|
+
}
|
|
38853
|
+
const startLine = startRef.line;
|
|
38854
|
+
const endLine = endRef ? endRef.line : startLine;
|
|
38855
|
+
if (endLine < startLine) {
|
|
38856
|
+
return `Error editing file: end_line (${endLine}) must be >= start_line (${startLine}).`;
|
|
38857
|
+
}
|
|
38858
|
+
if (position !== void 0 && position !== null && position !== "before" && position !== "after") {
|
|
38859
|
+
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.';
|
|
38860
|
+
}
|
|
38861
|
+
const content = await import_fs4.promises.readFile(resolvedPath2, "utf-8");
|
|
38862
|
+
const fileLines = content.split("\n");
|
|
38863
|
+
if (startLine > fileLines.length) {
|
|
38864
|
+
return `Error editing file: Line ${startLine} is beyond file length (${fileLines.length} lines). Use 'extract' to read the current file content.`;
|
|
38865
|
+
}
|
|
38866
|
+
if (endLine > fileLines.length) {
|
|
38867
|
+
return `Error editing file: Line ${endLine} is beyond file length (${fileLines.length} lines). Use 'extract' to read the current file content.`;
|
|
38868
|
+
}
|
|
38869
|
+
if (startRef.hash) {
|
|
38870
|
+
const validation = validateLineHash(startLine, startRef.hash, fileLines);
|
|
38871
|
+
if (!validation.valid) {
|
|
38872
|
+
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.`;
|
|
38873
|
+
}
|
|
38874
|
+
}
|
|
38875
|
+
if (endRef && endRef.hash) {
|
|
38876
|
+
const validation = validateLineHash(endLine, endRef.hash, fileLines);
|
|
38877
|
+
if (!validation.valid) {
|
|
38878
|
+
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.`;
|
|
38879
|
+
}
|
|
38880
|
+
}
|
|
38881
|
+
const { cleaned, modifications } = cleanNewString(new_string, fileLines, startLine, endLine, position);
|
|
38882
|
+
if (debug) {
|
|
38883
|
+
if (modifications.length > 0) {
|
|
38884
|
+
console.error(`[Edit] Heuristic corrections: ${modifications.join(", ")}`);
|
|
38885
|
+
}
|
|
38886
|
+
}
|
|
38887
|
+
const newLines = cleaned === "" ? [] : cleaned.split("\n");
|
|
38888
|
+
if (position === "after") {
|
|
38889
|
+
fileLines.splice(startLine, 0, ...newLines);
|
|
38890
|
+
await import_fs4.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
|
|
38891
|
+
if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
38892
|
+
const action = `${newLines.length} line${newLines.length !== 1 ? "s" : ""} inserted after line ${startLine}`;
|
|
38893
|
+
return buildLineEditResponse(file_path, startLine, startLine, newLines.length, fileLines, startLine, action, modifications);
|
|
38894
|
+
} else if (position === "before") {
|
|
38895
|
+
fileLines.splice(startLine - 1, 0, ...newLines);
|
|
38896
|
+
await import_fs4.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
|
|
38897
|
+
if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
38898
|
+
const action = `${newLines.length} line${newLines.length !== 1 ? "s" : ""} inserted before line ${startLine}`;
|
|
38899
|
+
return buildLineEditResponse(file_path, startLine, startLine, newLines.length, fileLines, startLine - 1, action, modifications);
|
|
38900
|
+
} else {
|
|
38901
|
+
const replacedCount = endLine - startLine + 1;
|
|
38902
|
+
fileLines.splice(startLine - 1, replacedCount, ...newLines);
|
|
38903
|
+
await import_fs4.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
|
|
38904
|
+
if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
38905
|
+
let action;
|
|
38906
|
+
if (newLines.length === 0) {
|
|
38907
|
+
action = `${replacedCount} line${replacedCount !== 1 ? "s" : ""} deleted (lines ${startLine}-${endLine})`;
|
|
38908
|
+
} else if (startLine === endLine) {
|
|
38909
|
+
action = `line ${startLine} replaced with ${newLines.length} line${newLines.length !== 1 ? "s" : ""}`;
|
|
38910
|
+
} else {
|
|
38911
|
+
action = `lines ${startLine}-${endLine} replaced with ${newLines.length} line${newLines.length !== 1 ? "s" : ""}`;
|
|
38912
|
+
}
|
|
38913
|
+
return buildLineEditResponse(file_path, startLine, endLine, newLines.length, fileLines, startLine - 1, action, modifications);
|
|
38914
|
+
}
|
|
38915
|
+
}
|
|
38331
38916
|
var import_ai, import_fs4, import_path5, import_fs5, editTool, createTool, editSchema, createSchema, editDescription, createDescription, editToolDefinition, createToolDefinition;
|
|
38332
38917
|
var init_edit = __esm({
|
|
38333
38918
|
"src/tools/edit.js"() {
|
|
@@ -38337,24 +38922,31 @@ var init_edit = __esm({
|
|
|
38337
38922
|
import_path5 = require("path");
|
|
38338
38923
|
import_fs5 = require("fs");
|
|
38339
38924
|
init_path_validation();
|
|
38925
|
+
init_fuzzyMatch();
|
|
38926
|
+
init_symbolEdit();
|
|
38927
|
+
init_hashline();
|
|
38928
|
+
init_lineEditHeuristics();
|
|
38340
38929
|
editTool = (options = {}) => {
|
|
38341
38930
|
const { debug, allowedFolders, cwd, workspaceRoot } = parseFileToolOptions(options);
|
|
38342
38931
|
return (0, import_ai.tool)({
|
|
38343
38932
|
name: "edit",
|
|
38344
|
-
description: `Edit files using
|
|
38933
|
+
description: `Edit files using text replacement, AST-aware symbol operations, or line-targeted editing.
|
|
38345
38934
|
|
|
38346
|
-
|
|
38935
|
+
Modes:
|
|
38936
|
+
1. Text edit: Provide old_string + new_string to find and replace text (with fuzzy matching fallback)
|
|
38937
|
+
2. Symbol replace: Provide symbol + new_string to replace an entire function/class/method by name
|
|
38938
|
+
3. Symbol insert: Provide symbol + new_string + position to insert code before/after a symbol
|
|
38939
|
+
4. Line-targeted edit: Provide start_line + new_string to edit by line number (from extract/search output)
|
|
38347
38940
|
|
|
38348
38941
|
Parameters:
|
|
38349
38942
|
- 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`,
|
|
38943
|
+
- new_string: Replacement text or new code content
|
|
38944
|
+
- old_string: (optional) Text to find and replace. If omitted, symbol or start_line must be provided.
|
|
38945
|
+
- replace_all: (optional) Replace all occurrences (text mode only)
|
|
38946
|
+
- symbol: (optional) Symbol name for AST-aware editing (e.g. "myFunction", "MyClass.myMethod")
|
|
38947
|
+
- position: (optional) "before" or "after" \u2014 insert code near a symbol or line instead of replacing it
|
|
38948
|
+
- start_line: (optional) Line reference (e.g. "42" or "42:ab") for line-targeted editing
|
|
38949
|
+
- end_line: (optional) End of line range, inclusive (e.g. "55" or "55:cd")`,
|
|
38358
38950
|
inputSchema: {
|
|
38359
38951
|
type: "object",
|
|
38360
38952
|
properties: {
|
|
@@ -38364,30 +38956,44 @@ Important:
|
|
|
38364
38956
|
},
|
|
38365
38957
|
old_string: {
|
|
38366
38958
|
type: "string",
|
|
38367
|
-
description: "
|
|
38959
|
+
description: "Text to find and replace (for text-based editing)"
|
|
38368
38960
|
},
|
|
38369
38961
|
new_string: {
|
|
38370
38962
|
type: "string",
|
|
38371
|
-
description: "
|
|
38963
|
+
description: "Replacement text or new code content"
|
|
38372
38964
|
},
|
|
38373
38965
|
replace_all: {
|
|
38374
38966
|
type: "boolean",
|
|
38375
|
-
description: "Replace all occurrences (default: false)",
|
|
38967
|
+
description: "Replace all occurrences (default: false, text mode only)",
|
|
38376
38968
|
default: false
|
|
38969
|
+
},
|
|
38970
|
+
symbol: {
|
|
38971
|
+
type: "string",
|
|
38972
|
+
description: 'Symbol name for AST-aware editing (e.g. "myFunction", "MyClass.myMethod")'
|
|
38973
|
+
},
|
|
38974
|
+
position: {
|
|
38975
|
+
type: "string",
|
|
38976
|
+
enum: ["before", "after"],
|
|
38977
|
+
description: "Insert before/after symbol or line (requires symbol or start_line, omit to replace)"
|
|
38978
|
+
},
|
|
38979
|
+
start_line: {
|
|
38980
|
+
type: "string",
|
|
38981
|
+
description: 'Line reference for line-targeted editing (e.g. "42" or "42:ab" with hash)'
|
|
38982
|
+
},
|
|
38983
|
+
end_line: {
|
|
38984
|
+
type: "string",
|
|
38985
|
+
description: 'End of line range, inclusive (e.g. "55" or "55:cd"). Defaults to start_line.'
|
|
38377
38986
|
}
|
|
38378
38987
|
},
|
|
38379
|
-
required: ["file_path", "
|
|
38988
|
+
required: ["file_path", "new_string"]
|
|
38380
38989
|
},
|
|
38381
|
-
execute: async ({ file_path, old_string, new_string, replace_all = false }) => {
|
|
38990
|
+
execute: async ({ file_path, old_string, new_string, replace_all = false, symbol: symbol15, position, start_line, end_line }) => {
|
|
38382
38991
|
try {
|
|
38383
38992
|
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`;
|
|
38993
|
+
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
38994
|
}
|
|
38389
38995
|
if (new_string === void 0 || new_string === null || typeof new_string !== "string") {
|
|
38390
|
-
return `Error editing file: Invalid new_string - must be a string
|
|
38996
|
+
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
38997
|
}
|
|
38392
38998
|
const resolvedPath2 = (0, import_path5.isAbsolute)(file_path) ? file_path : (0, import_path5.resolve)(cwd || process.cwd(), file_path);
|
|
38393
38999
|
if (debug) {
|
|
@@ -38395,34 +39001,64 @@ Important:
|
|
|
38395
39001
|
}
|
|
38396
39002
|
if (!isPathAllowed(resolvedPath2, allowedFolders)) {
|
|
38397
39003
|
const relativePath = toRelativePath(resolvedPath2, workspaceRoot);
|
|
38398
|
-
return `Error editing file: Permission denied - ${relativePath} is outside allowed directories
|
|
39004
|
+
return `Error editing file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
|
|
38399
39005
|
}
|
|
38400
39006
|
if (!(0, import_fs5.existsSync)(resolvedPath2)) {
|
|
38401
|
-
return `Error editing file: File not found - ${file_path}
|
|
39007
|
+
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.`;
|
|
39008
|
+
}
|
|
39009
|
+
if (options.fileTracker && !options.fileTracker.isFileSeen(resolvedPath2)) {
|
|
39010
|
+
const displayPath = toRelativePath(resolvedPath2, workspaceRoot);
|
|
39011
|
+
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.
|
|
39012
|
+
|
|
39013
|
+
Example: <extract><targets>${displayPath}</targets></extract>`;
|
|
39014
|
+
}
|
|
39015
|
+
if (symbol15 !== void 0 && symbol15 !== null) {
|
|
39016
|
+
return await handleSymbolEdit({ resolvedPath: resolvedPath2, file_path, symbol: symbol15, new_string, position, debug, cwd, fileTracker: options.fileTracker });
|
|
39017
|
+
}
|
|
39018
|
+
if (start_line !== void 0 && start_line !== null) {
|
|
39019
|
+
return await handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_line, end_line, new_string, position, debug, fileTracker: options.fileTracker });
|
|
39020
|
+
}
|
|
39021
|
+
if (old_string === void 0 || old_string === null) {
|
|
39022
|
+
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").';
|
|
39023
|
+
}
|
|
39024
|
+
if (typeof old_string !== "string") {
|
|
39025
|
+
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
39026
|
}
|
|
38403
39027
|
const content = await import_fs4.promises.readFile(resolvedPath2, "utf-8");
|
|
39028
|
+
let matchTarget = old_string;
|
|
39029
|
+
let matchStrategy = "exact";
|
|
38404
39030
|
if (!content.includes(old_string)) {
|
|
38405
|
-
|
|
39031
|
+
const fuzzy = findFuzzyMatch(content, old_string);
|
|
39032
|
+
if (!fuzzy) {
|
|
39033
|
+
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.`;
|
|
39034
|
+
}
|
|
39035
|
+
matchTarget = fuzzy.matchedText;
|
|
39036
|
+
matchStrategy = fuzzy.strategy;
|
|
39037
|
+
if (debug) {
|
|
39038
|
+
console.error(`[Edit] Exact match failed, used ${matchStrategy} matching`);
|
|
39039
|
+
}
|
|
38406
39040
|
}
|
|
38407
|
-
const occurrences = content.split(
|
|
39041
|
+
const occurrences = content.split(matchTarget).length - 1;
|
|
38408
39042
|
if (!replace_all && occurrences > 1) {
|
|
38409
|
-
return `Error editing file: Multiple occurrences found - the old_string appears ${occurrences} times.
|
|
39043
|
+
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
39044
|
}
|
|
38411
39045
|
let newContent;
|
|
38412
39046
|
if (replace_all) {
|
|
38413
|
-
newContent = content.replaceAll(
|
|
39047
|
+
newContent = content.replaceAll(matchTarget, new_string);
|
|
38414
39048
|
} else {
|
|
38415
|
-
newContent = content.replace(
|
|
39049
|
+
newContent = content.replace(matchTarget, new_string);
|
|
38416
39050
|
}
|
|
38417
39051
|
if (newContent === content) {
|
|
38418
|
-
return `Error editing file: No changes made - old_string and new_string
|
|
39052
|
+
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
39053
|
}
|
|
38420
39054
|
await import_fs4.promises.writeFile(resolvedPath2, newContent, "utf-8");
|
|
39055
|
+
if (options.fileTracker) await options.fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
38421
39056
|
const replacedCount = replace_all ? occurrences : 1;
|
|
38422
39057
|
if (debug) {
|
|
38423
39058
|
console.error(`[Edit] Successfully edited ${resolvedPath2}, replaced ${replacedCount} occurrence(s)`);
|
|
38424
39059
|
}
|
|
38425
|
-
|
|
39060
|
+
const strategyNote = matchStrategy !== "exact" ? `, matched via ${matchStrategy}` : "";
|
|
39061
|
+
return `Successfully edited ${file_path} (${replacedCount} replacement${replacedCount !== 1 ? "s" : ""}${strategyNote})`;
|
|
38426
39062
|
} catch (error2) {
|
|
38427
39063
|
console.error("[Edit] Error:", error2);
|
|
38428
39064
|
return `Error editing file: ${error2.message}`;
|
|
@@ -38469,10 +39105,10 @@ Important:
|
|
|
38469
39105
|
execute: async ({ file_path, content, overwrite = false }) => {
|
|
38470
39106
|
try {
|
|
38471
39107
|
if (!file_path || typeof file_path !== "string" || file_path.trim() === "") {
|
|
38472
|
-
return `Error creating file: Invalid file_path - must be a non-empty string
|
|
39108
|
+
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
39109
|
}
|
|
38474
39110
|
if (content === void 0 || content === null || typeof content !== "string") {
|
|
38475
|
-
return `Error creating file: Invalid content - must be a string
|
|
39111
|
+
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
39112
|
}
|
|
38477
39113
|
const resolvedPath2 = (0, import_path5.isAbsolute)(file_path) ? file_path : (0, import_path5.resolve)(cwd || process.cwd(), file_path);
|
|
38478
39114
|
if (debug) {
|
|
@@ -38480,15 +39116,17 @@ Important:
|
|
|
38480
39116
|
}
|
|
38481
39117
|
if (!isPathAllowed(resolvedPath2, allowedFolders)) {
|
|
38482
39118
|
const relativePath = toRelativePath(resolvedPath2, workspaceRoot);
|
|
38483
|
-
return `Error creating file: Permission denied - ${relativePath} is outside allowed directories
|
|
39119
|
+
return `Error creating file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
|
|
38484
39120
|
}
|
|
38485
39121
|
if ((0, import_fs5.existsSync)(resolvedPath2) && !overwrite) {
|
|
38486
39122
|
return `Error creating file: File already exists - ${file_path}. Use overwrite: true to replace it.`;
|
|
38487
39123
|
}
|
|
39124
|
+
const existed = (0, import_fs5.existsSync)(resolvedPath2);
|
|
38488
39125
|
const dir = (0, import_path5.dirname)(resolvedPath2);
|
|
38489
39126
|
await import_fs4.promises.mkdir(dir, { recursive: true });
|
|
38490
39127
|
await import_fs4.promises.writeFile(resolvedPath2, content, "utf-8");
|
|
38491
|
-
|
|
39128
|
+
if (options.fileTracker) await options.fileTracker.trackFileAfterWrite(resolvedPath2);
|
|
39129
|
+
const action = existed && overwrite ? "overwrote" : "created";
|
|
38492
39130
|
const bytes = Buffer.byteLength(content, "utf-8");
|
|
38493
39131
|
if (debug) {
|
|
38494
39132
|
console.error(`[Create] Successfully ${action} ${resolvedPath2}`);
|
|
@@ -38510,18 +39148,35 @@ Important:
|
|
|
38510
39148
|
},
|
|
38511
39149
|
old_string: {
|
|
38512
39150
|
type: "string",
|
|
38513
|
-
description: "
|
|
39151
|
+
description: "Text to find and replace (for text-based editing)"
|
|
38514
39152
|
},
|
|
38515
39153
|
new_string: {
|
|
38516
39154
|
type: "string",
|
|
38517
|
-
description: "
|
|
39155
|
+
description: "Replacement text or new code content"
|
|
38518
39156
|
},
|
|
38519
39157
|
replace_all: {
|
|
38520
39158
|
type: "boolean",
|
|
38521
|
-
description: "Replace all occurrences (default: false)"
|
|
39159
|
+
description: "Replace all occurrences (default: false, text mode only)"
|
|
39160
|
+
},
|
|
39161
|
+
symbol: {
|
|
39162
|
+
type: "string",
|
|
39163
|
+
description: 'Symbol name for AST-aware editing (e.g. "myFunction", "MyClass.myMethod")'
|
|
39164
|
+
},
|
|
39165
|
+
position: {
|
|
39166
|
+
type: "string",
|
|
39167
|
+
enum: ["before", "after"],
|
|
39168
|
+
description: "Insert before/after symbol or line (requires symbol or start_line, omit to replace)"
|
|
39169
|
+
},
|
|
39170
|
+
start_line: {
|
|
39171
|
+
type: "string",
|
|
39172
|
+
description: 'Line reference for line-targeted editing (e.g. "42" or "42:ab" with hash)'
|
|
39173
|
+
},
|
|
39174
|
+
end_line: {
|
|
39175
|
+
type: "string",
|
|
39176
|
+
description: 'End of line range, inclusive (e.g. "55" or "55:cd"). Defaults to start_line.'
|
|
38522
39177
|
}
|
|
38523
39178
|
},
|
|
38524
|
-
required: ["file_path", "
|
|
39179
|
+
required: ["file_path", "new_string"]
|
|
38525
39180
|
};
|
|
38526
39181
|
createSchema = {
|
|
38527
39182
|
type: "object",
|
|
@@ -38541,50 +39196,123 @@ Important:
|
|
|
38541
39196
|
},
|
|
38542
39197
|
required: ["file_path", "content"]
|
|
38543
39198
|
};
|
|
38544
|
-
editDescription = "Edit files using
|
|
39199
|
+
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
39200
|
createDescription = "Create new files with specified content. Will create parent directories if needed.";
|
|
38546
39201
|
editToolDefinition = `
|
|
38547
39202
|
## edit
|
|
38548
39203
|
Description: ${editDescription}
|
|
38549
39204
|
|
|
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)
|
|
39205
|
+
Four editing modes \u2014 choose based on the scope of your change:
|
|
38555
39206
|
|
|
38556
|
-
|
|
38557
|
-
|
|
38558
|
-
|
|
38559
|
-
|
|
39207
|
+
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.
|
|
39208
|
+
|
|
39209
|
+
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.
|
|
39210
|
+
|
|
39211
|
+
3. **Symbol insert** (symbol + new_string + position): For adding new code before or after an existing symbol. Set position to "before" or "after".
|
|
39212
|
+
|
|
39213
|
+
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
39214
|
|
|
38561
39215
|
Parameters:
|
|
38562
39216
|
- 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
|
-
|
|
39217
|
+
- new_string: (required) Replacement text or new code content
|
|
39218
|
+
- old_string: (optional) Text to find and replace \u2014 copy verbatim from the file, do not paraphrase or reformat
|
|
39219
|
+
- replace_all: (optional, default: false) Replace all occurrences of old_string (text mode only)
|
|
39220
|
+
- symbol: (optional) Name of a code symbol (e.g. "myFunction", "MyClass.myMethod") \u2014 must match a function, class, or method definition
|
|
39221
|
+
- position: (optional) "before" or "after" \u2014 insert new_string near the symbol or line instead of replacing it
|
|
39222
|
+
- start_line: (optional) Line reference for line-targeted editing (e.g. "42" or "42:ab")
|
|
39223
|
+
- end_line: (optional) End of line range, inclusive (e.g. "55" or "55:cd"). Defaults to start_line.
|
|
39224
|
+
|
|
39225
|
+
Mode selection rules (priority order):
|
|
39226
|
+
- If symbol is provided, symbol mode is used (old_string and start_line are ignored)
|
|
39227
|
+
- If start_line is provided (without symbol), line-targeted mode is used
|
|
39228
|
+
- If old_string is provided (without symbol or start_line), text mode is used
|
|
39229
|
+
- If none are provided, the tool returns an error with guidance
|
|
39230
|
+
|
|
39231
|
+
When to use each mode:
|
|
39232
|
+
- Small edits (a line or a few lines): use text mode with old_string
|
|
39233
|
+
- Replacing entire functions/classes/methods: use symbol mode \u2014 no exact text matching needed
|
|
39234
|
+
- Editing specific lines from extract/search output: use line-targeted mode with start_line
|
|
39235
|
+
- 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
|
|
39236
|
+
|
|
39237
|
+
Error handling:
|
|
39238
|
+
- If an edit fails, read the error message carefully \u2014 it contains specific instructions for how to fix the call and retry
|
|
39239
|
+
- Common fixes: use 'search'/'extract' to get exact file content, add more context to old_string, switch between text and symbol modes
|
|
39240
|
+
- Line-targeted hash mismatch: the file changed since last read; the error provides updated line:hash references
|
|
38571
39241
|
|
|
38572
39242
|
Examples:
|
|
39243
|
+
|
|
39244
|
+
Text edit (find and replace):
|
|
38573
39245
|
<edit>
|
|
38574
39246
|
<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>
|
|
39247
|
+
<old_string>return false;</old_string>
|
|
39248
|
+
<new_string>return true;</new_string>
|
|
38581
39249
|
</edit>
|
|
38582
39250
|
|
|
39251
|
+
Text edit with replace_all:
|
|
38583
39252
|
<edit>
|
|
38584
39253
|
<file_path>config.json</file_path>
|
|
38585
39254
|
<old_string>"debug": false</old_string>
|
|
38586
39255
|
<new_string>"debug": true</new_string>
|
|
38587
39256
|
<replace_all>true</replace_all>
|
|
39257
|
+
</edit>
|
|
39258
|
+
|
|
39259
|
+
Symbol replace (rewrite entire function by name):
|
|
39260
|
+
<edit>
|
|
39261
|
+
<file_path>src/utils.js</file_path>
|
|
39262
|
+
<symbol>calculateTotal</symbol>
|
|
39263
|
+
<new_string>function calculateTotal(items) {
|
|
39264
|
+
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
|
39265
|
+
}</new_string>
|
|
39266
|
+
</edit>
|
|
39267
|
+
|
|
39268
|
+
Symbol insert (add new function after existing one):
|
|
39269
|
+
<edit>
|
|
39270
|
+
<file_path>src/utils.js</file_path>
|
|
39271
|
+
<symbol>calculateTotal</symbol>
|
|
39272
|
+
<position>after</position>
|
|
39273
|
+
<new_string>function calculateTax(total, rate) {
|
|
39274
|
+
return total * rate;
|
|
39275
|
+
}</new_string>
|
|
39276
|
+
</edit>
|
|
39277
|
+
|
|
39278
|
+
Line-targeted edit (replace a line):
|
|
39279
|
+
<edit>
|
|
39280
|
+
<file_path>src/main.js</file_path>
|
|
39281
|
+
<start_line>42</start_line>
|
|
39282
|
+
<new_string> return processItems(order.items);</new_string>
|
|
39283
|
+
</edit>
|
|
39284
|
+
|
|
39285
|
+
Line-targeted edit (replace a range of lines):
|
|
39286
|
+
<edit>
|
|
39287
|
+
<file_path>src/main.js</file_path>
|
|
39288
|
+
<start_line>42</start_line>
|
|
39289
|
+
<end_line>55</end_line>
|
|
39290
|
+
<new_string> // simplified implementation
|
|
39291
|
+
return processItems(order.items);</new_string>
|
|
39292
|
+
</edit>
|
|
39293
|
+
|
|
39294
|
+
Line-targeted edit with hash verification:
|
|
39295
|
+
<edit>
|
|
39296
|
+
<file_path>src/main.js</file_path>
|
|
39297
|
+
<start_line>42:ab</start_line>
|
|
39298
|
+
<end_line>55:cd</end_line>
|
|
39299
|
+
<new_string> return processItems(order.items);</new_string>
|
|
39300
|
+
</edit>
|
|
39301
|
+
|
|
39302
|
+
Line-targeted insert (add code after a line):
|
|
39303
|
+
<edit>
|
|
39304
|
+
<file_path>src/main.js</file_path>
|
|
39305
|
+
<start_line>42</start_line>
|
|
39306
|
+
<position>after</position>
|
|
39307
|
+
<new_string> const validated = validate(input);</new_string>
|
|
39308
|
+
</edit>
|
|
39309
|
+
|
|
39310
|
+
Line-targeted delete (remove lines):
|
|
39311
|
+
<edit>
|
|
39312
|
+
<file_path>src/main.js</file_path>
|
|
39313
|
+
<start_line>42</start_line>
|
|
39314
|
+
<end_line>45</end_line>
|
|
39315
|
+
<new_string></new_string>
|
|
38588
39316
|
</edit>`;
|
|
38589
39317
|
createToolDefinition = `
|
|
38590
39318
|
## create
|
|
@@ -39121,7 +39849,7 @@ function getValidParamsForTool(toolName) {
|
|
|
39121
39849
|
};
|
|
39122
39850
|
const schema = schemaMap[toolName];
|
|
39123
39851
|
if (!schema) {
|
|
39124
|
-
return ["path", "directory", "pattern", "recursive", "includeHidden", "task", "files", "
|
|
39852
|
+
return ["path", "directory", "pattern", "recursive", "includeHidden", "task", "files", "result"];
|
|
39125
39853
|
}
|
|
39126
39854
|
if (toolName === "attempt_completion") {
|
|
39127
39855
|
return ["result"];
|
|
@@ -39134,6 +39862,10 @@ function getValidParamsForTool(toolName) {
|
|
|
39134
39862
|
}
|
|
39135
39863
|
return [];
|
|
39136
39864
|
}
|
|
39865
|
+
function unescapeXmlEntities(str) {
|
|
39866
|
+
if (typeof str !== "string") return str;
|
|
39867
|
+
return str.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/&/g, "&");
|
|
39868
|
+
}
|
|
39137
39869
|
function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
|
|
39138
39870
|
let earliestToolName = null;
|
|
39139
39871
|
let earliestOpenIndex = Infinity;
|
|
@@ -39190,10 +39922,10 @@ function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
|
|
|
39190
39922
|
}
|
|
39191
39923
|
paramCloseIndex = nextTagIndex;
|
|
39192
39924
|
}
|
|
39193
|
-
let paramValue = innerContent.substring(
|
|
39925
|
+
let paramValue = unescapeXmlEntities(innerContent.substring(
|
|
39194
39926
|
paramOpenIndex + paramOpenTag.length,
|
|
39195
39927
|
paramCloseIndex
|
|
39196
|
-
).trim();
|
|
39928
|
+
).trim());
|
|
39197
39929
|
if (paramValue.toLowerCase() === "true") {
|
|
39198
39930
|
paramValue = true;
|
|
39199
39931
|
} else if (paramValue.toLowerCase() === "false") {
|
|
@@ -39207,7 +39939,7 @@ function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
|
|
|
39207
39939
|
params[paramName] = paramValue;
|
|
39208
39940
|
}
|
|
39209
39941
|
if (toolName === "attempt_completion") {
|
|
39210
|
-
params["result"] = innerContent.trim();
|
|
39942
|
+
params["result"] = unescapeXmlEntities(innerContent.trim());
|
|
39211
39943
|
if (params.command) {
|
|
39212
39944
|
delete params.command;
|
|
39213
39945
|
}
|
|
@@ -39242,7 +39974,6 @@ function detectUnrecognizedToolCall(xmlString, validTools) {
|
|
|
39242
39974
|
"listSkills",
|
|
39243
39975
|
"useSkill",
|
|
39244
39976
|
"readImage",
|
|
39245
|
-
"implement",
|
|
39246
39977
|
"edit",
|
|
39247
39978
|
"create",
|
|
39248
39979
|
"delegate",
|
|
@@ -39617,6 +40348,8 @@ User: Read file inside the dependency
|
|
|
39617
40348
|
</extract>
|
|
39618
40349
|
|
|
39619
40350
|
</examples>
|
|
40351
|
+
|
|
40352
|
+
**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
40353
|
`;
|
|
39621
40354
|
delegateToolDefinition = `
|
|
39622
40355
|
## delegate
|
|
@@ -39772,7 +40505,7 @@ Capabilities:
|
|
|
39772
40505
|
`;
|
|
39773
40506
|
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
40507
|
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.";
|
|
40508
|
+
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
40509
|
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
40510
|
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
40511
|
DEFAULT_VALID_TOOLS = [
|
|
@@ -39787,7 +40520,6 @@ Capabilities:
|
|
|
39787
40520
|
"useSkill",
|
|
39788
40521
|
"listFiles",
|
|
39789
40522
|
"searchFiles",
|
|
39790
|
-
"implement",
|
|
39791
40523
|
"bash",
|
|
39792
40524
|
"task",
|
|
39793
40525
|
"attempt_completion"
|
|
@@ -39912,6 +40644,7 @@ var init_vercel = __esm({
|
|
|
39912
40644
|
init_analyzeAll();
|
|
39913
40645
|
init_common2();
|
|
39914
40646
|
init_error_types();
|
|
40647
|
+
init_hashline();
|
|
39915
40648
|
CODE_SEARCH_SCHEMA = {
|
|
39916
40649
|
type: "object",
|
|
39917
40650
|
properties: {
|
|
@@ -39930,8 +40663,15 @@ var init_vercel = __esm({
|
|
|
39930
40663
|
maxTokens = 2e4,
|
|
39931
40664
|
debug = false,
|
|
39932
40665
|
outline = false,
|
|
39933
|
-
searchDelegate = false
|
|
40666
|
+
searchDelegate = false,
|
|
40667
|
+
hashLines = false
|
|
39934
40668
|
} = options;
|
|
40669
|
+
const maybeAnnotate = (result) => {
|
|
40670
|
+
if (hashLines && typeof result === "string") {
|
|
40671
|
+
return annotateOutputWithHashes(result);
|
|
40672
|
+
}
|
|
40673
|
+
return result;
|
|
40674
|
+
};
|
|
39935
40675
|
return (0, import_ai2.tool)({
|
|
39936
40676
|
name: "search",
|
|
39937
40677
|
description: searchDelegate ? `${searchDescription} (delegates code search to a subagent and returns extracted code blocks)` : searchDescription,
|
|
@@ -39973,7 +40713,12 @@ var init_vercel = __esm({
|
|
|
39973
40713
|
};
|
|
39974
40714
|
if (!searchDelegate) {
|
|
39975
40715
|
try {
|
|
39976
|
-
|
|
40716
|
+
const result = maybeAnnotate(await runRawSearch());
|
|
40717
|
+
if (options.fileTracker && typeof result === "string") {
|
|
40718
|
+
options.fileTracker.trackFilesFromOutput(result, options.cwd || ".").catch(() => {
|
|
40719
|
+
});
|
|
40720
|
+
}
|
|
40721
|
+
return result;
|
|
39977
40722
|
} catch (error2) {
|
|
39978
40723
|
console.error("Error executing search command:", error2);
|
|
39979
40724
|
return formatErrorForAI(error2);
|
|
@@ -40016,7 +40761,12 @@ var init_vercel = __esm({
|
|
|
40016
40761
|
if (debug) {
|
|
40017
40762
|
console.error("Delegated search returned no targets; falling back to raw search");
|
|
40018
40763
|
}
|
|
40019
|
-
|
|
40764
|
+
const fallbackResult = maybeAnnotate(await runRawSearch());
|
|
40765
|
+
if (options.fileTracker && typeof fallbackResult === "string") {
|
|
40766
|
+
options.fileTracker.trackFilesFromOutput(fallbackResult, options.cwd || ".").catch(() => {
|
|
40767
|
+
});
|
|
40768
|
+
}
|
|
40769
|
+
return fallbackResult;
|
|
40020
40770
|
}
|
|
40021
40771
|
const resolutionBase = searchPaths[0] || options.cwd || ".";
|
|
40022
40772
|
const resolvedTargets = targets.map((target) => resolveTargetPath(target, resolutionBase));
|
|
@@ -40031,13 +40781,18 @@ var init_vercel = __esm({
|
|
|
40031
40781
|
const extractResult = await extract(extractOptions);
|
|
40032
40782
|
if (resolutionBase && typeof extractResult === "string") {
|
|
40033
40783
|
const wsPrefix = resolutionBase.endsWith("/") ? resolutionBase : resolutionBase + "/";
|
|
40034
|
-
return extractResult.split(wsPrefix).join("");
|
|
40784
|
+
return maybeAnnotate(extractResult.split(wsPrefix).join(""));
|
|
40035
40785
|
}
|
|
40036
|
-
return extractResult;
|
|
40786
|
+
return maybeAnnotate(extractResult);
|
|
40037
40787
|
} catch (error2) {
|
|
40038
40788
|
console.error("Delegated search failed, falling back to raw search:", error2);
|
|
40039
40789
|
try {
|
|
40040
|
-
|
|
40790
|
+
const fallbackResult2 = maybeAnnotate(await runRawSearch());
|
|
40791
|
+
if (options.fileTracker && typeof fallbackResult2 === "string") {
|
|
40792
|
+
options.fileTracker.trackFilesFromOutput(fallbackResult2, options.cwd || ".").catch(() => {
|
|
40793
|
+
});
|
|
40794
|
+
}
|
|
40795
|
+
return fallbackResult2;
|
|
40041
40796
|
} catch (fallbackError) {
|
|
40042
40797
|
console.error("Error executing search command:", fallbackError);
|
|
40043
40798
|
return formatErrorForAI(fallbackError);
|
|
@@ -40083,7 +40838,7 @@ var init_vercel = __esm({
|
|
|
40083
40838
|
});
|
|
40084
40839
|
};
|
|
40085
40840
|
extractTool = (options = {}) => {
|
|
40086
|
-
const { debug = false, outline = false } = options;
|
|
40841
|
+
const { debug = false, outline = false, hashLines = false } = options;
|
|
40087
40842
|
return (0, import_ai2.tool)({
|
|
40088
40843
|
name: "extract",
|
|
40089
40844
|
description: extractDescription,
|
|
@@ -40100,6 +40855,7 @@ var init_vercel = __esm({
|
|
|
40100
40855
|
}
|
|
40101
40856
|
let tempFilePath = null;
|
|
40102
40857
|
let extractOptions = { cwd: effectiveCwd };
|
|
40858
|
+
let extractFiles = null;
|
|
40103
40859
|
if (input_content) {
|
|
40104
40860
|
const { writeFileSync: writeFileSync2, unlinkSync } = await import("fs");
|
|
40105
40861
|
const { join: join5 } = await import("path");
|
|
@@ -40123,13 +40879,13 @@ var init_vercel = __esm({
|
|
|
40123
40879
|
};
|
|
40124
40880
|
} else if (targets) {
|
|
40125
40881
|
const parsedTargets = parseTargets(targets);
|
|
40126
|
-
|
|
40882
|
+
extractFiles = parsedTargets.map((target) => resolveTargetPath(target, effectiveCwd));
|
|
40127
40883
|
let effectiveFormat = format2;
|
|
40128
40884
|
if (outline && format2 === "outline-xml") {
|
|
40129
40885
|
effectiveFormat = "xml";
|
|
40130
40886
|
}
|
|
40131
40887
|
extractOptions = {
|
|
40132
|
-
files,
|
|
40888
|
+
files: extractFiles,
|
|
40133
40889
|
cwd: effectiveCwd,
|
|
40134
40890
|
allowTests: allow_tests ?? true,
|
|
40135
40891
|
contextLines: context_lines,
|
|
@@ -40139,6 +40895,10 @@ var init_vercel = __esm({
|
|
|
40139
40895
|
throw new Error("Either targets or input_content must be provided");
|
|
40140
40896
|
}
|
|
40141
40897
|
const results = await extract(extractOptions);
|
|
40898
|
+
if (options.fileTracker && extractFiles && extractFiles.length > 0) {
|
|
40899
|
+
options.fileTracker.trackFilesFromExtract(extractFiles, effectiveCwd).catch(() => {
|
|
40900
|
+
});
|
|
40901
|
+
}
|
|
40142
40902
|
if (tempFilePath) {
|
|
40143
40903
|
const { unlinkSync } = await import("fs");
|
|
40144
40904
|
try {
|
|
@@ -40150,6 +40910,9 @@ var init_vercel = __esm({
|
|
|
40150
40910
|
console.error(`Warning: Failed to remove temporary file: ${cleanupError.message}`);
|
|
40151
40911
|
}
|
|
40152
40912
|
}
|
|
40913
|
+
if (hashLines && typeof results === "string") {
|
|
40914
|
+
return annotateOutputWithHashes(results);
|
|
40915
|
+
}
|
|
40153
40916
|
return results;
|
|
40154
40917
|
} catch (error2) {
|
|
40155
40918
|
console.error("Error executing extract command:", error2);
|
|
@@ -40349,6 +41112,7 @@ var init_bashDefaults = __esm({
|
|
|
40349
41112
|
"tree:*",
|
|
40350
41113
|
// Git read-only operations
|
|
40351
41114
|
"git:status",
|
|
41115
|
+
"git:status:*",
|
|
40352
41116
|
"git:log",
|
|
40353
41117
|
"git:log:*",
|
|
40354
41118
|
"git:diff",
|
|
@@ -40367,14 +41131,109 @@ var init_bashDefaults = __esm({
|
|
|
40367
41131
|
"git:blame",
|
|
40368
41132
|
"git:blame:*",
|
|
40369
41133
|
"git:shortlog",
|
|
41134
|
+
"git:shortlog:*",
|
|
40370
41135
|
"git:reflog",
|
|
41136
|
+
"git:reflog:*",
|
|
40371
41137
|
"git:ls-files",
|
|
41138
|
+
"git:ls-files:*",
|
|
40372
41139
|
"git:ls-tree",
|
|
41140
|
+
"git:ls-tree:*",
|
|
41141
|
+
"git:ls-remote",
|
|
41142
|
+
"git:ls-remote:*",
|
|
40373
41143
|
"git:rev-parse",
|
|
41144
|
+
"git:rev-parse:*",
|
|
40374
41145
|
"git:rev-list",
|
|
41146
|
+
"git:rev-list:*",
|
|
41147
|
+
"git:cat-file",
|
|
41148
|
+
"git:cat-file:*",
|
|
41149
|
+
"git:diff-tree",
|
|
41150
|
+
"git:diff-tree:*",
|
|
41151
|
+
"git:diff-files",
|
|
41152
|
+
"git:diff-files:*",
|
|
41153
|
+
"git:diff-index",
|
|
41154
|
+
"git:diff-index:*",
|
|
41155
|
+
"git:for-each-ref",
|
|
41156
|
+
"git:for-each-ref:*",
|
|
41157
|
+
"git:merge-base",
|
|
41158
|
+
"git:merge-base:*",
|
|
41159
|
+
"git:name-rev",
|
|
41160
|
+
"git:name-rev:*",
|
|
41161
|
+
"git:count-objects",
|
|
41162
|
+
"git:count-objects:*",
|
|
41163
|
+
"git:verify-commit",
|
|
41164
|
+
"git:verify-commit:*",
|
|
41165
|
+
"git:verify-tag",
|
|
41166
|
+
"git:verify-tag:*",
|
|
41167
|
+
"git:check-ignore",
|
|
41168
|
+
"git:check-ignore:*",
|
|
41169
|
+
"git:check-attr",
|
|
41170
|
+
"git:check-attr:*",
|
|
41171
|
+
"git:stash:list",
|
|
41172
|
+
"git:stash:show",
|
|
41173
|
+
"git:stash:show:*",
|
|
41174
|
+
"git:worktree:list",
|
|
41175
|
+
"git:worktree:list:*",
|
|
41176
|
+
"git:notes:list",
|
|
41177
|
+
"git:notes:show",
|
|
41178
|
+
"git:notes:show:*",
|
|
40375
41179
|
"git:--version",
|
|
40376
41180
|
"git:help",
|
|
40377
41181
|
"git:help:*",
|
|
41182
|
+
// GitHub CLI (gh) read-only operations
|
|
41183
|
+
"gh:--version",
|
|
41184
|
+
"gh:help",
|
|
41185
|
+
"gh:help:*",
|
|
41186
|
+
"gh:status",
|
|
41187
|
+
"gh:auth:status",
|
|
41188
|
+
"gh:auth:status:*",
|
|
41189
|
+
"gh:issue:list",
|
|
41190
|
+
"gh:issue:list:*",
|
|
41191
|
+
"gh:issue:view",
|
|
41192
|
+
"gh:issue:view:*",
|
|
41193
|
+
"gh:issue:status",
|
|
41194
|
+
"gh:issue:status:*",
|
|
41195
|
+
"gh:pr:list",
|
|
41196
|
+
"gh:pr:list:*",
|
|
41197
|
+
"gh:pr:view",
|
|
41198
|
+
"gh:pr:view:*",
|
|
41199
|
+
"gh:pr:status",
|
|
41200
|
+
"gh:pr:status:*",
|
|
41201
|
+
"gh:pr:diff",
|
|
41202
|
+
"gh:pr:diff:*",
|
|
41203
|
+
"gh:pr:checks",
|
|
41204
|
+
"gh:pr:checks:*",
|
|
41205
|
+
"gh:repo:list",
|
|
41206
|
+
"gh:repo:list:*",
|
|
41207
|
+
"gh:repo:view",
|
|
41208
|
+
"gh:repo:view:*",
|
|
41209
|
+
"gh:release:list",
|
|
41210
|
+
"gh:release:list:*",
|
|
41211
|
+
"gh:release:view",
|
|
41212
|
+
"gh:release:view:*",
|
|
41213
|
+
"gh:run:list",
|
|
41214
|
+
"gh:run:list:*",
|
|
41215
|
+
"gh:run:view",
|
|
41216
|
+
"gh:run:view:*",
|
|
41217
|
+
"gh:workflow:list",
|
|
41218
|
+
"gh:workflow:list:*",
|
|
41219
|
+
"gh:workflow:view",
|
|
41220
|
+
"gh:workflow:view:*",
|
|
41221
|
+
"gh:gist:list",
|
|
41222
|
+
"gh:gist:list:*",
|
|
41223
|
+
"gh:gist:view",
|
|
41224
|
+
"gh:gist:view:*",
|
|
41225
|
+
"gh:search:issues",
|
|
41226
|
+
"gh:search:issues:*",
|
|
41227
|
+
"gh:search:prs",
|
|
41228
|
+
"gh:search:prs:*",
|
|
41229
|
+
"gh:search:repos",
|
|
41230
|
+
"gh:search:repos:*",
|
|
41231
|
+
"gh:search:code",
|
|
41232
|
+
"gh:search:code:*",
|
|
41233
|
+
"gh:search:commits",
|
|
41234
|
+
"gh:search:commits:*",
|
|
41235
|
+
"gh:api",
|
|
41236
|
+
"gh:api:*",
|
|
40378
41237
|
// Package managers (information only)
|
|
40379
41238
|
"npm:list",
|
|
40380
41239
|
"npm:ls",
|
|
@@ -40685,14 +41544,132 @@ var init_bashDefaults = __esm({
|
|
|
40685
41544
|
"git:push",
|
|
40686
41545
|
"git:push:*",
|
|
40687
41546
|
"git:force",
|
|
40688
|
-
"git:reset
|
|
40689
|
-
"git:
|
|
41547
|
+
"git:reset",
|
|
41548
|
+
"git:reset:*",
|
|
41549
|
+
"git:clean",
|
|
41550
|
+
"git:clean:*",
|
|
41551
|
+
"git:rm",
|
|
40690
41552
|
"git:rm:*",
|
|
40691
41553
|
"git:commit",
|
|
41554
|
+
"git:commit:*",
|
|
40692
41555
|
"git:merge",
|
|
41556
|
+
"git:merge:*",
|
|
40693
41557
|
"git:rebase",
|
|
41558
|
+
"git:rebase:*",
|
|
40694
41559
|
"git:cherry-pick",
|
|
41560
|
+
"git:cherry-pick:*",
|
|
40695
41561
|
"git:stash:drop",
|
|
41562
|
+
"git:stash:drop:*",
|
|
41563
|
+
"git:stash:pop",
|
|
41564
|
+
"git:stash:pop:*",
|
|
41565
|
+
"git:stash:push",
|
|
41566
|
+
"git:stash:push:*",
|
|
41567
|
+
"git:stash:clear",
|
|
41568
|
+
"git:branch:-d",
|
|
41569
|
+
"git:branch:-d:*",
|
|
41570
|
+
"git:branch:-D",
|
|
41571
|
+
"git:branch:-D:*",
|
|
41572
|
+
"git:branch:--delete",
|
|
41573
|
+
"git:branch:--delete:*",
|
|
41574
|
+
"git:tag:-d",
|
|
41575
|
+
"git:tag:-d:*",
|
|
41576
|
+
"git:tag:--delete",
|
|
41577
|
+
"git:tag:--delete:*",
|
|
41578
|
+
"git:remote:remove",
|
|
41579
|
+
"git:remote:remove:*",
|
|
41580
|
+
"git:remote:rm",
|
|
41581
|
+
"git:remote:rm:*",
|
|
41582
|
+
"git:checkout:--force",
|
|
41583
|
+
"git:checkout:--force:*",
|
|
41584
|
+
"git:checkout:-f",
|
|
41585
|
+
"git:checkout:-f:*",
|
|
41586
|
+
"git:submodule:deinit",
|
|
41587
|
+
"git:submodule:deinit:*",
|
|
41588
|
+
"git:notes:add",
|
|
41589
|
+
"git:notes:add:*",
|
|
41590
|
+
"git:notes:remove",
|
|
41591
|
+
"git:notes:remove:*",
|
|
41592
|
+
"git:worktree:add",
|
|
41593
|
+
"git:worktree:add:*",
|
|
41594
|
+
"git:worktree:remove",
|
|
41595
|
+
"git:worktree:remove:*",
|
|
41596
|
+
// Dangerous GitHub CLI (gh) write operations
|
|
41597
|
+
"gh:issue:create",
|
|
41598
|
+
"gh:issue:create:*",
|
|
41599
|
+
"gh:issue:close",
|
|
41600
|
+
"gh:issue:close:*",
|
|
41601
|
+
"gh:issue:delete",
|
|
41602
|
+
"gh:issue:delete:*",
|
|
41603
|
+
"gh:issue:edit",
|
|
41604
|
+
"gh:issue:edit:*",
|
|
41605
|
+
"gh:issue:reopen",
|
|
41606
|
+
"gh:issue:reopen:*",
|
|
41607
|
+
"gh:issue:comment",
|
|
41608
|
+
"gh:issue:comment:*",
|
|
41609
|
+
"gh:pr:create",
|
|
41610
|
+
"gh:pr:create:*",
|
|
41611
|
+
"gh:pr:close",
|
|
41612
|
+
"gh:pr:close:*",
|
|
41613
|
+
"gh:pr:merge",
|
|
41614
|
+
"gh:pr:merge:*",
|
|
41615
|
+
"gh:pr:edit",
|
|
41616
|
+
"gh:pr:edit:*",
|
|
41617
|
+
"gh:pr:reopen",
|
|
41618
|
+
"gh:pr:reopen:*",
|
|
41619
|
+
"gh:pr:review",
|
|
41620
|
+
"gh:pr:review:*",
|
|
41621
|
+
"gh:pr:comment",
|
|
41622
|
+
"gh:pr:comment:*",
|
|
41623
|
+
"gh:repo:create",
|
|
41624
|
+
"gh:repo:create:*",
|
|
41625
|
+
"gh:repo:delete",
|
|
41626
|
+
"gh:repo:delete:*",
|
|
41627
|
+
"gh:repo:fork",
|
|
41628
|
+
"gh:repo:fork:*",
|
|
41629
|
+
"gh:repo:rename",
|
|
41630
|
+
"gh:repo:rename:*",
|
|
41631
|
+
"gh:repo:archive",
|
|
41632
|
+
"gh:repo:archive:*",
|
|
41633
|
+
"gh:repo:clone",
|
|
41634
|
+
"gh:repo:clone:*",
|
|
41635
|
+
"gh:release:create",
|
|
41636
|
+
"gh:release:create:*",
|
|
41637
|
+
"gh:release:delete",
|
|
41638
|
+
"gh:release:delete:*",
|
|
41639
|
+
"gh:release:edit",
|
|
41640
|
+
"gh:release:edit:*",
|
|
41641
|
+
"gh:run:cancel",
|
|
41642
|
+
"gh:run:cancel:*",
|
|
41643
|
+
"gh:run:rerun",
|
|
41644
|
+
"gh:run:rerun:*",
|
|
41645
|
+
"gh:workflow:run",
|
|
41646
|
+
"gh:workflow:run:*",
|
|
41647
|
+
"gh:workflow:enable",
|
|
41648
|
+
"gh:workflow:enable:*",
|
|
41649
|
+
"gh:workflow:disable",
|
|
41650
|
+
"gh:workflow:disable:*",
|
|
41651
|
+
"gh:gist:create",
|
|
41652
|
+
"gh:gist:create:*",
|
|
41653
|
+
"gh:gist:delete",
|
|
41654
|
+
"gh:gist:delete:*",
|
|
41655
|
+
"gh:gist:edit",
|
|
41656
|
+
"gh:gist:edit:*",
|
|
41657
|
+
"gh:secret:set",
|
|
41658
|
+
"gh:secret:set:*",
|
|
41659
|
+
"gh:secret:delete",
|
|
41660
|
+
"gh:secret:delete:*",
|
|
41661
|
+
"gh:variable:set",
|
|
41662
|
+
"gh:variable:set:*",
|
|
41663
|
+
"gh:variable:delete",
|
|
41664
|
+
"gh:variable:delete:*",
|
|
41665
|
+
"gh:label:create",
|
|
41666
|
+
"gh:label:create:*",
|
|
41667
|
+
"gh:label:delete",
|
|
41668
|
+
"gh:label:delete:*",
|
|
41669
|
+
"gh:ssh-key:add",
|
|
41670
|
+
"gh:ssh-key:add:*",
|
|
41671
|
+
"gh:ssh-key:delete",
|
|
41672
|
+
"gh:ssh-key:delete:*",
|
|
40696
41673
|
// File system mounting and partitioning
|
|
40697
41674
|
"mount",
|
|
40698
41675
|
"mount:*",
|
|
@@ -41497,7 +42474,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
41497
42474
|
console.log(`[BashExecutor] Working directory: "${cwd}"`);
|
|
41498
42475
|
console.log(`[BashExecutor] Timeout: ${timeout}ms`);
|
|
41499
42476
|
}
|
|
41500
|
-
return new Promise((
|
|
42477
|
+
return new Promise((resolve8, reject2) => {
|
|
41501
42478
|
const processEnv = {
|
|
41502
42479
|
...process.env,
|
|
41503
42480
|
...env
|
|
@@ -41514,7 +42491,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
41514
42491
|
} else {
|
|
41515
42492
|
const args = parseCommandForExecution(command);
|
|
41516
42493
|
if (!args || args.length === 0) {
|
|
41517
|
-
|
|
42494
|
+
resolve8({
|
|
41518
42495
|
success: false,
|
|
41519
42496
|
error: "Failed to parse command",
|
|
41520
42497
|
stdout: "",
|
|
@@ -41599,7 +42576,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
41599
42576
|
success = false;
|
|
41600
42577
|
error2 = `Command exited with code ${code}`;
|
|
41601
42578
|
}
|
|
41602
|
-
|
|
42579
|
+
resolve8({
|
|
41603
42580
|
success,
|
|
41604
42581
|
error: error2,
|
|
41605
42582
|
stdout: stdout.trim(),
|
|
@@ -41619,7 +42596,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
41619
42596
|
if (debug) {
|
|
41620
42597
|
console.log(`[BashExecutor] Spawn error:`, error2);
|
|
41621
42598
|
}
|
|
41622
|
-
|
|
42599
|
+
resolve8({
|
|
41623
42600
|
success: false,
|
|
41624
42601
|
error: `Failed to execute command: ${error2.message}`,
|
|
41625
42602
|
stdout: "",
|
|
@@ -43031,14 +44008,14 @@ var require_executor = __commonJS({
|
|
|
43031
44008
|
function asyncDone(callback) {
|
|
43032
44009
|
let isInstant = false;
|
|
43033
44010
|
let instant;
|
|
43034
|
-
const p5 = new Promise((
|
|
44011
|
+
const p5 = new Promise((resolve8, reject2) => {
|
|
43035
44012
|
callback((err, result) => {
|
|
43036
44013
|
if (err)
|
|
43037
44014
|
reject2(err);
|
|
43038
44015
|
else {
|
|
43039
44016
|
isInstant = true;
|
|
43040
44017
|
instant = result;
|
|
43041
|
-
|
|
44018
|
+
resolve8({ result });
|
|
43042
44019
|
}
|
|
43043
44020
|
});
|
|
43044
44021
|
});
|
|
@@ -43061,10 +44038,10 @@ var require_executor = __commonJS({
|
|
|
43061
44038
|
}
|
|
43062
44039
|
async function execAsync4(ticks, tree, scope, context, doneOriginal, inLoopOrSwitch) {
|
|
43063
44040
|
let done = doneOriginal;
|
|
43064
|
-
const p5 = new Promise((
|
|
44041
|
+
const p5 = new Promise((resolve8) => {
|
|
43065
44042
|
done = (e5, r5) => {
|
|
43066
44043
|
doneOriginal(e5, r5);
|
|
43067
|
-
|
|
44044
|
+
resolve8();
|
|
43068
44045
|
};
|
|
43069
44046
|
});
|
|
43070
44047
|
if (!_execNoneRecurse(ticks, tree, scope, context, done, true, inLoopOrSwitch) && utils.isLisp(tree)) {
|
|
@@ -51828,33 +52805,31 @@ var init_runtime = __esm({
|
|
|
51828
52805
|
}
|
|
51829
52806
|
});
|
|
51830
52807
|
|
|
51831
|
-
// node_modules/balanced-match/index.js
|
|
51832
|
-
var
|
|
51833
|
-
|
|
51834
|
-
|
|
51835
|
-
|
|
51836
|
-
|
|
51837
|
-
|
|
51838
|
-
|
|
51839
|
-
var r5 = range2(a5, b5, str);
|
|
52808
|
+
// node_modules/balanced-match/dist/esm/index.js
|
|
52809
|
+
var balanced, maybeMatch, range2;
|
|
52810
|
+
var init_esm = __esm({
|
|
52811
|
+
"node_modules/balanced-match/dist/esm/index.js"() {
|
|
52812
|
+
balanced = (a5, b5, str) => {
|
|
52813
|
+
const ma = a5 instanceof RegExp ? maybeMatch(a5, str) : a5;
|
|
52814
|
+
const mb = b5 instanceof RegExp ? maybeMatch(b5, str) : b5;
|
|
52815
|
+
const r5 = ma !== null && mb != null && range2(ma, mb, str);
|
|
51840
52816
|
return r5 && {
|
|
51841
52817
|
start: r5[0],
|
|
51842
52818
|
end: r5[1],
|
|
51843
52819
|
pre: str.slice(0, r5[0]),
|
|
51844
|
-
body: str.slice(r5[0] +
|
|
51845
|
-
post: str.slice(r5[1] +
|
|
52820
|
+
body: str.slice(r5[0] + ma.length, r5[1]),
|
|
52821
|
+
post: str.slice(r5[1] + mb.length)
|
|
51846
52822
|
};
|
|
51847
|
-
}
|
|
51848
|
-
|
|
51849
|
-
|
|
52823
|
+
};
|
|
52824
|
+
maybeMatch = (reg, str) => {
|
|
52825
|
+
const m5 = str.match(reg);
|
|
51850
52826
|
return m5 ? m5[0] : null;
|
|
51851
|
-
}
|
|
51852
|
-
|
|
51853
|
-
|
|
51854
|
-
|
|
51855
|
-
|
|
51856
|
-
|
|
51857
|
-
var i5 = ai;
|
|
52827
|
+
};
|
|
52828
|
+
range2 = (a5, b5, str) => {
|
|
52829
|
+
let begs, beg, left, right = void 0, result;
|
|
52830
|
+
let ai = str.indexOf(a5);
|
|
52831
|
+
let bi = str.indexOf(b5, ai + 1);
|
|
52832
|
+
let i5 = ai;
|
|
51858
52833
|
if (ai >= 0 && bi > 0) {
|
|
51859
52834
|
if (a5 === b5) {
|
|
51860
52835
|
return [ai, bi];
|
|
@@ -51862,14 +52837,16 @@ var require_balanced_match = __commonJS({
|
|
|
51862
52837
|
begs = [];
|
|
51863
52838
|
left = str.length;
|
|
51864
52839
|
while (i5 >= 0 && !result) {
|
|
51865
|
-
if (i5
|
|
52840
|
+
if (i5 === ai) {
|
|
51866
52841
|
begs.push(i5);
|
|
51867
52842
|
ai = str.indexOf(a5, i5 + 1);
|
|
51868
|
-
} else if (begs.length
|
|
51869
|
-
|
|
52843
|
+
} else if (begs.length === 1) {
|
|
52844
|
+
const r5 = begs.pop();
|
|
52845
|
+
if (r5 !== void 0)
|
|
52846
|
+
result = [r5, bi];
|
|
51870
52847
|
} else {
|
|
51871
52848
|
beg = begs.pop();
|
|
51872
|
-
if (beg < left) {
|
|
52849
|
+
if (beg !== void 0 && beg < left) {
|
|
51873
52850
|
left = beg;
|
|
51874
52851
|
right = bi;
|
|
51875
52852
|
}
|
|
@@ -51877,163 +52854,179 @@ var require_balanced_match = __commonJS({
|
|
|
51877
52854
|
}
|
|
51878
52855
|
i5 = ai < bi && ai >= 0 ? ai : bi;
|
|
51879
52856
|
}
|
|
51880
|
-
if (begs.length) {
|
|
52857
|
+
if (begs.length && right !== void 0) {
|
|
51881
52858
|
result = [left, right];
|
|
51882
52859
|
}
|
|
51883
52860
|
}
|
|
51884
52861
|
return result;
|
|
51885
|
-
}
|
|
52862
|
+
};
|
|
51886
52863
|
}
|
|
51887
52864
|
});
|
|
51888
52865
|
|
|
51889
|
-
// node_modules/brace-expansion/index.js
|
|
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
|
-
|
|
51935
|
-
|
|
51936
|
-
|
|
51937
|
-
|
|
51938
|
-
|
|
51939
|
-
|
|
51940
|
-
|
|
51941
|
-
|
|
51942
|
-
|
|
51943
|
-
|
|
51944
|
-
|
|
51945
|
-
|
|
51946
|
-
|
|
52866
|
+
// node_modules/brace-expansion/dist/esm/index.js
|
|
52867
|
+
function numeric(str) {
|
|
52868
|
+
return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
|
|
52869
|
+
}
|
|
52870
|
+
function escapeBraces(str) {
|
|
52871
|
+
return str.replace(slashPattern, escSlash).replace(openPattern, escOpen).replace(closePattern, escClose).replace(commaPattern, escComma).replace(periodPattern, escPeriod);
|
|
52872
|
+
}
|
|
52873
|
+
function unescapeBraces(str) {
|
|
52874
|
+
return str.replace(escSlashPattern, "\\").replace(escOpenPattern, "{").replace(escClosePattern, "}").replace(escCommaPattern, ",").replace(escPeriodPattern, ".");
|
|
52875
|
+
}
|
|
52876
|
+
function parseCommaParts(str) {
|
|
52877
|
+
if (!str) {
|
|
52878
|
+
return [""];
|
|
52879
|
+
}
|
|
52880
|
+
const parts = [];
|
|
52881
|
+
const m5 = balanced("{", "}", str);
|
|
52882
|
+
if (!m5) {
|
|
52883
|
+
return str.split(",");
|
|
52884
|
+
}
|
|
52885
|
+
const { pre, body, post } = m5;
|
|
52886
|
+
const p5 = pre.split(",");
|
|
52887
|
+
p5[p5.length - 1] += "{" + body + "}";
|
|
52888
|
+
const postParts = parseCommaParts(post);
|
|
52889
|
+
if (post.length) {
|
|
52890
|
+
;
|
|
52891
|
+
p5[p5.length - 1] += postParts.shift();
|
|
52892
|
+
p5.push.apply(p5, postParts);
|
|
52893
|
+
}
|
|
52894
|
+
parts.push.apply(parts, p5);
|
|
52895
|
+
return parts;
|
|
52896
|
+
}
|
|
52897
|
+
function expand(str, options = {}) {
|
|
52898
|
+
if (!str) {
|
|
52899
|
+
return [];
|
|
52900
|
+
}
|
|
52901
|
+
const { max = EXPANSION_MAX } = options;
|
|
52902
|
+
if (str.slice(0, 2) === "{}") {
|
|
52903
|
+
str = "\\{\\}" + str.slice(2);
|
|
52904
|
+
}
|
|
52905
|
+
return expand_(escapeBraces(str), max, true).map(unescapeBraces);
|
|
52906
|
+
}
|
|
52907
|
+
function embrace(str) {
|
|
52908
|
+
return "{" + str + "}";
|
|
52909
|
+
}
|
|
52910
|
+
function isPadded(el) {
|
|
52911
|
+
return /^-?0\d/.test(el);
|
|
52912
|
+
}
|
|
52913
|
+
function lte(i5, y2) {
|
|
52914
|
+
return i5 <= y2;
|
|
52915
|
+
}
|
|
52916
|
+
function gte(i5, y2) {
|
|
52917
|
+
return i5 >= y2;
|
|
52918
|
+
}
|
|
52919
|
+
function expand_(str, max, isTop) {
|
|
52920
|
+
const expansions = [];
|
|
52921
|
+
const m5 = balanced("{", "}", str);
|
|
52922
|
+
if (!m5)
|
|
52923
|
+
return [str];
|
|
52924
|
+
const pre = m5.pre;
|
|
52925
|
+
const post = m5.post.length ? expand_(m5.post, max, false) : [""];
|
|
52926
|
+
if (/\$$/.test(m5.pre)) {
|
|
52927
|
+
for (let k5 = 0; k5 < post.length && k5 < max; k5++) {
|
|
52928
|
+
const expansion = pre + "{" + m5.body + "}" + post[k5];
|
|
52929
|
+
expansions.push(expansion);
|
|
51947
52930
|
}
|
|
51948
|
-
|
|
51949
|
-
|
|
51950
|
-
|
|
51951
|
-
|
|
51952
|
-
|
|
51953
|
-
|
|
51954
|
-
if (
|
|
51955
|
-
|
|
51956
|
-
|
|
51957
|
-
|
|
51958
|
-
|
|
51959
|
-
|
|
51960
|
-
|
|
51961
|
-
|
|
51962
|
-
|
|
51963
|
-
|
|
51964
|
-
|
|
51965
|
-
|
|
51966
|
-
|
|
51967
|
-
|
|
51968
|
-
|
|
51969
|
-
|
|
51970
|
-
|
|
51971
|
-
|
|
51972
|
-
|
|
51973
|
-
|
|
51974
|
-
|
|
51975
|
-
|
|
51976
|
-
|
|
51977
|
-
|
|
51978
|
-
|
|
51979
|
-
|
|
51980
|
-
|
|
51981
|
-
|
|
51982
|
-
|
|
52931
|
+
} else {
|
|
52932
|
+
const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m5.body);
|
|
52933
|
+
const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m5.body);
|
|
52934
|
+
const isSequence = isNumericSequence || isAlphaSequence;
|
|
52935
|
+
const isOptions = m5.body.indexOf(",") >= 0;
|
|
52936
|
+
if (!isSequence && !isOptions) {
|
|
52937
|
+
if (m5.post.match(/,(?!,).*\}/)) {
|
|
52938
|
+
str = m5.pre + "{" + m5.body + escClose + m5.post;
|
|
52939
|
+
return expand_(str, max, true);
|
|
52940
|
+
}
|
|
52941
|
+
return [str];
|
|
52942
|
+
}
|
|
52943
|
+
let n5;
|
|
52944
|
+
if (isSequence) {
|
|
52945
|
+
n5 = m5.body.split(/\.\./);
|
|
52946
|
+
} else {
|
|
52947
|
+
n5 = parseCommaParts(m5.body);
|
|
52948
|
+
if (n5.length === 1 && n5[0] !== void 0) {
|
|
52949
|
+
n5 = expand_(n5[0], max, false).map(embrace);
|
|
52950
|
+
if (n5.length === 1) {
|
|
52951
|
+
return post.map((p5) => m5.pre + n5[0] + p5);
|
|
52952
|
+
}
|
|
52953
|
+
}
|
|
52954
|
+
}
|
|
52955
|
+
let N;
|
|
52956
|
+
if (isSequence && n5[0] !== void 0 && n5[1] !== void 0) {
|
|
52957
|
+
const x5 = numeric(n5[0]);
|
|
52958
|
+
const y2 = numeric(n5[1]);
|
|
52959
|
+
const width = Math.max(n5[0].length, n5[1].length);
|
|
52960
|
+
let incr = n5.length === 3 && n5[2] !== void 0 ? Math.abs(numeric(n5[2])) : 1;
|
|
52961
|
+
let test = lte;
|
|
52962
|
+
const reverse = y2 < x5;
|
|
52963
|
+
if (reverse) {
|
|
52964
|
+
incr *= -1;
|
|
52965
|
+
test = gte;
|
|
52966
|
+
}
|
|
52967
|
+
const pad = n5.some(isPadded);
|
|
52968
|
+
N = [];
|
|
52969
|
+
for (let i5 = x5; test(i5, y2); i5 += incr) {
|
|
52970
|
+
let c5;
|
|
52971
|
+
if (isAlphaSequence) {
|
|
52972
|
+
c5 = String.fromCharCode(i5);
|
|
52973
|
+
if (c5 === "\\") {
|
|
52974
|
+
c5 = "";
|
|
51983
52975
|
}
|
|
51984
|
-
}
|
|
51985
|
-
|
|
51986
|
-
|
|
51987
|
-
|
|
51988
|
-
|
|
51989
|
-
|
|
51990
|
-
|
|
51991
|
-
|
|
51992
|
-
|
|
51993
|
-
|
|
51994
|
-
incr *= -1;
|
|
51995
|
-
test = gte;
|
|
51996
|
-
}
|
|
51997
|
-
var pad = n5.some(isPadded);
|
|
51998
|
-
N = [];
|
|
51999
|
-
for (var i5 = x5; test(i5, y2); i5 += incr) {
|
|
52000
|
-
var c5;
|
|
52001
|
-
if (isAlphaSequence) {
|
|
52002
|
-
c5 = String.fromCharCode(i5);
|
|
52003
|
-
if (c5 === "\\")
|
|
52004
|
-
c5 = "";
|
|
52005
|
-
} else {
|
|
52006
|
-
c5 = String(i5);
|
|
52007
|
-
if (pad) {
|
|
52008
|
-
var need = width - c5.length;
|
|
52009
|
-
if (need > 0) {
|
|
52010
|
-
var z2 = new Array(need + 1).join("0");
|
|
52011
|
-
if (i5 < 0)
|
|
52012
|
-
c5 = "-" + z2 + c5.slice(1);
|
|
52013
|
-
else
|
|
52014
|
-
c5 = z2 + c5;
|
|
52015
|
-
}
|
|
52976
|
+
} else {
|
|
52977
|
+
c5 = String(i5);
|
|
52978
|
+
if (pad) {
|
|
52979
|
+
const need = width - c5.length;
|
|
52980
|
+
if (need > 0) {
|
|
52981
|
+
const z2 = new Array(need + 1).join("0");
|
|
52982
|
+
if (i5 < 0) {
|
|
52983
|
+
c5 = "-" + z2 + c5.slice(1);
|
|
52984
|
+
} else {
|
|
52985
|
+
c5 = z2 + c5;
|
|
52016
52986
|
}
|
|
52017
52987
|
}
|
|
52018
|
-
N.push(c5);
|
|
52019
|
-
}
|
|
52020
|
-
} else {
|
|
52021
|
-
N = [];
|
|
52022
|
-
for (var j5 = 0; j5 < n5.length; j5++) {
|
|
52023
|
-
N.push.apply(N, expand2(n5[j5], false));
|
|
52024
52988
|
}
|
|
52025
52989
|
}
|
|
52026
|
-
|
|
52027
|
-
|
|
52028
|
-
|
|
52029
|
-
|
|
52030
|
-
|
|
52031
|
-
|
|
52990
|
+
N.push(c5);
|
|
52991
|
+
}
|
|
52992
|
+
} else {
|
|
52993
|
+
N = [];
|
|
52994
|
+
for (let j5 = 0; j5 < n5.length; j5++) {
|
|
52995
|
+
N.push.apply(N, expand_(n5[j5], max, false));
|
|
52996
|
+
}
|
|
52997
|
+
}
|
|
52998
|
+
for (let j5 = 0; j5 < N.length; j5++) {
|
|
52999
|
+
for (let k5 = 0; k5 < post.length && expansions.length < max; k5++) {
|
|
53000
|
+
const expansion = pre + N[j5] + post[k5];
|
|
53001
|
+
if (!isTop || isSequence || expansion) {
|
|
53002
|
+
expansions.push(expansion);
|
|
52032
53003
|
}
|
|
52033
53004
|
}
|
|
52034
|
-
return expansions;
|
|
52035
53005
|
}
|
|
52036
53006
|
}
|
|
53007
|
+
return expansions;
|
|
53008
|
+
}
|
|
53009
|
+
var escSlash, escOpen, escClose, escComma, escPeriod, escSlashPattern, escOpenPattern, escClosePattern, escCommaPattern, escPeriodPattern, slashPattern, openPattern, closePattern, commaPattern, periodPattern, EXPANSION_MAX;
|
|
53010
|
+
var init_esm2 = __esm({
|
|
53011
|
+
"node_modules/brace-expansion/dist/esm/index.js"() {
|
|
53012
|
+
init_esm();
|
|
53013
|
+
escSlash = "\0SLASH" + Math.random() + "\0";
|
|
53014
|
+
escOpen = "\0OPEN" + Math.random() + "\0";
|
|
53015
|
+
escClose = "\0CLOSE" + Math.random() + "\0";
|
|
53016
|
+
escComma = "\0COMMA" + Math.random() + "\0";
|
|
53017
|
+
escPeriod = "\0PERIOD" + Math.random() + "\0";
|
|
53018
|
+
escSlashPattern = new RegExp(escSlash, "g");
|
|
53019
|
+
escOpenPattern = new RegExp(escOpen, "g");
|
|
53020
|
+
escClosePattern = new RegExp(escClose, "g");
|
|
53021
|
+
escCommaPattern = new RegExp(escComma, "g");
|
|
53022
|
+
escPeriodPattern = new RegExp(escPeriod, "g");
|
|
53023
|
+
slashPattern = /\\\\/g;
|
|
53024
|
+
openPattern = /\\{/g;
|
|
53025
|
+
closePattern = /\\}/g;
|
|
53026
|
+
commaPattern = /\\,/g;
|
|
53027
|
+
periodPattern = /\\./g;
|
|
53028
|
+
EXPANSION_MAX = 1e5;
|
|
53029
|
+
}
|
|
52037
53030
|
});
|
|
52038
53031
|
|
|
52039
53032
|
// node_modules/minimatch/dist/esm/assert-valid-pattern.js
|
|
@@ -52616,11 +53609,13 @@ var init_ast = __esm({
|
|
|
52616
53609
|
let escaping = false;
|
|
52617
53610
|
let re = "";
|
|
52618
53611
|
let uflag = false;
|
|
53612
|
+
let inStar = false;
|
|
52619
53613
|
for (let i5 = 0; i5 < glob2.length; i5++) {
|
|
52620
53614
|
const c5 = glob2.charAt(i5);
|
|
52621
53615
|
if (escaping) {
|
|
52622
53616
|
escaping = false;
|
|
52623
53617
|
re += (reSpecials.has(c5) ? "\\" : "") + c5;
|
|
53618
|
+
inStar = false;
|
|
52624
53619
|
continue;
|
|
52625
53620
|
}
|
|
52626
53621
|
if (c5 === "\\") {
|
|
@@ -52638,16 +53633,19 @@ var init_ast = __esm({
|
|
|
52638
53633
|
uflag = uflag || needUflag;
|
|
52639
53634
|
i5 += consumed - 1;
|
|
52640
53635
|
hasMagic2 = hasMagic2 || magic;
|
|
53636
|
+
inStar = false;
|
|
52641
53637
|
continue;
|
|
52642
53638
|
}
|
|
52643
53639
|
}
|
|
52644
53640
|
if (c5 === "*") {
|
|
52645
|
-
if (
|
|
52646
|
-
|
|
52647
|
-
|
|
52648
|
-
|
|
53641
|
+
if (inStar)
|
|
53642
|
+
continue;
|
|
53643
|
+
inStar = true;
|
|
53644
|
+
re += noEmpty && /^[*]+$/.test(glob2) ? starNoEmpty : star;
|
|
52649
53645
|
hasMagic2 = true;
|
|
52650
53646
|
continue;
|
|
53647
|
+
} else {
|
|
53648
|
+
inStar = false;
|
|
52651
53649
|
}
|
|
52652
53650
|
if (c5 === "?") {
|
|
52653
53651
|
re += qmark;
|
|
@@ -52673,10 +53671,10 @@ var init_escape = __esm({
|
|
|
52673
53671
|
});
|
|
52674
53672
|
|
|
52675
53673
|
// node_modules/minimatch/dist/esm/index.js
|
|
52676
|
-
var
|
|
52677
|
-
var
|
|
53674
|
+
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;
|
|
53675
|
+
var init_esm3 = __esm({
|
|
52678
53676
|
"node_modules/minimatch/dist/esm/index.js"() {
|
|
52679
|
-
|
|
53677
|
+
init_esm2();
|
|
52680
53678
|
init_assert_valid_pattern();
|
|
52681
53679
|
init_ast();
|
|
52682
53680
|
init_escape();
|
|
@@ -52799,7 +53797,7 @@ var init_esm = __esm({
|
|
|
52799
53797
|
if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
|
|
52800
53798
|
return [pattern];
|
|
52801
53799
|
}
|
|
52802
|
-
return (
|
|
53800
|
+
return expand(pattern);
|
|
52803
53801
|
};
|
|
52804
53802
|
minimatch.braceExpand = braceExpand;
|
|
52805
53803
|
makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
|
|
@@ -53405,7 +54403,7 @@ var init_esm = __esm({
|
|
|
53405
54403
|
|
|
53406
54404
|
// node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js
|
|
53407
54405
|
var perf, warned, PROCESS, emitWarning, AC, AS, shouldWarn, TYPE, isPosInt, getUintArray, ZeroArray, Stack, LRUCache;
|
|
53408
|
-
var
|
|
54406
|
+
var init_esm4 = __esm({
|
|
53409
54407
|
"node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js"() {
|
|
53410
54408
|
perf = typeof performance === "object" && performance && typeof performance.now === "function" ? performance : Date;
|
|
53411
54409
|
warned = /* @__PURE__ */ new Set();
|
|
@@ -54779,7 +55777,7 @@ var init_esm2 = __esm({
|
|
|
54779
55777
|
|
|
54780
55778
|
// node_modules/minipass/dist/esm/index.js
|
|
54781
55779
|
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;
|
|
54782
|
-
var
|
|
55780
|
+
var init_esm5 = __esm({
|
|
54783
55781
|
"node_modules/minipass/dist/esm/index.js"() {
|
|
54784
55782
|
import_node_events = require("node:events");
|
|
54785
55783
|
import_node_stream = __toESM(require("node:stream"), 1);
|
|
@@ -55509,10 +56507,10 @@ var init_esm3 = __esm({
|
|
|
55509
56507
|
* Return a void Promise that resolves once the stream ends.
|
|
55510
56508
|
*/
|
|
55511
56509
|
async promise() {
|
|
55512
|
-
return new Promise((
|
|
56510
|
+
return new Promise((resolve8, reject2) => {
|
|
55513
56511
|
this.on(DESTROYED, () => reject2(new Error("stream destroyed")));
|
|
55514
56512
|
this.on("error", (er) => reject2(er));
|
|
55515
|
-
this.on("end", () =>
|
|
56513
|
+
this.on("end", () => resolve8());
|
|
55516
56514
|
});
|
|
55517
56515
|
}
|
|
55518
56516
|
/**
|
|
@@ -55536,7 +56534,7 @@ var init_esm3 = __esm({
|
|
|
55536
56534
|
return Promise.resolve({ done: false, value: res });
|
|
55537
56535
|
if (this[EOF])
|
|
55538
56536
|
return stop();
|
|
55539
|
-
let
|
|
56537
|
+
let resolve8;
|
|
55540
56538
|
let reject2;
|
|
55541
56539
|
const onerr = (er) => {
|
|
55542
56540
|
this.off("data", ondata);
|
|
@@ -55550,19 +56548,19 @@ var init_esm3 = __esm({
|
|
|
55550
56548
|
this.off("end", onend);
|
|
55551
56549
|
this.off(DESTROYED, ondestroy);
|
|
55552
56550
|
this.pause();
|
|
55553
|
-
|
|
56551
|
+
resolve8({ value, done: !!this[EOF] });
|
|
55554
56552
|
};
|
|
55555
56553
|
const onend = () => {
|
|
55556
56554
|
this.off("error", onerr);
|
|
55557
56555
|
this.off("data", ondata);
|
|
55558
56556
|
this.off(DESTROYED, ondestroy);
|
|
55559
56557
|
stop();
|
|
55560
|
-
|
|
56558
|
+
resolve8({ done: true, value: void 0 });
|
|
55561
56559
|
};
|
|
55562
56560
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
55563
56561
|
return new Promise((res2, rej) => {
|
|
55564
56562
|
reject2 = rej;
|
|
55565
|
-
|
|
56563
|
+
resolve8 = res2;
|
|
55566
56564
|
this.once(DESTROYED, ondestroy);
|
|
55567
56565
|
this.once("error", onerr);
|
|
55568
56566
|
this.once("end", onend);
|
|
@@ -55666,15 +56664,15 @@ var init_esm3 = __esm({
|
|
|
55666
56664
|
|
|
55667
56665
|
// node_modules/path-scurry/dist/esm/index.js
|
|
55668
56666
|
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;
|
|
55669
|
-
var
|
|
56667
|
+
var init_esm6 = __esm({
|
|
55670
56668
|
"node_modules/path-scurry/dist/esm/index.js"() {
|
|
55671
|
-
|
|
56669
|
+
init_esm4();
|
|
55672
56670
|
import_node_path = require("node:path");
|
|
55673
56671
|
import_node_url = require("node:url");
|
|
55674
56672
|
import_fs7 = require("fs");
|
|
55675
56673
|
actualFS = __toESM(require("node:fs"), 1);
|
|
55676
56674
|
import_promises = require("node:fs/promises");
|
|
55677
|
-
|
|
56675
|
+
init_esm5();
|
|
55678
56676
|
realpathSync2 = import_fs7.realpathSync.native;
|
|
55679
56677
|
defaultFS = {
|
|
55680
56678
|
lstatSync: import_fs7.lstatSync,
|
|
@@ -56546,9 +57544,9 @@ var init_esm4 = __esm({
|
|
|
56546
57544
|
if (this.#asyncReaddirInFlight) {
|
|
56547
57545
|
await this.#asyncReaddirInFlight;
|
|
56548
57546
|
} else {
|
|
56549
|
-
let
|
|
57547
|
+
let resolve8 = () => {
|
|
56550
57548
|
};
|
|
56551
|
-
this.#asyncReaddirInFlight = new Promise((res) =>
|
|
57549
|
+
this.#asyncReaddirInFlight = new Promise((res) => resolve8 = res);
|
|
56552
57550
|
try {
|
|
56553
57551
|
for (const e5 of await this.#fs.promises.readdir(fullpath, {
|
|
56554
57552
|
withFileTypes: true
|
|
@@ -56561,7 +57559,7 @@ var init_esm4 = __esm({
|
|
|
56561
57559
|
children.provisional = 0;
|
|
56562
57560
|
}
|
|
56563
57561
|
this.#asyncReaddirInFlight = void 0;
|
|
56564
|
-
|
|
57562
|
+
resolve8();
|
|
56565
57563
|
}
|
|
56566
57564
|
return children.slice(0, children.provisional);
|
|
56567
57565
|
}
|
|
@@ -57404,7 +58402,7 @@ var init_esm4 = __esm({
|
|
|
57404
58402
|
var isPatternList, isGlobList, Pattern;
|
|
57405
58403
|
var init_pattern = __esm({
|
|
57406
58404
|
"node_modules/glob/dist/esm/pattern.js"() {
|
|
57407
|
-
|
|
58405
|
+
init_esm3();
|
|
57408
58406
|
isPatternList = (pl) => pl.length >= 1;
|
|
57409
58407
|
isGlobList = (gl) => gl.length >= 1;
|
|
57410
58408
|
Pattern = class _Pattern {
|
|
@@ -57575,7 +58573,7 @@ var init_pattern = __esm({
|
|
|
57575
58573
|
var defaultPlatform2, Ignore;
|
|
57576
58574
|
var init_ignore = __esm({
|
|
57577
58575
|
"node_modules/glob/dist/esm/ignore.js"() {
|
|
57578
|
-
|
|
58576
|
+
init_esm3();
|
|
57579
58577
|
init_pattern();
|
|
57580
58578
|
defaultPlatform2 = typeof process === "object" && process && typeof process.platform === "string" ? process.platform : "linux";
|
|
57581
58579
|
Ignore = class {
|
|
@@ -57669,7 +58667,7 @@ var init_ignore = __esm({
|
|
|
57669
58667
|
var HasWalkedCache, MatchRecord, SubWalks, Processor;
|
|
57670
58668
|
var init_processor = __esm({
|
|
57671
58669
|
"node_modules/glob/dist/esm/processor.js"() {
|
|
57672
|
-
|
|
58670
|
+
init_esm3();
|
|
57673
58671
|
HasWalkedCache = class _HasWalkedCache {
|
|
57674
58672
|
store;
|
|
57675
58673
|
constructor(store = /* @__PURE__ */ new Map()) {
|
|
@@ -57896,7 +58894,7 @@ var init_processor = __esm({
|
|
|
57896
58894
|
var makeIgnore, GlobUtil, GlobWalker, GlobStream;
|
|
57897
58895
|
var init_walker = __esm({
|
|
57898
58896
|
"node_modules/glob/dist/esm/walker.js"() {
|
|
57899
|
-
|
|
58897
|
+
init_esm5();
|
|
57900
58898
|
init_ignore();
|
|
57901
58899
|
init_processor();
|
|
57902
58900
|
makeIgnore = (ignore2, opts) => typeof ignore2 === "string" ? new Ignore([ignore2], opts) : Array.isArray(ignore2) ? new Ignore(ignore2, opts) : ignore2;
|
|
@@ -58231,9 +59229,9 @@ var init_walker = __esm({
|
|
|
58231
59229
|
var import_node_url2, defaultPlatform3, Glob;
|
|
58232
59230
|
var init_glob = __esm({
|
|
58233
59231
|
"node_modules/glob/dist/esm/glob.js"() {
|
|
58234
|
-
|
|
59232
|
+
init_esm3();
|
|
58235
59233
|
import_node_url2 = require("node:url");
|
|
58236
|
-
|
|
59234
|
+
init_esm6();
|
|
58237
59235
|
init_pattern();
|
|
58238
59236
|
init_walker();
|
|
58239
59237
|
defaultPlatform3 = typeof process === "object" && process && typeof process.platform === "string" ? process.platform : "linux";
|
|
@@ -58441,7 +59439,7 @@ var init_glob = __esm({
|
|
|
58441
59439
|
var hasMagic;
|
|
58442
59440
|
var init_has_magic = __esm({
|
|
58443
59441
|
"node_modules/glob/dist/esm/has-magic.js"() {
|
|
58444
|
-
|
|
59442
|
+
init_esm3();
|
|
58445
59443
|
hasMagic = (pattern, options = {}) => {
|
|
58446
59444
|
if (!Array.isArray(pattern)) {
|
|
58447
59445
|
pattern = [pattern];
|
|
@@ -58475,12 +59473,12 @@ function globIterate(pattern, options = {}) {
|
|
|
58475
59473
|
return new Glob(pattern, options).iterate();
|
|
58476
59474
|
}
|
|
58477
59475
|
var streamSync, stream, iterateSync, iterate, sync, glob;
|
|
58478
|
-
var
|
|
59476
|
+
var init_esm7 = __esm({
|
|
58479
59477
|
"node_modules/glob/dist/esm/index.js"() {
|
|
58480
|
-
|
|
59478
|
+
init_esm3();
|
|
58481
59479
|
init_glob();
|
|
58482
59480
|
init_has_magic();
|
|
58483
|
-
|
|
59481
|
+
init_esm3();
|
|
58484
59482
|
init_glob();
|
|
58485
59483
|
init_has_magic();
|
|
58486
59484
|
init_ignore();
|
|
@@ -59440,7 +60438,7 @@ var init_executePlan = __esm({
|
|
|
59440
60438
|
init_query();
|
|
59441
60439
|
init_extract();
|
|
59442
60440
|
init_delegate();
|
|
59443
|
-
|
|
60441
|
+
init_esm7();
|
|
59444
60442
|
init_bash();
|
|
59445
60443
|
RAW_OUTPUT_START = "<<<RAW_OUTPUT>>>";
|
|
59446
60444
|
RAW_OUTPUT_END = "<<<END_RAW_OUTPUT>>>";
|
|
@@ -59712,13 +60710,271 @@ var init_file_lister = __esm({
|
|
|
59712
60710
|
}
|
|
59713
60711
|
});
|
|
59714
60712
|
|
|
60713
|
+
// src/tools/fileTracker.js
|
|
60714
|
+
function computeContentHash(content) {
|
|
60715
|
+
const normalized = (content || "").split("\n").map((l5) => l5.trimEnd()).join("\n");
|
|
60716
|
+
return (0, import_crypto3.createHash)("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
60717
|
+
}
|
|
60718
|
+
function extractFilePath(target) {
|
|
60719
|
+
const hashIdx = target.indexOf("#");
|
|
60720
|
+
if (hashIdx !== -1) {
|
|
60721
|
+
return target.slice(0, hashIdx);
|
|
60722
|
+
}
|
|
60723
|
+
const colonIdx = target.lastIndexOf(":");
|
|
60724
|
+
if (colonIdx !== -1) {
|
|
60725
|
+
const after = target.slice(colonIdx + 1);
|
|
60726
|
+
if (/^\d+(-\d+)?$/.test(after)) {
|
|
60727
|
+
return target.slice(0, colonIdx);
|
|
60728
|
+
}
|
|
60729
|
+
}
|
|
60730
|
+
return target;
|
|
60731
|
+
}
|
|
60732
|
+
function extractSymbolName(target) {
|
|
60733
|
+
const hashIdx = target.indexOf("#");
|
|
60734
|
+
if (hashIdx !== -1) {
|
|
60735
|
+
const symbol15 = target.slice(hashIdx + 1);
|
|
60736
|
+
return symbol15 || null;
|
|
60737
|
+
}
|
|
60738
|
+
return null;
|
|
60739
|
+
}
|
|
60740
|
+
function parseFilePathsFromOutput(output) {
|
|
60741
|
+
const paths = [];
|
|
60742
|
+
const regex = /^(?:File:\s+|---\s+)([^\s].*?)(?:\s+---)?$/gm;
|
|
60743
|
+
let match2;
|
|
60744
|
+
while ((match2 = regex.exec(output)) !== null) {
|
|
60745
|
+
const path9 = match2[1].trim();
|
|
60746
|
+
if (path9 && !path9.startsWith("Results") && !path9.startsWith("Page") && (path9.includes("/") || path9.includes(".") || path9.includes("\\"))) {
|
|
60747
|
+
paths.push(path9);
|
|
60748
|
+
}
|
|
60749
|
+
}
|
|
60750
|
+
return paths;
|
|
60751
|
+
}
|
|
60752
|
+
var import_crypto3, import_path10, FileTracker;
|
|
60753
|
+
var init_fileTracker = __esm({
|
|
60754
|
+
"src/tools/fileTracker.js"() {
|
|
60755
|
+
"use strict";
|
|
60756
|
+
import_crypto3 = require("crypto");
|
|
60757
|
+
import_path10 = require("path");
|
|
60758
|
+
init_symbolEdit();
|
|
60759
|
+
FileTracker = class {
|
|
60760
|
+
/**
|
|
60761
|
+
* @param {Object} [options]
|
|
60762
|
+
* @param {boolean} [options.debug=false] - Enable debug logging
|
|
60763
|
+
*/
|
|
60764
|
+
constructor(options = {}) {
|
|
60765
|
+
this.debug = options.debug || false;
|
|
60766
|
+
this._seenFiles = /* @__PURE__ */ new Set();
|
|
60767
|
+
this._contentRecords = /* @__PURE__ */ new Map();
|
|
60768
|
+
}
|
|
60769
|
+
/**
|
|
60770
|
+
* Mark a file as "seen" — the LLM has read its content.
|
|
60771
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60772
|
+
*/
|
|
60773
|
+
markFileSeen(resolvedPath2) {
|
|
60774
|
+
this._seenFiles.add(resolvedPath2);
|
|
60775
|
+
if (this.debug) {
|
|
60776
|
+
console.error(`[FileTracker] Marked as seen: ${resolvedPath2}`);
|
|
60777
|
+
}
|
|
60778
|
+
}
|
|
60779
|
+
/**
|
|
60780
|
+
* Check if a file has been seen in this session.
|
|
60781
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60782
|
+
* @returns {boolean}
|
|
60783
|
+
*/
|
|
60784
|
+
isFileSeen(resolvedPath2) {
|
|
60785
|
+
return this._seenFiles.has(resolvedPath2);
|
|
60786
|
+
}
|
|
60787
|
+
/**
|
|
60788
|
+
* Store a content hash for a symbol in a file.
|
|
60789
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60790
|
+
* @param {string} symbolName - Symbol name (e.g. "calculateTotal")
|
|
60791
|
+
* @param {string} code - The symbol's source code
|
|
60792
|
+
* @param {number} startLine - 1-indexed start line
|
|
60793
|
+
* @param {number} endLine - 1-indexed end line
|
|
60794
|
+
* @param {string} [source='extract'] - How the content was obtained
|
|
60795
|
+
*/
|
|
60796
|
+
trackSymbolContent(resolvedPath2, symbolName, code, startLine, endLine, source = "extract") {
|
|
60797
|
+
const key = `${resolvedPath2}#${symbolName}`;
|
|
60798
|
+
const contentHash = computeContentHash(code);
|
|
60799
|
+
this._contentRecords.set(key, {
|
|
60800
|
+
contentHash,
|
|
60801
|
+
startLine,
|
|
60802
|
+
endLine,
|
|
60803
|
+
symbolName,
|
|
60804
|
+
source,
|
|
60805
|
+
timestamp: Date.now()
|
|
60806
|
+
});
|
|
60807
|
+
if (this.debug) {
|
|
60808
|
+
console.error(`[FileTracker] Tracked symbol ${key} (hash: ${contentHash}, lines ${startLine}-${endLine})`);
|
|
60809
|
+
}
|
|
60810
|
+
}
|
|
60811
|
+
/**
|
|
60812
|
+
* Look up a stored content record for a symbol.
|
|
60813
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60814
|
+
* @param {string} symbolName - Symbol name
|
|
60815
|
+
* @returns {Object|null} The stored record or null
|
|
60816
|
+
*/
|
|
60817
|
+
getSymbolRecord(resolvedPath2, symbolName) {
|
|
60818
|
+
return this._contentRecords.get(`${resolvedPath2}#${symbolName}`) || null;
|
|
60819
|
+
}
|
|
60820
|
+
/**
|
|
60821
|
+
* Check if a symbol's current content matches what was stored.
|
|
60822
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60823
|
+
* @param {string} symbolName - Symbol name
|
|
60824
|
+
* @param {string} currentCode - The symbol's current source code (from findSymbol)
|
|
60825
|
+
* @returns {{ok: boolean, reason?: string, message?: string}}
|
|
60826
|
+
*/
|
|
60827
|
+
checkSymbolContent(resolvedPath2, symbolName, currentCode) {
|
|
60828
|
+
const key = `${resolvedPath2}#${symbolName}`;
|
|
60829
|
+
const record = this._contentRecords.get(key);
|
|
60830
|
+
if (!record) {
|
|
60831
|
+
return { ok: true };
|
|
60832
|
+
}
|
|
60833
|
+
const currentHash = computeContentHash(currentCode);
|
|
60834
|
+
if (currentHash === record.contentHash) {
|
|
60835
|
+
return { ok: true };
|
|
60836
|
+
}
|
|
60837
|
+
return {
|
|
60838
|
+
ok: false,
|
|
60839
|
+
reason: "stale",
|
|
60840
|
+
message: `Symbol "${symbolName}" has changed since you last read it (hash: ${record.contentHash} \u2192 ${currentHash}).`
|
|
60841
|
+
};
|
|
60842
|
+
}
|
|
60843
|
+
/**
|
|
60844
|
+
* Track files from extract target strings.
|
|
60845
|
+
* Marks each file as seen. For #symbol targets, calls findSymbol to get and hash the code.
|
|
60846
|
+
* @param {string[]} targets - Array of extract targets (e.g. ["file.js#fn", "file.js:10-20"])
|
|
60847
|
+
* @param {string} cwd - Working directory for resolving relative paths
|
|
60848
|
+
*/
|
|
60849
|
+
async trackFilesFromExtract(targets, cwd) {
|
|
60850
|
+
const seenPaths = /* @__PURE__ */ new Set();
|
|
60851
|
+
const symbolPromises = [];
|
|
60852
|
+
for (const target of targets) {
|
|
60853
|
+
const filePath = extractFilePath(target);
|
|
60854
|
+
const resolved = (0, import_path10.isAbsolute)(filePath) ? filePath : (0, import_path10.resolve)(cwd, filePath);
|
|
60855
|
+
if (!seenPaths.has(resolved)) {
|
|
60856
|
+
seenPaths.add(resolved);
|
|
60857
|
+
this.markFileSeen(resolved);
|
|
60858
|
+
}
|
|
60859
|
+
const symbolName = extractSymbolName(target);
|
|
60860
|
+
if (symbolName) {
|
|
60861
|
+
symbolPromises.push(
|
|
60862
|
+
findSymbol(resolved, symbolName, cwd).then((symbolInfo) => {
|
|
60863
|
+
if (symbolInfo) {
|
|
60864
|
+
this.trackSymbolContent(
|
|
60865
|
+
resolved,
|
|
60866
|
+
symbolName,
|
|
60867
|
+
symbolInfo.code,
|
|
60868
|
+
symbolInfo.startLine,
|
|
60869
|
+
symbolInfo.endLine,
|
|
60870
|
+
"extract"
|
|
60871
|
+
);
|
|
60872
|
+
}
|
|
60873
|
+
}).catch((err) => {
|
|
60874
|
+
if (this.debug) {
|
|
60875
|
+
console.error(`[FileTracker] Failed to track symbol "${symbolName}" in ${resolved}: ${err.message}`);
|
|
60876
|
+
}
|
|
60877
|
+
})
|
|
60878
|
+
);
|
|
60879
|
+
}
|
|
60880
|
+
}
|
|
60881
|
+
if (symbolPromises.length > 0) {
|
|
60882
|
+
await Promise.all(symbolPromises);
|
|
60883
|
+
}
|
|
60884
|
+
}
|
|
60885
|
+
/**
|
|
60886
|
+
* Track files discovered in probe search/extract output.
|
|
60887
|
+
* Parses "File: path" headers and "--- path ---" separators, marks each as "seen".
|
|
60888
|
+
* @param {string} output - Probe output text
|
|
60889
|
+
* @param {string} cwd - Working directory for resolving relative paths
|
|
60890
|
+
*/
|
|
60891
|
+
async trackFilesFromOutput(output, cwd) {
|
|
60892
|
+
const paths = parseFilePathsFromOutput(output);
|
|
60893
|
+
for (const filePath of paths) {
|
|
60894
|
+
const resolved = (0, import_path10.isAbsolute)(filePath) ? filePath : (0, import_path10.resolve)(cwd, filePath);
|
|
60895
|
+
this.markFileSeen(resolved);
|
|
60896
|
+
}
|
|
60897
|
+
}
|
|
60898
|
+
/**
|
|
60899
|
+
* Check if a file is safe to edit (seen-check only).
|
|
60900
|
+
* Mode-specific content verification happens in edit handlers.
|
|
60901
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60902
|
+
* @returns {{ok: boolean, reason?: string, message?: string}}
|
|
60903
|
+
*/
|
|
60904
|
+
checkBeforeEdit(resolvedPath2) {
|
|
60905
|
+
if (!this._seenFiles.has(resolvedPath2)) {
|
|
60906
|
+
return {
|
|
60907
|
+
ok: false,
|
|
60908
|
+
reason: "untracked",
|
|
60909
|
+
message: "This file has not been read yet in this session. Use extract or search to read the file first."
|
|
60910
|
+
};
|
|
60911
|
+
}
|
|
60912
|
+
return { ok: true };
|
|
60913
|
+
}
|
|
60914
|
+
/**
|
|
60915
|
+
* Mark a file as seen after a successful write (backward compat).
|
|
60916
|
+
* Also invalidates content records for the file since its content changed.
|
|
60917
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60918
|
+
*/
|
|
60919
|
+
async trackFileAfterWrite(resolvedPath2) {
|
|
60920
|
+
this.markFileSeen(resolvedPath2);
|
|
60921
|
+
this.invalidateFileRecords(resolvedPath2);
|
|
60922
|
+
}
|
|
60923
|
+
/**
|
|
60924
|
+
* Update the stored hash for a symbol after a successful write.
|
|
60925
|
+
* Enables chained edits to the same symbol.
|
|
60926
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60927
|
+
* @param {string} symbolName - Symbol name
|
|
60928
|
+
* @param {string} code - The symbol's new source code
|
|
60929
|
+
* @param {number} startLine - 1-indexed start line (new position)
|
|
60930
|
+
* @param {number} endLine - 1-indexed end line (new position)
|
|
60931
|
+
*/
|
|
60932
|
+
trackSymbolAfterWrite(resolvedPath2, symbolName, code, startLine, endLine) {
|
|
60933
|
+
this.trackSymbolContent(resolvedPath2, symbolName, code, startLine, endLine, "edit");
|
|
60934
|
+
}
|
|
60935
|
+
/**
|
|
60936
|
+
* Remove all content records for a file.
|
|
60937
|
+
* Called after non-symbol edits (text/line mode) since those change content
|
|
60938
|
+
* without providing a symbol-level update.
|
|
60939
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60940
|
+
*/
|
|
60941
|
+
invalidateFileRecords(resolvedPath2) {
|
|
60942
|
+
const prefix = resolvedPath2 + "#";
|
|
60943
|
+
for (const key of this._contentRecords.keys()) {
|
|
60944
|
+
if (key.startsWith(prefix)) {
|
|
60945
|
+
this._contentRecords.delete(key);
|
|
60946
|
+
}
|
|
60947
|
+
}
|
|
60948
|
+
if (this.debug) {
|
|
60949
|
+
console.error(`[FileTracker] Invalidated content records for ${resolvedPath2}`);
|
|
60950
|
+
}
|
|
60951
|
+
}
|
|
60952
|
+
/**
|
|
60953
|
+
* Quick sync check if a file is being tracked (alias for isFileSeen).
|
|
60954
|
+
* @param {string} resolvedPath - Absolute path to the file
|
|
60955
|
+
* @returns {boolean}
|
|
60956
|
+
*/
|
|
60957
|
+
isTracked(resolvedPath2) {
|
|
60958
|
+
return this.isFileSeen(resolvedPath2);
|
|
60959
|
+
}
|
|
60960
|
+
/**
|
|
60961
|
+
* Clear all tracking state.
|
|
60962
|
+
*/
|
|
60963
|
+
clear() {
|
|
60964
|
+
this._seenFiles.clear();
|
|
60965
|
+
this._contentRecords.clear();
|
|
60966
|
+
}
|
|
60967
|
+
};
|
|
60968
|
+
}
|
|
60969
|
+
});
|
|
60970
|
+
|
|
59715
60971
|
// src/agent/simpleTelemetry.js
|
|
59716
|
-
var import_fs9,
|
|
60972
|
+
var import_fs9, import_path11;
|
|
59717
60973
|
var init_simpleTelemetry = __esm({
|
|
59718
60974
|
"src/agent/simpleTelemetry.js"() {
|
|
59719
60975
|
"use strict";
|
|
59720
60976
|
import_fs9 = require("fs");
|
|
59721
|
-
|
|
60977
|
+
import_path11 = require("path");
|
|
59722
60978
|
}
|
|
59723
60979
|
});
|
|
59724
60980
|
|
|
@@ -59817,19 +61073,19 @@ function createWrappedTools(baseTools) {
|
|
|
59817
61073
|
}
|
|
59818
61074
|
return wrappedTools;
|
|
59819
61075
|
}
|
|
59820
|
-
var import_child_process8, import_util12,
|
|
61076
|
+
var import_child_process8, import_util12, import_crypto4, import_events, import_fs10, import_fs11, import_path12, toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
|
|
59821
61077
|
var init_probeTool = __esm({
|
|
59822
61078
|
"src/agent/probeTool.js"() {
|
|
59823
61079
|
"use strict";
|
|
59824
61080
|
init_index();
|
|
59825
61081
|
import_child_process8 = require("child_process");
|
|
59826
61082
|
import_util12 = require("util");
|
|
59827
|
-
|
|
61083
|
+
import_crypto4 = require("crypto");
|
|
59828
61084
|
import_events = require("events");
|
|
59829
61085
|
import_fs10 = __toESM(require("fs"), 1);
|
|
59830
61086
|
import_fs11 = require("fs");
|
|
59831
|
-
|
|
59832
|
-
|
|
61087
|
+
import_path12 = __toESM(require("path"), 1);
|
|
61088
|
+
init_esm7();
|
|
59833
61089
|
init_symlink_utils();
|
|
59834
61090
|
toolCallEmitter = new import_events.EventEmitter();
|
|
59835
61091
|
activeToolExecutions = /* @__PURE__ */ new Map();
|
|
@@ -59839,7 +61095,7 @@ var init_probeTool = __esm({
|
|
|
59839
61095
|
// Spread schema, description etc.
|
|
59840
61096
|
execute: async (params) => {
|
|
59841
61097
|
const debug = process.env.DEBUG === "1";
|
|
59842
|
-
const toolSessionId = params.sessionId || (0,
|
|
61098
|
+
const toolSessionId = params.sessionId || (0, import_crypto4.randomUUID)();
|
|
59843
61099
|
if (debug) {
|
|
59844
61100
|
console.log(`[DEBUG] probeTool: Executing ${toolName} for session ${toolSessionId}`);
|
|
59845
61101
|
}
|
|
@@ -59917,17 +61173,17 @@ var init_probeTool = __esm({
|
|
|
59917
61173
|
execute: async (params) => {
|
|
59918
61174
|
const { directory = ".", workingDirectory } = params;
|
|
59919
61175
|
const baseCwd = workingDirectory || process.cwd();
|
|
59920
|
-
const secureBaseDir =
|
|
61176
|
+
const secureBaseDir = import_path12.default.resolve(baseCwd);
|
|
59921
61177
|
const isDependencyPath = directory.startsWith("/dep/") || directory.startsWith("go:") || directory.startsWith("js:") || directory.startsWith("rust:");
|
|
59922
61178
|
let targetDir;
|
|
59923
|
-
if (
|
|
59924
|
-
targetDir =
|
|
59925
|
-
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir +
|
|
61179
|
+
if (import_path12.default.isAbsolute(directory)) {
|
|
61180
|
+
targetDir = import_path12.default.resolve(directory);
|
|
61181
|
+
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path12.default.sep) && targetDir !== secureBaseDir) {
|
|
59926
61182
|
throw new Error(`Path traversal attempt detected. Cannot access directory outside workspace: ${directory}`);
|
|
59927
61183
|
}
|
|
59928
61184
|
} else {
|
|
59929
|
-
targetDir =
|
|
59930
|
-
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir +
|
|
61185
|
+
targetDir = import_path12.default.resolve(secureBaseDir, directory);
|
|
61186
|
+
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path12.default.sep) && targetDir !== secureBaseDir) {
|
|
59931
61187
|
throw new Error(`Path traversal attempt detected. Access denied: ${directory}`);
|
|
59932
61188
|
}
|
|
59933
61189
|
}
|
|
@@ -59944,7 +61200,7 @@ var init_probeTool = __esm({
|
|
|
59944
61200
|
return `${(size / (1024 * 1024 * 1024)).toFixed(1)}G`;
|
|
59945
61201
|
};
|
|
59946
61202
|
const entries = await Promise.all(files.map(async (file) => {
|
|
59947
|
-
const fullPath =
|
|
61203
|
+
const fullPath = import_path12.default.join(targetDir, file.name);
|
|
59948
61204
|
const entryType = await getEntryType(file, fullPath);
|
|
59949
61205
|
return {
|
|
59950
61206
|
name: file.name,
|
|
@@ -59981,17 +61237,17 @@ var init_probeTool = __esm({
|
|
|
59981
61237
|
throw new Error("Pattern is required for file search");
|
|
59982
61238
|
}
|
|
59983
61239
|
const baseCwd = workingDirectory || process.cwd();
|
|
59984
|
-
const secureBaseDir =
|
|
61240
|
+
const secureBaseDir = import_path12.default.resolve(baseCwd);
|
|
59985
61241
|
const isDependencyPath = directory.startsWith("/dep/") || directory.startsWith("go:") || directory.startsWith("js:") || directory.startsWith("rust:");
|
|
59986
61242
|
let targetDir;
|
|
59987
|
-
if (
|
|
59988
|
-
targetDir =
|
|
59989
|
-
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir +
|
|
61243
|
+
if (import_path12.default.isAbsolute(directory)) {
|
|
61244
|
+
targetDir = import_path12.default.resolve(directory);
|
|
61245
|
+
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path12.default.sep) && targetDir !== secureBaseDir) {
|
|
59990
61246
|
throw new Error(`Path traversal attempt detected. Cannot access directory outside workspace: ${directory}`);
|
|
59991
61247
|
}
|
|
59992
61248
|
} else {
|
|
59993
|
-
targetDir =
|
|
59994
|
-
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir +
|
|
61249
|
+
targetDir = import_path12.default.resolve(secureBaseDir, directory);
|
|
61250
|
+
if (!isDependencyPath && !targetDir.startsWith(secureBaseDir + import_path12.default.sep) && targetDir !== secureBaseDir) {
|
|
59995
61251
|
throw new Error(`Path traversal attempt detected. Access denied: ${directory}`);
|
|
59996
61252
|
}
|
|
59997
61253
|
}
|
|
@@ -60568,6 +61824,7 @@ var init_index = __esm({
|
|
|
60568
61824
|
init_executePlan();
|
|
60569
61825
|
init_bash();
|
|
60570
61826
|
init_edit();
|
|
61827
|
+
init_fileTracker();
|
|
60571
61828
|
init_ProbeAgent();
|
|
60572
61829
|
init_simpleTelemetry();
|
|
60573
61830
|
init_probeTool();
|
|
@@ -60749,39 +62006,14 @@ function parseXmlToolCallWithThinking(xmlString, validTools) {
|
|
|
60749
62006
|
const toolCall = parseXmlToolCall(cleanedXmlString, validTools);
|
|
60750
62007
|
return toolCall ? { ...toolCall, thinkingContent } : null;
|
|
60751
62008
|
}
|
|
60752
|
-
var
|
|
62009
|
+
var import_crypto5, listFilesToolDefinition, searchFilesToolDefinition, listSkillsToolDefinition, useSkillToolDefinition, readImageToolDefinition;
|
|
60753
62010
|
var init_tools2 = __esm({
|
|
60754
62011
|
"src/agent/tools.js"() {
|
|
60755
62012
|
"use strict";
|
|
60756
62013
|
init_index();
|
|
60757
|
-
|
|
62014
|
+
import_crypto5 = require("crypto");
|
|
60758
62015
|
init_xmlParsingUtils();
|
|
60759
62016
|
init_tasks();
|
|
60760
|
-
implementToolDefinition = `
|
|
60761
|
-
## implement
|
|
60762
|
-
Description: Implement a given task. Can modify files. Can be used ONLY if task explicitly stated that something requires modification or implementation.
|
|
60763
|
-
|
|
60764
|
-
Parameters:
|
|
60765
|
-
- task: (required) The task description. Should be as detailed as possible, ideally pointing to exact files which needs be modified or created.
|
|
60766
|
-
- autoCommits: (optional) Whether to enable auto-commits in aider. Default is false.
|
|
60767
|
-
|
|
60768
|
-
Usage Example:
|
|
60769
|
-
|
|
60770
|
-
<examples>
|
|
60771
|
-
|
|
60772
|
-
User: Can you implement a function to calculate Fibonacci numbers in main.js?
|
|
60773
|
-
<implement>
|
|
60774
|
-
<task>Implement a recursive function to calculate the nth Fibonacci number in main.js</task>
|
|
60775
|
-
</implement>
|
|
60776
|
-
|
|
60777
|
-
User: Can you implement a function to calculate Fibonacci numbers in main.js with auto-commits?
|
|
60778
|
-
<implement>
|
|
60779
|
-
<task>Implement a recursive function to calculate the nth Fibonacci number in main.js</task>
|
|
60780
|
-
<autoCommits>true</autoCommits>
|
|
60781
|
-
</implement>
|
|
60782
|
-
|
|
60783
|
-
</examples>
|
|
60784
|
-
`;
|
|
60785
62017
|
listFilesToolDefinition = `
|
|
60786
62018
|
## listFiles
|
|
60787
62019
|
Description: List files and directories in a specified location.
|
|
@@ -60905,7 +62137,7 @@ function createMockProvider() {
|
|
|
60905
62137
|
provider: "mock",
|
|
60906
62138
|
// Mock the doGenerate method used by Vercel AI SDK
|
|
60907
62139
|
doGenerate: async ({ messages, tools: tools2 }) => {
|
|
60908
|
-
await new Promise((
|
|
62140
|
+
await new Promise((resolve8) => setTimeout(resolve8, 10));
|
|
60909
62141
|
return {
|
|
60910
62142
|
text: "This is a mock response for testing",
|
|
60911
62143
|
toolCalls: [],
|
|
@@ -66108,23 +67340,23 @@ var init_regexp_parser = __esm({
|
|
|
66108
67340
|
return ASSERT_NEVER_REACH_HERE();
|
|
66109
67341
|
}
|
|
66110
67342
|
quantifier(isBacktracking = false) {
|
|
66111
|
-
let
|
|
67343
|
+
let range3 = void 0;
|
|
66112
67344
|
const begin = this.idx;
|
|
66113
67345
|
switch (this.popChar()) {
|
|
66114
67346
|
case "*":
|
|
66115
|
-
|
|
67347
|
+
range3 = {
|
|
66116
67348
|
atLeast: 0,
|
|
66117
67349
|
atMost: Infinity
|
|
66118
67350
|
};
|
|
66119
67351
|
break;
|
|
66120
67352
|
case "+":
|
|
66121
|
-
|
|
67353
|
+
range3 = {
|
|
66122
67354
|
atLeast: 1,
|
|
66123
67355
|
atMost: Infinity
|
|
66124
67356
|
};
|
|
66125
67357
|
break;
|
|
66126
67358
|
case "?":
|
|
66127
|
-
|
|
67359
|
+
range3 = {
|
|
66128
67360
|
atLeast: 0,
|
|
66129
67361
|
atMost: 1
|
|
66130
67362
|
};
|
|
@@ -66133,7 +67365,7 @@ var init_regexp_parser = __esm({
|
|
|
66133
67365
|
const atLeast = this.integerIncludingZero();
|
|
66134
67366
|
switch (this.popChar()) {
|
|
66135
67367
|
case "}":
|
|
66136
|
-
|
|
67368
|
+
range3 = {
|
|
66137
67369
|
atLeast,
|
|
66138
67370
|
atMost: atLeast
|
|
66139
67371
|
};
|
|
@@ -66142,12 +67374,12 @@ var init_regexp_parser = __esm({
|
|
|
66142
67374
|
let atMost;
|
|
66143
67375
|
if (this.isDigit()) {
|
|
66144
67376
|
atMost = this.integerIncludingZero();
|
|
66145
|
-
|
|
67377
|
+
range3 = {
|
|
66146
67378
|
atLeast,
|
|
66147
67379
|
atMost
|
|
66148
67380
|
};
|
|
66149
67381
|
} else {
|
|
66150
|
-
|
|
67382
|
+
range3 = {
|
|
66151
67383
|
atLeast,
|
|
66152
67384
|
atMost: Infinity
|
|
66153
67385
|
};
|
|
@@ -66155,25 +67387,25 @@ var init_regexp_parser = __esm({
|
|
|
66155
67387
|
this.consumeChar("}");
|
|
66156
67388
|
break;
|
|
66157
67389
|
}
|
|
66158
|
-
if (isBacktracking === true &&
|
|
67390
|
+
if (isBacktracking === true && range3 === void 0) {
|
|
66159
67391
|
return void 0;
|
|
66160
67392
|
}
|
|
66161
|
-
ASSERT_EXISTS(
|
|
67393
|
+
ASSERT_EXISTS(range3);
|
|
66162
67394
|
break;
|
|
66163
67395
|
}
|
|
66164
|
-
if (isBacktracking === true &&
|
|
67396
|
+
if (isBacktracking === true && range3 === void 0) {
|
|
66165
67397
|
return void 0;
|
|
66166
67398
|
}
|
|
66167
|
-
if (ASSERT_EXISTS(
|
|
67399
|
+
if (ASSERT_EXISTS(range3)) {
|
|
66168
67400
|
if (this.peekChar(0) === "?") {
|
|
66169
67401
|
this.consumeChar("?");
|
|
66170
|
-
|
|
67402
|
+
range3.greedy = false;
|
|
66171
67403
|
} else {
|
|
66172
|
-
|
|
67404
|
+
range3.greedy = true;
|
|
66173
67405
|
}
|
|
66174
|
-
|
|
66175
|
-
|
|
66176
|
-
return
|
|
67406
|
+
range3.type = "Quantifier";
|
|
67407
|
+
range3.loc = this.loc(begin);
|
|
67408
|
+
return range3;
|
|
66177
67409
|
}
|
|
66178
67410
|
}
|
|
66179
67411
|
atom() {
|
|
@@ -66875,18 +68107,18 @@ function firstCharOptimizedIndices(ast, result, ignoreCase) {
|
|
|
66875
68107
|
if (typeof code === "number") {
|
|
66876
68108
|
addOptimizedIdxToResult(code, result, ignoreCase);
|
|
66877
68109
|
} else {
|
|
66878
|
-
const
|
|
68110
|
+
const range3 = code;
|
|
66879
68111
|
if (ignoreCase === true) {
|
|
66880
|
-
for (let rangeCode =
|
|
68112
|
+
for (let rangeCode = range3.from; rangeCode <= range3.to; rangeCode++) {
|
|
66881
68113
|
addOptimizedIdxToResult(rangeCode, result, ignoreCase);
|
|
66882
68114
|
}
|
|
66883
68115
|
} else {
|
|
66884
|
-
for (let rangeCode =
|
|
68116
|
+
for (let rangeCode = range3.from; rangeCode <= range3.to && rangeCode < minOptimizationVal; rangeCode++) {
|
|
66885
68117
|
addOptimizedIdxToResult(rangeCode, result, ignoreCase);
|
|
66886
68118
|
}
|
|
66887
|
-
if (
|
|
66888
|
-
const minUnOptVal =
|
|
66889
|
-
const maxUnOptVal =
|
|
68119
|
+
if (range3.to >= minOptimizationVal) {
|
|
68120
|
+
const minUnOptVal = range3.from >= minOptimizationVal ? range3.from : minOptimizationVal;
|
|
68121
|
+
const maxUnOptVal = range3.to;
|
|
66890
68122
|
const minOptIdx = charCodeToOptimizedIndex(minUnOptVal);
|
|
66891
68123
|
const maxOptIdx = charCodeToOptimizedIndex(maxUnOptVal);
|
|
66892
68124
|
for (let currOptIdx = minOptIdx; currOptIdx <= maxOptIdx; currOptIdx++) {
|
|
@@ -66947,8 +68179,8 @@ function findCode(setNode, targetCharCodes) {
|
|
|
66947
68179
|
if (typeof codeOrRange === "number") {
|
|
66948
68180
|
return includes_default(targetCharCodes, codeOrRange);
|
|
66949
68181
|
} else {
|
|
66950
|
-
const
|
|
66951
|
-
return find_default(targetCharCodes, (targetCode) =>
|
|
68182
|
+
const range3 = codeOrRange;
|
|
68183
|
+
return find_default(targetCharCodes, (targetCode) => range3.from <= targetCode && targetCode <= range3.to) !== void 0;
|
|
66952
68184
|
}
|
|
66953
68185
|
});
|
|
66954
68186
|
}
|
|
@@ -84853,8 +86085,8 @@ var require_createRange = __commonJS({
|
|
|
84853
86085
|
var require_range = __commonJS({
|
|
84854
86086
|
"node_modules/lodash/range.js"(exports2, module2) {
|
|
84855
86087
|
var createRange = require_createRange();
|
|
84856
|
-
var
|
|
84857
|
-
module2.exports =
|
|
86088
|
+
var range3 = createRange();
|
|
86089
|
+
module2.exports = range3;
|
|
84858
86090
|
}
|
|
84859
86091
|
});
|
|
84860
86092
|
|
|
@@ -94095,7 +95327,7 @@ var require_compile = __commonJS({
|
|
|
94095
95327
|
const schOrFunc = root2.refs[ref2];
|
|
94096
95328
|
if (schOrFunc)
|
|
94097
95329
|
return schOrFunc;
|
|
94098
|
-
let _sch =
|
|
95330
|
+
let _sch = resolve8.call(this, root2, ref2);
|
|
94099
95331
|
if (_sch === void 0) {
|
|
94100
95332
|
const schema = (_a16 = root2.localRefs) === null || _a16 === void 0 ? void 0 : _a16[ref2];
|
|
94101
95333
|
const { schemaId } = this.opts;
|
|
@@ -94122,7 +95354,7 @@ var require_compile = __commonJS({
|
|
|
94122
95354
|
function sameSchemaEnv(s1, s22) {
|
|
94123
95355
|
return s1.schema === s22.schema && s1.root === s22.root && s1.baseId === s22.baseId;
|
|
94124
95356
|
}
|
|
94125
|
-
function
|
|
95357
|
+
function resolve8(root2, ref2) {
|
|
94126
95358
|
let sch;
|
|
94127
95359
|
while (typeof (sch = this.refs[ref2]) == "string")
|
|
94128
95360
|
ref2 = sch;
|
|
@@ -94697,7 +95929,7 @@ var require_fast_uri = __commonJS({
|
|
|
94697
95929
|
}
|
|
94698
95930
|
return uri;
|
|
94699
95931
|
}
|
|
94700
|
-
function
|
|
95932
|
+
function resolve8(baseURI, relativeURI, options) {
|
|
94701
95933
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
94702
95934
|
const resolved = resolveComponent(parse9(baseURI, schemelessOptions), parse9(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
94703
95935
|
schemelessOptions.skipEscape = true;
|
|
@@ -94924,7 +96156,7 @@ var require_fast_uri = __commonJS({
|
|
|
94924
96156
|
var fastUri = {
|
|
94925
96157
|
SCHEMES,
|
|
94926
96158
|
normalize: normalize3,
|
|
94927
|
-
resolve:
|
|
96159
|
+
resolve: resolve8,
|
|
94928
96160
|
resolveComponent,
|
|
94929
96161
|
equal,
|
|
94930
96162
|
serialize,
|
|
@@ -97619,6 +98851,7 @@ __export(schemaUtils_exports, {
|
|
|
97619
98851
|
replaceMermaidDiagramsInMarkdown: () => replaceMermaidDiagramsInMarkdown,
|
|
97620
98852
|
sanitizeMarkdownEscapesInJson: () => sanitizeMarkdownEscapesInJson,
|
|
97621
98853
|
tryAutoWrapForSimpleSchema: () => tryAutoWrapForSimpleSchema,
|
|
98854
|
+
tryExtractValidJsonPrefix: () => tryExtractValidJsonPrefix,
|
|
97622
98855
|
tryMaidAutoFix: () => tryMaidAutoFix,
|
|
97623
98856
|
validateAndFixMermaidResponse: () => validateAndFixMermaidResponse,
|
|
97624
98857
|
validateJsonResponse: () => validateJsonResponse,
|
|
@@ -98005,6 +99238,13 @@ function validateJsonResponse(response, options = {}) {
|
|
|
98005
99238
|
errorPosition = response.indexOf(problematicToken);
|
|
98006
99239
|
}
|
|
98007
99240
|
}
|
|
99241
|
+
const prefixResult = tryExtractValidJsonPrefix(responseToValidate, { schema, debug });
|
|
99242
|
+
if (prefixResult && prefixResult.isValid) {
|
|
99243
|
+
if (debug) {
|
|
99244
|
+
console.log(`[DEBUG] JSON validation: Recovered valid JSON prefix (${prefixResult.extracted.length} chars) from response with trailing content`);
|
|
99245
|
+
}
|
|
99246
|
+
return { isValid: true, parsed: prefixResult.parsed };
|
|
99247
|
+
}
|
|
98008
99248
|
let enhancedError = error2.message;
|
|
98009
99249
|
let errorContext = null;
|
|
98010
99250
|
if (errorPosition !== null && errorPosition >= 0 && response && response.length > 0) {
|
|
@@ -98055,6 +99295,84 @@ ${errorContext.pointer}`);
|
|
|
98055
99295
|
};
|
|
98056
99296
|
}
|
|
98057
99297
|
}
|
|
99298
|
+
function tryExtractValidJsonPrefix(response, options = {}) {
|
|
99299
|
+
const { schema = null, debug = false } = options;
|
|
99300
|
+
if (!response || typeof response !== "string") {
|
|
99301
|
+
return null;
|
|
99302
|
+
}
|
|
99303
|
+
const trimmed = response.trim();
|
|
99304
|
+
if (trimmed.length === 0) {
|
|
99305
|
+
return null;
|
|
99306
|
+
}
|
|
99307
|
+
const firstChar = trimmed[0];
|
|
99308
|
+
if (firstChar !== "{" && firstChar !== "[") {
|
|
99309
|
+
return null;
|
|
99310
|
+
}
|
|
99311
|
+
try {
|
|
99312
|
+
JSON.parse(trimmed);
|
|
99313
|
+
return null;
|
|
99314
|
+
} catch {
|
|
99315
|
+
}
|
|
99316
|
+
const openChar = firstChar;
|
|
99317
|
+
const closeChar = openChar === "{" ? "}" : "]";
|
|
99318
|
+
let depth = 0;
|
|
99319
|
+
let inString = false;
|
|
99320
|
+
let escapeNext = false;
|
|
99321
|
+
let endPos = -1;
|
|
99322
|
+
for (let i5 = 0; i5 < trimmed.length; i5++) {
|
|
99323
|
+
const char = trimmed[i5];
|
|
99324
|
+
if (escapeNext) {
|
|
99325
|
+
escapeNext = false;
|
|
99326
|
+
continue;
|
|
99327
|
+
}
|
|
99328
|
+
if (char === "\\" && inString) {
|
|
99329
|
+
escapeNext = true;
|
|
99330
|
+
continue;
|
|
99331
|
+
}
|
|
99332
|
+
if (char === '"') {
|
|
99333
|
+
inString = !inString;
|
|
99334
|
+
continue;
|
|
99335
|
+
}
|
|
99336
|
+
if (inString) {
|
|
99337
|
+
continue;
|
|
99338
|
+
}
|
|
99339
|
+
if (char === openChar) {
|
|
99340
|
+
depth++;
|
|
99341
|
+
} else if (char === closeChar) {
|
|
99342
|
+
depth--;
|
|
99343
|
+
if (depth === 0) {
|
|
99344
|
+
endPos = i5 + 1;
|
|
99345
|
+
break;
|
|
99346
|
+
}
|
|
99347
|
+
}
|
|
99348
|
+
}
|
|
99349
|
+
if (endPos <= 0 || endPos >= trimmed.length) {
|
|
99350
|
+
return null;
|
|
99351
|
+
}
|
|
99352
|
+
const remainder = trimmed.substring(endPos).trim();
|
|
99353
|
+
if (remainder.length === 0) {
|
|
99354
|
+
return null;
|
|
99355
|
+
}
|
|
99356
|
+
const prefix = trimmed.substring(0, endPos);
|
|
99357
|
+
try {
|
|
99358
|
+
const parsed = JSON.parse(prefix);
|
|
99359
|
+
if (debug) {
|
|
99360
|
+
console.log(`[DEBUG] tryExtractValidJsonPrefix: Extracted valid JSON prefix (${prefix.length} chars), stripped trailing content (${remainder.length} chars)`);
|
|
99361
|
+
}
|
|
99362
|
+
if (schema) {
|
|
99363
|
+
const schemaValidation = validateJsonResponse(prefix, { debug, schema });
|
|
99364
|
+
if (!schemaValidation.isValid) {
|
|
99365
|
+
if (debug) {
|
|
99366
|
+
console.log(`[DEBUG] tryExtractValidJsonPrefix: Prefix is valid JSON but fails schema validation: ${schemaValidation.error}`);
|
|
99367
|
+
}
|
|
99368
|
+
return null;
|
|
99369
|
+
}
|
|
99370
|
+
}
|
|
99371
|
+
return { isValid: true, parsed, extracted: prefix };
|
|
99372
|
+
} catch {
|
|
99373
|
+
return null;
|
|
99374
|
+
}
|
|
99375
|
+
}
|
|
98058
99376
|
function validateXmlResponse(response) {
|
|
98059
99377
|
const xmlPattern = /<\/?[\w\s="'.-]+>/g;
|
|
98060
99378
|
const tags = response.match(xmlPattern);
|
|
@@ -99447,13 +100765,13 @@ function loadMCPConfiguration() {
|
|
|
99447
100765
|
// Environment variable path
|
|
99448
100766
|
process.env.MCP_CONFIG_PATH,
|
|
99449
100767
|
// Local project paths
|
|
99450
|
-
(0,
|
|
99451
|
-
(0,
|
|
100768
|
+
(0, import_path13.join)(process.cwd(), ".mcp", "config.json"),
|
|
100769
|
+
(0, import_path13.join)(process.cwd(), "mcp.config.json"),
|
|
99452
100770
|
// Home directory paths
|
|
99453
|
-
(0,
|
|
99454
|
-
(0,
|
|
100771
|
+
(0, import_path13.join)((0, import_os3.homedir)(), ".config", "probe", "mcp.json"),
|
|
100772
|
+
(0, import_path13.join)((0, import_os3.homedir)(), ".mcp", "config.json"),
|
|
99455
100773
|
// Claude-style config location
|
|
99456
|
-
(0,
|
|
100774
|
+
(0, import_path13.join)((0, import_os3.homedir)(), "Library", "Application Support", "Claude", "mcp_config.json")
|
|
99457
100775
|
].filter(Boolean);
|
|
99458
100776
|
let config = null;
|
|
99459
100777
|
for (const configPath of configPaths) {
|
|
@@ -99580,16 +100898,16 @@ function parseEnabledServers(config) {
|
|
|
99580
100898
|
}
|
|
99581
100899
|
return servers;
|
|
99582
100900
|
}
|
|
99583
|
-
var import_fs12,
|
|
100901
|
+
var import_fs12, import_path13, import_os3, import_url4, __filename4, __dirname4, DEFAULT_TIMEOUT, MAX_TIMEOUT, DEFAULT_CONFIG;
|
|
99584
100902
|
var init_config = __esm({
|
|
99585
100903
|
"src/agent/mcp/config.js"() {
|
|
99586
100904
|
"use strict";
|
|
99587
100905
|
import_fs12 = require("fs");
|
|
99588
|
-
|
|
100906
|
+
import_path13 = require("path");
|
|
99589
100907
|
import_os3 = require("os");
|
|
99590
100908
|
import_url4 = require("url");
|
|
99591
100909
|
__filename4 = (0, import_url4.fileURLToPath)("file:///");
|
|
99592
|
-
__dirname4 = (0,
|
|
100910
|
+
__dirname4 = (0, import_path13.dirname)(__filename4);
|
|
99593
100911
|
DEFAULT_TIMEOUT = 3e4;
|
|
99594
100912
|
MAX_TIMEOUT = (() => {
|
|
99595
100913
|
if (process.env.MCP_MAX_TIMEOUT) {
|
|
@@ -99603,7 +100921,7 @@ var init_config = __esm({
|
|
|
99603
100921
|
// Example probe server configuration
|
|
99604
100922
|
"probe-local": {
|
|
99605
100923
|
command: "node",
|
|
99606
|
-
args: [(0,
|
|
100924
|
+
args: [(0, import_path13.join)(__dirname4, "../../../examples/chat/mcpServer.js")],
|
|
99607
100925
|
transport: "stdio",
|
|
99608
100926
|
enabled: false
|
|
99609
100927
|
},
|
|
@@ -100156,7 +101474,7 @@ function parseXmlMcpToolCall(xmlString, mcpToolNames = []) {
|
|
|
100156
101474
|
let match2;
|
|
100157
101475
|
while ((match2 = paramPattern.exec(content)) !== null) {
|
|
100158
101476
|
const [, paramName, paramValue] = match2;
|
|
100159
|
-
params[paramName] = paramValue.trim();
|
|
101477
|
+
params[paramName] = unescapeXmlEntities(paramValue.trim());
|
|
100160
101478
|
}
|
|
100161
101479
|
}
|
|
100162
101480
|
return { toolName, params };
|
|
@@ -100206,7 +101524,7 @@ function parseNativeXmlTool(xmlString, toolName) {
|
|
|
100206
101524
|
while ((match2 = paramPattern.exec(content)) !== null) {
|
|
100207
101525
|
const [, paramName, paramValue] = match2;
|
|
100208
101526
|
if (paramName !== "params") {
|
|
100209
|
-
params[paramName] = paramValue.trim();
|
|
101527
|
+
params[paramName] = unescapeXmlEntities(paramValue.trim());
|
|
100210
101528
|
}
|
|
100211
101529
|
}
|
|
100212
101530
|
if (Object.keys(params).length > 0) {
|
|
@@ -100221,6 +101539,7 @@ var init_xmlBridge = __esm({
|
|
|
100221
101539
|
init_client2();
|
|
100222
101540
|
init_config();
|
|
100223
101541
|
init_xmlParsingUtils();
|
|
101542
|
+
init_common2();
|
|
100224
101543
|
MCPXmlBridge = class {
|
|
100225
101544
|
constructor(options = {}) {
|
|
100226
101545
|
this.debug = options.debug || false;
|
|
@@ -105186,7 +106505,7 @@ var require_compose_scalar = __commonJS({
|
|
|
105186
106505
|
var resolveBlockScalar = require_resolve_block_scalar();
|
|
105187
106506
|
var resolveFlowScalar = require_resolve_flow_scalar();
|
|
105188
106507
|
function composeScalar(ctx, token, tagToken, onError) {
|
|
105189
|
-
const { value, type, comment, range:
|
|
106508
|
+
const { value, type, comment, range: range3 } = token.type === "block-scalar" ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError) : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
|
|
105190
106509
|
const tagName = tagToken ? ctx.directives.tagName(tagToken.source, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg)) : null;
|
|
105191
106510
|
let tag2;
|
|
105192
106511
|
if (ctx.options.stringKeys && ctx.atKey) {
|
|
@@ -105206,7 +106525,7 @@ var require_compose_scalar = __commonJS({
|
|
|
105206
106525
|
onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg);
|
|
105207
106526
|
scalar = new Scalar.Scalar(value);
|
|
105208
106527
|
}
|
|
105209
|
-
scalar.range =
|
|
106528
|
+
scalar.range = range3;
|
|
105210
106529
|
scalar.source = value;
|
|
105211
106530
|
if (type)
|
|
105212
106531
|
scalar.type = type;
|
|
@@ -107797,17 +109116,17 @@ async function parseSkillFile(skillFilePath, directoryName) {
|
|
|
107797
109116
|
description,
|
|
107798
109117
|
skillFilePath,
|
|
107799
109118
|
directoryName,
|
|
107800
|
-
sourceDir: (0,
|
|
109119
|
+
sourceDir: (0, import_path14.dirname)(skillFilePath)
|
|
107801
109120
|
},
|
|
107802
109121
|
error: null
|
|
107803
109122
|
};
|
|
107804
109123
|
}
|
|
107805
|
-
var import_promises2,
|
|
109124
|
+
var import_promises2, import_path14, import_yaml, SKILL_NAME_REGEX, MAX_SKILL_NAME_LENGTH, MAX_DESCRIPTION_CHARS;
|
|
107806
109125
|
var init_parser7 = __esm({
|
|
107807
109126
|
"src/agent/skills/parser.js"() {
|
|
107808
109127
|
"use strict";
|
|
107809
109128
|
import_promises2 = require("fs/promises");
|
|
107810
|
-
|
|
109129
|
+
import_path14 = require("path");
|
|
107811
109130
|
import_yaml = __toESM(require_dist(), 1);
|
|
107812
109131
|
SKILL_NAME_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
107813
109132
|
MAX_SKILL_NAME_LENGTH = 64;
|
|
@@ -107817,12 +109136,12 @@ var init_parser7 = __esm({
|
|
|
107817
109136
|
|
|
107818
109137
|
// src/agent/skills/registry.js
|
|
107819
109138
|
function isPathInside(basePath, targetPath) {
|
|
107820
|
-
const base2 = (0,
|
|
107821
|
-
const target = (0,
|
|
107822
|
-
const rel = (0,
|
|
109139
|
+
const base2 = (0, import_path15.resolve)(basePath);
|
|
109140
|
+
const target = (0, import_path15.resolve)(targetPath);
|
|
109141
|
+
const rel = (0, import_path15.relative)(base2, target);
|
|
107823
109142
|
if (rel === "") return true;
|
|
107824
|
-
if (rel === ".." || rel.startsWith(`..${
|
|
107825
|
-
if ((0,
|
|
109143
|
+
if (rel === ".." || rel.startsWith(`..${import_path15.sep}`)) return false;
|
|
109144
|
+
if ((0, import_path15.isAbsolute)(rel)) return false;
|
|
107826
109145
|
return true;
|
|
107827
109146
|
}
|
|
107828
109147
|
function isSafeEntryName(name14) {
|
|
@@ -107830,19 +109149,19 @@ function isSafeEntryName(name14) {
|
|
|
107830
109149
|
if (name14.includes("\0")) return false;
|
|
107831
109150
|
return !name14.includes("/") && !name14.includes("\\");
|
|
107832
109151
|
}
|
|
107833
|
-
var import_fs13, import_promises3,
|
|
109152
|
+
var import_fs13, import_promises3, import_path15, DEFAULT_SKILL_DIRS, SKILL_FILE_NAME, SkillRegistry;
|
|
107834
109153
|
var init_registry = __esm({
|
|
107835
109154
|
"src/agent/skills/registry.js"() {
|
|
107836
109155
|
"use strict";
|
|
107837
109156
|
import_fs13 = require("fs");
|
|
107838
109157
|
import_promises3 = require("fs/promises");
|
|
107839
|
-
|
|
109158
|
+
import_path15 = require("path");
|
|
107840
109159
|
init_parser7();
|
|
107841
109160
|
DEFAULT_SKILL_DIRS = [".claude/skills", ".codex/skills", "skills", ".skills"];
|
|
107842
109161
|
SKILL_FILE_NAME = "SKILL.md";
|
|
107843
109162
|
SkillRegistry = class {
|
|
107844
109163
|
constructor({ repoRoot, skillDirs = DEFAULT_SKILL_DIRS, debug = false } = {}) {
|
|
107845
|
-
this.repoRoot = repoRoot ? (0,
|
|
109164
|
+
this.repoRoot = repoRoot ? (0, import_path15.resolve)(repoRoot) : process.cwd();
|
|
107846
109165
|
this.repoRootReal = null;
|
|
107847
109166
|
this.skillDirs = Array.isArray(skillDirs) && skillDirs.length > 0 ? skillDirs : DEFAULT_SKILL_DIRS;
|
|
107848
109167
|
this.debug = debug;
|
|
@@ -107896,8 +109215,8 @@ var init_registry = __esm({
|
|
|
107896
109215
|
}
|
|
107897
109216
|
}
|
|
107898
109217
|
async _resolveSkillDir(skillDir) {
|
|
107899
|
-
const resolved = (0,
|
|
107900
|
-
const repoRoot = this.repoRootReal || (0,
|
|
109218
|
+
const resolved = (0, import_path15.isAbsolute)(skillDir) ? (0, import_path15.resolve)(skillDir) : (0, import_path15.resolve)(this.repoRoot, skillDir);
|
|
109219
|
+
const repoRoot = this.repoRootReal || (0, import_path15.resolve)(this.repoRoot);
|
|
107901
109220
|
const resolvedReal = await this._resolveRealPath(resolved);
|
|
107902
109221
|
if (!resolvedReal) return null;
|
|
107903
109222
|
if (!isPathInside(repoRoot, resolvedReal)) {
|
|
@@ -107928,8 +109247,8 @@ var init_registry = __esm({
|
|
|
107928
109247
|
}
|
|
107929
109248
|
continue;
|
|
107930
109249
|
}
|
|
107931
|
-
const skillFolder = (0,
|
|
107932
|
-
const skillFilePath = (0,
|
|
109250
|
+
const skillFolder = (0, import_path15.join)(dirPath, entry.name);
|
|
109251
|
+
const skillFilePath = (0, import_path15.join)(skillFolder, SKILL_FILE_NAME);
|
|
107933
109252
|
let skillStat;
|
|
107934
109253
|
try {
|
|
107935
109254
|
skillStat = await (0, import_promises3.lstat)(skillFilePath);
|
|
@@ -108087,7 +109406,7 @@ function extractErrorInfo(error2) {
|
|
|
108087
109406
|
};
|
|
108088
109407
|
}
|
|
108089
109408
|
function sleep(ms) {
|
|
108090
|
-
return new Promise((
|
|
109409
|
+
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
108091
109410
|
}
|
|
108092
109411
|
var DEFAULT_RETRYABLE_ERRORS, RetryManager;
|
|
108093
109412
|
var init_RetryManager = __esm({
|
|
@@ -108867,9 +110186,9 @@ async function truncateIfNeeded(content, tokenCounter, sessionId, maxTokens) {
|
|
|
108867
110186
|
let tempFilePath = null;
|
|
108868
110187
|
let fileError = null;
|
|
108869
110188
|
try {
|
|
108870
|
-
const tempDir = (0,
|
|
110189
|
+
const tempDir = (0, import_path16.join)((0, import_os4.tmpdir)(), "probe-output");
|
|
108871
110190
|
await (0, import_promises4.mkdir)(tempDir, { recursive: true });
|
|
108872
|
-
tempFilePath = (0,
|
|
110191
|
+
tempFilePath = (0, import_path16.join)(tempDir, `tool-output-${sessionId || "unknown"}-${(0, import_crypto6.randomUUID)()}.txt`);
|
|
108873
110192
|
await (0, import_promises4.writeFile)(tempFilePath, content, "utf8");
|
|
108874
110193
|
} catch (err) {
|
|
108875
110194
|
fileError = err.message || "Unknown file system error";
|
|
@@ -108917,14 +110236,14 @@ ${truncatedBody}
|
|
|
108917
110236
|
error: fileError || void 0
|
|
108918
110237
|
};
|
|
108919
110238
|
}
|
|
108920
|
-
var import_promises4, import_os4,
|
|
110239
|
+
var import_promises4, import_os4, import_path16, import_crypto6, DEFAULT_MAX_OUTPUT_TOKENS, CHARS_PER_TOKEN2, TAIL_TOKENS, MIN_LIMIT_FOR_TAIL;
|
|
108921
110240
|
var init_outputTruncator = __esm({
|
|
108922
110241
|
"src/agent/outputTruncator.js"() {
|
|
108923
110242
|
"use strict";
|
|
108924
110243
|
import_promises4 = require("fs/promises");
|
|
108925
110244
|
import_os4 = require("os");
|
|
108926
|
-
|
|
108927
|
-
|
|
110245
|
+
import_path16 = require("path");
|
|
110246
|
+
import_crypto6 = require("crypto");
|
|
108928
110247
|
DEFAULT_MAX_OUTPUT_TOKENS = 2e4;
|
|
108929
110248
|
CHARS_PER_TOKEN2 = 4;
|
|
108930
110249
|
TAIL_TOKENS = 1e3;
|
|
@@ -108933,13 +110252,13 @@ var init_outputTruncator = __esm({
|
|
|
108933
110252
|
});
|
|
108934
110253
|
|
|
108935
110254
|
// src/agent/mcp/built-in-server.js
|
|
108936
|
-
var import_http, import_events2,
|
|
110255
|
+
var import_http, import_events2, import_crypto7, import_server, import_sse2, import_streamableHttp, import_types3, InMemoryEventStore, BuiltInMCPServer;
|
|
108937
110256
|
var init_built_in_server = __esm({
|
|
108938
110257
|
"src/agent/mcp/built-in-server.js"() {
|
|
108939
110258
|
"use strict";
|
|
108940
110259
|
import_http = require("http");
|
|
108941
110260
|
import_events2 = require("events");
|
|
108942
|
-
|
|
110261
|
+
import_crypto7 = require("crypto");
|
|
108943
110262
|
import_server = require("@modelcontextprotocol/sdk/server/index.js");
|
|
108944
110263
|
import_sse2 = require("@modelcontextprotocol/sdk/server/sse.js");
|
|
108945
110264
|
import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
@@ -109015,7 +110334,7 @@ var init_built_in_server = __esm({
|
|
|
109015
110334
|
}
|
|
109016
110335
|
});
|
|
109017
110336
|
this.registerHandlers();
|
|
109018
|
-
return new Promise((
|
|
110337
|
+
return new Promise((resolve8, reject2) => {
|
|
109019
110338
|
this.httpServer.listen(this.port, this.host, async () => {
|
|
109020
110339
|
const address = this.httpServer.address();
|
|
109021
110340
|
this.port = address.port;
|
|
@@ -109025,7 +110344,7 @@ var init_built_in_server = __esm({
|
|
|
109025
110344
|
console.log(`[MCP] Messages endpoint: http://${this.host}:${this.port}/messages`);
|
|
109026
110345
|
}
|
|
109027
110346
|
this.emit("ready", { host: this.host, port: this.port });
|
|
109028
|
-
|
|
110347
|
+
resolve8({ host: this.host, port: this.port });
|
|
109029
110348
|
});
|
|
109030
110349
|
this.httpServer.on("error", reject2);
|
|
109031
110350
|
});
|
|
@@ -109183,7 +110502,7 @@ var init_built_in_server = __esm({
|
|
|
109183
110502
|
}
|
|
109184
110503
|
const eventStore = new InMemoryEventStore();
|
|
109185
110504
|
transport = new import_streamableHttp.StreamableHTTPServerTransport({
|
|
109186
|
-
sessionIdGenerator: () => (0,
|
|
110505
|
+
sessionIdGenerator: () => (0, import_crypto7.randomUUID)(),
|
|
109187
110506
|
eventStore,
|
|
109188
110507
|
// Enable resumability
|
|
109189
110508
|
onsessioninitialized: (newSessionId) => {
|
|
@@ -109244,7 +110563,7 @@ var init_built_in_server = __esm({
|
|
|
109244
110563
|
* Parse request body as JSON
|
|
109245
110564
|
*/
|
|
109246
110565
|
async parseRequestBody(req) {
|
|
109247
|
-
return new Promise((
|
|
110566
|
+
return new Promise((resolve8, reject2) => {
|
|
109248
110567
|
let body = "";
|
|
109249
110568
|
req.on("data", (chunk) => {
|
|
109250
110569
|
body += chunk.toString();
|
|
@@ -109252,7 +110571,7 @@ var init_built_in_server = __esm({
|
|
|
109252
110571
|
req.on("end", () => {
|
|
109253
110572
|
try {
|
|
109254
110573
|
const parsed = body ? JSON.parse(body) : null;
|
|
109255
|
-
|
|
110574
|
+
resolve8(parsed);
|
|
109256
110575
|
} catch (error2) {
|
|
109257
110576
|
reject2(error2);
|
|
109258
110577
|
}
|
|
@@ -109559,12 +110878,12 @@ data: ${JSON.stringify(data3)}
|
|
|
109559
110878
|
}
|
|
109560
110879
|
this.connections.clear();
|
|
109561
110880
|
if (this.httpServer) {
|
|
109562
|
-
return new Promise((
|
|
110881
|
+
return new Promise((resolve8) => {
|
|
109563
110882
|
this.httpServer.close(() => {
|
|
109564
110883
|
if (this.debug) {
|
|
109565
110884
|
console.log("[MCP] Built-in server stopped");
|
|
109566
110885
|
}
|
|
109567
|
-
|
|
110886
|
+
resolve8();
|
|
109568
110887
|
});
|
|
109569
110888
|
});
|
|
109570
110889
|
}
|
|
@@ -109646,7 +110965,7 @@ __export(enhanced_claude_code_exports, {
|
|
|
109646
110965
|
async function createEnhancedClaudeCLIEngine(options = {}) {
|
|
109647
110966
|
const { agent, systemPrompt, customPrompt, debug, sessionId, allowedTools, timeout = 12e4 } = options;
|
|
109648
110967
|
const session = new Session(
|
|
109649
|
-
sessionId || (0,
|
|
110968
|
+
sessionId || (0, import_crypto8.randomBytes)(8).toString("hex"),
|
|
109650
110969
|
debug
|
|
109651
110970
|
);
|
|
109652
110971
|
let mcpServer = null;
|
|
@@ -109663,12 +110982,12 @@ async function createEnhancedClaudeCLIEngine(options = {}) {
|
|
|
109663
110982
|
console.log("[DEBUG] Built-in MCP server started");
|
|
109664
110983
|
console.log("[DEBUG] MCP URL:", `http://${host}:${port}/mcp`);
|
|
109665
110984
|
}
|
|
109666
|
-
mcpConfigPath =
|
|
110985
|
+
mcpConfigPath = import_path17.default.join(import_os5.default.tmpdir(), `probe-mcp-${session.id}.json`);
|
|
109667
110986
|
const mcpConfig = {
|
|
109668
110987
|
mcpServers: {
|
|
109669
110988
|
probe: {
|
|
109670
110989
|
command: "node",
|
|
109671
|
-
args: [
|
|
110990
|
+
args: [import_path17.default.join(process.cwd(), "mcp-probe-server.js")],
|
|
109672
110991
|
env: {
|
|
109673
110992
|
PROBE_WORKSPACE: process.cwd(),
|
|
109674
110993
|
DEBUG: debug ? "true" : "false"
|
|
@@ -109893,8 +111212,8 @@ ${opts.schema}`;
|
|
|
109893
111212
|
break;
|
|
109894
111213
|
}
|
|
109895
111214
|
} else if (!processEnded) {
|
|
109896
|
-
await new Promise((
|
|
109897
|
-
resolver =
|
|
111215
|
+
await new Promise((resolve8) => {
|
|
111216
|
+
resolver = resolve8;
|
|
109898
111217
|
});
|
|
109899
111218
|
}
|
|
109900
111219
|
}
|
|
@@ -110093,14 +111412,14 @@ function combinePrompts(systemPrompt, customPrompt, agent) {
|
|
|
110093
111412
|
}
|
|
110094
111413
|
return systemPrompt || "";
|
|
110095
111414
|
}
|
|
110096
|
-
var import_child_process9,
|
|
111415
|
+
var import_child_process9, import_crypto8, import_promises5, import_path17, import_os5, import_events3;
|
|
110097
111416
|
var init_enhanced_claude_code = __esm({
|
|
110098
111417
|
"src/agent/engines/enhanced-claude-code.js"() {
|
|
110099
111418
|
"use strict";
|
|
110100
111419
|
import_child_process9 = require("child_process");
|
|
110101
|
-
|
|
111420
|
+
import_crypto8 = require("crypto");
|
|
110102
111421
|
import_promises5 = __toESM(require("fs/promises"), 1);
|
|
110103
|
-
|
|
111422
|
+
import_path17 = __toESM(require("path"), 1);
|
|
110104
111423
|
import_os5 = __toESM(require("os"), 1);
|
|
110105
111424
|
import_events3 = require("events");
|
|
110106
111425
|
init_built_in_server();
|
|
@@ -110116,7 +111435,7 @@ __export(codex_exports, {
|
|
|
110116
111435
|
async function createCodexEngine(options = {}) {
|
|
110117
111436
|
const { agent, systemPrompt, customPrompt, debug, sessionId, allowedTools, model } = options;
|
|
110118
111437
|
const session = new Session(
|
|
110119
|
-
sessionId || (0,
|
|
111438
|
+
sessionId || (0, import_crypto9.randomBytes)(8).toString("hex"),
|
|
110120
111439
|
debug
|
|
110121
111440
|
);
|
|
110122
111441
|
let mcpServer = null;
|
|
@@ -110158,12 +111477,12 @@ async function createCodexEngine(options = {}) {
|
|
|
110158
111477
|
}
|
|
110159
111478
|
}
|
|
110160
111479
|
if (message.id !== void 0 && pendingRequests.has(message.id)) {
|
|
110161
|
-
const { resolve:
|
|
111480
|
+
const { resolve: resolve8, reject: reject2 } = pendingRequests.get(message.id);
|
|
110162
111481
|
pendingRequests.delete(message.id);
|
|
110163
111482
|
if (message.error) {
|
|
110164
111483
|
reject2(new Error(message.error.message || JSON.stringify(message.error)));
|
|
110165
111484
|
} else {
|
|
110166
|
-
|
|
111485
|
+
resolve8(message.result);
|
|
110167
111486
|
}
|
|
110168
111487
|
}
|
|
110169
111488
|
if (message.method === "codex/event" && message.params) {
|
|
@@ -110184,7 +111503,7 @@ async function createCodexEngine(options = {}) {
|
|
|
110184
111503
|
});
|
|
110185
111504
|
}
|
|
110186
111505
|
function sendRequest(method, params = {}) {
|
|
110187
|
-
return new Promise((
|
|
111506
|
+
return new Promise((resolve8, reject2) => {
|
|
110188
111507
|
const id = ++requestId;
|
|
110189
111508
|
const request = {
|
|
110190
111509
|
jsonrpc: "2.0",
|
|
@@ -110192,7 +111511,7 @@ async function createCodexEngine(options = {}) {
|
|
|
110192
111511
|
method,
|
|
110193
111512
|
params
|
|
110194
111513
|
};
|
|
110195
|
-
pendingRequests.set(id, { resolve:
|
|
111514
|
+
pendingRequests.set(id, { resolve: resolve8, reject: reject2 });
|
|
110196
111515
|
setTimeout(() => {
|
|
110197
111516
|
if (pendingRequests.has(id)) {
|
|
110198
111517
|
pendingRequests.delete(id);
|
|
@@ -110255,7 +111574,7 @@ ${prompt}`;
|
|
|
110255
111574
|
const reqId = requestId + 1;
|
|
110256
111575
|
let fullResponse = "";
|
|
110257
111576
|
let gotSessionId = false;
|
|
110258
|
-
const eventPromise = new Promise((
|
|
111577
|
+
const eventPromise = new Promise((resolve8) => {
|
|
110259
111578
|
eventHandlers.set(reqId, (eventParams) => {
|
|
110260
111579
|
const msg = eventParams.msg;
|
|
110261
111580
|
if (msg.type === "session_configured" && msg.session_id && !gotSessionId) {
|
|
@@ -110275,7 +111594,7 @@ ${prompt}`;
|
|
|
110275
111594
|
});
|
|
110276
111595
|
setTimeout(() => {
|
|
110277
111596
|
eventHandlers.delete(reqId);
|
|
110278
|
-
|
|
111597
|
+
resolve8();
|
|
110279
111598
|
}, 6e5);
|
|
110280
111599
|
});
|
|
110281
111600
|
const resultPromise = sendRequest("tools/call", {
|
|
@@ -110371,12 +111690,12 @@ function combinePrompts2(systemPrompt, customPrompt, agent) {
|
|
|
110371
111690
|
}
|
|
110372
111691
|
return systemPrompt || "";
|
|
110373
111692
|
}
|
|
110374
|
-
var import_child_process10,
|
|
111693
|
+
var import_child_process10, import_crypto9, import_readline;
|
|
110375
111694
|
var init_codex = __esm({
|
|
110376
111695
|
"src/agent/engines/codex.js"() {
|
|
110377
111696
|
"use strict";
|
|
110378
111697
|
import_child_process10 = require("child_process");
|
|
110379
|
-
|
|
111698
|
+
import_crypto9 = require("crypto");
|
|
110380
111699
|
import_readline = require("readline");
|
|
110381
111700
|
init_built_in_server();
|
|
110382
111701
|
init_Session();
|
|
@@ -110482,7 +111801,7 @@ Your content here
|
|
|
110482
111801
|
|
|
110483
111802
|
Do NOT wrap in other tags like <api_call>, <tool_name>, <function>, etc.`;
|
|
110484
111803
|
}
|
|
110485
|
-
var import_dotenv2, import_anthropic2, import_openai2, import_google2, import_ai6,
|
|
111804
|
+
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;
|
|
110486
111805
|
var init_ProbeAgent = __esm({
|
|
110487
111806
|
"src/agent/ProbeAgent.js"() {
|
|
110488
111807
|
import_dotenv2 = __toESM(require_main(), 1);
|
|
@@ -110491,17 +111810,18 @@ var init_ProbeAgent = __esm({
|
|
|
110491
111810
|
import_google2 = require("@ai-sdk/google");
|
|
110492
111811
|
init_dist3();
|
|
110493
111812
|
import_ai6 = require("ai");
|
|
110494
|
-
|
|
111813
|
+
import_crypto10 = require("crypto");
|
|
110495
111814
|
import_events4 = require("events");
|
|
110496
111815
|
import_fs14 = require("fs");
|
|
110497
111816
|
import_promises6 = require("fs/promises");
|
|
110498
|
-
|
|
111817
|
+
import_path18 = require("path");
|
|
110499
111818
|
init_tokenCounter();
|
|
110500
111819
|
init_InMemoryStorageAdapter();
|
|
110501
111820
|
init_HookManager();
|
|
110502
111821
|
init_imageConfig();
|
|
110503
111822
|
init_tools2();
|
|
110504
111823
|
init_common2();
|
|
111824
|
+
init_fileTracker();
|
|
110505
111825
|
init_probeTool();
|
|
110506
111826
|
init_mockProvider();
|
|
110507
111827
|
init_index();
|
|
@@ -110543,7 +111863,7 @@ var init_ProbeAgent = __esm({
|
|
|
110543
111863
|
* @param {string} [options.customPrompt] - Custom prompt to replace the default system message
|
|
110544
111864
|
* @param {string} [options.systemPrompt] - Alias for customPrompt; takes precedence when both are provided
|
|
110545
111865
|
* @param {string} [options.promptType] - Predefined prompt type (code-explorer, code-searcher, architect, code-review, support)
|
|
110546
|
-
* @param {boolean} [options.allowEdit=false] - Allow the use of the '
|
|
111866
|
+
* @param {boolean} [options.allowEdit=false] - Allow the use of the 'edit' and 'create' tools
|
|
110547
111867
|
* @param {boolean} [options.enableDelegate=false] - Enable the delegate tool for task distribution to subagents
|
|
110548
111868
|
* @param {boolean} [options.enableExecutePlan=false] - Enable the execute_plan DSL orchestration tool
|
|
110549
111869
|
* @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)
|
|
@@ -110588,10 +111908,11 @@ var init_ProbeAgent = __esm({
|
|
|
110588
111908
|
* @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.
|
|
110589
111909
|
*/
|
|
110590
111910
|
constructor(options = {}) {
|
|
110591
|
-
this.sessionId = options.sessionId || (0,
|
|
111911
|
+
this.sessionId = options.sessionId || (0, import_crypto10.randomUUID)();
|
|
110592
111912
|
this.customPrompt = options.systemPrompt || options.customPrompt || null;
|
|
110593
111913
|
this.promptType = options.promptType || "code-explorer";
|
|
110594
111914
|
this.allowEdit = !!options.allowEdit;
|
|
111915
|
+
this.hashLines = options.hashLines !== void 0 ? !!options.hashLines : this.allowEdit;
|
|
110595
111916
|
this.enableDelegate = !!options.enableDelegate;
|
|
110596
111917
|
this.enableExecutePlan = !!options.enableExecutePlan;
|
|
110597
111918
|
this.debug = options.debug || process.env.DEBUG === "1";
|
|
@@ -110653,7 +111974,8 @@ var init_ProbeAgent = __esm({
|
|
|
110653
111974
|
if (this.debug) {
|
|
110654
111975
|
console.log(`[DEBUG] Generated session ID for agent: ${this.sessionId}`);
|
|
110655
111976
|
console.log(`[DEBUG] Maximum tool iterations configured: ${MAX_TOOL_ITERATIONS}`);
|
|
110656
|
-
console.log(`[DEBUG] Allow Edit
|
|
111977
|
+
console.log(`[DEBUG] Allow Edit: ${this.allowEdit}`);
|
|
111978
|
+
console.log(`[DEBUG] Hash Lines: ${this.hashLines}`);
|
|
110657
111979
|
console.log(`[DEBUG] Search delegation enabled: ${this.searchDelegate}`);
|
|
110658
111980
|
console.log(`[DEBUG] Workspace root: ${this.workspaceRoot}`);
|
|
110659
111981
|
console.log(`[DEBUG] Working directory (cwd): ${this.cwd}`);
|
|
@@ -111038,9 +112360,12 @@ var init_ProbeAgent = __esm({
|
|
|
111038
112360
|
cwd: this.cwd,
|
|
111039
112361
|
workspaceRoot: this.workspaceRoot,
|
|
111040
112362
|
allowedFolders: this.allowedFolders,
|
|
112363
|
+
// File state tracking for safe multi-edit workflows (only when editing is enabled)
|
|
112364
|
+
fileTracker: this.allowEdit ? new FileTracker({ debug: this.debug }) : null,
|
|
111041
112365
|
outline: this.outline,
|
|
111042
112366
|
searchDelegate: this.searchDelegate,
|
|
111043
112367
|
allowEdit: this.allowEdit,
|
|
112368
|
+
hashLines: this.hashLines,
|
|
111044
112369
|
enableDelegate: this.enableDelegate,
|
|
111045
112370
|
enableExecutePlan: this.enableExecutePlan,
|
|
111046
112371
|
enableBash: this.enableBash,
|
|
@@ -111111,7 +112436,7 @@ var init_ProbeAgent = __esm({
|
|
|
111111
112436
|
if (!imagePath) {
|
|
111112
112437
|
throw new Error("Image path is required");
|
|
111113
112438
|
}
|
|
111114
|
-
const filename = (0,
|
|
112439
|
+
const filename = (0, import_path18.basename)(imagePath);
|
|
111115
112440
|
const extension = filename.toLowerCase().split(".").pop();
|
|
111116
112441
|
if (!extension || !SUPPORTED_IMAGE_EXTENSIONS.includes(extension)) {
|
|
111117
112442
|
throw new Error(`Invalid or unsupported image extension: ${extension}. Supported formats: ${SUPPORTED_IMAGE_EXTENSIONS.join(", ")}`);
|
|
@@ -111825,7 +113150,7 @@ var init_ProbeAgent = __esm({
|
|
|
111825
113150
|
let resolvedPath2 = imagePath;
|
|
111826
113151
|
if (!imagePath.includes("/") && !imagePath.includes("\\")) {
|
|
111827
113152
|
for (const dir of listFilesDirectories) {
|
|
111828
|
-
const potentialPath = (0,
|
|
113153
|
+
const potentialPath = (0, import_path18.resolve)(dir, imagePath);
|
|
111829
113154
|
const loaded = await this.loadImageIfValid(potentialPath);
|
|
111830
113155
|
if (loaded) {
|
|
111831
113156
|
if (this.debug) {
|
|
@@ -111850,7 +113175,7 @@ var init_ProbeAgent = __esm({
|
|
|
111850
113175
|
let match2;
|
|
111851
113176
|
while ((match2 = fileHeaderPattern.exec(content)) !== null) {
|
|
111852
113177
|
const filePath = match2[1].trim();
|
|
111853
|
-
const dir = (0,
|
|
113178
|
+
const dir = (0, import_path18.dirname)(filePath);
|
|
111854
113179
|
if (dir && dir !== ".") {
|
|
111855
113180
|
directories.push(dir);
|
|
111856
113181
|
if (this.debug) {
|
|
@@ -111895,17 +113220,17 @@ var init_ProbeAgent = __esm({
|
|
|
111895
113220
|
const allowedDirs = this.allowedFolders && this.allowedFolders.length > 0 ? this.allowedFolders : [process.cwd()];
|
|
111896
113221
|
let absolutePath;
|
|
111897
113222
|
let isPathAllowed2 = false;
|
|
111898
|
-
if ((0,
|
|
111899
|
-
absolutePath = safeRealpath((0,
|
|
113223
|
+
if ((0, import_path18.isAbsolute)(imagePath)) {
|
|
113224
|
+
absolutePath = safeRealpath((0, import_path18.resolve)(imagePath));
|
|
111900
113225
|
isPathAllowed2 = allowedDirs.some((dir) => {
|
|
111901
113226
|
const resolvedDir = safeRealpath(dir);
|
|
111902
|
-
return absolutePath === resolvedDir || absolutePath.startsWith(resolvedDir +
|
|
113227
|
+
return absolutePath === resolvedDir || absolutePath.startsWith(resolvedDir + import_path18.sep);
|
|
111903
113228
|
});
|
|
111904
113229
|
} else {
|
|
111905
113230
|
for (const dir of allowedDirs) {
|
|
111906
113231
|
const resolvedDir = safeRealpath(dir);
|
|
111907
|
-
const resolvedPath2 = safeRealpath((0,
|
|
111908
|
-
if (resolvedPath2 === resolvedDir || resolvedPath2.startsWith(resolvedDir +
|
|
113232
|
+
const resolvedPath2 = safeRealpath((0, import_path18.resolve)(dir, imagePath));
|
|
113233
|
+
if (resolvedPath2 === resolvedDir || resolvedPath2.startsWith(resolvedDir + import_path18.sep)) {
|
|
111909
113234
|
absolutePath = resolvedPath2;
|
|
111910
113235
|
isPathAllowed2 = true;
|
|
111911
113236
|
break;
|
|
@@ -112093,8 +113418,8 @@ var init_ProbeAgent = __esm({
|
|
|
112093
113418
|
const hasConfiguredName = !!configuredName;
|
|
112094
113419
|
let guidanceCandidates = [];
|
|
112095
113420
|
if (hasConfiguredName) {
|
|
112096
|
-
const targetName = (0,
|
|
112097
|
-
if (configuredName !== targetName || configuredName.includes("/") || configuredName.includes("\\") || configuredName.includes("..") || (0,
|
|
113421
|
+
const targetName = (0, import_path18.basename)(configuredName);
|
|
113422
|
+
if (configuredName !== targetName || configuredName.includes("/") || configuredName.includes("\\") || configuredName.includes("..") || (0, import_path18.isAbsolute)(configuredName)) {
|
|
112098
113423
|
console.warn(`[WARN] Invalid architectureFileName (must be a simple filename): ${configuredName}`);
|
|
112099
113424
|
} else if (targetName) {
|
|
112100
113425
|
const targetLower = targetName.toLowerCase();
|
|
@@ -112161,7 +113486,7 @@ var init_ProbeAgent = __esm({
|
|
|
112161
113486
|
pushEntry(architectureMatch);
|
|
112162
113487
|
const contexts = [];
|
|
112163
113488
|
for (const entry of uniqueEntries) {
|
|
112164
|
-
const filePath = (0,
|
|
113489
|
+
const filePath = (0, import_path18.resolve)(rootDirectory, entry.name);
|
|
112165
113490
|
try {
|
|
112166
113491
|
const content = await (0, import_promises6.readFile)(filePath, "utf8");
|
|
112167
113492
|
let kind = "other";
|
|
@@ -112226,10 +113551,10 @@ ${this.architectureContext.content}
|
|
|
112226
113551
|
}
|
|
112227
113552
|
_getSkillsRepoRoot() {
|
|
112228
113553
|
if (this.workspaceRoot) {
|
|
112229
|
-
return (0,
|
|
113554
|
+
return (0, import_path18.resolve)(this.workspaceRoot);
|
|
112230
113555
|
}
|
|
112231
113556
|
if (this.allowedFolders && this.allowedFolders.length > 0) {
|
|
112232
|
-
return (0,
|
|
113557
|
+
return (0, import_path18.resolve)(this.allowedFolders[0]);
|
|
112233
113558
|
}
|
|
112234
113559
|
return process.cwd();
|
|
112235
113560
|
}
|
|
@@ -112418,10 +113743,6 @@ Workspace: ${this.allowedFolders.join(", ")}`;
|
|
|
112418
113743
|
}
|
|
112419
113744
|
if (isToolAllowed("readImage")) {
|
|
112420
113745
|
toolDefinitions += `${readImageToolDefinition}
|
|
112421
|
-
`;
|
|
112422
|
-
}
|
|
112423
|
-
if (this.allowEdit && isToolAllowed("implement")) {
|
|
112424
|
-
toolDefinitions += `${implementToolDefinition}
|
|
112425
113746
|
`;
|
|
112426
113747
|
}
|
|
112427
113748
|
if (this.allowEdit && isToolAllowed("edit")) {
|
|
@@ -112503,7 +113824,7 @@ The configuration is loaded from src/config.js lines 15-25 which contains the da
|
|
|
112503
113824
|
availableToolsList += "- query: Search code using structural AST patterns.\n";
|
|
112504
113825
|
}
|
|
112505
113826
|
if (isToolAllowed("extract")) {
|
|
112506
|
-
availableToolsList +=
|
|
113827
|
+
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';
|
|
112507
113828
|
}
|
|
112508
113829
|
if (isToolAllowed("listFiles")) {
|
|
112509
113830
|
availableToolsList += "- listFiles: List files and directories in a specified location.\n";
|
|
@@ -112520,11 +113841,8 @@ The configuration is loaded from src/config.js lines 15-25 which contains the da
|
|
|
112520
113841
|
if (isToolAllowed("readImage")) {
|
|
112521
113842
|
availableToolsList += "- readImage: Read and load an image file for AI analysis.\n";
|
|
112522
113843
|
}
|
|
112523
|
-
if (this.allowEdit && isToolAllowed("implement")) {
|
|
112524
|
-
availableToolsList += "- implement: Implement a feature or fix a bug using aider.\n";
|
|
112525
|
-
}
|
|
112526
113844
|
if (this.allowEdit && isToolAllowed("edit")) {
|
|
112527
|
-
availableToolsList += "- edit: Edit files using
|
|
113845
|
+
availableToolsList += "- edit: Edit files using text replacement, AST-aware symbol operations, or line-targeted editing.\n";
|
|
112528
113846
|
}
|
|
112529
113847
|
if (this.allowEdit && isToolAllowed("create")) {
|
|
112530
113848
|
availableToolsList += "- create: Create new files with specified content.\n";
|
|
@@ -112612,8 +113930,14 @@ Follow these instructions carefully:
|
|
|
112612
113930
|
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.
|
|
112613
113931
|
9. Prefer concise and focused search queries. Use specific keywords and phrases to narrow down results.${this.allowEdit ? `
|
|
112614
113932
|
10. When modifying files, choose the appropriate tool:
|
|
112615
|
-
- Use 'edit' for
|
|
112616
|
-
|
|
113933
|
+
- Use 'edit' for all code modifications:
|
|
113934
|
+
* For small changes (a line or a few lines), use old_string + new_string \u2014 copy old_string verbatim from the file.
|
|
113935
|
+
* For rewriting entire functions/classes/methods, use the symbol parameter instead (no exact text matching needed).
|
|
113936
|
+
* 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.' : ""}
|
|
113937
|
+
* 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.
|
|
113938
|
+
- Use 'create' for new files or complete file rewrites.
|
|
113939
|
+
- If an edit fails, read the error message \u2014 it tells you exactly how to fix the call and retry.
|
|
113940
|
+
- 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.` : ""}
|
|
112617
113941
|
</instructions>
|
|
112618
113942
|
`;
|
|
112619
113943
|
let systemMessage = "";
|
|
@@ -112839,8 +114163,8 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
112839
114163
|
let currentIteration = 0;
|
|
112840
114164
|
let completionAttempted = false;
|
|
112841
114165
|
let finalResult = "I was unable to complete your request due to reaching the maximum number of tool iterations.";
|
|
112842
|
-
const baseMaxIterations = this.maxIterations || MAX_TOOL_ITERATIONS;
|
|
112843
|
-
const maxIterations = options.schema ? baseMaxIterations + 4 : baseMaxIterations;
|
|
114166
|
+
const baseMaxIterations = options._maxIterationsOverride || this.maxIterations || MAX_TOOL_ITERATIONS;
|
|
114167
|
+
const maxIterations = options._maxIterationsOverride ? baseMaxIterations : options.schema ? baseMaxIterations + 4 : baseMaxIterations;
|
|
112844
114168
|
const isClaudeCode = this.clientApiProvider === "claude-code" || process.env.USE_CLAUDE_CODE === "true";
|
|
112845
114169
|
const isCodex = this.clientApiProvider === "codex" || process.env.USE_CODEX === "true";
|
|
112846
114170
|
if (isClaudeCode) {
|
|
@@ -113113,8 +114437,11 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
113113
114437
|
if (this.enableSkills && this.allowedTools.isEnabled("useSkill")) validTools.push("useSkill");
|
|
113114
114438
|
if (this.allowedTools.isEnabled("readImage")) validTools.push("readImage");
|
|
113115
114439
|
validTools.push("attempt_completion");
|
|
113116
|
-
if (this.allowEdit && this.allowedTools.isEnabled("
|
|
113117
|
-
validTools.push("
|
|
114440
|
+
if (this.allowEdit && this.allowedTools.isEnabled("edit")) {
|
|
114441
|
+
validTools.push("edit");
|
|
114442
|
+
}
|
|
114443
|
+
if (this.allowEdit && this.allowedTools.isEnabled("create")) {
|
|
114444
|
+
validTools.push("create");
|
|
113118
114445
|
}
|
|
113119
114446
|
if (this.enableBash && this.allowedTools.isEnabled("bash")) {
|
|
113120
114447
|
validTools.push("bash");
|
|
@@ -113336,10 +114663,10 @@ ${errorXml}
|
|
|
113336
114663
|
try {
|
|
113337
114664
|
let resolvedWorkingDirectory = this.workspaceRoot || this.cwd || this.allowedFolders && this.allowedFolders[0] || process.cwd();
|
|
113338
114665
|
if (params.workingDirectory) {
|
|
113339
|
-
const requestedDir = safeRealpath((0,
|
|
114666
|
+
const requestedDir = safeRealpath((0, import_path18.isAbsolute)(params.workingDirectory) ? (0, import_path18.resolve)(params.workingDirectory) : (0, import_path18.resolve)(resolvedWorkingDirectory, params.workingDirectory));
|
|
113340
114667
|
const isWithinAllowed = !this.allowedFolders || this.allowedFolders.length === 0 || this.allowedFolders.some((folder) => {
|
|
113341
114668
|
const resolvedFolder = safeRealpath(folder);
|
|
113342
|
-
return requestedDir === resolvedFolder || requestedDir.startsWith(resolvedFolder +
|
|
114669
|
+
return requestedDir === resolvedFolder || requestedDir.startsWith(resolvedFolder + import_path18.sep);
|
|
113343
114670
|
});
|
|
113344
114671
|
if (isWithinAllowed) {
|
|
113345
114672
|
resolvedWorkingDirectory = requestedDir;
|
|
@@ -113407,6 +114734,8 @@ ${errorXml}
|
|
|
113407
114734
|
// Inherit bash enablement
|
|
113408
114735
|
bashConfig: this.bashConfig,
|
|
113409
114736
|
// Inherit bash configuration
|
|
114737
|
+
allowEdit: this.allowEdit,
|
|
114738
|
+
// Inherit edit/create permission
|
|
113410
114739
|
allowedTools: allowedToolsForDelegate,
|
|
113411
114740
|
// Inherit allowed tools from parent
|
|
113412
114741
|
debug: this.debug,
|
|
@@ -113479,7 +114808,7 @@ ${errorXml}
|
|
|
113479
114808
|
currentMessages.push({ role: "assistant", content: assistantResponseContent });
|
|
113480
114809
|
let toolResultContent = typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult, null, 2);
|
|
113481
114810
|
if (this.workspaceRoot && toolResultContent) {
|
|
113482
|
-
const wsPrefix = this.workspaceRoot.endsWith(
|
|
114811
|
+
const wsPrefix = this.workspaceRoot.endsWith(import_path18.sep) ? this.workspaceRoot : this.workspaceRoot + import_path18.sep;
|
|
113483
114812
|
toolResultContent = toolResultContent.split(wsPrefix).join("");
|
|
113484
114813
|
}
|
|
113485
114814
|
const { cleanedContent, extractedBlocks } = extractRawOutputBlocks(toolResultContent);
|
|
@@ -114072,13 +115401,16 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
114072
115401
|
options.schema,
|
|
114073
115402
|
0
|
|
114074
115403
|
);
|
|
115404
|
+
const { schema: _unusedSchema1, ...schemaDefCorrectionOptions } = options;
|
|
114075
115405
|
finalResult = await this.answer(schemaDefinitionPrompt, [], {
|
|
114076
|
-
...
|
|
115406
|
+
...schemaDefCorrectionOptions,
|
|
114077
115407
|
_schemaFormatted: true,
|
|
114078
115408
|
_skipValidation: true,
|
|
114079
115409
|
// Skip validation in recursive correction calls to prevent loops
|
|
114080
|
-
_completionPromptProcessed: true
|
|
115410
|
+
_completionPromptProcessed: true,
|
|
114081
115411
|
// Prevent cascading completion prompts in retry calls
|
|
115412
|
+
_maxIterationsOverride: 3
|
|
115413
|
+
// Correction should complete in 1-2 iterations (issue #447)
|
|
114082
115414
|
});
|
|
114083
115415
|
finalResult = cleanSchemaResponse(finalResult);
|
|
114084
115416
|
validation = validateJsonResponse(finalResult);
|
|
@@ -114126,15 +115458,18 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
114126
115458
|
retryCount
|
|
114127
115459
|
);
|
|
114128
115460
|
}
|
|
115461
|
+
const { schema: _unusedSchema2, ...correctionOptions } = options;
|
|
114129
115462
|
finalResult = await this.answer(correctionPrompt, [], {
|
|
114130
|
-
...
|
|
115463
|
+
...correctionOptions,
|
|
114131
115464
|
_schemaFormatted: true,
|
|
114132
115465
|
_skipValidation: true,
|
|
114133
115466
|
// Skip validation in recursive correction calls to prevent loops
|
|
114134
115467
|
_disableTools: true,
|
|
114135
115468
|
// Only allow attempt_completion - prevent AI from using search/query tools
|
|
114136
|
-
_completionPromptProcessed: true
|
|
115469
|
+
_completionPromptProcessed: true,
|
|
114137
115470
|
// Prevent cascading completion prompts in retry calls
|
|
115471
|
+
_maxIterationsOverride: 3
|
|
115472
|
+
// Correction should complete in 1-2 iterations (issue #447)
|
|
114138
115473
|
});
|
|
114139
115474
|
finalResult = cleanSchemaResponse(finalResult);
|
|
114140
115475
|
validation = validateJsonResponse(finalResult, { debug: this.debug });
|
|
@@ -114329,7 +115664,7 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
114329
115664
|
*/
|
|
114330
115665
|
clone(options = {}) {
|
|
114331
115666
|
const {
|
|
114332
|
-
sessionId = (0,
|
|
115667
|
+
sessionId = (0, import_crypto10.randomUUID)(),
|
|
114333
115668
|
stripInternalMessages = true,
|
|
114334
115669
|
keepSystemMessage = true,
|
|
114335
115670
|
deepCopy = true,
|