@probelabs/probe 0.6.0-rc104 → 0.6.0-rc106
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/build/agent/ProbeAgent.js +12 -1
- package/build/agent/bashCommandUtils.js +200 -0
- package/build/agent/bashDefaults.js +202 -0
- package/build/agent/bashExecutor.js +319 -0
- package/build/agent/bashPermissions.js +228 -0
- package/build/agent/index.js +1551 -167
- package/build/agent/mcp/xmlBridge.js +34 -6
- package/build/agent/probeTool.js +9 -0
- package/build/agent/schemaUtils.js +28 -8
- package/build/agent/tools.js +22 -76
- package/build/agent/xmlParsingUtils.js +118 -0
- package/build/index.js +6 -0
- package/build/tools/bash.js +216 -0
- package/build/tools/common.js +64 -0
- package/build/tools/index.js +6 -0
- package/cjs/agent/ProbeAgent.cjs +1506 -188
- package/cjs/index.cjs +1581 -197
- package/package.json +2 -2
- package/src/agent/ProbeAgent.js +12 -1
- package/src/agent/bashCommandUtils.js +200 -0
- package/src/agent/bashDefaults.js +202 -0
- package/src/agent/bashExecutor.js +319 -0
- package/src/agent/bashPermissions.js +228 -0
- package/src/agent/index.js +83 -2
- package/src/agent/mcp/xmlBridge.js +34 -6
- package/src/agent/probeTool.js +9 -0
- package/src/agent/schemaUtils.js +28 -8
- package/src/agent/tools.js +22 -76
- package/src/agent/xmlParsingUtils.js +118 -0
- package/src/index.js +6 -0
- package/src/tools/bash.js +216 -0
- package/src/tools/common.js +64 -0
- package/src/tools/index.js +6 -0
package/build/agent/index.js
CHANGED
|
@@ -2190,7 +2190,7 @@ var require_headStream = __commonJS({
|
|
|
2190
2190
|
if ((0, stream_type_check_1.isReadableStream)(stream)) {
|
|
2191
2191
|
return (0, headStream_browser_1.headStream)(stream, bytes);
|
|
2192
2192
|
}
|
|
2193
|
-
return new Promise((
|
|
2193
|
+
return new Promise((resolve5, reject) => {
|
|
2194
2194
|
const collector = new Collector();
|
|
2195
2195
|
collector.limit = bytes;
|
|
2196
2196
|
stream.pipe(collector);
|
|
@@ -2201,7 +2201,7 @@ var require_headStream = __commonJS({
|
|
|
2201
2201
|
collector.on("error", reject);
|
|
2202
2202
|
collector.on("finish", function() {
|
|
2203
2203
|
const bytes2 = new Uint8Array(Buffer.concat(this.buffers));
|
|
2204
|
-
|
|
2204
|
+
resolve5(bytes2);
|
|
2205
2205
|
});
|
|
2206
2206
|
});
|
|
2207
2207
|
};
|
|
@@ -2459,21 +2459,21 @@ var require_dist_cjs15 = __commonJS({
|
|
|
2459
2459
|
let sendBody = true;
|
|
2460
2460
|
if (expect === "100-continue") {
|
|
2461
2461
|
sendBody = await Promise.race([
|
|
2462
|
-
new Promise((
|
|
2463
|
-
timeoutId = Number(timing.setTimeout(() =>
|
|
2462
|
+
new Promise((resolve5) => {
|
|
2463
|
+
timeoutId = Number(timing.setTimeout(() => resolve5(true), Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
|
|
2464
2464
|
}),
|
|
2465
|
-
new Promise((
|
|
2465
|
+
new Promise((resolve5) => {
|
|
2466
2466
|
httpRequest.on("continue", () => {
|
|
2467
2467
|
timing.clearTimeout(timeoutId);
|
|
2468
|
-
|
|
2468
|
+
resolve5(true);
|
|
2469
2469
|
});
|
|
2470
2470
|
httpRequest.on("response", () => {
|
|
2471
2471
|
timing.clearTimeout(timeoutId);
|
|
2472
|
-
|
|
2472
|
+
resolve5(false);
|
|
2473
2473
|
});
|
|
2474
2474
|
httpRequest.on("error", () => {
|
|
2475
2475
|
timing.clearTimeout(timeoutId);
|
|
2476
|
-
|
|
2476
|
+
resolve5(false);
|
|
2477
2477
|
});
|
|
2478
2478
|
})
|
|
2479
2479
|
]);
|
|
@@ -2509,13 +2509,13 @@ var require_dist_cjs15 = __commonJS({
|
|
|
2509
2509
|
constructor(options) {
|
|
2510
2510
|
this.socketWarningTimestamp = 0;
|
|
2511
2511
|
this.metadata = { handlerProtocol: "http/1.1" };
|
|
2512
|
-
this.configProvider = new Promise((
|
|
2512
|
+
this.configProvider = new Promise((resolve5, reject) => {
|
|
2513
2513
|
if (typeof options === "function") {
|
|
2514
2514
|
options().then((_options) => {
|
|
2515
|
-
|
|
2515
|
+
resolve5(this.resolveDefaultConfig(_options));
|
|
2516
2516
|
}).catch(reject);
|
|
2517
2517
|
} else {
|
|
2518
|
-
|
|
2518
|
+
resolve5(this.resolveDefaultConfig(options));
|
|
2519
2519
|
}
|
|
2520
2520
|
});
|
|
2521
2521
|
}
|
|
@@ -2599,7 +2599,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2599
2599
|
return new Promise((_resolve, _reject) => {
|
|
2600
2600
|
let writeRequestBodyPromise = void 0;
|
|
2601
2601
|
const timeouts = [];
|
|
2602
|
-
const
|
|
2602
|
+
const resolve5 = /* @__PURE__ */ __name(async (arg) => {
|
|
2603
2603
|
await writeRequestBodyPromise;
|
|
2604
2604
|
timeouts.forEach(timing.clearTimeout);
|
|
2605
2605
|
_resolve(arg);
|
|
@@ -2669,7 +2669,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2669
2669
|
headers: getTransformedHeaders(res.headers),
|
|
2670
2670
|
body: res
|
|
2671
2671
|
});
|
|
2672
|
-
|
|
2672
|
+
resolve5({ response: httpResponse });
|
|
2673
2673
|
});
|
|
2674
2674
|
req.on("error", (err) => {
|
|
2675
2675
|
if (NODEJS_TIMEOUT_ERROR_CODES.includes(err.code)) {
|
|
@@ -2858,13 +2858,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2858
2858
|
constructor(options) {
|
|
2859
2859
|
this.metadata = { handlerProtocol: "h2" };
|
|
2860
2860
|
this.connectionManager = new NodeHttp2ConnectionManager({});
|
|
2861
|
-
this.configProvider = new Promise((
|
|
2861
|
+
this.configProvider = new Promise((resolve5, reject) => {
|
|
2862
2862
|
if (typeof options === "function") {
|
|
2863
2863
|
options().then((opts) => {
|
|
2864
|
-
|
|
2864
|
+
resolve5(opts || {});
|
|
2865
2865
|
}).catch(reject);
|
|
2866
2866
|
} else {
|
|
2867
|
-
|
|
2867
|
+
resolve5(options || {});
|
|
2868
2868
|
}
|
|
2869
2869
|
});
|
|
2870
2870
|
}
|
|
@@ -2897,7 +2897,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2897
2897
|
return new Promise((_resolve, _reject) => {
|
|
2898
2898
|
let fulfilled = false;
|
|
2899
2899
|
let writeRequestBodyPromise = void 0;
|
|
2900
|
-
const
|
|
2900
|
+
const resolve5 = /* @__PURE__ */ __name(async (arg) => {
|
|
2901
2901
|
await writeRequestBodyPromise;
|
|
2902
2902
|
_resolve(arg);
|
|
2903
2903
|
}, "resolve");
|
|
@@ -2953,7 +2953,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2953
2953
|
body: req
|
|
2954
2954
|
});
|
|
2955
2955
|
fulfilled = true;
|
|
2956
|
-
|
|
2956
|
+
resolve5({ response: httpResponse });
|
|
2957
2957
|
if (disableConcurrentStreams) {
|
|
2958
2958
|
session.close();
|
|
2959
2959
|
this.connectionManager.deleteSession(authority, session);
|
|
@@ -3042,7 +3042,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
3042
3042
|
if (isReadableStreamInstance(stream)) {
|
|
3043
3043
|
return collectReadableStream(stream);
|
|
3044
3044
|
}
|
|
3045
|
-
return new Promise((
|
|
3045
|
+
return new Promise((resolve5, reject) => {
|
|
3046
3046
|
const collector = new Collector();
|
|
3047
3047
|
stream.pipe(collector);
|
|
3048
3048
|
stream.on("error", (err) => {
|
|
@@ -3052,7 +3052,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
3052
3052
|
collector.on("error", reject);
|
|
3053
3053
|
collector.on("finish", function() {
|
|
3054
3054
|
const bytes = new Uint8Array(Buffer.concat(this.bufferedBytes));
|
|
3055
|
-
|
|
3055
|
+
resolve5(bytes);
|
|
3056
3056
|
});
|
|
3057
3057
|
});
|
|
3058
3058
|
}, "streamCollector");
|
|
@@ -3117,7 +3117,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
3117
3117
|
}
|
|
3118
3118
|
__name(createRequest, "createRequest");
|
|
3119
3119
|
function requestTimeout(timeoutInMs = 0) {
|
|
3120
|
-
return new Promise((
|
|
3120
|
+
return new Promise((resolve5, reject) => {
|
|
3121
3121
|
if (timeoutInMs) {
|
|
3122
3122
|
setTimeout(() => {
|
|
3123
3123
|
const timeoutError = new Error(`Request did not complete within ${timeoutInMs} ms`);
|
|
@@ -3244,7 +3244,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
3244
3244
|
];
|
|
3245
3245
|
if (abortSignal) {
|
|
3246
3246
|
raceOfPromises.push(
|
|
3247
|
-
new Promise((
|
|
3247
|
+
new Promise((resolve5, reject) => {
|
|
3248
3248
|
const onAbort = /* @__PURE__ */ __name(() => {
|
|
3249
3249
|
const abortError = new Error("Request aborted");
|
|
3250
3250
|
abortError.name = "AbortError";
|
|
@@ -3312,7 +3312,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
3312
3312
|
}
|
|
3313
3313
|
__name(collectStream, "collectStream");
|
|
3314
3314
|
function readToBase64(blob) {
|
|
3315
|
-
return new Promise((
|
|
3315
|
+
return new Promise((resolve5, reject) => {
|
|
3316
3316
|
const reader = new FileReader();
|
|
3317
3317
|
reader.onloadend = () => {
|
|
3318
3318
|
if (reader.readyState !== 2) {
|
|
@@ -3321,7 +3321,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
3321
3321
|
const result = reader.result ?? "";
|
|
3322
3322
|
const commaIndex = result.indexOf(",");
|
|
3323
3323
|
const dataOffset = commaIndex > -1 ? commaIndex + 1 : result.length;
|
|
3324
|
-
|
|
3324
|
+
resolve5(result.substring(dataOffset));
|
|
3325
3325
|
};
|
|
3326
3326
|
reader.onabort = () => reject(new Error("Read aborted"));
|
|
3327
3327
|
reader.onerror = () => reject(reader.error);
|
|
@@ -3808,9 +3808,10 @@ var TypeRegistry;
|
|
|
3808
3808
|
var init_TypeRegistry = __esm({
|
|
3809
3809
|
"node_modules/@smithy/core/dist-es/submodules/schema/TypeRegistry.js"() {
|
|
3810
3810
|
TypeRegistry = class _TypeRegistry {
|
|
3811
|
-
constructor(namespace, schemas = /* @__PURE__ */ new Map()) {
|
|
3811
|
+
constructor(namespace, schemas = /* @__PURE__ */ new Map(), exceptions = /* @__PURE__ */ new Map()) {
|
|
3812
3812
|
this.namespace = namespace;
|
|
3813
3813
|
this.schemas = schemas;
|
|
3814
|
+
this.exceptions = exceptions;
|
|
3814
3815
|
}
|
|
3815
3816
|
static for(namespace) {
|
|
3816
3817
|
if (!_TypeRegistry.registries.has(namespace)) {
|
|
@@ -3820,8 +3821,7 @@ var init_TypeRegistry = __esm({
|
|
|
3820
3821
|
}
|
|
3821
3822
|
register(shapeId, schema) {
|
|
3822
3823
|
const qualifiedName = this.normalizeShapeId(shapeId);
|
|
3823
|
-
|
|
3824
|
-
registry.schemas.set(qualifiedName, schema);
|
|
3824
|
+
this.schemas.set(qualifiedName, schema);
|
|
3825
3825
|
}
|
|
3826
3826
|
getSchema(shapeId) {
|
|
3827
3827
|
const id = this.normalizeShapeId(shapeId);
|
|
@@ -3830,6 +3830,12 @@ var init_TypeRegistry = __esm({
|
|
|
3830
3830
|
}
|
|
3831
3831
|
return this.schemas.get(id);
|
|
3832
3832
|
}
|
|
3833
|
+
registerError(errorSchema, ctor) {
|
|
3834
|
+
this.exceptions.set(errorSchema, ctor);
|
|
3835
|
+
}
|
|
3836
|
+
getErrorCtor(errorSchema) {
|
|
3837
|
+
return this.exceptions.get(errorSchema);
|
|
3838
|
+
}
|
|
3833
3839
|
getBaseException() {
|
|
3834
3840
|
for (const [id, schema] of this.schemas.entries()) {
|
|
3835
3841
|
if (id.startsWith("smithy.ts.sdk.synthetic.") && id.endsWith("ServiceException")) {
|
|
@@ -3841,9 +3847,9 @@ var init_TypeRegistry = __esm({
|
|
|
3841
3847
|
find(predicate) {
|
|
3842
3848
|
return [...this.schemas.values()].find(predicate);
|
|
3843
3849
|
}
|
|
3844
|
-
|
|
3845
|
-
_TypeRegistry.registries.delete(this.namespace);
|
|
3850
|
+
clear() {
|
|
3846
3851
|
this.schemas.clear();
|
|
3852
|
+
this.exceptions.clear();
|
|
3847
3853
|
}
|
|
3848
3854
|
normalizeShapeId(shapeId) {
|
|
3849
3855
|
if (shapeId.includes("#")) {
|
|
@@ -3991,7 +3997,7 @@ var init_ErrorSchema = __esm({
|
|
|
3991
3997
|
traits,
|
|
3992
3998
|
memberNames,
|
|
3993
3999
|
memberList,
|
|
3994
|
-
ctor
|
|
4000
|
+
ctor: null
|
|
3995
4001
|
});
|
|
3996
4002
|
}
|
|
3997
4003
|
});
|
|
@@ -4960,11 +4966,11 @@ function __metadata(metadataKey, metadataValue) {
|
|
|
4960
4966
|
}
|
|
4961
4967
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
4962
4968
|
function adopt(value) {
|
|
4963
|
-
return value instanceof P ? value : new P(function(
|
|
4964
|
-
|
|
4969
|
+
return value instanceof P ? value : new P(function(resolve5) {
|
|
4970
|
+
resolve5(value);
|
|
4965
4971
|
});
|
|
4966
4972
|
}
|
|
4967
|
-
return new (P || (P = Promise))(function(
|
|
4973
|
+
return new (P || (P = Promise))(function(resolve5, reject) {
|
|
4968
4974
|
function fulfilled(value) {
|
|
4969
4975
|
try {
|
|
4970
4976
|
step(generator.next(value));
|
|
@@ -4980,7 +4986,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
4980
4986
|
}
|
|
4981
4987
|
}
|
|
4982
4988
|
function step(result) {
|
|
4983
|
-
result.done ?
|
|
4989
|
+
result.done ? resolve5(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
4984
4990
|
}
|
|
4985
4991
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
4986
4992
|
});
|
|
@@ -5171,14 +5177,14 @@ function __asyncValues(o3) {
|
|
|
5171
5177
|
}, i3);
|
|
5172
5178
|
function verb(n3) {
|
|
5173
5179
|
i3[n3] = o3[n3] && function(v3) {
|
|
5174
|
-
return new Promise(function(
|
|
5175
|
-
v3 = o3[n3](v3), settle(
|
|
5180
|
+
return new Promise(function(resolve5, reject) {
|
|
5181
|
+
v3 = o3[n3](v3), settle(resolve5, reject, v3.done, v3.value);
|
|
5176
5182
|
});
|
|
5177
5183
|
};
|
|
5178
5184
|
}
|
|
5179
|
-
function settle(
|
|
5185
|
+
function settle(resolve5, reject, d3, v3) {
|
|
5180
5186
|
Promise.resolve(v3).then(function(v4) {
|
|
5181
|
-
|
|
5187
|
+
resolve5({ value: v4, done: d3 });
|
|
5182
5188
|
}, reject);
|
|
5183
5189
|
}
|
|
5184
5190
|
}
|
|
@@ -10149,16 +10155,18 @@ var init_SmithyRpcV2CborProtocol = __esm({
|
|
|
10149
10155
|
if (dataObject.Message) {
|
|
10150
10156
|
dataObject.message = dataObject.Message;
|
|
10151
10157
|
}
|
|
10152
|
-
const
|
|
10158
|
+
const synthetic = TypeRegistry.for("smithy.ts.sdk.synthetic." + namespace);
|
|
10159
|
+
const baseExceptionSchema = synthetic.getBaseException();
|
|
10153
10160
|
if (baseExceptionSchema) {
|
|
10154
|
-
const
|
|
10155
|
-
throw Object.assign(new
|
|
10161
|
+
const ErrorCtor2 = synthetic.getErrorCtor(baseExceptionSchema);
|
|
10162
|
+
throw Object.assign(new ErrorCtor2({ name: errorName }), errorMetadata, dataObject);
|
|
10156
10163
|
}
|
|
10157
10164
|
throw Object.assign(new Error(errorName), errorMetadata, dataObject);
|
|
10158
10165
|
}
|
|
10159
10166
|
const ns = NormalizedSchema.of(errorSchema);
|
|
10167
|
+
const ErrorCtor = registry.getErrorCtor(errorSchema);
|
|
10160
10168
|
const message = dataObject.message ?? dataObject.Message ?? "Unknown";
|
|
10161
|
-
const exception = new
|
|
10169
|
+
const exception = new ErrorCtor(message);
|
|
10162
10170
|
const output = {};
|
|
10163
10171
|
for (const [name14, member] of ns.structIterator()) {
|
|
10164
10172
|
output[name14] = this.deserializer.readValue(member, dataObject[name14]);
|
|
@@ -15824,7 +15832,7 @@ var require_dist_cjs37 = __commonJS({
|
|
|
15824
15832
|
);
|
|
15825
15833
|
}
|
|
15826
15834
|
waitForReady(socket, connectionTimeout) {
|
|
15827
|
-
return new Promise((
|
|
15835
|
+
return new Promise((resolve5, reject) => {
|
|
15828
15836
|
const timeout = setTimeout(() => {
|
|
15829
15837
|
this.removeNotUsableSockets(socket.url);
|
|
15830
15838
|
reject({
|
|
@@ -15835,7 +15843,7 @@ var require_dist_cjs37 = __commonJS({
|
|
|
15835
15843
|
}, connectionTimeout);
|
|
15836
15844
|
socket.onopen = () => {
|
|
15837
15845
|
clearTimeout(timeout);
|
|
15838
|
-
|
|
15846
|
+
resolve5();
|
|
15839
15847
|
};
|
|
15840
15848
|
});
|
|
15841
15849
|
}
|
|
@@ -15844,10 +15852,10 @@ var require_dist_cjs37 = __commonJS({
|
|
|
15844
15852
|
let socketErrorOccurred = false;
|
|
15845
15853
|
let reject = /* @__PURE__ */ __name(() => {
|
|
15846
15854
|
}, "reject");
|
|
15847
|
-
let
|
|
15855
|
+
let resolve5 = /* @__PURE__ */ __name(() => {
|
|
15848
15856
|
}, "resolve");
|
|
15849
15857
|
socket.onmessage = (event) => {
|
|
15850
|
-
|
|
15858
|
+
resolve5({
|
|
15851
15859
|
done: false,
|
|
15852
15860
|
value: new Uint8Array(event.data)
|
|
15853
15861
|
});
|
|
@@ -15863,7 +15871,7 @@ var require_dist_cjs37 = __commonJS({
|
|
|
15863
15871
|
if (streamError) {
|
|
15864
15872
|
reject(streamError);
|
|
15865
15873
|
} else {
|
|
15866
|
-
|
|
15874
|
+
resolve5({
|
|
15867
15875
|
done: true,
|
|
15868
15876
|
value: void 0
|
|
15869
15877
|
// unchecked because done=true.
|
|
@@ -15874,7 +15882,7 @@ var require_dist_cjs37 = __commonJS({
|
|
|
15874
15882
|
[Symbol.asyncIterator]: () => ({
|
|
15875
15883
|
next: /* @__PURE__ */ __name(() => {
|
|
15876
15884
|
return new Promise((_resolve, _reject) => {
|
|
15877
|
-
|
|
15885
|
+
resolve5 = _resolve;
|
|
15878
15886
|
reject = _reject;
|
|
15879
15887
|
});
|
|
15880
15888
|
}, "next")
|
|
@@ -16397,13 +16405,13 @@ var require_dist_cjs42 = __commonJS({
|
|
|
16397
16405
|
...data2.default && { default: data2.default }
|
|
16398
16406
|
}
|
|
16399
16407
|
), "getConfigData");
|
|
16400
|
-
var
|
|
16408
|
+
var import_path12 = __require("path");
|
|
16401
16409
|
var import_getHomeDir = require_getHomeDir();
|
|
16402
16410
|
var ENV_CONFIG_PATH = "AWS_CONFIG_FILE";
|
|
16403
|
-
var getConfigFilepath = /* @__PURE__ */ __name(() => process.env[ENV_CONFIG_PATH] || (0,
|
|
16411
|
+
var getConfigFilepath = /* @__PURE__ */ __name(() => process.env[ENV_CONFIG_PATH] || (0, import_path12.join)((0, import_getHomeDir.getHomeDir)(), ".aws", "config"), "getConfigFilepath");
|
|
16404
16412
|
var import_getHomeDir2 = require_getHomeDir();
|
|
16405
16413
|
var ENV_CREDENTIALS_PATH = "AWS_SHARED_CREDENTIALS_FILE";
|
|
16406
|
-
var getCredentialsFilepath = /* @__PURE__ */ __name(() => process.env[ENV_CREDENTIALS_PATH] || (0,
|
|
16414
|
+
var getCredentialsFilepath = /* @__PURE__ */ __name(() => process.env[ENV_CREDENTIALS_PATH] || (0, import_path12.join)((0, import_getHomeDir2.getHomeDir)(), ".aws", "credentials"), "getCredentialsFilepath");
|
|
16407
16415
|
var import_getHomeDir3 = require_getHomeDir();
|
|
16408
16416
|
var prefixKeyRegex = /^([\w-]+)\s(["'])?([\w-@\+\.%:/]+)\2$/;
|
|
16409
16417
|
var profileNameBlockList = ["__proto__", "profile __proto__"];
|
|
@@ -16461,11 +16469,11 @@ var require_dist_cjs42 = __commonJS({
|
|
|
16461
16469
|
const relativeHomeDirPrefix = "~/";
|
|
16462
16470
|
let resolvedFilepath = filepath;
|
|
16463
16471
|
if (filepath.startsWith(relativeHomeDirPrefix)) {
|
|
16464
|
-
resolvedFilepath = (0,
|
|
16472
|
+
resolvedFilepath = (0, import_path12.join)(homeDir, filepath.slice(2));
|
|
16465
16473
|
}
|
|
16466
16474
|
let resolvedConfigFilepath = configFilepath;
|
|
16467
16475
|
if (configFilepath.startsWith(relativeHomeDirPrefix)) {
|
|
16468
|
-
resolvedConfigFilepath = (0,
|
|
16476
|
+
resolvedConfigFilepath = (0, import_path12.join)(homeDir, configFilepath.slice(2));
|
|
16469
16477
|
}
|
|
16470
16478
|
const parsedFiles = await Promise.all([
|
|
16471
16479
|
(0, import_slurpFile.slurpFile)(resolvedConfigFilepath, {
|
|
@@ -17120,7 +17128,7 @@ var require_dist_cjs46 = __commonJS({
|
|
|
17120
17128
|
this.refillTokenBucket();
|
|
17121
17129
|
if (amount > this.currentCapacity) {
|
|
17122
17130
|
const delay = (amount - this.currentCapacity) / this.fillRate * 1e3;
|
|
17123
|
-
await new Promise((
|
|
17131
|
+
await new Promise((resolve5) => _DefaultRateLimiter.setTimeoutFn(resolve5, delay));
|
|
17124
17132
|
}
|
|
17125
17133
|
this.currentCapacity = this.currentCapacity - amount;
|
|
17126
17134
|
}
|
|
@@ -17511,7 +17519,7 @@ var require_dist_cjs47 = __commonJS({
|
|
|
17511
17519
|
const delayFromResponse = getDelayFromRetryAfterHeader(err.$response);
|
|
17512
17520
|
const delay = Math.max(delayFromResponse || 0, delayFromDecider);
|
|
17513
17521
|
totalDelay += delay;
|
|
17514
|
-
await new Promise((
|
|
17522
|
+
await new Promise((resolve5) => setTimeout(resolve5, delay));
|
|
17515
17523
|
continue;
|
|
17516
17524
|
}
|
|
17517
17525
|
if (!err.$metadata) {
|
|
@@ -17671,7 +17679,7 @@ var require_dist_cjs47 = __commonJS({
|
|
|
17671
17679
|
attempts = retryToken.getRetryCount();
|
|
17672
17680
|
const delay = retryToken.getRetryDelay();
|
|
17673
17681
|
totalRetryDelay += delay;
|
|
17674
|
-
await new Promise((
|
|
17682
|
+
await new Promise((resolve5) => setTimeout(resolve5, delay));
|
|
17675
17683
|
}
|
|
17676
17684
|
}
|
|
17677
17685
|
} else {
|
|
@@ -18014,7 +18022,7 @@ var require_dist_cjs49 = __commonJS({
|
|
|
18014
18022
|
var import_buffer = __require("buffer");
|
|
18015
18023
|
var import_http = __require("http");
|
|
18016
18024
|
function httpRequest(options) {
|
|
18017
|
-
return new Promise((
|
|
18025
|
+
return new Promise((resolve5, reject) => {
|
|
18018
18026
|
const req = (0, import_http.request)({
|
|
18019
18027
|
method: "GET",
|
|
18020
18028
|
...options,
|
|
@@ -18043,7 +18051,7 @@ var require_dist_cjs49 = __commonJS({
|
|
|
18043
18051
|
chunks.push(chunk);
|
|
18044
18052
|
});
|
|
18045
18053
|
res.on("end", () => {
|
|
18046
|
-
|
|
18054
|
+
resolve5(import_buffer.Buffer.concat(chunks));
|
|
18047
18055
|
req.destroy();
|
|
18048
18056
|
});
|
|
18049
18057
|
});
|
|
@@ -18478,7 +18486,7 @@ var require_retry_wrapper = __commonJS({
|
|
|
18478
18486
|
try {
|
|
18479
18487
|
return await toRetry();
|
|
18480
18488
|
} catch (e3) {
|
|
18481
|
-
await new Promise((
|
|
18489
|
+
await new Promise((resolve5) => setTimeout(resolve5, delayMs));
|
|
18482
18490
|
}
|
|
18483
18491
|
}
|
|
18484
18492
|
return await toRetry();
|
|
@@ -18922,7 +18930,7 @@ var require_dist_cjs53 = __commonJS({
|
|
|
18922
18930
|
calculateBodyLength: () => calculateBodyLength3
|
|
18923
18931
|
});
|
|
18924
18932
|
module.exports = __toCommonJS2(index_exports);
|
|
18925
|
-
var
|
|
18933
|
+
var import_fs9 = __require("fs");
|
|
18926
18934
|
var calculateBodyLength3 = /* @__PURE__ */ __name((body) => {
|
|
18927
18935
|
if (!body) {
|
|
18928
18936
|
return 0;
|
|
@@ -18936,9 +18944,9 @@ var require_dist_cjs53 = __commonJS({
|
|
|
18936
18944
|
} else if (typeof body.start === "number" && typeof body.end === "number") {
|
|
18937
18945
|
return body.end + 1 - body.start;
|
|
18938
18946
|
} else if (typeof body.path === "string" || Buffer.isBuffer(body.path)) {
|
|
18939
|
-
return (0,
|
|
18947
|
+
return (0, import_fs9.lstatSync)(body.path).size;
|
|
18940
18948
|
} else if (typeof body.fd === "number") {
|
|
18941
|
-
return (0,
|
|
18949
|
+
return (0, import_fs9.fstatSync)(body.fd).size;
|
|
18942
18950
|
}
|
|
18943
18951
|
throw new Error(`Body Length computation failed for ${body}`);
|
|
18944
18952
|
}, "calculateBodyLength");
|
|
@@ -20976,8 +20984,8 @@ var require_dist_cjs57 = __commonJS({
|
|
|
20976
20984
|
}
|
|
20977
20985
|
}, "validateTokenKey");
|
|
20978
20986
|
var import_shared_ini_file_loader = require_dist_cjs42();
|
|
20979
|
-
var
|
|
20980
|
-
var { writeFile } =
|
|
20987
|
+
var import_fs9 = __require("fs");
|
|
20988
|
+
var { writeFile } = import_fs9.promises;
|
|
20981
20989
|
var writeSSOTokenToFile = /* @__PURE__ */ __name((id, ssoToken) => {
|
|
20982
20990
|
const tokenFilepath = (0, import_shared_ini_file_loader.getSSOTokenFilepath)(id);
|
|
20983
20991
|
const tokenString = JSON.stringify(ssoToken, null, 2);
|
|
@@ -22619,7 +22627,7 @@ var require_dist_cjs59 = __commonJS({
|
|
|
22619
22627
|
module.exports = __toCommonJS2(index_exports);
|
|
22620
22628
|
var import_property_provider2 = require_dist_cjs24();
|
|
22621
22629
|
var import_shared_ini_file_loader = require_dist_cjs42();
|
|
22622
|
-
var
|
|
22630
|
+
var import_child_process9 = __require("child_process");
|
|
22623
22631
|
var import_util7 = __require("util");
|
|
22624
22632
|
var import_client7 = (init_client(), __toCommonJS(client_exports));
|
|
22625
22633
|
var getValidatedProcessCredentials = /* @__PURE__ */ __name((profileName, data2, profiles) => {
|
|
@@ -22656,7 +22664,7 @@ var require_dist_cjs59 = __commonJS({
|
|
|
22656
22664
|
if (profiles[profileName]) {
|
|
22657
22665
|
const credentialProcess = profile["credential_process"];
|
|
22658
22666
|
if (credentialProcess !== void 0) {
|
|
22659
|
-
const execPromise = (0, import_util7.promisify)(import_shared_ini_file_loader.externalDataInterceptor?.getTokenRecord?.().exec ??
|
|
22667
|
+
const execPromise = (0, import_util7.promisify)(import_shared_ini_file_loader.externalDataInterceptor?.getTokenRecord?.().exec ?? import_child_process9.exec);
|
|
22660
22668
|
try {
|
|
22661
22669
|
const { stdout } = await execPromise(credentialProcess);
|
|
22662
22670
|
let data2;
|
|
@@ -23395,7 +23403,7 @@ var require_dist_cjs64 = __commonJS({
|
|
|
23395
23403
|
streamEnded = true;
|
|
23396
23404
|
});
|
|
23397
23405
|
while (!generationEnded) {
|
|
23398
|
-
const value = await new Promise((
|
|
23406
|
+
const value = await new Promise((resolve5) => setTimeout(() => resolve5(records.shift()), 0));
|
|
23399
23407
|
if (value) {
|
|
23400
23408
|
yield value;
|
|
23401
23409
|
}
|
|
@@ -26772,16 +26780,16 @@ function prepareTools(mode) {
|
|
|
26772
26780
|
}
|
|
26773
26781
|
const toolWarnings = [];
|
|
26774
26782
|
const bedrockTools = [];
|
|
26775
|
-
for (const
|
|
26776
|
-
if (
|
|
26777
|
-
toolWarnings.push({ type: "unsupported-tool", tool:
|
|
26783
|
+
for (const tool3 of tools2) {
|
|
26784
|
+
if (tool3.type === "provider-defined") {
|
|
26785
|
+
toolWarnings.push({ type: "unsupported-tool", tool: tool3 });
|
|
26778
26786
|
} else {
|
|
26779
26787
|
bedrockTools.push({
|
|
26780
26788
|
toolSpec: {
|
|
26781
|
-
name:
|
|
26782
|
-
description:
|
|
26789
|
+
name: tool3.name,
|
|
26790
|
+
description: tool3.description,
|
|
26783
26791
|
inputSchema: {
|
|
26784
|
-
json:
|
|
26792
|
+
json: tool3.parameters
|
|
26785
26793
|
}
|
|
26786
26794
|
}
|
|
26787
26795
|
});
|
|
@@ -28945,7 +28953,7 @@ function createMessagePreview(message, charsPerSide = 200) {
|
|
|
28945
28953
|
const end = message.substring(message.length - charsPerSide);
|
|
28946
28954
|
return `${start}...${end}`;
|
|
28947
28955
|
}
|
|
28948
|
-
var searchSchema, querySchema, extractSchema, delegateSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, attemptCompletionToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, DEFAULT_VALID_TOOLS;
|
|
28956
|
+
var searchSchema, querySchema, extractSchema, delegateSchema, bashSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, attemptCompletionToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, DEFAULT_VALID_TOOLS;
|
|
28949
28957
|
var init_common2 = __esm({
|
|
28950
28958
|
"src/tools/common.js"() {
|
|
28951
28959
|
"use strict";
|
|
@@ -28976,6 +28984,12 @@ var init_common2 = __esm({
|
|
|
28976
28984
|
delegateSchema = z2.object({
|
|
28977
28985
|
task: z2.string().describe("The task to delegate to a subagent. Be specific about what needs to be accomplished.")
|
|
28978
28986
|
});
|
|
28987
|
+
bashSchema = z2.object({
|
|
28988
|
+
command: z2.string().describe("The bash command to execute"),
|
|
28989
|
+
workingDirectory: z2.string().optional().describe("Directory to execute the command in (optional)"),
|
|
28990
|
+
timeout: z2.number().optional().describe("Command timeout in milliseconds (optional)"),
|
|
28991
|
+
env: z2.record(z2.string()).optional().describe("Additional environment variables (optional)")
|
|
28992
|
+
});
|
|
28979
28993
|
attemptCompletionSchema = {
|
|
28980
28994
|
// Custom validation that requires result parameter but allows direct XML response
|
|
28981
28995
|
safeParse: (params) => {
|
|
@@ -29238,7 +29252,7 @@ async function delegate({ task, timeout = 300, debug = false, currentIteration =
|
|
|
29238
29252
|
console.error(`[DELEGATE] Using binary at: ${binaryPath}`);
|
|
29239
29253
|
console.error(`[DELEGATE] Command args: ${args.join(" ")}`);
|
|
29240
29254
|
}
|
|
29241
|
-
return new Promise((
|
|
29255
|
+
return new Promise((resolve5, reject) => {
|
|
29242
29256
|
const delegationSpan = tracer ? tracer.createDelegationSpan(sessionId, task) : null;
|
|
29243
29257
|
const process2 = spawn(binaryPath, args, {
|
|
29244
29258
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -29303,7 +29317,7 @@ async function delegate({ task, timeout = 300, debug = false, currentIteration =
|
|
|
29303
29317
|
delegationSpan.end();
|
|
29304
29318
|
}
|
|
29305
29319
|
}
|
|
29306
|
-
|
|
29320
|
+
resolve5(response);
|
|
29307
29321
|
} else {
|
|
29308
29322
|
const errorMessage = stderr.trim() || `Delegate process failed with exit code ${code}`;
|
|
29309
29323
|
if (debug) {
|
|
@@ -29496,10 +29510,10 @@ var init_vercel = __esm({
|
|
|
29496
29510
|
let extractOptions = { path: extractPath };
|
|
29497
29511
|
if (input_content) {
|
|
29498
29512
|
const { writeFileSync: writeFileSync2, unlinkSync } = await import("fs");
|
|
29499
|
-
const { join:
|
|
29513
|
+
const { join: join3 } = await import("path");
|
|
29500
29514
|
const { tmpdir } = await import("os");
|
|
29501
29515
|
const { randomUUID: randomUUID7 } = await import("crypto");
|
|
29502
|
-
tempFilePath =
|
|
29516
|
+
tempFilePath = join3(tmpdir(), `probe-extract-${randomUUID7()}.txt`);
|
|
29503
29517
|
writeFileSync2(tempFilePath, input_content);
|
|
29504
29518
|
if (debug) {
|
|
29505
29519
|
console.error(`Created temporary file for input content: ${tempFilePath}`);
|
|
@@ -29576,6 +29590,1247 @@ var init_vercel = __esm({
|
|
|
29576
29590
|
}
|
|
29577
29591
|
});
|
|
29578
29592
|
|
|
29593
|
+
// src/agent/bashDefaults.js
|
|
29594
|
+
var DEFAULT_ALLOW_PATTERNS, DEFAULT_DENY_PATTERNS;
|
|
29595
|
+
var init_bashDefaults = __esm({
|
|
29596
|
+
"src/agent/bashDefaults.js"() {
|
|
29597
|
+
"use strict";
|
|
29598
|
+
DEFAULT_ALLOW_PATTERNS = [
|
|
29599
|
+
// Basic navigation and listing
|
|
29600
|
+
"ls",
|
|
29601
|
+
"dir",
|
|
29602
|
+
"pwd",
|
|
29603
|
+
"cd",
|
|
29604
|
+
"cd:*",
|
|
29605
|
+
// File reading commands
|
|
29606
|
+
"cat",
|
|
29607
|
+
"cat:*",
|
|
29608
|
+
"head",
|
|
29609
|
+
"head:*",
|
|
29610
|
+
"tail",
|
|
29611
|
+
"tail:*",
|
|
29612
|
+
"less",
|
|
29613
|
+
"more",
|
|
29614
|
+
"view",
|
|
29615
|
+
// File information and metadata
|
|
29616
|
+
"file",
|
|
29617
|
+
"file:*",
|
|
29618
|
+
"stat",
|
|
29619
|
+
"stat:*",
|
|
29620
|
+
"wc",
|
|
29621
|
+
"wc:*",
|
|
29622
|
+
"du",
|
|
29623
|
+
"du:*",
|
|
29624
|
+
"df",
|
|
29625
|
+
"df:*",
|
|
29626
|
+
"realpath",
|
|
29627
|
+
"realpath:*",
|
|
29628
|
+
// Search and find commands (read-only) - find restricted to safe operations
|
|
29629
|
+
"find",
|
|
29630
|
+
"find:-name:*",
|
|
29631
|
+
"find:-type:*",
|
|
29632
|
+
"find:-size:*",
|
|
29633
|
+
"find:-mtime:*",
|
|
29634
|
+
"find:-newer:*",
|
|
29635
|
+
"find:-path:*",
|
|
29636
|
+
"find:-iname:*",
|
|
29637
|
+
"find:-maxdepth:*",
|
|
29638
|
+
"find:-mindepth:*",
|
|
29639
|
+
"find:-print",
|
|
29640
|
+
"grep",
|
|
29641
|
+
"grep:*",
|
|
29642
|
+
"egrep",
|
|
29643
|
+
"egrep:*",
|
|
29644
|
+
"fgrep",
|
|
29645
|
+
"fgrep:*",
|
|
29646
|
+
"rg",
|
|
29647
|
+
"rg:*",
|
|
29648
|
+
"ag",
|
|
29649
|
+
"ag:*",
|
|
29650
|
+
"ack",
|
|
29651
|
+
"ack:*",
|
|
29652
|
+
"which",
|
|
29653
|
+
"which:*",
|
|
29654
|
+
"whereis",
|
|
29655
|
+
"whereis:*",
|
|
29656
|
+
"locate",
|
|
29657
|
+
"locate:*",
|
|
29658
|
+
"type",
|
|
29659
|
+
"type:*",
|
|
29660
|
+
"command",
|
|
29661
|
+
"command:*",
|
|
29662
|
+
// Tree and structure visualization
|
|
29663
|
+
"tree",
|
|
29664
|
+
"tree:*",
|
|
29665
|
+
// Git read-only operations
|
|
29666
|
+
"git:status",
|
|
29667
|
+
"git:log",
|
|
29668
|
+
"git:log:*",
|
|
29669
|
+
"git:diff",
|
|
29670
|
+
"git:diff:*",
|
|
29671
|
+
"git:show",
|
|
29672
|
+
"git:show:*",
|
|
29673
|
+
"git:branch",
|
|
29674
|
+
"git:branch:*",
|
|
29675
|
+
"git:tag",
|
|
29676
|
+
"git:tag:*",
|
|
29677
|
+
"git:describe",
|
|
29678
|
+
"git:describe:*",
|
|
29679
|
+
"git:remote",
|
|
29680
|
+
"git:remote:*",
|
|
29681
|
+
"git:config:*",
|
|
29682
|
+
"git:blame",
|
|
29683
|
+
"git:blame:*",
|
|
29684
|
+
"git:shortlog",
|
|
29685
|
+
"git:reflog",
|
|
29686
|
+
"git:ls-files",
|
|
29687
|
+
"git:ls-tree",
|
|
29688
|
+
"git:rev-parse",
|
|
29689
|
+
"git:rev-list",
|
|
29690
|
+
"git:--version",
|
|
29691
|
+
"git:help",
|
|
29692
|
+
"git:help:*",
|
|
29693
|
+
// Package managers (information only)
|
|
29694
|
+
"npm:list",
|
|
29695
|
+
"npm:ls",
|
|
29696
|
+
"npm:view",
|
|
29697
|
+
"npm:info",
|
|
29698
|
+
"npm:show",
|
|
29699
|
+
"npm:outdated",
|
|
29700
|
+
"npm:audit",
|
|
29701
|
+
"npm:--version",
|
|
29702
|
+
"yarn:list",
|
|
29703
|
+
"yarn:info",
|
|
29704
|
+
"yarn:--version",
|
|
29705
|
+
"pnpm:list",
|
|
29706
|
+
"pnpm:--version",
|
|
29707
|
+
"pip:list",
|
|
29708
|
+
"pip:show",
|
|
29709
|
+
"pip:--version",
|
|
29710
|
+
"pip3:list",
|
|
29711
|
+
"pip3:show",
|
|
29712
|
+
"pip3:--version",
|
|
29713
|
+
"gem:list",
|
|
29714
|
+
"gem:--version",
|
|
29715
|
+
"bundle:list",
|
|
29716
|
+
"bundle:show",
|
|
29717
|
+
"bundle:--version",
|
|
29718
|
+
"composer:show",
|
|
29719
|
+
"composer:--version",
|
|
29720
|
+
// Language and runtime versions
|
|
29721
|
+
"node:--version",
|
|
29722
|
+
"node:-v",
|
|
29723
|
+
"python:--version",
|
|
29724
|
+
"python:-V",
|
|
29725
|
+
"python3:--version",
|
|
29726
|
+
"python3:-V",
|
|
29727
|
+
"ruby:--version",
|
|
29728
|
+
"ruby:-v",
|
|
29729
|
+
"go:version",
|
|
29730
|
+
"go:env",
|
|
29731
|
+
"go:list",
|
|
29732
|
+
"go:mod:graph",
|
|
29733
|
+
"rustc:--version",
|
|
29734
|
+
"cargo:--version",
|
|
29735
|
+
"cargo:tree",
|
|
29736
|
+
"cargo:metadata",
|
|
29737
|
+
"java:--version",
|
|
29738
|
+
"java:-version",
|
|
29739
|
+
"javac:--version",
|
|
29740
|
+
"mvn:--version",
|
|
29741
|
+
"gradle:--version",
|
|
29742
|
+
"php:--version",
|
|
29743
|
+
"dotnet:--version",
|
|
29744
|
+
"dotnet:list",
|
|
29745
|
+
// Database client versions (connection info only)
|
|
29746
|
+
"psql:--version",
|
|
29747
|
+
"mysql:--version",
|
|
29748
|
+
"redis-cli:--version",
|
|
29749
|
+
"mongo:--version",
|
|
29750
|
+
"sqlite3:--version",
|
|
29751
|
+
// System information
|
|
29752
|
+
"uname",
|
|
29753
|
+
"uname:*",
|
|
29754
|
+
"hostname",
|
|
29755
|
+
"whoami",
|
|
29756
|
+
"id",
|
|
29757
|
+
"groups",
|
|
29758
|
+
"date",
|
|
29759
|
+
"cal",
|
|
29760
|
+
"uptime",
|
|
29761
|
+
"w",
|
|
29762
|
+
"users",
|
|
29763
|
+
"sleep",
|
|
29764
|
+
"sleep:*",
|
|
29765
|
+
// Environment and shell
|
|
29766
|
+
"env",
|
|
29767
|
+
"printenv",
|
|
29768
|
+
"echo",
|
|
29769
|
+
"echo:*",
|
|
29770
|
+
"printf",
|
|
29771
|
+
"printf:*",
|
|
29772
|
+
"export",
|
|
29773
|
+
"export:*",
|
|
29774
|
+
"set",
|
|
29775
|
+
"unset",
|
|
29776
|
+
// Process information (read-only)
|
|
29777
|
+
"ps",
|
|
29778
|
+
"ps:*",
|
|
29779
|
+
"pgrep",
|
|
29780
|
+
"pgrep:*",
|
|
29781
|
+
"jobs",
|
|
29782
|
+
"top:-n:1",
|
|
29783
|
+
// Network information (read-only)
|
|
29784
|
+
"ifconfig",
|
|
29785
|
+
"ip:addr",
|
|
29786
|
+
"ip:link",
|
|
29787
|
+
"hostname:-I",
|
|
29788
|
+
"ping:-c:*",
|
|
29789
|
+
"traceroute",
|
|
29790
|
+
"nslookup",
|
|
29791
|
+
"dig",
|
|
29792
|
+
// Text processing and utilities (awk removed - too powerful)
|
|
29793
|
+
"sed:-n:*",
|
|
29794
|
+
"cut",
|
|
29795
|
+
"cut:*",
|
|
29796
|
+
"sort",
|
|
29797
|
+
"sort:*",
|
|
29798
|
+
"uniq",
|
|
29799
|
+
"uniq:*",
|
|
29800
|
+
"tr",
|
|
29801
|
+
"tr:*",
|
|
29802
|
+
"column",
|
|
29803
|
+
"column:*",
|
|
29804
|
+
"paste",
|
|
29805
|
+
"paste:*",
|
|
29806
|
+
"join",
|
|
29807
|
+
"join:*",
|
|
29808
|
+
"comm",
|
|
29809
|
+
"comm:*",
|
|
29810
|
+
"diff",
|
|
29811
|
+
"diff:*",
|
|
29812
|
+
"cmp",
|
|
29813
|
+
"cmp:*",
|
|
29814
|
+
"patch:--dry-run:*",
|
|
29815
|
+
// Hashing and encoding (read-only)
|
|
29816
|
+
"md5sum",
|
|
29817
|
+
"md5sum:*",
|
|
29818
|
+
"sha1sum",
|
|
29819
|
+
"sha1sum:*",
|
|
29820
|
+
"sha256sum",
|
|
29821
|
+
"sha256sum:*",
|
|
29822
|
+
"base64",
|
|
29823
|
+
"base64:-d",
|
|
29824
|
+
"od",
|
|
29825
|
+
"od:*",
|
|
29826
|
+
"hexdump",
|
|
29827
|
+
"hexdump:*",
|
|
29828
|
+
// Archive and compression (list/view only)
|
|
29829
|
+
"tar:-tf:*",
|
|
29830
|
+
"tar:-tzf:*",
|
|
29831
|
+
"unzip:-l:*",
|
|
29832
|
+
"zip:-l:*",
|
|
29833
|
+
"gzip:-l:*",
|
|
29834
|
+
"gunzip:-l:*",
|
|
29835
|
+
// Help and documentation
|
|
29836
|
+
"man",
|
|
29837
|
+
"man:*",
|
|
29838
|
+
"--help",
|
|
29839
|
+
"help",
|
|
29840
|
+
"info",
|
|
29841
|
+
"info:*",
|
|
29842
|
+
"whatis",
|
|
29843
|
+
"whatis:*",
|
|
29844
|
+
"apropos",
|
|
29845
|
+
"apropos:*",
|
|
29846
|
+
// Make (dry run and info)
|
|
29847
|
+
"make:-n",
|
|
29848
|
+
"make:--dry-run",
|
|
29849
|
+
"make:-p",
|
|
29850
|
+
"make:--print-data-base",
|
|
29851
|
+
// Docker (read-only operations)
|
|
29852
|
+
"docker:ps",
|
|
29853
|
+
"docker:images",
|
|
29854
|
+
"docker:version",
|
|
29855
|
+
"docker:info",
|
|
29856
|
+
"docker:logs:*",
|
|
29857
|
+
"docker:inspect:*",
|
|
29858
|
+
// Test runners (list/info only)
|
|
29859
|
+
"jest:--listTests",
|
|
29860
|
+
"mocha:--help",
|
|
29861
|
+
"pytest:--collect-only"
|
|
29862
|
+
];
|
|
29863
|
+
DEFAULT_DENY_PATTERNS = [
|
|
29864
|
+
// Dangerous file operations
|
|
29865
|
+
"rm:-rf",
|
|
29866
|
+
"rm:-f:/",
|
|
29867
|
+
"rm:/",
|
|
29868
|
+
"rm:-rf:*",
|
|
29869
|
+
"rmdir",
|
|
29870
|
+
"chmod:777",
|
|
29871
|
+
"chmod:-R:777",
|
|
29872
|
+
"chown",
|
|
29873
|
+
"chgrp",
|
|
29874
|
+
"dd",
|
|
29875
|
+
"dd:*",
|
|
29876
|
+
"shred",
|
|
29877
|
+
"shred:*",
|
|
29878
|
+
// Dangerous find operations that can execute arbitrary commands
|
|
29879
|
+
"find:-exec:*",
|
|
29880
|
+
"find:*:-exec:*",
|
|
29881
|
+
"find:-execdir:*",
|
|
29882
|
+
"find:*:-execdir:*",
|
|
29883
|
+
"find:-ok:*",
|
|
29884
|
+
"find:*:-ok:*",
|
|
29885
|
+
"find:-okdir:*",
|
|
29886
|
+
"find:*:-okdir:*",
|
|
29887
|
+
// Powerful scripting tools that can execute arbitrary commands
|
|
29888
|
+
"awk",
|
|
29889
|
+
"awk:*",
|
|
29890
|
+
"perl",
|
|
29891
|
+
"perl:*",
|
|
29892
|
+
"python:-c:*",
|
|
29893
|
+
"node:-e:*",
|
|
29894
|
+
// System administration and modification
|
|
29895
|
+
"sudo:*",
|
|
29896
|
+
"su",
|
|
29897
|
+
"su:*",
|
|
29898
|
+
"passwd",
|
|
29899
|
+
"adduser",
|
|
29900
|
+
"useradd",
|
|
29901
|
+
"userdel",
|
|
29902
|
+
"usermod",
|
|
29903
|
+
"groupadd",
|
|
29904
|
+
"groupdel",
|
|
29905
|
+
"visudo",
|
|
29906
|
+
// Package installation and removal
|
|
29907
|
+
"npm:install",
|
|
29908
|
+
"npm:i",
|
|
29909
|
+
"npm:uninstall",
|
|
29910
|
+
"npm:publish",
|
|
29911
|
+
"npm:unpublish",
|
|
29912
|
+
"npm:link",
|
|
29913
|
+
"npm:update",
|
|
29914
|
+
"yarn:install",
|
|
29915
|
+
"yarn:add",
|
|
29916
|
+
"yarn:remove",
|
|
29917
|
+
"yarn:upgrade",
|
|
29918
|
+
"pnpm:install",
|
|
29919
|
+
"pnpm:add",
|
|
29920
|
+
"pnpm:remove",
|
|
29921
|
+
"pip:install",
|
|
29922
|
+
"pip:uninstall",
|
|
29923
|
+
"pip:upgrade",
|
|
29924
|
+
"pip3:install",
|
|
29925
|
+
"pip3:uninstall",
|
|
29926
|
+
"pip3:upgrade",
|
|
29927
|
+
"gem:install",
|
|
29928
|
+
"gem:uninstall",
|
|
29929
|
+
"gem:update",
|
|
29930
|
+
"bundle:install",
|
|
29931
|
+
"bundle:update",
|
|
29932
|
+
"composer:install",
|
|
29933
|
+
"composer:update",
|
|
29934
|
+
"composer:remove",
|
|
29935
|
+
"apt:*",
|
|
29936
|
+
"apt-get:*",
|
|
29937
|
+
"yum:*",
|
|
29938
|
+
"dnf:*",
|
|
29939
|
+
"zypper:*",
|
|
29940
|
+
"brew:install",
|
|
29941
|
+
"brew:uninstall",
|
|
29942
|
+
"brew:upgrade",
|
|
29943
|
+
"conda:install",
|
|
29944
|
+
"conda:remove",
|
|
29945
|
+
"conda:update",
|
|
29946
|
+
// Service and system control
|
|
29947
|
+
"systemctl:*",
|
|
29948
|
+
"service:*",
|
|
29949
|
+
"chkconfig:*",
|
|
29950
|
+
"initctl:*",
|
|
29951
|
+
"upstart:*",
|
|
29952
|
+
// Network operations that could be dangerous
|
|
29953
|
+
"curl:-d:*",
|
|
29954
|
+
"curl:--data:*",
|
|
29955
|
+
"curl:-X:POST:*",
|
|
29956
|
+
"curl:-X:PUT:*",
|
|
29957
|
+
"wget:-O:/",
|
|
29958
|
+
"wget:--post-data:*",
|
|
29959
|
+
"ssh",
|
|
29960
|
+
"ssh:*",
|
|
29961
|
+
"scp",
|
|
29962
|
+
"scp:*",
|
|
29963
|
+
"sftp",
|
|
29964
|
+
"sftp:*",
|
|
29965
|
+
"rsync:*",
|
|
29966
|
+
"nc",
|
|
29967
|
+
"nc:*",
|
|
29968
|
+
"netcat",
|
|
29969
|
+
"netcat:*",
|
|
29970
|
+
"telnet",
|
|
29971
|
+
"telnet:*",
|
|
29972
|
+
"ftp",
|
|
29973
|
+
"ftp:*",
|
|
29974
|
+
// Process control and termination
|
|
29975
|
+
"kill",
|
|
29976
|
+
"kill:*",
|
|
29977
|
+
"killall",
|
|
29978
|
+
"killall:*",
|
|
29979
|
+
"pkill",
|
|
29980
|
+
"pkill:*",
|
|
29981
|
+
"nohup:*",
|
|
29982
|
+
"disown:*",
|
|
29983
|
+
// System control and shutdown
|
|
29984
|
+
"shutdown",
|
|
29985
|
+
"shutdown:*",
|
|
29986
|
+
"reboot",
|
|
29987
|
+
"halt",
|
|
29988
|
+
"poweroff",
|
|
29989
|
+
"init",
|
|
29990
|
+
"telinit",
|
|
29991
|
+
// Kernel and module operations
|
|
29992
|
+
"insmod",
|
|
29993
|
+
"insmod:*",
|
|
29994
|
+
"rmmod",
|
|
29995
|
+
"rmmod:*",
|
|
29996
|
+
"modprobe",
|
|
29997
|
+
"modprobe:*",
|
|
29998
|
+
"sysctl:-w:*",
|
|
29999
|
+
// Dangerous git operations
|
|
30000
|
+
"git:push",
|
|
30001
|
+
"git:push:*",
|
|
30002
|
+
"git:force",
|
|
30003
|
+
"git:reset:--hard:*",
|
|
30004
|
+
"git:clean:-fd",
|
|
30005
|
+
"git:rm:*",
|
|
30006
|
+
"git:commit",
|
|
30007
|
+
"git:merge",
|
|
30008
|
+
"git:rebase",
|
|
30009
|
+
"git:cherry-pick",
|
|
30010
|
+
"git:stash:drop",
|
|
30011
|
+
// File system mounting and partitioning
|
|
30012
|
+
"mount",
|
|
30013
|
+
"mount:*",
|
|
30014
|
+
"umount",
|
|
30015
|
+
"umount:*",
|
|
30016
|
+
"fdisk",
|
|
30017
|
+
"fdisk:*",
|
|
30018
|
+
"parted",
|
|
30019
|
+
"parted:*",
|
|
30020
|
+
"mkfs",
|
|
30021
|
+
"mkfs:*",
|
|
30022
|
+
"fsck",
|
|
30023
|
+
"fsck:*",
|
|
30024
|
+
// Cron and scheduling
|
|
30025
|
+
"crontab",
|
|
30026
|
+
"crontab:*",
|
|
30027
|
+
"at",
|
|
30028
|
+
"at:*",
|
|
30029
|
+
"batch",
|
|
30030
|
+
"batch:*",
|
|
30031
|
+
// Compression with potential overwrite
|
|
30032
|
+
"tar:-xf:*",
|
|
30033
|
+
"unzip",
|
|
30034
|
+
"unzip:*",
|
|
30035
|
+
"gzip:*",
|
|
30036
|
+
"gunzip:*",
|
|
30037
|
+
// Build and compilation that might modify files
|
|
30038
|
+
"make",
|
|
30039
|
+
"make:install",
|
|
30040
|
+
"make:clean",
|
|
30041
|
+
"cargo:build",
|
|
30042
|
+
"cargo:install",
|
|
30043
|
+
"npm:run:build",
|
|
30044
|
+
"yarn:build",
|
|
30045
|
+
"mvn:install",
|
|
30046
|
+
"gradle:build",
|
|
30047
|
+
// Docker operations that could modify state
|
|
30048
|
+
"docker:run",
|
|
30049
|
+
"docker:run:*",
|
|
30050
|
+
"docker:exec",
|
|
30051
|
+
"docker:exec:*",
|
|
30052
|
+
"docker:build",
|
|
30053
|
+
"docker:build:*",
|
|
30054
|
+
"docker:pull",
|
|
30055
|
+
"docker:push",
|
|
30056
|
+
"docker:rm",
|
|
30057
|
+
"docker:rmi",
|
|
30058
|
+
"docker:stop",
|
|
30059
|
+
"docker:start",
|
|
30060
|
+
// Database operations
|
|
30061
|
+
"mysql:-e:DROP",
|
|
30062
|
+
"psql:-c:DROP",
|
|
30063
|
+
"redis-cli:FLUSHALL",
|
|
30064
|
+
"mongo:--eval:*",
|
|
30065
|
+
// Text editors that could modify files
|
|
30066
|
+
"vi",
|
|
30067
|
+
"vi:*",
|
|
30068
|
+
"vim",
|
|
30069
|
+
"vim:*",
|
|
30070
|
+
"nano",
|
|
30071
|
+
"nano:*",
|
|
30072
|
+
"emacs",
|
|
30073
|
+
"emacs:*",
|
|
30074
|
+
"sed:-i:*",
|
|
30075
|
+
"perl:-i:*",
|
|
30076
|
+
// Potentially dangerous utilities
|
|
30077
|
+
"eval",
|
|
30078
|
+
"eval:*",
|
|
30079
|
+
"exec",
|
|
30080
|
+
"exec:*",
|
|
30081
|
+
"source",
|
|
30082
|
+
"source:*",
|
|
30083
|
+
"bash:-c:*",
|
|
30084
|
+
"sh:-c:*",
|
|
30085
|
+
"zsh:-c:*"
|
|
30086
|
+
];
|
|
30087
|
+
}
|
|
30088
|
+
});
|
|
30089
|
+
|
|
30090
|
+
// src/agent/bashCommandUtils.js
|
|
30091
|
+
function parseSimpleCommand(command) {
|
|
30092
|
+
if (!command || typeof command !== "string") {
|
|
30093
|
+
return {
|
|
30094
|
+
success: false,
|
|
30095
|
+
error: "Command must be a non-empty string",
|
|
30096
|
+
command: null,
|
|
30097
|
+
args: [],
|
|
30098
|
+
isComplex: false
|
|
30099
|
+
};
|
|
30100
|
+
}
|
|
30101
|
+
const trimmed = command.trim();
|
|
30102
|
+
if (!trimmed) {
|
|
30103
|
+
return {
|
|
30104
|
+
success: false,
|
|
30105
|
+
error: "Command cannot be empty",
|
|
30106
|
+
command: null,
|
|
30107
|
+
args: [],
|
|
30108
|
+
isComplex: false
|
|
30109
|
+
};
|
|
30110
|
+
}
|
|
30111
|
+
const complexPatterns = [
|
|
30112
|
+
/\|/,
|
|
30113
|
+
// Pipes
|
|
30114
|
+
/&&/,
|
|
30115
|
+
// Logical AND
|
|
30116
|
+
/\|\|/,
|
|
30117
|
+
// Logical OR
|
|
30118
|
+
/(?<!\\);/,
|
|
30119
|
+
// Command separator (but not escaped \;)
|
|
30120
|
+
/&$/,
|
|
30121
|
+
// Background execution
|
|
30122
|
+
/\$\(/,
|
|
30123
|
+
// Command substitution $()
|
|
30124
|
+
/`/,
|
|
30125
|
+
// Command substitution ``
|
|
30126
|
+
/>/,
|
|
30127
|
+
// Redirection >
|
|
30128
|
+
/</,
|
|
30129
|
+
// Redirection <
|
|
30130
|
+
/\*\*/,
|
|
30131
|
+
// Glob patterns (potentially dangerous)
|
|
30132
|
+
/^\s*\{.*,.*\}|\{.*\.\.\.*\}/
|
|
30133
|
+
// Brace expansion like {a,b} or {1..10} (but not find {} placeholders)
|
|
30134
|
+
];
|
|
30135
|
+
for (const pattern of complexPatterns) {
|
|
30136
|
+
if (pattern.test(trimmed)) {
|
|
30137
|
+
return {
|
|
30138
|
+
success: false,
|
|
30139
|
+
error: "Complex shell commands with pipes, operators, or redirections are not supported for security reasons",
|
|
30140
|
+
command: null,
|
|
30141
|
+
args: [],
|
|
30142
|
+
isComplex: true,
|
|
30143
|
+
detected: pattern.toString()
|
|
30144
|
+
};
|
|
30145
|
+
}
|
|
30146
|
+
}
|
|
30147
|
+
const args = [];
|
|
30148
|
+
let current = "";
|
|
30149
|
+
let inQuotes = false;
|
|
30150
|
+
let quoteChar = "";
|
|
30151
|
+
let escaped = false;
|
|
30152
|
+
for (let i3 = 0; i3 < trimmed.length; i3++) {
|
|
30153
|
+
const char = trimmed[i3];
|
|
30154
|
+
const nextChar = i3 + 1 < trimmed.length ? trimmed[i3 + 1] : "";
|
|
30155
|
+
if (escaped) {
|
|
30156
|
+
current += char;
|
|
30157
|
+
escaped = false;
|
|
30158
|
+
continue;
|
|
30159
|
+
}
|
|
30160
|
+
if (char === "\\" && !inQuotes) {
|
|
30161
|
+
escaped = true;
|
|
30162
|
+
continue;
|
|
30163
|
+
}
|
|
30164
|
+
if (!inQuotes && (char === '"' || char === "'")) {
|
|
30165
|
+
inQuotes = true;
|
|
30166
|
+
quoteChar = char;
|
|
30167
|
+
} else if (inQuotes && char === quoteChar) {
|
|
30168
|
+
inQuotes = false;
|
|
30169
|
+
quoteChar = "";
|
|
30170
|
+
} else if (!inQuotes && char === " ") {
|
|
30171
|
+
if (current.trim()) {
|
|
30172
|
+
args.push(current.trim());
|
|
30173
|
+
current = "";
|
|
30174
|
+
}
|
|
30175
|
+
} else {
|
|
30176
|
+
current += char;
|
|
30177
|
+
}
|
|
30178
|
+
}
|
|
30179
|
+
if (current.trim()) {
|
|
30180
|
+
args.push(current.trim());
|
|
30181
|
+
}
|
|
30182
|
+
if (inQuotes) {
|
|
30183
|
+
return {
|
|
30184
|
+
success: false,
|
|
30185
|
+
error: `Unclosed quote in command: ${quoteChar}`,
|
|
30186
|
+
command: null,
|
|
30187
|
+
args: [],
|
|
30188
|
+
isComplex: false
|
|
30189
|
+
};
|
|
30190
|
+
}
|
|
30191
|
+
if (args.length === 0) {
|
|
30192
|
+
return {
|
|
30193
|
+
success: false,
|
|
30194
|
+
error: "No command found after parsing",
|
|
30195
|
+
command: null,
|
|
30196
|
+
args: [],
|
|
30197
|
+
isComplex: false
|
|
30198
|
+
};
|
|
30199
|
+
}
|
|
30200
|
+
const [baseCommand, ...commandArgs] = args;
|
|
30201
|
+
return {
|
|
30202
|
+
success: true,
|
|
30203
|
+
error: null,
|
|
30204
|
+
command: baseCommand,
|
|
30205
|
+
args: commandArgs,
|
|
30206
|
+
fullArgs: args,
|
|
30207
|
+
isComplex: false,
|
|
30208
|
+
original: command
|
|
30209
|
+
};
|
|
30210
|
+
}
|
|
30211
|
+
function isComplexCommand(command) {
|
|
30212
|
+
const result = parseSimpleCommand(command);
|
|
30213
|
+
return result.isComplex;
|
|
30214
|
+
}
|
|
30215
|
+
function parseCommand(command) {
|
|
30216
|
+
const result = parseSimpleCommand(command);
|
|
30217
|
+
if (!result.success) {
|
|
30218
|
+
return {
|
|
30219
|
+
command: "",
|
|
30220
|
+
args: [],
|
|
30221
|
+
error: result.error,
|
|
30222
|
+
isComplex: result.isComplex
|
|
30223
|
+
};
|
|
30224
|
+
}
|
|
30225
|
+
return {
|
|
30226
|
+
command: result.command,
|
|
30227
|
+
args: result.args,
|
|
30228
|
+
error: null,
|
|
30229
|
+
isComplex: result.isComplex
|
|
30230
|
+
};
|
|
30231
|
+
}
|
|
30232
|
+
function parseCommandForExecution(command) {
|
|
30233
|
+
const result = parseSimpleCommand(command);
|
|
30234
|
+
if (!result.success) {
|
|
30235
|
+
return null;
|
|
30236
|
+
}
|
|
30237
|
+
return result.fullArgs;
|
|
30238
|
+
}
|
|
30239
|
+
var init_bashCommandUtils = __esm({
|
|
30240
|
+
"src/agent/bashCommandUtils.js"() {
|
|
30241
|
+
"use strict";
|
|
30242
|
+
}
|
|
30243
|
+
});
|
|
30244
|
+
|
|
30245
|
+
// src/agent/bashPermissions.js
|
|
30246
|
+
function matchesPattern(parsedCommand, pattern) {
|
|
30247
|
+
if (!parsedCommand || !pattern) return false;
|
|
30248
|
+
const { command, args } = parsedCommand;
|
|
30249
|
+
if (!command) return false;
|
|
30250
|
+
const patternParts = pattern.split(":");
|
|
30251
|
+
const commandName = patternParts[0];
|
|
30252
|
+
if (commandName === "*") {
|
|
30253
|
+
return true;
|
|
30254
|
+
} else if (commandName !== command) {
|
|
30255
|
+
return false;
|
|
30256
|
+
}
|
|
30257
|
+
if (patternParts.length === 1) {
|
|
30258
|
+
return true;
|
|
30259
|
+
}
|
|
30260
|
+
for (let i3 = 1; i3 < patternParts.length; i3++) {
|
|
30261
|
+
const patternArg = patternParts[i3];
|
|
30262
|
+
const argIndex = i3 - 1;
|
|
30263
|
+
if (patternArg === "*") {
|
|
30264
|
+
continue;
|
|
30265
|
+
}
|
|
30266
|
+
if (argIndex >= args.length) {
|
|
30267
|
+
return false;
|
|
30268
|
+
}
|
|
30269
|
+
const actualArg = args[argIndex];
|
|
30270
|
+
if (patternArg !== actualArg) {
|
|
30271
|
+
return false;
|
|
30272
|
+
}
|
|
30273
|
+
}
|
|
30274
|
+
return true;
|
|
30275
|
+
}
|
|
30276
|
+
function matchesAnyPattern(parsedCommand, patterns) {
|
|
30277
|
+
if (!patterns || patterns.length === 0) return false;
|
|
30278
|
+
return patterns.some((pattern) => matchesPattern(parsedCommand, pattern));
|
|
30279
|
+
}
|
|
30280
|
+
var BashPermissionChecker;
|
|
30281
|
+
var init_bashPermissions = __esm({
|
|
30282
|
+
"src/agent/bashPermissions.js"() {
|
|
30283
|
+
"use strict";
|
|
30284
|
+
init_bashDefaults();
|
|
30285
|
+
init_bashCommandUtils();
|
|
30286
|
+
BashPermissionChecker = class {
|
|
30287
|
+
/**
|
|
30288
|
+
* Create a permission checker
|
|
30289
|
+
* @param {Object} config - Configuration options
|
|
30290
|
+
* @param {string[]} [config.allow] - Additional allow patterns
|
|
30291
|
+
* @param {string[]} [config.deny] - Additional deny patterns
|
|
30292
|
+
* @param {boolean} [config.disableDefaultAllow] - Disable default allow list
|
|
30293
|
+
* @param {boolean} [config.disableDefaultDeny] - Disable default deny list
|
|
30294
|
+
* @param {boolean} [config.debug] - Enable debug logging
|
|
30295
|
+
*/
|
|
30296
|
+
constructor(config = {}) {
|
|
30297
|
+
this.debug = config.debug || false;
|
|
30298
|
+
this.allowPatterns = [];
|
|
30299
|
+
if (!config.disableDefaultAllow) {
|
|
30300
|
+
this.allowPatterns.push(...DEFAULT_ALLOW_PATTERNS);
|
|
30301
|
+
if (this.debug) {
|
|
30302
|
+
console.log(`[BashPermissions] Added ${DEFAULT_ALLOW_PATTERNS.length} default allow patterns`);
|
|
30303
|
+
}
|
|
30304
|
+
}
|
|
30305
|
+
if (config.allow && Array.isArray(config.allow)) {
|
|
30306
|
+
this.allowPatterns.push(...config.allow);
|
|
30307
|
+
if (this.debug) {
|
|
30308
|
+
console.log(`[BashPermissions] Added ${config.allow.length} custom allow patterns:`, config.allow);
|
|
30309
|
+
}
|
|
30310
|
+
}
|
|
30311
|
+
this.denyPatterns = [];
|
|
30312
|
+
if (!config.disableDefaultDeny) {
|
|
30313
|
+
this.denyPatterns.push(...DEFAULT_DENY_PATTERNS);
|
|
30314
|
+
if (this.debug) {
|
|
30315
|
+
console.log(`[BashPermissions] Added ${DEFAULT_DENY_PATTERNS.length} default deny patterns`);
|
|
30316
|
+
}
|
|
30317
|
+
}
|
|
30318
|
+
if (config.deny && Array.isArray(config.deny)) {
|
|
30319
|
+
this.denyPatterns.push(...config.deny);
|
|
30320
|
+
if (this.debug) {
|
|
30321
|
+
console.log(`[BashPermissions] Added ${config.deny.length} custom deny patterns:`, config.deny);
|
|
30322
|
+
}
|
|
30323
|
+
}
|
|
30324
|
+
if (this.debug) {
|
|
30325
|
+
console.log(`[BashPermissions] Total patterns - Allow: ${this.allowPatterns.length}, Deny: ${this.denyPatterns.length}`);
|
|
30326
|
+
}
|
|
30327
|
+
}
|
|
30328
|
+
/**
|
|
30329
|
+
* Check if a simple command is allowed (rejects complex commands for security)
|
|
30330
|
+
* @param {string} command - Command to check
|
|
30331
|
+
* @returns {Object} Permission result
|
|
30332
|
+
*/
|
|
30333
|
+
check(command) {
|
|
30334
|
+
if (!command || typeof command !== "string") {
|
|
30335
|
+
return {
|
|
30336
|
+
allowed: false,
|
|
30337
|
+
reason: "Invalid or empty command",
|
|
30338
|
+
command
|
|
30339
|
+
};
|
|
30340
|
+
}
|
|
30341
|
+
if (isComplexCommand(command)) {
|
|
30342
|
+
return {
|
|
30343
|
+
allowed: false,
|
|
30344
|
+
reason: "Complex shell commands with pipes, operators, or redirections are not supported for security reasons",
|
|
30345
|
+
command,
|
|
30346
|
+
isComplex: true
|
|
30347
|
+
};
|
|
30348
|
+
}
|
|
30349
|
+
const parsed = parseCommand(command);
|
|
30350
|
+
if (parsed.error) {
|
|
30351
|
+
return {
|
|
30352
|
+
allowed: false,
|
|
30353
|
+
reason: parsed.error,
|
|
30354
|
+
command
|
|
30355
|
+
};
|
|
30356
|
+
}
|
|
30357
|
+
if (!parsed.command) {
|
|
30358
|
+
return {
|
|
30359
|
+
allowed: false,
|
|
30360
|
+
reason: "No valid command found",
|
|
30361
|
+
command
|
|
30362
|
+
};
|
|
30363
|
+
}
|
|
30364
|
+
if (this.debug) {
|
|
30365
|
+
console.log(`[BashPermissions] Checking simple command: "${command}"`);
|
|
30366
|
+
console.log(`[BashPermissions] Parsed: ${parsed.command} with args: [${parsed.args.join(", ")}]`);
|
|
30367
|
+
}
|
|
30368
|
+
if (matchesAnyPattern(parsed, this.denyPatterns)) {
|
|
30369
|
+
const matchedPatterns = this.denyPatterns.filter((pattern) => matchesPattern(parsed, pattern));
|
|
30370
|
+
return {
|
|
30371
|
+
allowed: false,
|
|
30372
|
+
reason: `Command matches deny pattern: ${matchedPatterns[0]}`,
|
|
30373
|
+
command,
|
|
30374
|
+
parsed,
|
|
30375
|
+
matchedPatterns
|
|
30376
|
+
};
|
|
30377
|
+
}
|
|
30378
|
+
if (this.allowPatterns.length > 0) {
|
|
30379
|
+
if (!matchesAnyPattern(parsed, this.allowPatterns)) {
|
|
30380
|
+
return {
|
|
30381
|
+
allowed: false,
|
|
30382
|
+
reason: "Command not in allow list",
|
|
30383
|
+
command,
|
|
30384
|
+
parsed
|
|
30385
|
+
};
|
|
30386
|
+
}
|
|
30387
|
+
}
|
|
30388
|
+
const result = {
|
|
30389
|
+
allowed: true,
|
|
30390
|
+
command,
|
|
30391
|
+
parsed,
|
|
30392
|
+
isComplex: false
|
|
30393
|
+
};
|
|
30394
|
+
if (this.debug) {
|
|
30395
|
+
console.log(`[BashPermissions] ALLOWED - command passed all checks`);
|
|
30396
|
+
}
|
|
30397
|
+
return result;
|
|
30398
|
+
}
|
|
30399
|
+
/**
|
|
30400
|
+
* Get configuration summary
|
|
30401
|
+
* @returns {Object} Configuration info
|
|
30402
|
+
*/
|
|
30403
|
+
getConfig() {
|
|
30404
|
+
return {
|
|
30405
|
+
allowPatterns: this.allowPatterns.length,
|
|
30406
|
+
denyPatterns: this.denyPatterns.length,
|
|
30407
|
+
totalPatterns: this.allowPatterns.length + this.denyPatterns.length
|
|
30408
|
+
};
|
|
30409
|
+
}
|
|
30410
|
+
};
|
|
30411
|
+
}
|
|
30412
|
+
});
|
|
30413
|
+
|
|
30414
|
+
// src/agent/bashExecutor.js
|
|
30415
|
+
import { spawn as spawn2 } from "child_process";
|
|
30416
|
+
import { resolve, join } from "path";
|
|
30417
|
+
import { existsSync } from "fs";
|
|
30418
|
+
async function executeBashCommand(command, options = {}) {
|
|
30419
|
+
const {
|
|
30420
|
+
workingDirectory = process.cwd(),
|
|
30421
|
+
timeout = 12e4,
|
|
30422
|
+
// 2 minutes default
|
|
30423
|
+
env = {},
|
|
30424
|
+
maxBuffer = 10 * 1024 * 1024,
|
|
30425
|
+
// 10MB
|
|
30426
|
+
debug = false
|
|
30427
|
+
} = options;
|
|
30428
|
+
let cwd = workingDirectory;
|
|
30429
|
+
try {
|
|
30430
|
+
cwd = resolve(cwd);
|
|
30431
|
+
if (!existsSync(cwd)) {
|
|
30432
|
+
throw new Error(`Working directory does not exist: ${cwd}`);
|
|
30433
|
+
}
|
|
30434
|
+
} catch (error2) {
|
|
30435
|
+
return {
|
|
30436
|
+
success: false,
|
|
30437
|
+
error: `Invalid working directory: ${error2.message}`,
|
|
30438
|
+
stdout: "",
|
|
30439
|
+
stderr: "",
|
|
30440
|
+
exitCode: 1,
|
|
30441
|
+
command,
|
|
30442
|
+
workingDirectory: cwd,
|
|
30443
|
+
duration: 0
|
|
30444
|
+
};
|
|
30445
|
+
}
|
|
30446
|
+
const startTime = Date.now();
|
|
30447
|
+
if (debug) {
|
|
30448
|
+
console.log(`[BashExecutor] Executing command: "${command}"`);
|
|
30449
|
+
console.log(`[BashExecutor] Working directory: "${cwd}"`);
|
|
30450
|
+
console.log(`[BashExecutor] Timeout: ${timeout}ms`);
|
|
30451
|
+
}
|
|
30452
|
+
return new Promise((resolve5, reject) => {
|
|
30453
|
+
const processEnv = {
|
|
30454
|
+
...process.env,
|
|
30455
|
+
...env
|
|
30456
|
+
};
|
|
30457
|
+
const args = parseCommandForExecution(command);
|
|
30458
|
+
if (!args || args.length === 0) {
|
|
30459
|
+
resolve5({
|
|
30460
|
+
success: false,
|
|
30461
|
+
error: "Failed to parse command",
|
|
30462
|
+
stdout: "",
|
|
30463
|
+
stderr: "",
|
|
30464
|
+
exitCode: 1,
|
|
30465
|
+
command,
|
|
30466
|
+
workingDirectory: cwd,
|
|
30467
|
+
duration: Date.now() - startTime
|
|
30468
|
+
});
|
|
30469
|
+
return;
|
|
30470
|
+
}
|
|
30471
|
+
const [cmd, ...cmdArgs] = args;
|
|
30472
|
+
const child = spawn2(cmd, cmdArgs, {
|
|
30473
|
+
cwd,
|
|
30474
|
+
env: processEnv,
|
|
30475
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
30476
|
+
// stdin ignored, capture stdout/stderr
|
|
30477
|
+
shell: false,
|
|
30478
|
+
// For security
|
|
30479
|
+
windowsHide: true
|
|
30480
|
+
});
|
|
30481
|
+
let stdout = "";
|
|
30482
|
+
let stderr = "";
|
|
30483
|
+
let killed = false;
|
|
30484
|
+
let timeoutHandle;
|
|
30485
|
+
if (timeout > 0) {
|
|
30486
|
+
timeoutHandle = setTimeout(() => {
|
|
30487
|
+
if (!killed) {
|
|
30488
|
+
killed = true;
|
|
30489
|
+
child.kill("SIGTERM");
|
|
30490
|
+
setTimeout(() => {
|
|
30491
|
+
if (child.exitCode === null) {
|
|
30492
|
+
child.kill("SIGKILL");
|
|
30493
|
+
}
|
|
30494
|
+
}, 5e3);
|
|
30495
|
+
}
|
|
30496
|
+
}, timeout);
|
|
30497
|
+
}
|
|
30498
|
+
child.stdout.on("data", (data2) => {
|
|
30499
|
+
const chunk = data2.toString();
|
|
30500
|
+
if (stdout.length + chunk.length <= maxBuffer) {
|
|
30501
|
+
stdout += chunk;
|
|
30502
|
+
} else {
|
|
30503
|
+
if (!killed) {
|
|
30504
|
+
killed = true;
|
|
30505
|
+
child.kill("SIGTERM");
|
|
30506
|
+
}
|
|
30507
|
+
}
|
|
30508
|
+
});
|
|
30509
|
+
child.stderr.on("data", (data2) => {
|
|
30510
|
+
const chunk = data2.toString();
|
|
30511
|
+
if (stderr.length + chunk.length <= maxBuffer) {
|
|
30512
|
+
stderr += chunk;
|
|
30513
|
+
} else {
|
|
30514
|
+
if (!killed) {
|
|
30515
|
+
killed = true;
|
|
30516
|
+
child.kill("SIGTERM");
|
|
30517
|
+
}
|
|
30518
|
+
}
|
|
30519
|
+
});
|
|
30520
|
+
child.on("close", (code, signal) => {
|
|
30521
|
+
if (timeoutHandle) {
|
|
30522
|
+
clearTimeout(timeoutHandle);
|
|
30523
|
+
}
|
|
30524
|
+
const duration = Date.now() - startTime;
|
|
30525
|
+
if (debug) {
|
|
30526
|
+
console.log(`[BashExecutor] Command completed - Code: ${code}, Signal: ${signal}, Duration: ${duration}ms`);
|
|
30527
|
+
console.log(`[BashExecutor] Stdout length: ${stdout.length}, Stderr length: ${stderr.length}`);
|
|
30528
|
+
}
|
|
30529
|
+
let success = true;
|
|
30530
|
+
let error2 = "";
|
|
30531
|
+
if (killed) {
|
|
30532
|
+
success = false;
|
|
30533
|
+
if (stdout.length + stderr.length > maxBuffer) {
|
|
30534
|
+
error2 = `Command output exceeded maximum buffer size (${maxBuffer} bytes)`;
|
|
30535
|
+
} else {
|
|
30536
|
+
error2 = `Command timed out after ${timeout}ms`;
|
|
30537
|
+
}
|
|
30538
|
+
} else if (code !== 0) {
|
|
30539
|
+
success = false;
|
|
30540
|
+
error2 = `Command exited with code ${code}`;
|
|
30541
|
+
}
|
|
30542
|
+
resolve5({
|
|
30543
|
+
success,
|
|
30544
|
+
error: error2,
|
|
30545
|
+
stdout: stdout.trim(),
|
|
30546
|
+
stderr: stderr.trim(),
|
|
30547
|
+
exitCode: code,
|
|
30548
|
+
signal,
|
|
30549
|
+
command,
|
|
30550
|
+
workingDirectory: cwd,
|
|
30551
|
+
duration,
|
|
30552
|
+
killed
|
|
30553
|
+
});
|
|
30554
|
+
});
|
|
30555
|
+
child.on("error", (error2) => {
|
|
30556
|
+
if (timeoutHandle) {
|
|
30557
|
+
clearTimeout(timeoutHandle);
|
|
30558
|
+
}
|
|
30559
|
+
if (debug) {
|
|
30560
|
+
console.log(`[BashExecutor] Spawn error:`, error2);
|
|
30561
|
+
}
|
|
30562
|
+
resolve5({
|
|
30563
|
+
success: false,
|
|
30564
|
+
error: `Failed to execute command: ${error2.message}`,
|
|
30565
|
+
stdout: "",
|
|
30566
|
+
stderr: "",
|
|
30567
|
+
exitCode: 1,
|
|
30568
|
+
command,
|
|
30569
|
+
workingDirectory: cwd,
|
|
30570
|
+
duration: Date.now() - startTime
|
|
30571
|
+
});
|
|
30572
|
+
});
|
|
30573
|
+
});
|
|
30574
|
+
}
|
|
30575
|
+
function formatExecutionResult(result, includeMetadata = false) {
|
|
30576
|
+
if (!result) {
|
|
30577
|
+
return "No result available";
|
|
30578
|
+
}
|
|
30579
|
+
let output = "";
|
|
30580
|
+
if (includeMetadata) {
|
|
30581
|
+
output += `Command: ${result.command}
|
|
30582
|
+
`;
|
|
30583
|
+
output += `Working directory: ${result.workingDirectory}
|
|
30584
|
+
`;
|
|
30585
|
+
output += `Duration: ${result.duration}ms
|
|
30586
|
+
`;
|
|
30587
|
+
output += `Exit Code: ${result.exitCode}
|
|
30588
|
+
`;
|
|
30589
|
+
if (result.signal) {
|
|
30590
|
+
output += `Signal: ${result.signal}
|
|
30591
|
+
`;
|
|
30592
|
+
}
|
|
30593
|
+
output += "\n";
|
|
30594
|
+
}
|
|
30595
|
+
if (result.stdout) {
|
|
30596
|
+
if (includeMetadata) {
|
|
30597
|
+
output += "--- STDOUT ---\n";
|
|
30598
|
+
}
|
|
30599
|
+
output += result.stdout;
|
|
30600
|
+
if (includeMetadata && result.stderr) {
|
|
30601
|
+
output += "\n";
|
|
30602
|
+
}
|
|
30603
|
+
}
|
|
30604
|
+
if (result.stderr) {
|
|
30605
|
+
if (includeMetadata) {
|
|
30606
|
+
if (result.stdout) output += "\n";
|
|
30607
|
+
output += "--- STDERR ---\n";
|
|
30608
|
+
} else if (result.stdout) {
|
|
30609
|
+
output += "\n--- STDERR ---\n";
|
|
30610
|
+
}
|
|
30611
|
+
output += result.stderr;
|
|
30612
|
+
}
|
|
30613
|
+
if (!result.success && result.error && !result.stderr) {
|
|
30614
|
+
if (output) output += "\n";
|
|
30615
|
+
output += `Error: ${result.error}`;
|
|
30616
|
+
}
|
|
30617
|
+
if (!result.success && result.exitCode !== void 0 && result.exitCode !== 0) {
|
|
30618
|
+
if (output) output += "\n";
|
|
30619
|
+
output += `Exit code: ${result.exitCode}`;
|
|
30620
|
+
}
|
|
30621
|
+
return output || (result.success ? "Command completed successfully (no output)" : "Command failed (no output)");
|
|
30622
|
+
}
|
|
30623
|
+
function validateExecutionOptions(options = {}) {
|
|
30624
|
+
const errors = [];
|
|
30625
|
+
const warnings = [];
|
|
30626
|
+
if (options.timeout !== void 0) {
|
|
30627
|
+
if (typeof options.timeout !== "number" || options.timeout < 0) {
|
|
30628
|
+
errors.push("timeout must be a non-negative number");
|
|
30629
|
+
} else if (options.timeout > 6e5) {
|
|
30630
|
+
warnings.push("timeout is very high (>10 minutes)");
|
|
30631
|
+
}
|
|
30632
|
+
}
|
|
30633
|
+
if (options.maxBuffer !== void 0) {
|
|
30634
|
+
if (typeof options.maxBuffer !== "number" || options.maxBuffer < 1024) {
|
|
30635
|
+
errors.push("maxBuffer must be at least 1024 bytes");
|
|
30636
|
+
} else if (options.maxBuffer > 100 * 1024 * 1024) {
|
|
30637
|
+
warnings.push("maxBuffer is very high (>100MB)");
|
|
30638
|
+
}
|
|
30639
|
+
}
|
|
30640
|
+
if (options.workingDirectory) {
|
|
30641
|
+
if (typeof options.workingDirectory !== "string") {
|
|
30642
|
+
errors.push("workingDirectory must be a string");
|
|
30643
|
+
} else if (!existsSync(options.workingDirectory)) {
|
|
30644
|
+
errors.push(`workingDirectory does not exist: ${options.workingDirectory}`);
|
|
30645
|
+
}
|
|
30646
|
+
}
|
|
30647
|
+
if (options.env && typeof options.env !== "object") {
|
|
30648
|
+
errors.push("env must be an object");
|
|
30649
|
+
}
|
|
30650
|
+
return {
|
|
30651
|
+
valid: errors.length === 0,
|
|
30652
|
+
errors,
|
|
30653
|
+
warnings
|
|
30654
|
+
};
|
|
30655
|
+
}
|
|
30656
|
+
var init_bashExecutor = __esm({
|
|
30657
|
+
"src/agent/bashExecutor.js"() {
|
|
30658
|
+
"use strict";
|
|
30659
|
+
init_bashCommandUtils();
|
|
30660
|
+
}
|
|
30661
|
+
});
|
|
30662
|
+
|
|
30663
|
+
// src/tools/bash.js
|
|
30664
|
+
import { tool as tool2 } from "ai";
|
|
30665
|
+
import { resolve as resolve2 } from "path";
|
|
30666
|
+
var bashTool;
|
|
30667
|
+
var init_bash = __esm({
|
|
30668
|
+
"src/tools/bash.js"() {
|
|
30669
|
+
"use strict";
|
|
30670
|
+
init_bashPermissions();
|
|
30671
|
+
init_bashExecutor();
|
|
30672
|
+
bashTool = (options = {}) => {
|
|
30673
|
+
const {
|
|
30674
|
+
bashConfig = {},
|
|
30675
|
+
debug = false,
|
|
30676
|
+
defaultPath,
|
|
30677
|
+
allowedFolders = []
|
|
30678
|
+
} = options;
|
|
30679
|
+
const permissionChecker = new BashPermissionChecker({
|
|
30680
|
+
allow: bashConfig.allow,
|
|
30681
|
+
deny: bashConfig.deny,
|
|
30682
|
+
disableDefaultAllow: bashConfig.disableDefaultAllow,
|
|
30683
|
+
disableDefaultDeny: bashConfig.disableDefaultDeny,
|
|
30684
|
+
debug
|
|
30685
|
+
});
|
|
30686
|
+
const getDefaultWorkingDirectory = () => {
|
|
30687
|
+
if (bashConfig.workingDirectory) {
|
|
30688
|
+
return bashConfig.workingDirectory;
|
|
30689
|
+
}
|
|
30690
|
+
if (defaultPath) {
|
|
30691
|
+
return defaultPath;
|
|
30692
|
+
}
|
|
30693
|
+
if (allowedFolders && allowedFolders.length > 0) {
|
|
30694
|
+
return allowedFolders[0];
|
|
30695
|
+
}
|
|
30696
|
+
return process.cwd();
|
|
30697
|
+
};
|
|
30698
|
+
return tool2({
|
|
30699
|
+
name: "bash",
|
|
30700
|
+
description: `Execute bash commands for system exploration and development tasks.
|
|
30701
|
+
|
|
30702
|
+
Security: This tool has built-in security with allow/deny lists. By default, only safe read-only commands are allowed for code exploration.
|
|
30703
|
+
|
|
30704
|
+
Parameters:
|
|
30705
|
+
- command: (required) The bash command to execute
|
|
30706
|
+
- workingDirectory: (optional) Directory to execute command in
|
|
30707
|
+
- timeout: (optional) Command timeout in milliseconds
|
|
30708
|
+
- env: (optional) Additional environment variables
|
|
30709
|
+
|
|
30710
|
+
Examples of allowed commands by default:
|
|
30711
|
+
- File exploration: ls, cat, head, tail, find, grep
|
|
30712
|
+
- Git operations: git status, git log, git diff, git show
|
|
30713
|
+
- Package info: npm list, pip list, cargo --version
|
|
30714
|
+
- System info: whoami, pwd, uname, date
|
|
30715
|
+
|
|
30716
|
+
Dangerous commands are blocked by default (rm -rf, sudo, npm install, etc.)`,
|
|
30717
|
+
inputSchema: {
|
|
30718
|
+
type: "object",
|
|
30719
|
+
properties: {
|
|
30720
|
+
command: {
|
|
30721
|
+
type: "string",
|
|
30722
|
+
description: "The bash command to execute"
|
|
30723
|
+
},
|
|
30724
|
+
workingDirectory: {
|
|
30725
|
+
type: "string",
|
|
30726
|
+
description: "Directory to execute the command in (optional)"
|
|
30727
|
+
},
|
|
30728
|
+
timeout: {
|
|
30729
|
+
type: "number",
|
|
30730
|
+
description: "Command timeout in milliseconds (optional)",
|
|
30731
|
+
minimum: 1e3,
|
|
30732
|
+
maximum: 6e5
|
|
30733
|
+
},
|
|
30734
|
+
env: {
|
|
30735
|
+
type: "object",
|
|
30736
|
+
description: "Additional environment variables (optional)",
|
|
30737
|
+
additionalProperties: {
|
|
30738
|
+
type: "string"
|
|
30739
|
+
}
|
|
30740
|
+
}
|
|
30741
|
+
},
|
|
30742
|
+
required: ["command"],
|
|
30743
|
+
additionalProperties: false
|
|
30744
|
+
},
|
|
30745
|
+
execute: async ({ command, workingDirectory, timeout, env }) => {
|
|
30746
|
+
try {
|
|
30747
|
+
if (command === null || command === void 0 || typeof command !== "string") {
|
|
30748
|
+
return "Error: Command is required and must be a string";
|
|
30749
|
+
}
|
|
30750
|
+
if (command.trim().length === 0) {
|
|
30751
|
+
return "Error: Command cannot be empty";
|
|
30752
|
+
}
|
|
30753
|
+
const permissionResult = permissionChecker.check(command.trim());
|
|
30754
|
+
if (!permissionResult.allowed) {
|
|
30755
|
+
if (debug) {
|
|
30756
|
+
console.log(`[BashTool] Permission denied for command: "${command}"`);
|
|
30757
|
+
console.log(`[BashTool] Reason: ${permissionResult.reason}`);
|
|
30758
|
+
}
|
|
30759
|
+
return `Permission denied: ${permissionResult.reason}
|
|
30760
|
+
|
|
30761
|
+
This command is not allowed by the current security policy.
|
|
30762
|
+
|
|
30763
|
+
Common reasons:
|
|
30764
|
+
1. The command is in the deny list (potentially dangerous)
|
|
30765
|
+
2. The command is not in the allow list (not a recognized safe command)
|
|
30766
|
+
|
|
30767
|
+
If you believe this command should be allowed, you can:
|
|
30768
|
+
- Use the --bash-allow option to add specific patterns
|
|
30769
|
+
- Use the --no-default-bash-deny flag to remove default restrictions (not recommended)
|
|
30770
|
+
|
|
30771
|
+
For code exploration, try these safe alternatives:
|
|
30772
|
+
- ls, cat, head, tail for file operations
|
|
30773
|
+
- find, grep, rg for searching
|
|
30774
|
+
- git status, git log, git show for git operations
|
|
30775
|
+
- npm list, pip list for package information`;
|
|
30776
|
+
}
|
|
30777
|
+
const workingDir = workingDirectory || getDefaultWorkingDirectory();
|
|
30778
|
+
if (allowedFolders && allowedFolders.length > 0) {
|
|
30779
|
+
const resolvedWorkingDir = resolve2(workingDir);
|
|
30780
|
+
const isAllowed = allowedFolders.some((folder) => {
|
|
30781
|
+
const resolvedFolder = resolve2(folder);
|
|
30782
|
+
return resolvedWorkingDir.startsWith(resolvedFolder);
|
|
30783
|
+
});
|
|
30784
|
+
if (!isAllowed) {
|
|
30785
|
+
return `Error: Working directory "${workingDir}" is not within allowed folders: ${allowedFolders.join(", ")}`;
|
|
30786
|
+
}
|
|
30787
|
+
}
|
|
30788
|
+
const executionOptions = {
|
|
30789
|
+
workingDirectory: workingDir,
|
|
30790
|
+
timeout: timeout || bashConfig.timeout || 12e4,
|
|
30791
|
+
env: { ...bashConfig.env, ...env },
|
|
30792
|
+
maxBuffer: bashConfig.maxBuffer,
|
|
30793
|
+
debug
|
|
30794
|
+
};
|
|
30795
|
+
const validation = validateExecutionOptions(executionOptions);
|
|
30796
|
+
if (!validation.valid) {
|
|
30797
|
+
return `Error: Invalid execution options: ${validation.errors.join(", ")}`;
|
|
30798
|
+
}
|
|
30799
|
+
if (validation.warnings.length > 0 && debug) {
|
|
30800
|
+
console.log("[BashTool] Warnings:", validation.warnings);
|
|
30801
|
+
}
|
|
30802
|
+
if (debug) {
|
|
30803
|
+
console.log(`[BashTool] Executing command: "${command}"`);
|
|
30804
|
+
console.log(`[BashTool] Working directory: "${workingDir}"`);
|
|
30805
|
+
console.log(`[BashTool] Timeout: ${executionOptions.timeout}ms`);
|
|
30806
|
+
}
|
|
30807
|
+
const result = await executeBashCommand(command.trim(), executionOptions);
|
|
30808
|
+
if (debug) {
|
|
30809
|
+
console.log(`[BashTool] Command completed - Success: ${result.success}, Duration: ${result.duration}ms`);
|
|
30810
|
+
}
|
|
30811
|
+
const formattedResult = formatExecutionResult(result, debug);
|
|
30812
|
+
if (!result.success) {
|
|
30813
|
+
let errorInfo = `
|
|
30814
|
+
|
|
30815
|
+
Command failed with exit code ${result.exitCode}`;
|
|
30816
|
+
if (result.killed) {
|
|
30817
|
+
errorInfo += ` (${result.error})`;
|
|
30818
|
+
}
|
|
30819
|
+
return formattedResult + errorInfo;
|
|
30820
|
+
}
|
|
30821
|
+
return formattedResult;
|
|
30822
|
+
} catch (error2) {
|
|
30823
|
+
if (debug) {
|
|
30824
|
+
console.error("[BashTool] Execution error:", error2);
|
|
30825
|
+
}
|
|
30826
|
+
return `Error executing bash command: ${error2.message}`;
|
|
30827
|
+
}
|
|
30828
|
+
}
|
|
30829
|
+
});
|
|
30830
|
+
};
|
|
30831
|
+
}
|
|
30832
|
+
});
|
|
30833
|
+
|
|
29579
30834
|
// src/tools/langchain.js
|
|
29580
30835
|
var init_langchain = __esm({
|
|
29581
30836
|
"src/tools/langchain.js"() {
|
|
@@ -29724,16 +30979,19 @@ var init_tools = __esm({
|
|
|
29724
30979
|
"src/tools/index.js"() {
|
|
29725
30980
|
"use strict";
|
|
29726
30981
|
init_vercel();
|
|
30982
|
+
init_bash();
|
|
29727
30983
|
init_langchain();
|
|
29728
30984
|
init_common2();
|
|
29729
30985
|
init_system_message();
|
|
29730
30986
|
init_vercel();
|
|
30987
|
+
init_bash();
|
|
29731
30988
|
init_system_message();
|
|
29732
30989
|
tools = {
|
|
29733
30990
|
searchTool: searchTool(),
|
|
29734
30991
|
queryTool: queryTool(),
|
|
29735
30992
|
extractTool: extractTool(),
|
|
29736
30993
|
delegateTool: delegateTool(),
|
|
30994
|
+
bashTool: bashTool(),
|
|
29737
30995
|
DEFAULT_SYSTEM_MESSAGE
|
|
29738
30996
|
};
|
|
29739
30997
|
}
|
|
@@ -29840,7 +31098,7 @@ var init_file_lister = __esm({
|
|
|
29840
31098
|
});
|
|
29841
31099
|
|
|
29842
31100
|
// src/agent/simpleTelemetry.js
|
|
29843
|
-
import { existsSync, mkdirSync, createWriteStream } from "fs";
|
|
31101
|
+
import { existsSync as existsSync2, mkdirSync, createWriteStream } from "fs";
|
|
29844
31102
|
import { dirname } from "path";
|
|
29845
31103
|
function initializeSimpleTelemetryFromOptions(options) {
|
|
29846
31104
|
const telemetry = new SimpleTelemetry({
|
|
@@ -29869,7 +31127,7 @@ var init_simpleTelemetry = __esm({
|
|
|
29869
31127
|
initializeFileExporter() {
|
|
29870
31128
|
try {
|
|
29871
31129
|
const dir = dirname(this.filePath);
|
|
29872
|
-
if (!
|
|
31130
|
+
if (!existsSync2(dir)) {
|
|
29873
31131
|
mkdirSync(dir, { recursive: true });
|
|
29874
31132
|
}
|
|
29875
31133
|
this.stream = createWriteStream(this.filePath, { flags: "a" });
|
|
@@ -29933,20 +31191,20 @@ var init_simpleTelemetry = __esm({
|
|
|
29933
31191
|
}
|
|
29934
31192
|
async flush() {
|
|
29935
31193
|
if (this.stream) {
|
|
29936
|
-
return new Promise((
|
|
29937
|
-
this.stream.once("drain",
|
|
31194
|
+
return new Promise((resolve5) => {
|
|
31195
|
+
this.stream.once("drain", resolve5);
|
|
29938
31196
|
if (!this.stream.writableNeedDrain) {
|
|
29939
|
-
|
|
31197
|
+
resolve5();
|
|
29940
31198
|
}
|
|
29941
31199
|
});
|
|
29942
31200
|
}
|
|
29943
31201
|
}
|
|
29944
31202
|
async shutdown() {
|
|
29945
31203
|
if (this.stream) {
|
|
29946
|
-
return new Promise((
|
|
31204
|
+
return new Promise((resolve5) => {
|
|
29947
31205
|
this.stream.end(() => {
|
|
29948
31206
|
console.log(`[SimpleTelemetry] File stream closed: ${this.filePath}`);
|
|
29949
|
-
|
|
31207
|
+
resolve5();
|
|
29950
31208
|
});
|
|
29951
31209
|
});
|
|
29952
31210
|
}
|
|
@@ -30078,25 +31336,21 @@ var init_index = __esm({
|
|
|
30078
31336
|
init_system_message();
|
|
30079
31337
|
init_common2();
|
|
30080
31338
|
init_vercel();
|
|
31339
|
+
init_bash();
|
|
30081
31340
|
init_ProbeAgent();
|
|
30082
31341
|
init_simpleTelemetry();
|
|
30083
31342
|
}
|
|
30084
31343
|
});
|
|
30085
31344
|
|
|
30086
|
-
// src/agent/
|
|
30087
|
-
|
|
30088
|
-
|
|
30089
|
-
return {
|
|
30090
|
-
searchTool: searchTool(configOptions),
|
|
30091
|
-
queryTool: queryTool(configOptions),
|
|
30092
|
-
extractTool: extractTool(configOptions),
|
|
30093
|
-
delegateTool: delegateTool(configOptions)
|
|
30094
|
-
};
|
|
31345
|
+
// src/agent/xmlParsingUtils.js
|
|
31346
|
+
function removeThinkingTags(xmlString) {
|
|
31347
|
+
return xmlString.replace(/<thinking>[\s\S]*?<\/thinking>/g, "").trim();
|
|
30095
31348
|
}
|
|
30096
|
-
function
|
|
31349
|
+
function extractThinkingContent(xmlString) {
|
|
30097
31350
|
const thinkingMatch = xmlString.match(/<thinking>([\s\S]*?)<\/thinking>/);
|
|
30098
|
-
|
|
30099
|
-
|
|
31351
|
+
return thinkingMatch ? thinkingMatch[1].trim() : null;
|
|
31352
|
+
}
|
|
31353
|
+
function checkAttemptCompleteRecovery(cleanedXmlString, validTools = []) {
|
|
30100
31354
|
const attemptCompletePatterns = [
|
|
30101
31355
|
// Standard shorthand with optional whitespace
|
|
30102
31356
|
/^<attempt_complete>\s*$/,
|
|
@@ -30126,28 +31380,65 @@ function parseXmlToolCallWithThinking(xmlString, validTools) {
|
|
|
30126
31380
|
params: { result: "__PREVIOUS_RESPONSE__" }
|
|
30127
31381
|
};
|
|
30128
31382
|
}
|
|
30129
|
-
|
|
30130
|
-
if (process.env.DEBUG === "1" && thinkingContent) {
|
|
30131
|
-
console.log(`[DEBUG] AI Thinking Process:
|
|
30132
|
-
${thinkingContent}`);
|
|
30133
|
-
}
|
|
30134
|
-
return parsedTool;
|
|
31383
|
+
return null;
|
|
30135
31384
|
}
|
|
30136
31385
|
function hasOtherToolTags(xmlString, validTools = []) {
|
|
30137
31386
|
const defaultTools = ["search", "query", "extract", "listFiles", "searchFiles", "implement", "attempt_completion"];
|
|
30138
31387
|
const toolsToCheck = validTools.length > 0 ? validTools : defaultTools;
|
|
30139
|
-
for (const
|
|
30140
|
-
if (
|
|
31388
|
+
for (const tool3 of toolsToCheck) {
|
|
31389
|
+
if (tool3 !== "attempt_completion" && xmlString.includes(`<${tool3}`)) {
|
|
30141
31390
|
return true;
|
|
30142
31391
|
}
|
|
30143
31392
|
}
|
|
30144
31393
|
return false;
|
|
30145
31394
|
}
|
|
31395
|
+
function processXmlWithThinkingAndRecovery(xmlString, validTools = []) {
|
|
31396
|
+
const thinkingContent = extractThinkingContent(xmlString);
|
|
31397
|
+
const cleanedXmlString = removeThinkingTags(xmlString);
|
|
31398
|
+
const recoveryResult = checkAttemptCompleteRecovery(cleanedXmlString, validTools);
|
|
31399
|
+
if (process.env.DEBUG === "1" && thinkingContent) {
|
|
31400
|
+
console.log(`[DEBUG] AI Thinking Process:
|
|
31401
|
+
${thinkingContent}`);
|
|
31402
|
+
}
|
|
31403
|
+
return {
|
|
31404
|
+
cleanedXmlString,
|
|
31405
|
+
thinkingContent,
|
|
31406
|
+
recoveryResult
|
|
31407
|
+
};
|
|
31408
|
+
}
|
|
31409
|
+
var init_xmlParsingUtils = __esm({
|
|
31410
|
+
"src/agent/xmlParsingUtils.js"() {
|
|
31411
|
+
"use strict";
|
|
31412
|
+
}
|
|
31413
|
+
});
|
|
31414
|
+
|
|
31415
|
+
// src/agent/tools.js
|
|
31416
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
31417
|
+
function createTools(configOptions) {
|
|
31418
|
+
const tools2 = {
|
|
31419
|
+
searchTool: searchTool(configOptions),
|
|
31420
|
+
queryTool: queryTool(configOptions),
|
|
31421
|
+
extractTool: extractTool(configOptions),
|
|
31422
|
+
delegateTool: delegateTool(configOptions)
|
|
31423
|
+
};
|
|
31424
|
+
if (configOptions.enableBash) {
|
|
31425
|
+
tools2.bashTool = bashTool(configOptions);
|
|
31426
|
+
}
|
|
31427
|
+
return tools2;
|
|
31428
|
+
}
|
|
31429
|
+
function parseXmlToolCallWithThinking(xmlString, validTools) {
|
|
31430
|
+
const { cleanedXmlString, recoveryResult } = processXmlWithThinkingAndRecovery(xmlString, validTools);
|
|
31431
|
+
if (recoveryResult) {
|
|
31432
|
+
return recoveryResult;
|
|
31433
|
+
}
|
|
31434
|
+
return parseXmlToolCall(cleanedXmlString, validTools);
|
|
31435
|
+
}
|
|
30146
31436
|
var implementToolDefinition, listFilesToolDefinition, searchFilesToolDefinition;
|
|
30147
31437
|
var init_tools2 = __esm({
|
|
30148
31438
|
"src/agent/tools.js"() {
|
|
30149
31439
|
"use strict";
|
|
30150
31440
|
init_index();
|
|
31441
|
+
init_xmlParsingUtils();
|
|
30151
31442
|
implementToolDefinition = `
|
|
30152
31443
|
## implement
|
|
30153
31444
|
Description: Implement a given task. Can modify files. Can be used ONLY if task explicitly stated that something requires modification or implementation.
|
|
@@ -30284,6 +31575,13 @@ function createWrappedTools(baseTools) {
|
|
|
30284
31575
|
baseTools.delegateTool.execute
|
|
30285
31576
|
);
|
|
30286
31577
|
}
|
|
31578
|
+
if (baseTools.bashTool) {
|
|
31579
|
+
wrappedTools.bashToolInstance = wrapToolWithEmitter(
|
|
31580
|
+
baseTools.bashTool,
|
|
31581
|
+
"bash",
|
|
31582
|
+
baseTools.bashTool.execute
|
|
31583
|
+
);
|
|
31584
|
+
}
|
|
30287
31585
|
return wrappedTools;
|
|
30288
31586
|
}
|
|
30289
31587
|
var toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
|
|
@@ -30293,9 +31591,9 @@ var init_probeTool = __esm({
|
|
|
30293
31591
|
init_index();
|
|
30294
31592
|
toolCallEmitter = new EventEmitter();
|
|
30295
31593
|
activeToolExecutions = /* @__PURE__ */ new Map();
|
|
30296
|
-
wrapToolWithEmitter = (
|
|
31594
|
+
wrapToolWithEmitter = (tool3, toolName, baseExecute) => {
|
|
30297
31595
|
return {
|
|
30298
|
-
...
|
|
31596
|
+
...tool3,
|
|
30299
31597
|
// Spread schema, description etc.
|
|
30300
31598
|
execute: async (params) => {
|
|
30301
31599
|
const debug = process.env.DEBUG === "1";
|
|
@@ -30436,7 +31734,7 @@ function createMockProvider() {
|
|
|
30436
31734
|
provider: "mock",
|
|
30437
31735
|
// Mock the doGenerate method used by Vercel AI SDK
|
|
30438
31736
|
doGenerate: async ({ messages, tools: tools2 }) => {
|
|
30439
|
-
await new Promise((
|
|
31737
|
+
await new Promise((resolve5) => setTimeout(resolve5, 10));
|
|
30440
31738
|
return {
|
|
30441
31739
|
text: "This is a mock response for testing",
|
|
30442
31740
|
toolCalls: [],
|
|
@@ -31070,7 +32368,7 @@ ${decodedContent}
|
|
|
31070
32368
|
}
|
|
31071
32369
|
if (needsQuoting(content)) {
|
|
31072
32370
|
wasFixed = true;
|
|
31073
|
-
const safeContent = content.replace(/"/g, "'");
|
|
32371
|
+
const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
|
|
31074
32372
|
return `["${safeContent}"]`;
|
|
31075
32373
|
}
|
|
31076
32374
|
return match;
|
|
@@ -31083,7 +32381,7 @@ ${decodedContent}
|
|
|
31083
32381
|
}
|
|
31084
32382
|
if (needsQuoting(content)) {
|
|
31085
32383
|
wasFixed = true;
|
|
31086
|
-
const safeContent = content.replace(/"/g, "'");
|
|
32384
|
+
const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
|
|
31087
32385
|
return `{"${safeContent}"}`;
|
|
31088
32386
|
}
|
|
31089
32387
|
return match;
|
|
@@ -31253,7 +32551,7 @@ ${fixedContent}
|
|
|
31253
32551
|
}
|
|
31254
32552
|
if (needsQuoting(content)) {
|
|
31255
32553
|
wasFixed = true;
|
|
31256
|
-
const safeContent = content.replace(/"/g, "'");
|
|
32554
|
+
const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
|
|
31257
32555
|
return `["${safeContent}"]`;
|
|
31258
32556
|
}
|
|
31259
32557
|
return match;
|
|
@@ -31266,7 +32564,7 @@ ${fixedContent}
|
|
|
31266
32564
|
}
|
|
31267
32565
|
if (needsQuoting(content)) {
|
|
31268
32566
|
wasFixed = true;
|
|
31269
|
-
const safeContent = content.replace(/"/g, "'");
|
|
32567
|
+
const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
|
|
31270
32568
|
return `{"${safeContent}"}`;
|
|
31271
32569
|
}
|
|
31272
32570
|
return match;
|
|
@@ -31662,15 +32960,15 @@ Provide only the corrected Mermaid diagram within a mermaid code block. Do not a
|
|
|
31662
32960
|
});
|
|
31663
32961
|
|
|
31664
32962
|
// src/agent/mcp/config.js
|
|
31665
|
-
import { readFileSync, existsSync as
|
|
31666
|
-
import { join, dirname as dirname2 } from "path";
|
|
32963
|
+
import { readFileSync, existsSync as existsSync3, mkdirSync as mkdirSync2, writeFileSync } from "fs";
|
|
32964
|
+
import { join as join2, dirname as dirname2 } from "path";
|
|
31667
32965
|
import { homedir } from "os";
|
|
31668
32966
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
31669
32967
|
function loadMCPConfigurationFromPath(configPath) {
|
|
31670
32968
|
if (!configPath) {
|
|
31671
32969
|
throw new Error("Config path is required");
|
|
31672
32970
|
}
|
|
31673
|
-
if (!
|
|
32971
|
+
if (!existsSync3(configPath)) {
|
|
31674
32972
|
throw new Error(`MCP configuration file not found: ${configPath}`);
|
|
31675
32973
|
}
|
|
31676
32974
|
try {
|
|
@@ -31689,17 +32987,17 @@ function loadMCPConfiguration() {
|
|
|
31689
32987
|
// Environment variable path
|
|
31690
32988
|
process.env.MCP_CONFIG_PATH,
|
|
31691
32989
|
// Local project paths
|
|
31692
|
-
|
|
31693
|
-
|
|
32990
|
+
join2(process.cwd(), ".mcp", "config.json"),
|
|
32991
|
+
join2(process.cwd(), "mcp.config.json"),
|
|
31694
32992
|
// Home directory paths
|
|
31695
|
-
|
|
31696
|
-
|
|
32993
|
+
join2(homedir(), ".config", "probe", "mcp.json"),
|
|
32994
|
+
join2(homedir(), ".mcp", "config.json"),
|
|
31697
32995
|
// Claude-style config location
|
|
31698
|
-
|
|
32996
|
+
join2(homedir(), "Library", "Application Support", "Claude", "mcp_config.json")
|
|
31699
32997
|
].filter(Boolean);
|
|
31700
32998
|
let config = null;
|
|
31701
32999
|
for (const configPath of configPaths) {
|
|
31702
|
-
if (
|
|
33000
|
+
if (existsSync3(configPath)) {
|
|
31703
33001
|
try {
|
|
31704
33002
|
const content = readFileSync(configPath, "utf8");
|
|
31705
33003
|
config = JSON.parse(content);
|
|
@@ -31808,7 +33106,7 @@ var init_config = __esm({
|
|
|
31808
33106
|
// Example probe server configuration
|
|
31809
33107
|
"probe-local": {
|
|
31810
33108
|
command: "node",
|
|
31811
|
-
args: [
|
|
33109
|
+
args: [join2(__dirname4, "../../../examples/chat/mcpServer.js")],
|
|
31812
33110
|
transport: "stdio",
|
|
31813
33111
|
enabled: false
|
|
31814
33112
|
},
|
|
@@ -31965,12 +33263,12 @@ var init_client2 = __esm({
|
|
|
31965
33263
|
});
|
|
31966
33264
|
const toolsResponse = await client.listTools();
|
|
31967
33265
|
if (toolsResponse && toolsResponse.tools) {
|
|
31968
|
-
for (const
|
|
31969
|
-
const qualifiedName = `${name14}_${
|
|
33266
|
+
for (const tool3 of toolsResponse.tools) {
|
|
33267
|
+
const qualifiedName = `${name14}_${tool3.name}`;
|
|
31970
33268
|
this.tools.set(qualifiedName, {
|
|
31971
|
-
...
|
|
33269
|
+
...tool3,
|
|
31972
33270
|
serverName: name14,
|
|
31973
|
-
originalName:
|
|
33271
|
+
originalName: tool3.name
|
|
31974
33272
|
});
|
|
31975
33273
|
if (this.debug) {
|
|
31976
33274
|
console.error(`[MCP] Registered tool: ${qualifiedName}`);
|
|
@@ -31992,20 +33290,20 @@ var init_client2 = __esm({
|
|
|
31992
33290
|
* @param {Object} args - Tool arguments
|
|
31993
33291
|
*/
|
|
31994
33292
|
async callTool(toolName, args) {
|
|
31995
|
-
const
|
|
31996
|
-
if (!
|
|
33293
|
+
const tool3 = this.tools.get(toolName);
|
|
33294
|
+
if (!tool3) {
|
|
31997
33295
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
31998
33296
|
}
|
|
31999
|
-
const clientInfo = this.clients.get(
|
|
33297
|
+
const clientInfo = this.clients.get(tool3.serverName);
|
|
32000
33298
|
if (!clientInfo) {
|
|
32001
|
-
throw new Error(`Server ${
|
|
33299
|
+
throw new Error(`Server ${tool3.serverName} not connected`);
|
|
32002
33300
|
}
|
|
32003
33301
|
try {
|
|
32004
33302
|
if (this.debug) {
|
|
32005
33303
|
console.error(`[MCP] Calling ${toolName} with args:`, args);
|
|
32006
33304
|
}
|
|
32007
33305
|
const result = await clientInfo.client.callTool({
|
|
32008
|
-
name:
|
|
33306
|
+
name: tool3.originalName,
|
|
32009
33307
|
arguments: args
|
|
32010
33308
|
});
|
|
32011
33309
|
return result;
|
|
@@ -32020,11 +33318,11 @@ var init_client2 = __esm({
|
|
|
32020
33318
|
*/
|
|
32021
33319
|
getTools() {
|
|
32022
33320
|
const tools2 = {};
|
|
32023
|
-
for (const [name14,
|
|
33321
|
+
for (const [name14, tool3] of this.tools.entries()) {
|
|
32024
33322
|
tools2[name14] = {
|
|
32025
|
-
description:
|
|
32026
|
-
inputSchema:
|
|
32027
|
-
serverName:
|
|
33323
|
+
description: tool3.description,
|
|
33324
|
+
inputSchema: tool3.inputSchema,
|
|
33325
|
+
serverName: tool3.serverName
|
|
32028
33326
|
};
|
|
32029
33327
|
}
|
|
32030
33328
|
return tools2;
|
|
@@ -32035,10 +33333,10 @@ var init_client2 = __esm({
|
|
|
32035
33333
|
*/
|
|
32036
33334
|
getVercelTools() {
|
|
32037
33335
|
const tools2 = {};
|
|
32038
|
-
for (const [name14,
|
|
33336
|
+
for (const [name14, tool3] of this.tools.entries()) {
|
|
32039
33337
|
tools2[name14] = {
|
|
32040
|
-
description:
|
|
32041
|
-
inputSchema:
|
|
33338
|
+
description: tool3.description,
|
|
33339
|
+
inputSchema: tool3.inputSchema,
|
|
32042
33340
|
execute: async (args) => {
|
|
32043
33341
|
const result = await this.callTool(name14, args);
|
|
32044
33342
|
if (result.content && result.content[0]) {
|
|
@@ -32075,9 +33373,9 @@ var init_client2 = __esm({
|
|
|
32075
33373
|
});
|
|
32076
33374
|
|
|
32077
33375
|
// src/agent/mcp/xmlBridge.js
|
|
32078
|
-
function mcpToolToXmlDefinition(name14,
|
|
32079
|
-
const description =
|
|
32080
|
-
const inputSchema =
|
|
33376
|
+
function mcpToolToXmlDefinition(name14, tool3) {
|
|
33377
|
+
const description = tool3.description || "MCP tool";
|
|
33378
|
+
const inputSchema = tool3.inputSchema || tool3.parameters || {};
|
|
32081
33379
|
let paramDocs = "";
|
|
32082
33380
|
if (inputSchema.properties) {
|
|
32083
33381
|
paramDocs = "\n\nParameters (provide as JSON object):";
|
|
@@ -32151,11 +33449,9 @@ function parseXmlMcpToolCall(xmlString, mcpToolNames = []) {
|
|
|
32151
33449
|
return null;
|
|
32152
33450
|
}
|
|
32153
33451
|
function parseHybridXmlToolCall(xmlString, nativeTools = [], mcpBridge = null) {
|
|
32154
|
-
|
|
32155
|
-
|
|
32156
|
-
|
|
32157
|
-
return { ...nativeResult, type: "native" };
|
|
32158
|
-
}
|
|
33452
|
+
const nativeResult = parseNativeXmlToolWithThinking(xmlString, nativeTools);
|
|
33453
|
+
if (nativeResult) {
|
|
33454
|
+
return { ...nativeResult, type: "native" };
|
|
32159
33455
|
}
|
|
32160
33456
|
if (mcpBridge) {
|
|
32161
33457
|
const mcpResult = parseXmlMcpToolCall(xmlString, mcpBridge.getToolNames());
|
|
@@ -32165,6 +33461,19 @@ function parseHybridXmlToolCall(xmlString, nativeTools = [], mcpBridge = null) {
|
|
|
32165
33461
|
}
|
|
32166
33462
|
return null;
|
|
32167
33463
|
}
|
|
33464
|
+
function parseNativeXmlToolWithThinking(xmlString, validTools) {
|
|
33465
|
+
const { cleanedXmlString, recoveryResult } = processXmlWithThinkingAndRecovery(xmlString, validTools);
|
|
33466
|
+
if (recoveryResult) {
|
|
33467
|
+
return recoveryResult;
|
|
33468
|
+
}
|
|
33469
|
+
for (const toolName of validTools) {
|
|
33470
|
+
const result = parseNativeXmlTool(cleanedXmlString, toolName);
|
|
33471
|
+
if (result) {
|
|
33472
|
+
return result;
|
|
33473
|
+
}
|
|
33474
|
+
}
|
|
33475
|
+
return null;
|
|
33476
|
+
}
|
|
32168
33477
|
function parseNativeXmlTool(xmlString, toolName) {
|
|
32169
33478
|
const openTag = `<${toolName}>`;
|
|
32170
33479
|
const closeTag = `</${toolName}>`;
|
|
@@ -32194,6 +33503,7 @@ var init_xmlBridge = __esm({
|
|
|
32194
33503
|
"use strict";
|
|
32195
33504
|
init_client2();
|
|
32196
33505
|
init_config();
|
|
33506
|
+
init_xmlParsingUtils();
|
|
32197
33507
|
MCPXmlBridge = class {
|
|
32198
33508
|
constructor(options = {}) {
|
|
32199
33509
|
this.debug = options.debug || false;
|
|
@@ -32225,8 +33535,8 @@ var init_xmlBridge = __esm({
|
|
|
32225
33535
|
const result = await this.mcpManager.initialize(mcpConfigs);
|
|
32226
33536
|
const vercelTools = this.mcpManager.getVercelTools();
|
|
32227
33537
|
this.mcpTools = vercelTools;
|
|
32228
|
-
for (const [name14,
|
|
32229
|
-
this.xmlDefinitions[name14] = mcpToolToXmlDefinition(name14,
|
|
33538
|
+
for (const [name14, tool3] of Object.entries(vercelTools)) {
|
|
33539
|
+
this.xmlDefinitions[name14] = mcpToolToXmlDefinition(name14, tool3);
|
|
32230
33540
|
}
|
|
32231
33541
|
if (this.debug) {
|
|
32232
33542
|
console.error(`[MCP] Loaded ${Object.keys(vercelTools).length} MCP tools from ${result.connected} server(s)`);
|
|
@@ -32263,12 +33573,12 @@ var init_xmlBridge = __esm({
|
|
|
32263
33573
|
if (this.debug) {
|
|
32264
33574
|
console.error(`[MCP] Executing MCP tool: ${toolName} with params:`, params);
|
|
32265
33575
|
}
|
|
32266
|
-
const
|
|
32267
|
-
if (!
|
|
33576
|
+
const tool3 = this.mcpTools[toolName];
|
|
33577
|
+
if (!tool3) {
|
|
32268
33578
|
throw new Error(`Unknown MCP tool: ${toolName}`);
|
|
32269
33579
|
}
|
|
32270
33580
|
try {
|
|
32271
|
-
const result = await
|
|
33581
|
+
const result = await tool3.execute(params);
|
|
32272
33582
|
return {
|
|
32273
33583
|
success: true,
|
|
32274
33584
|
toolName,
|
|
@@ -32326,9 +33636,9 @@ import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
|
32326
33636
|
import { streamText } from "ai";
|
|
32327
33637
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
32328
33638
|
import { EventEmitter as EventEmitter2 } from "events";
|
|
32329
|
-
import { existsSync as
|
|
33639
|
+
import { existsSync as existsSync4 } from "fs";
|
|
32330
33640
|
import { readFile, stat } from "fs/promises";
|
|
32331
|
-
import { resolve, isAbsolute } from "path";
|
|
33641
|
+
import { resolve as resolve3, isAbsolute } from "path";
|
|
32332
33642
|
var MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, SUPPORTED_IMAGE_EXTENSIONS, MAX_IMAGE_FILE_SIZE, ProbeAgent;
|
|
32333
33643
|
var init_ProbeAgent = __esm({
|
|
32334
33644
|
"src/agent/ProbeAgent.js"() {
|
|
@@ -32377,6 +33687,8 @@ var init_ProbeAgent = __esm({
|
|
|
32377
33687
|
this.outline = !!options.outline;
|
|
32378
33688
|
this.maxResponseTokens = options.maxResponseTokens || parseInt(process.env.MAX_RESPONSE_TOKENS || "0", 10) || null;
|
|
32379
33689
|
this.disableMermaidValidation = !!options.disableMermaidValidation;
|
|
33690
|
+
this.enableBash = !!options.enableBash;
|
|
33691
|
+
this.bashConfig = options.bashConfig || {};
|
|
32380
33692
|
if (options.allowedFolders && Array.isArray(options.allowedFolders)) {
|
|
32381
33693
|
this.allowedFolders = options.allowedFolders;
|
|
32382
33694
|
} else if (options.path) {
|
|
@@ -32420,7 +33732,9 @@ var init_ProbeAgent = __esm({
|
|
|
32420
33732
|
debug: this.debug,
|
|
32421
33733
|
defaultPath: this.allowedFolders.length > 0 ? this.allowedFolders[0] : process.cwd(),
|
|
32422
33734
|
allowedFolders: this.allowedFolders,
|
|
32423
|
-
outline: this.outline
|
|
33735
|
+
outline: this.outline,
|
|
33736
|
+
enableBash: this.enableBash,
|
|
33737
|
+
bashConfig: this.bashConfig
|
|
32424
33738
|
};
|
|
32425
33739
|
const baseTools = createTools(configOptions);
|
|
32426
33740
|
const wrappedTools = createWrappedTools(baseTools);
|
|
@@ -32432,6 +33746,9 @@ var init_ProbeAgent = __esm({
|
|
|
32432
33746
|
listFiles: listFilesToolInstance,
|
|
32433
33747
|
searchFiles: searchFilesToolInstance
|
|
32434
33748
|
};
|
|
33749
|
+
if (this.enableBash && wrappedTools.bashToolInstance) {
|
|
33750
|
+
this.toolImplementations.bash = wrappedTools.bashToolInstance;
|
|
33751
|
+
}
|
|
32435
33752
|
this.wrappedTools = wrappedTools;
|
|
32436
33753
|
}
|
|
32437
33754
|
/**
|
|
@@ -32620,11 +33937,11 @@ var init_ProbeAgent = __esm({
|
|
|
32620
33937
|
let isPathAllowed = false;
|
|
32621
33938
|
if (isAbsolute(imagePath)) {
|
|
32622
33939
|
absolutePath = imagePath;
|
|
32623
|
-
isPathAllowed = allowedDirs.some((dir) => absolutePath.startsWith(
|
|
33940
|
+
isPathAllowed = allowedDirs.some((dir) => absolutePath.startsWith(resolve3(dir)));
|
|
32624
33941
|
} else {
|
|
32625
33942
|
for (const dir of allowedDirs) {
|
|
32626
|
-
const resolvedPath3 =
|
|
32627
|
-
if (resolvedPath3.startsWith(
|
|
33943
|
+
const resolvedPath3 = resolve3(dir, imagePath);
|
|
33944
|
+
if (resolvedPath3.startsWith(resolve3(dir))) {
|
|
32628
33945
|
absolutePath = resolvedPath3;
|
|
32629
33946
|
isPathAllowed = true;
|
|
32630
33947
|
break;
|
|
@@ -33799,8 +35116,8 @@ import {
|
|
|
33799
35116
|
ListToolsRequestSchema,
|
|
33800
35117
|
McpError
|
|
33801
35118
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
33802
|
-
import { readFileSync as readFileSync2, existsSync as
|
|
33803
|
-
import { resolve as
|
|
35119
|
+
import { readFileSync as readFileSync2, existsSync as existsSync5 } from "fs";
|
|
35120
|
+
import { resolve as resolve4 } from "path";
|
|
33804
35121
|
|
|
33805
35122
|
// src/agent/acp/server.js
|
|
33806
35123
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
@@ -34059,8 +35376,8 @@ var ACPConnection = class extends EventEmitter3 {
|
|
|
34059
35376
|
if (params !== null) {
|
|
34060
35377
|
message.params = params;
|
|
34061
35378
|
}
|
|
34062
|
-
return new Promise((
|
|
34063
|
-
this.pendingRequests.set(id, { resolve:
|
|
35379
|
+
return new Promise((resolve5, reject) => {
|
|
35380
|
+
this.pendingRequests.set(id, { resolve: resolve5, reject });
|
|
34064
35381
|
this.sendMessage(message);
|
|
34065
35382
|
setTimeout(() => {
|
|
34066
35383
|
if (this.pendingRequests.has(id)) {
|
|
@@ -34468,8 +35785,8 @@ import { randomUUID as randomUUID6 } from "crypto";
|
|
|
34468
35785
|
function readInputContent(input) {
|
|
34469
35786
|
if (!input) return null;
|
|
34470
35787
|
try {
|
|
34471
|
-
const resolvedPath3 =
|
|
34472
|
-
if (
|
|
35788
|
+
const resolvedPath3 = resolve4(input);
|
|
35789
|
+
if (existsSync5(resolvedPath3)) {
|
|
34473
35790
|
return readFileSync2(resolvedPath3, "utf-8").trim();
|
|
34474
35791
|
}
|
|
34475
35792
|
} catch (error2) {
|
|
@@ -34477,7 +35794,7 @@ function readInputContent(input) {
|
|
|
34477
35794
|
return input;
|
|
34478
35795
|
}
|
|
34479
35796
|
function readFromStdin() {
|
|
34480
|
-
return new Promise((
|
|
35797
|
+
return new Promise((resolve5, reject) => {
|
|
34481
35798
|
let data2 = "";
|
|
34482
35799
|
let hasReceivedData = false;
|
|
34483
35800
|
let dataChunks = [];
|
|
@@ -34502,7 +35819,7 @@ function readFromStdin() {
|
|
|
34502
35819
|
if (!trimmed && dataChunks.length === 0) {
|
|
34503
35820
|
reject(new Error("No input received from stdin"));
|
|
34504
35821
|
} else {
|
|
34505
|
-
|
|
35822
|
+
resolve5(trimmed);
|
|
34506
35823
|
}
|
|
34507
35824
|
});
|
|
34508
35825
|
process.stdin.on("error", (error2) => {
|
|
@@ -34545,8 +35862,16 @@ function parseArgs() {
|
|
|
34545
35862
|
// New flag to indicate stdin should be used
|
|
34546
35863
|
outline: false,
|
|
34547
35864
|
// New flag to enable outline format
|
|
34548
|
-
noMermaidValidation: false
|
|
35865
|
+
noMermaidValidation: false,
|
|
34549
35866
|
// New flag to disable mermaid validation
|
|
35867
|
+
// Bash tool configuration
|
|
35868
|
+
enableBash: false,
|
|
35869
|
+
bashAllow: null,
|
|
35870
|
+
bashDeny: null,
|
|
35871
|
+
bashTimeout: null,
|
|
35872
|
+
bashWorkingDir: null,
|
|
35873
|
+
disableDefaultBashAllow: false,
|
|
35874
|
+
disableDefaultBashDeny: false
|
|
34550
35875
|
};
|
|
34551
35876
|
for (let i3 = 0; i3 < args.length; i3++) {
|
|
34552
35877
|
const arg = args[i3];
|
|
@@ -34588,6 +35913,20 @@ function parseArgs() {
|
|
|
34588
35913
|
config.outline = true;
|
|
34589
35914
|
} else if (arg === "--no-mermaid-validation") {
|
|
34590
35915
|
config.noMermaidValidation = true;
|
|
35916
|
+
} else if (arg === "--enable-bash") {
|
|
35917
|
+
config.enableBash = true;
|
|
35918
|
+
} else if (arg === "--bash-allow" && i3 + 1 < args.length) {
|
|
35919
|
+
config.bashAllow = args[++i3];
|
|
35920
|
+
} else if (arg === "--bash-deny" && i3 + 1 < args.length) {
|
|
35921
|
+
config.bashDeny = args[++i3];
|
|
35922
|
+
} else if (arg === "--bash-timeout" && i3 + 1 < args.length) {
|
|
35923
|
+
config.bashTimeout = args[++i3];
|
|
35924
|
+
} else if (arg === "--bash-working-dir" && i3 + 1 < args.length) {
|
|
35925
|
+
config.bashWorkingDir = args[++i3];
|
|
35926
|
+
} else if (arg === "--no-default-bash-allow") {
|
|
35927
|
+
config.disableDefaultBashAllow = true;
|
|
35928
|
+
} else if (arg === "--no-default-bash-deny") {
|
|
35929
|
+
config.disableDefaultBashDeny = true;
|
|
34591
35930
|
} else if (!arg.startsWith("--") && !config.question) {
|
|
34592
35931
|
config.question = arg;
|
|
34593
35932
|
}
|
|
@@ -34629,6 +35968,15 @@ Options:
|
|
|
34629
35968
|
--no-mermaid-validation Disable automatic mermaid diagram validation and fixing
|
|
34630
35969
|
--help, -h Show this help message
|
|
34631
35970
|
|
|
35971
|
+
Bash Tool Options:
|
|
35972
|
+
--enable-bash Enable bash command execution for system exploration
|
|
35973
|
+
--bash-allow <patterns> Additional bash command patterns to allow (comma-separated)
|
|
35974
|
+
--bash-deny <patterns> Additional bash command patterns to deny (comma-separated)
|
|
35975
|
+
--no-default-bash-allow Disable default bash allow list (use only custom patterns)
|
|
35976
|
+
--no-default-bash-deny Disable default bash deny list (use only custom patterns)
|
|
35977
|
+
--bash-timeout <ms> Bash command timeout in milliseconds (default: 120000)
|
|
35978
|
+
--bash-working-dir <path> Default working directory for bash commands
|
|
35979
|
+
|
|
34632
35980
|
Environment Variables:
|
|
34633
35981
|
ANTHROPIC_API_KEY Anthropic Claude API key
|
|
34634
35982
|
OPENAI_API_KEY OpenAI GPT API key
|
|
@@ -34965,6 +36313,40 @@ async function main() {
|
|
|
34965
36313
|
process.exit(1);
|
|
34966
36314
|
}
|
|
34967
36315
|
}
|
|
36316
|
+
let bashConfig = null;
|
|
36317
|
+
if (config.enableBash) {
|
|
36318
|
+
bashConfig = {};
|
|
36319
|
+
if (config.bashAllow) {
|
|
36320
|
+
bashConfig.allow = config.bashAllow.split(",").map((p3) => p3.trim()).filter((p3) => p3.length > 0);
|
|
36321
|
+
}
|
|
36322
|
+
if (config.bashDeny) {
|
|
36323
|
+
bashConfig.deny = config.bashDeny.split(",").map((p3) => p3.trim()).filter((p3) => p3.length > 0);
|
|
36324
|
+
}
|
|
36325
|
+
if (config.disableDefaultBashAllow) {
|
|
36326
|
+
bashConfig.disableDefaultAllow = true;
|
|
36327
|
+
}
|
|
36328
|
+
if (config.disableDefaultBashDeny) {
|
|
36329
|
+
bashConfig.disableDefaultDeny = true;
|
|
36330
|
+
}
|
|
36331
|
+
if (config.bashTimeout) {
|
|
36332
|
+
const timeout = parseInt(config.bashTimeout, 10);
|
|
36333
|
+
if (isNaN(timeout) || timeout < 1e3) {
|
|
36334
|
+
console.error("Error: Bash timeout must be a number >= 1000 milliseconds");
|
|
36335
|
+
process.exit(1);
|
|
36336
|
+
}
|
|
36337
|
+
bashConfig.timeout = timeout;
|
|
36338
|
+
}
|
|
36339
|
+
if (config.bashWorkingDir) {
|
|
36340
|
+
if (!existsSync5(config.bashWorkingDir)) {
|
|
36341
|
+
console.error(`Error: Bash working directory does not exist: ${config.bashWorkingDir}`);
|
|
36342
|
+
process.exit(1);
|
|
36343
|
+
}
|
|
36344
|
+
bashConfig.workingDirectory = config.bashWorkingDir;
|
|
36345
|
+
}
|
|
36346
|
+
if (config.verbose) {
|
|
36347
|
+
console.log("Bash command execution enabled");
|
|
36348
|
+
}
|
|
36349
|
+
}
|
|
34968
36350
|
const agentConfig2 = {
|
|
34969
36351
|
path: config.path,
|
|
34970
36352
|
allowedFolders: config.allowedFolders,
|
|
@@ -34975,7 +36357,9 @@ async function main() {
|
|
|
34975
36357
|
tracer: appTracer,
|
|
34976
36358
|
outline: config.outline,
|
|
34977
36359
|
maxResponseTokens: config.maxResponseTokens,
|
|
34978
|
-
disableMermaidValidation: config.noMermaidValidation
|
|
36360
|
+
disableMermaidValidation: config.noMermaidValidation,
|
|
36361
|
+
enableBash: config.enableBash,
|
|
36362
|
+
bashConfig
|
|
34979
36363
|
};
|
|
34980
36364
|
const agent = new ProbeAgent(agentConfig2);
|
|
34981
36365
|
let result;
|