@probelabs/probe 0.6.0-rc105 → 0.6.0-rc107
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 +1523 -145
- package/build/agent/probeTool.js +9 -0
- package/build/agent/schemaUtils.js +89 -12
- package/build/agent/tools.js +13 -1
- 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 +1479 -167
- package/cjs/index.cjs +1554 -176
- package/package.json +9 -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/probeTool.js +9 -0
- package/src/agent/schemaUtils.js +89 -12
- package/src/agent/tools.js +13 -1
- 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,6 +31336,7 @@ 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
|
}
|
|
@@ -30126,8 +31385,8 @@ function checkAttemptCompleteRecovery(cleanedXmlString, validTools = []) {
|
|
|
30126
31385
|
function hasOtherToolTags(xmlString, validTools = []) {
|
|
30127
31386
|
const defaultTools = ["search", "query", "extract", "listFiles", "searchFiles", "implement", "attempt_completion"];
|
|
30128
31387
|
const toolsToCheck = validTools.length > 0 ? validTools : defaultTools;
|
|
30129
|
-
for (const
|
|
30130
|
-
if (
|
|
31388
|
+
for (const tool3 of toolsToCheck) {
|
|
31389
|
+
if (tool3 !== "attempt_completion" && xmlString.includes(`<${tool3}`)) {
|
|
30131
31390
|
return true;
|
|
30132
31391
|
}
|
|
30133
31392
|
}
|
|
@@ -30156,12 +31415,16 @@ var init_xmlParsingUtils = __esm({
|
|
|
30156
31415
|
// src/agent/tools.js
|
|
30157
31416
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
30158
31417
|
function createTools(configOptions) {
|
|
30159
|
-
|
|
31418
|
+
const tools2 = {
|
|
30160
31419
|
searchTool: searchTool(configOptions),
|
|
30161
31420
|
queryTool: queryTool(configOptions),
|
|
30162
31421
|
extractTool: extractTool(configOptions),
|
|
30163
31422
|
delegateTool: delegateTool(configOptions)
|
|
30164
31423
|
};
|
|
31424
|
+
if (configOptions.enableBash) {
|
|
31425
|
+
tools2.bashTool = bashTool(configOptions);
|
|
31426
|
+
}
|
|
31427
|
+
return tools2;
|
|
30165
31428
|
}
|
|
30166
31429
|
function parseXmlToolCallWithThinking(xmlString, validTools) {
|
|
30167
31430
|
const { cleanedXmlString, recoveryResult } = processXmlWithThinkingAndRecovery(xmlString, validTools);
|
|
@@ -30312,6 +31575,13 @@ function createWrappedTools(baseTools) {
|
|
|
30312
31575
|
baseTools.delegateTool.execute
|
|
30313
31576
|
);
|
|
30314
31577
|
}
|
|
31578
|
+
if (baseTools.bashTool) {
|
|
31579
|
+
wrappedTools.bashToolInstance = wrapToolWithEmitter(
|
|
31580
|
+
baseTools.bashTool,
|
|
31581
|
+
"bash",
|
|
31582
|
+
baseTools.bashTool.execute
|
|
31583
|
+
);
|
|
31584
|
+
}
|
|
30315
31585
|
return wrappedTools;
|
|
30316
31586
|
}
|
|
30317
31587
|
var toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
|
|
@@ -30321,9 +31591,9 @@ var init_probeTool = __esm({
|
|
|
30321
31591
|
init_index();
|
|
30322
31592
|
toolCallEmitter = new EventEmitter();
|
|
30323
31593
|
activeToolExecutions = /* @__PURE__ */ new Map();
|
|
30324
|
-
wrapToolWithEmitter = (
|
|
31594
|
+
wrapToolWithEmitter = (tool3, toolName, baseExecute) => {
|
|
30325
31595
|
return {
|
|
30326
|
-
...
|
|
31596
|
+
...tool3,
|
|
30327
31597
|
// Spread schema, description etc.
|
|
30328
31598
|
execute: async (params) => {
|
|
30329
31599
|
const debug = process.env.DEBUG === "1";
|
|
@@ -30464,7 +31734,7 @@ function createMockProvider() {
|
|
|
30464
31734
|
provider: "mock",
|
|
30465
31735
|
// Mock the doGenerate method used by Vercel AI SDK
|
|
30466
31736
|
doGenerate: async ({ messages, tools: tools2 }) => {
|
|
30467
|
-
await new Promise((
|
|
31737
|
+
await new Promise((resolve5) => setTimeout(resolve5, 10));
|
|
30468
31738
|
return {
|
|
30469
31739
|
text: "This is a mock response for testing",
|
|
30470
31740
|
toolCalls: [],
|
|
@@ -31094,11 +32364,19 @@ ${decodedContent}
|
|
|
31094
32364
|
if (trimmedLine.match(/\[[^\]]*\]/)) {
|
|
31095
32365
|
modifiedLine = modifiedLine.replace(/\[([^\]]*)\]/g, (match, content) => {
|
|
31096
32366
|
if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
|
|
32367
|
+
const innerContent = content.trim().slice(1, -1);
|
|
32368
|
+
if (innerContent.includes('"') || innerContent.includes("'")) {
|
|
32369
|
+
wasFixed = true;
|
|
32370
|
+
const decodedContent = decodeHtmlEntities(innerContent);
|
|
32371
|
+
const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
|
|
32372
|
+
return `["${safeContent}"]`;
|
|
32373
|
+
}
|
|
31097
32374
|
return match;
|
|
31098
32375
|
}
|
|
31099
32376
|
if (needsQuoting(content)) {
|
|
31100
32377
|
wasFixed = true;
|
|
31101
|
-
const
|
|
32378
|
+
const decodedContent = decodeHtmlEntities(content);
|
|
32379
|
+
const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
|
|
31102
32380
|
return `["${safeContent}"]`;
|
|
31103
32381
|
}
|
|
31104
32382
|
return match;
|
|
@@ -31107,11 +32385,19 @@ ${decodedContent}
|
|
|
31107
32385
|
if (trimmedLine.match(/\{[^{}]*\}/)) {
|
|
31108
32386
|
modifiedLine = modifiedLine.replace(/\{([^{}]*)\}/g, (match, content) => {
|
|
31109
32387
|
if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
|
|
32388
|
+
const innerContent = content.trim().slice(1, -1);
|
|
32389
|
+
if (innerContent.includes('"') || innerContent.includes("'")) {
|
|
32390
|
+
wasFixed = true;
|
|
32391
|
+
const decodedContent = decodeHtmlEntities(innerContent);
|
|
32392
|
+
const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
|
|
32393
|
+
return `{"${safeContent}"}`;
|
|
32394
|
+
}
|
|
31110
32395
|
return match;
|
|
31111
32396
|
}
|
|
31112
32397
|
if (needsQuoting(content)) {
|
|
31113
32398
|
wasFixed = true;
|
|
31114
|
-
const
|
|
32399
|
+
const decodedContent = decodeHtmlEntities(content);
|
|
32400
|
+
const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
|
|
31115
32401
|
return `{"${safeContent}"}`;
|
|
31116
32402
|
}
|
|
31117
32403
|
return match;
|
|
@@ -31277,11 +32563,19 @@ ${fixedContent}
|
|
|
31277
32563
|
if (trimmedLine.match(/\[[^\]]*\]/)) {
|
|
31278
32564
|
modifiedLine = modifiedLine.replace(/\[([^\]]*)\]/g, (match, content) => {
|
|
31279
32565
|
if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
|
|
32566
|
+
const innerContent = content.trim().slice(1, -1);
|
|
32567
|
+
if (innerContent.includes('"') || innerContent.includes("'")) {
|
|
32568
|
+
wasFixed = true;
|
|
32569
|
+
const decodedContent = decodeHtmlEntities(innerContent);
|
|
32570
|
+
const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
|
|
32571
|
+
return `["${safeContent}"]`;
|
|
32572
|
+
}
|
|
31280
32573
|
return match;
|
|
31281
32574
|
}
|
|
31282
32575
|
if (needsQuoting(content)) {
|
|
31283
32576
|
wasFixed = true;
|
|
31284
|
-
const
|
|
32577
|
+
const decodedContent = decodeHtmlEntities(content);
|
|
32578
|
+
const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
|
|
31285
32579
|
return `["${safeContent}"]`;
|
|
31286
32580
|
}
|
|
31287
32581
|
return match;
|
|
@@ -31290,11 +32584,19 @@ ${fixedContent}
|
|
|
31290
32584
|
if (trimmedLine.match(/\{[^{}]*\}/)) {
|
|
31291
32585
|
modifiedLine = modifiedLine.replace(/\{([^{}]*)\}/g, (match, content) => {
|
|
31292
32586
|
if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
|
|
32587
|
+
const innerContent = content.trim().slice(1, -1);
|
|
32588
|
+
if (innerContent.includes('"') || innerContent.includes("'")) {
|
|
32589
|
+
wasFixed = true;
|
|
32590
|
+
const decodedContent = decodeHtmlEntities(innerContent);
|
|
32591
|
+
const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
|
|
32592
|
+
return `{"${safeContent}"}`;
|
|
32593
|
+
}
|
|
31293
32594
|
return match;
|
|
31294
32595
|
}
|
|
31295
32596
|
if (needsQuoting(content)) {
|
|
31296
32597
|
wasFixed = true;
|
|
31297
|
-
const
|
|
32598
|
+
const decodedContent = decodeHtmlEntities(content);
|
|
32599
|
+
const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
|
|
31298
32600
|
return `{"${safeContent}"}`;
|
|
31299
32601
|
}
|
|
31300
32602
|
return match;
|
|
@@ -31519,6 +32821,8 @@ var init_schemaUtils = __esm({
|
|
|
31519
32821
|
"&": "&",
|
|
31520
32822
|
""": '"',
|
|
31521
32823
|
"'": "'",
|
|
32824
|
+
"'": "'",
|
|
32825
|
+
// Also handle XML/HTML5 apostrophe entity
|
|
31522
32826
|
" ": " "
|
|
31523
32827
|
};
|
|
31524
32828
|
MermaidFixingAgent = class {
|
|
@@ -31690,15 +32994,15 @@ Provide only the corrected Mermaid diagram within a mermaid code block. Do not a
|
|
|
31690
32994
|
});
|
|
31691
32995
|
|
|
31692
32996
|
// src/agent/mcp/config.js
|
|
31693
|
-
import { readFileSync, existsSync as
|
|
31694
|
-
import { join, dirname as dirname2 } from "path";
|
|
32997
|
+
import { readFileSync, existsSync as existsSync3, mkdirSync as mkdirSync2, writeFileSync } from "fs";
|
|
32998
|
+
import { join as join2, dirname as dirname2 } from "path";
|
|
31695
32999
|
import { homedir } from "os";
|
|
31696
33000
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
31697
33001
|
function loadMCPConfigurationFromPath(configPath) {
|
|
31698
33002
|
if (!configPath) {
|
|
31699
33003
|
throw new Error("Config path is required");
|
|
31700
33004
|
}
|
|
31701
|
-
if (!
|
|
33005
|
+
if (!existsSync3(configPath)) {
|
|
31702
33006
|
throw new Error(`MCP configuration file not found: ${configPath}`);
|
|
31703
33007
|
}
|
|
31704
33008
|
try {
|
|
@@ -31717,17 +33021,17 @@ function loadMCPConfiguration() {
|
|
|
31717
33021
|
// Environment variable path
|
|
31718
33022
|
process.env.MCP_CONFIG_PATH,
|
|
31719
33023
|
// Local project paths
|
|
31720
|
-
|
|
31721
|
-
|
|
33024
|
+
join2(process.cwd(), ".mcp", "config.json"),
|
|
33025
|
+
join2(process.cwd(), "mcp.config.json"),
|
|
31722
33026
|
// Home directory paths
|
|
31723
|
-
|
|
31724
|
-
|
|
33027
|
+
join2(homedir(), ".config", "probe", "mcp.json"),
|
|
33028
|
+
join2(homedir(), ".mcp", "config.json"),
|
|
31725
33029
|
// Claude-style config location
|
|
31726
|
-
|
|
33030
|
+
join2(homedir(), "Library", "Application Support", "Claude", "mcp_config.json")
|
|
31727
33031
|
].filter(Boolean);
|
|
31728
33032
|
let config = null;
|
|
31729
33033
|
for (const configPath of configPaths) {
|
|
31730
|
-
if (
|
|
33034
|
+
if (existsSync3(configPath)) {
|
|
31731
33035
|
try {
|
|
31732
33036
|
const content = readFileSync(configPath, "utf8");
|
|
31733
33037
|
config = JSON.parse(content);
|
|
@@ -31836,7 +33140,7 @@ var init_config = __esm({
|
|
|
31836
33140
|
// Example probe server configuration
|
|
31837
33141
|
"probe-local": {
|
|
31838
33142
|
command: "node",
|
|
31839
|
-
args: [
|
|
33143
|
+
args: [join2(__dirname4, "../../../examples/chat/mcpServer.js")],
|
|
31840
33144
|
transport: "stdio",
|
|
31841
33145
|
enabled: false
|
|
31842
33146
|
},
|
|
@@ -31993,12 +33297,12 @@ var init_client2 = __esm({
|
|
|
31993
33297
|
});
|
|
31994
33298
|
const toolsResponse = await client.listTools();
|
|
31995
33299
|
if (toolsResponse && toolsResponse.tools) {
|
|
31996
|
-
for (const
|
|
31997
|
-
const qualifiedName = `${name14}_${
|
|
33300
|
+
for (const tool3 of toolsResponse.tools) {
|
|
33301
|
+
const qualifiedName = `${name14}_${tool3.name}`;
|
|
31998
33302
|
this.tools.set(qualifiedName, {
|
|
31999
|
-
...
|
|
33303
|
+
...tool3,
|
|
32000
33304
|
serverName: name14,
|
|
32001
|
-
originalName:
|
|
33305
|
+
originalName: tool3.name
|
|
32002
33306
|
});
|
|
32003
33307
|
if (this.debug) {
|
|
32004
33308
|
console.error(`[MCP] Registered tool: ${qualifiedName}`);
|
|
@@ -32020,20 +33324,20 @@ var init_client2 = __esm({
|
|
|
32020
33324
|
* @param {Object} args - Tool arguments
|
|
32021
33325
|
*/
|
|
32022
33326
|
async callTool(toolName, args) {
|
|
32023
|
-
const
|
|
32024
|
-
if (!
|
|
33327
|
+
const tool3 = this.tools.get(toolName);
|
|
33328
|
+
if (!tool3) {
|
|
32025
33329
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
32026
33330
|
}
|
|
32027
|
-
const clientInfo = this.clients.get(
|
|
33331
|
+
const clientInfo = this.clients.get(tool3.serverName);
|
|
32028
33332
|
if (!clientInfo) {
|
|
32029
|
-
throw new Error(`Server ${
|
|
33333
|
+
throw new Error(`Server ${tool3.serverName} not connected`);
|
|
32030
33334
|
}
|
|
32031
33335
|
try {
|
|
32032
33336
|
if (this.debug) {
|
|
32033
33337
|
console.error(`[MCP] Calling ${toolName} with args:`, args);
|
|
32034
33338
|
}
|
|
32035
33339
|
const result = await clientInfo.client.callTool({
|
|
32036
|
-
name:
|
|
33340
|
+
name: tool3.originalName,
|
|
32037
33341
|
arguments: args
|
|
32038
33342
|
});
|
|
32039
33343
|
return result;
|
|
@@ -32048,11 +33352,11 @@ var init_client2 = __esm({
|
|
|
32048
33352
|
*/
|
|
32049
33353
|
getTools() {
|
|
32050
33354
|
const tools2 = {};
|
|
32051
|
-
for (const [name14,
|
|
33355
|
+
for (const [name14, tool3] of this.tools.entries()) {
|
|
32052
33356
|
tools2[name14] = {
|
|
32053
|
-
description:
|
|
32054
|
-
inputSchema:
|
|
32055
|
-
serverName:
|
|
33357
|
+
description: tool3.description,
|
|
33358
|
+
inputSchema: tool3.inputSchema,
|
|
33359
|
+
serverName: tool3.serverName
|
|
32056
33360
|
};
|
|
32057
33361
|
}
|
|
32058
33362
|
return tools2;
|
|
@@ -32063,10 +33367,10 @@ var init_client2 = __esm({
|
|
|
32063
33367
|
*/
|
|
32064
33368
|
getVercelTools() {
|
|
32065
33369
|
const tools2 = {};
|
|
32066
|
-
for (const [name14,
|
|
33370
|
+
for (const [name14, tool3] of this.tools.entries()) {
|
|
32067
33371
|
tools2[name14] = {
|
|
32068
|
-
description:
|
|
32069
|
-
inputSchema:
|
|
33372
|
+
description: tool3.description,
|
|
33373
|
+
inputSchema: tool3.inputSchema,
|
|
32070
33374
|
execute: async (args) => {
|
|
32071
33375
|
const result = await this.callTool(name14, args);
|
|
32072
33376
|
if (result.content && result.content[0]) {
|
|
@@ -32103,9 +33407,9 @@ var init_client2 = __esm({
|
|
|
32103
33407
|
});
|
|
32104
33408
|
|
|
32105
33409
|
// src/agent/mcp/xmlBridge.js
|
|
32106
|
-
function mcpToolToXmlDefinition(name14,
|
|
32107
|
-
const description =
|
|
32108
|
-
const inputSchema =
|
|
33410
|
+
function mcpToolToXmlDefinition(name14, tool3) {
|
|
33411
|
+
const description = tool3.description || "MCP tool";
|
|
33412
|
+
const inputSchema = tool3.inputSchema || tool3.parameters || {};
|
|
32109
33413
|
let paramDocs = "";
|
|
32110
33414
|
if (inputSchema.properties) {
|
|
32111
33415
|
paramDocs = "\n\nParameters (provide as JSON object):";
|
|
@@ -32265,8 +33569,8 @@ var init_xmlBridge = __esm({
|
|
|
32265
33569
|
const result = await this.mcpManager.initialize(mcpConfigs);
|
|
32266
33570
|
const vercelTools = this.mcpManager.getVercelTools();
|
|
32267
33571
|
this.mcpTools = vercelTools;
|
|
32268
|
-
for (const [name14,
|
|
32269
|
-
this.xmlDefinitions[name14] = mcpToolToXmlDefinition(name14,
|
|
33572
|
+
for (const [name14, tool3] of Object.entries(vercelTools)) {
|
|
33573
|
+
this.xmlDefinitions[name14] = mcpToolToXmlDefinition(name14, tool3);
|
|
32270
33574
|
}
|
|
32271
33575
|
if (this.debug) {
|
|
32272
33576
|
console.error(`[MCP] Loaded ${Object.keys(vercelTools).length} MCP tools from ${result.connected} server(s)`);
|
|
@@ -32303,12 +33607,12 @@ var init_xmlBridge = __esm({
|
|
|
32303
33607
|
if (this.debug) {
|
|
32304
33608
|
console.error(`[MCP] Executing MCP tool: ${toolName} with params:`, params);
|
|
32305
33609
|
}
|
|
32306
|
-
const
|
|
32307
|
-
if (!
|
|
33610
|
+
const tool3 = this.mcpTools[toolName];
|
|
33611
|
+
if (!tool3) {
|
|
32308
33612
|
throw new Error(`Unknown MCP tool: ${toolName}`);
|
|
32309
33613
|
}
|
|
32310
33614
|
try {
|
|
32311
|
-
const result = await
|
|
33615
|
+
const result = await tool3.execute(params);
|
|
32312
33616
|
return {
|
|
32313
33617
|
success: true,
|
|
32314
33618
|
toolName,
|
|
@@ -32366,9 +33670,9 @@ import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
|
32366
33670
|
import { streamText } from "ai";
|
|
32367
33671
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
32368
33672
|
import { EventEmitter as EventEmitter2 } from "events";
|
|
32369
|
-
import { existsSync as
|
|
33673
|
+
import { existsSync as existsSync4 } from "fs";
|
|
32370
33674
|
import { readFile, stat } from "fs/promises";
|
|
32371
|
-
import { resolve, isAbsolute } from "path";
|
|
33675
|
+
import { resolve as resolve3, isAbsolute } from "path";
|
|
32372
33676
|
var MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, SUPPORTED_IMAGE_EXTENSIONS, MAX_IMAGE_FILE_SIZE, ProbeAgent;
|
|
32373
33677
|
var init_ProbeAgent = __esm({
|
|
32374
33678
|
"src/agent/ProbeAgent.js"() {
|
|
@@ -32417,6 +33721,8 @@ var init_ProbeAgent = __esm({
|
|
|
32417
33721
|
this.outline = !!options.outline;
|
|
32418
33722
|
this.maxResponseTokens = options.maxResponseTokens || parseInt(process.env.MAX_RESPONSE_TOKENS || "0", 10) || null;
|
|
32419
33723
|
this.disableMermaidValidation = !!options.disableMermaidValidation;
|
|
33724
|
+
this.enableBash = !!options.enableBash;
|
|
33725
|
+
this.bashConfig = options.bashConfig || {};
|
|
32420
33726
|
if (options.allowedFolders && Array.isArray(options.allowedFolders)) {
|
|
32421
33727
|
this.allowedFolders = options.allowedFolders;
|
|
32422
33728
|
} else if (options.path) {
|
|
@@ -32460,7 +33766,9 @@ var init_ProbeAgent = __esm({
|
|
|
32460
33766
|
debug: this.debug,
|
|
32461
33767
|
defaultPath: this.allowedFolders.length > 0 ? this.allowedFolders[0] : process.cwd(),
|
|
32462
33768
|
allowedFolders: this.allowedFolders,
|
|
32463
|
-
outline: this.outline
|
|
33769
|
+
outline: this.outline,
|
|
33770
|
+
enableBash: this.enableBash,
|
|
33771
|
+
bashConfig: this.bashConfig
|
|
32464
33772
|
};
|
|
32465
33773
|
const baseTools = createTools(configOptions);
|
|
32466
33774
|
const wrappedTools = createWrappedTools(baseTools);
|
|
@@ -32472,6 +33780,9 @@ var init_ProbeAgent = __esm({
|
|
|
32472
33780
|
listFiles: listFilesToolInstance,
|
|
32473
33781
|
searchFiles: searchFilesToolInstance
|
|
32474
33782
|
};
|
|
33783
|
+
if (this.enableBash && wrappedTools.bashToolInstance) {
|
|
33784
|
+
this.toolImplementations.bash = wrappedTools.bashToolInstance;
|
|
33785
|
+
}
|
|
32475
33786
|
this.wrappedTools = wrappedTools;
|
|
32476
33787
|
}
|
|
32477
33788
|
/**
|
|
@@ -32660,11 +33971,11 @@ var init_ProbeAgent = __esm({
|
|
|
32660
33971
|
let isPathAllowed = false;
|
|
32661
33972
|
if (isAbsolute(imagePath)) {
|
|
32662
33973
|
absolutePath = imagePath;
|
|
32663
|
-
isPathAllowed = allowedDirs.some((dir) => absolutePath.startsWith(
|
|
33974
|
+
isPathAllowed = allowedDirs.some((dir) => absolutePath.startsWith(resolve3(dir)));
|
|
32664
33975
|
} else {
|
|
32665
33976
|
for (const dir of allowedDirs) {
|
|
32666
|
-
const resolvedPath3 =
|
|
32667
|
-
if (resolvedPath3.startsWith(
|
|
33977
|
+
const resolvedPath3 = resolve3(dir, imagePath);
|
|
33978
|
+
if (resolvedPath3.startsWith(resolve3(dir))) {
|
|
32668
33979
|
absolutePath = resolvedPath3;
|
|
32669
33980
|
isPathAllowed = true;
|
|
32670
33981
|
break;
|
|
@@ -33839,8 +35150,8 @@ import {
|
|
|
33839
35150
|
ListToolsRequestSchema,
|
|
33840
35151
|
McpError
|
|
33841
35152
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
33842
|
-
import { readFileSync as readFileSync2, existsSync as
|
|
33843
|
-
import { resolve as
|
|
35153
|
+
import { readFileSync as readFileSync2, existsSync as existsSync5 } from "fs";
|
|
35154
|
+
import { resolve as resolve4 } from "path";
|
|
33844
35155
|
|
|
33845
35156
|
// src/agent/acp/server.js
|
|
33846
35157
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
@@ -34099,8 +35410,8 @@ var ACPConnection = class extends EventEmitter3 {
|
|
|
34099
35410
|
if (params !== null) {
|
|
34100
35411
|
message.params = params;
|
|
34101
35412
|
}
|
|
34102
|
-
return new Promise((
|
|
34103
|
-
this.pendingRequests.set(id, { resolve:
|
|
35413
|
+
return new Promise((resolve5, reject) => {
|
|
35414
|
+
this.pendingRequests.set(id, { resolve: resolve5, reject });
|
|
34104
35415
|
this.sendMessage(message);
|
|
34105
35416
|
setTimeout(() => {
|
|
34106
35417
|
if (this.pendingRequests.has(id)) {
|
|
@@ -34508,8 +35819,8 @@ import { randomUUID as randomUUID6 } from "crypto";
|
|
|
34508
35819
|
function readInputContent(input) {
|
|
34509
35820
|
if (!input) return null;
|
|
34510
35821
|
try {
|
|
34511
|
-
const resolvedPath3 =
|
|
34512
|
-
if (
|
|
35822
|
+
const resolvedPath3 = resolve4(input);
|
|
35823
|
+
if (existsSync5(resolvedPath3)) {
|
|
34513
35824
|
return readFileSync2(resolvedPath3, "utf-8").trim();
|
|
34514
35825
|
}
|
|
34515
35826
|
} catch (error2) {
|
|
@@ -34517,7 +35828,7 @@ function readInputContent(input) {
|
|
|
34517
35828
|
return input;
|
|
34518
35829
|
}
|
|
34519
35830
|
function readFromStdin() {
|
|
34520
|
-
return new Promise((
|
|
35831
|
+
return new Promise((resolve5, reject) => {
|
|
34521
35832
|
let data2 = "";
|
|
34522
35833
|
let hasReceivedData = false;
|
|
34523
35834
|
let dataChunks = [];
|
|
@@ -34542,7 +35853,7 @@ function readFromStdin() {
|
|
|
34542
35853
|
if (!trimmed && dataChunks.length === 0) {
|
|
34543
35854
|
reject(new Error("No input received from stdin"));
|
|
34544
35855
|
} else {
|
|
34545
|
-
|
|
35856
|
+
resolve5(trimmed);
|
|
34546
35857
|
}
|
|
34547
35858
|
});
|
|
34548
35859
|
process.stdin.on("error", (error2) => {
|
|
@@ -34585,8 +35896,16 @@ function parseArgs() {
|
|
|
34585
35896
|
// New flag to indicate stdin should be used
|
|
34586
35897
|
outline: false,
|
|
34587
35898
|
// New flag to enable outline format
|
|
34588
|
-
noMermaidValidation: false
|
|
35899
|
+
noMermaidValidation: false,
|
|
34589
35900
|
// New flag to disable mermaid validation
|
|
35901
|
+
// Bash tool configuration
|
|
35902
|
+
enableBash: false,
|
|
35903
|
+
bashAllow: null,
|
|
35904
|
+
bashDeny: null,
|
|
35905
|
+
bashTimeout: null,
|
|
35906
|
+
bashWorkingDir: null,
|
|
35907
|
+
disableDefaultBashAllow: false,
|
|
35908
|
+
disableDefaultBashDeny: false
|
|
34590
35909
|
};
|
|
34591
35910
|
for (let i3 = 0; i3 < args.length; i3++) {
|
|
34592
35911
|
const arg = args[i3];
|
|
@@ -34628,6 +35947,20 @@ function parseArgs() {
|
|
|
34628
35947
|
config.outline = true;
|
|
34629
35948
|
} else if (arg === "--no-mermaid-validation") {
|
|
34630
35949
|
config.noMermaidValidation = true;
|
|
35950
|
+
} else if (arg === "--enable-bash") {
|
|
35951
|
+
config.enableBash = true;
|
|
35952
|
+
} else if (arg === "--bash-allow" && i3 + 1 < args.length) {
|
|
35953
|
+
config.bashAllow = args[++i3];
|
|
35954
|
+
} else if (arg === "--bash-deny" && i3 + 1 < args.length) {
|
|
35955
|
+
config.bashDeny = args[++i3];
|
|
35956
|
+
} else if (arg === "--bash-timeout" && i3 + 1 < args.length) {
|
|
35957
|
+
config.bashTimeout = args[++i3];
|
|
35958
|
+
} else if (arg === "--bash-working-dir" && i3 + 1 < args.length) {
|
|
35959
|
+
config.bashWorkingDir = args[++i3];
|
|
35960
|
+
} else if (arg === "--no-default-bash-allow") {
|
|
35961
|
+
config.disableDefaultBashAllow = true;
|
|
35962
|
+
} else if (arg === "--no-default-bash-deny") {
|
|
35963
|
+
config.disableDefaultBashDeny = true;
|
|
34631
35964
|
} else if (!arg.startsWith("--") && !config.question) {
|
|
34632
35965
|
config.question = arg;
|
|
34633
35966
|
}
|
|
@@ -34669,6 +36002,15 @@ Options:
|
|
|
34669
36002
|
--no-mermaid-validation Disable automatic mermaid diagram validation and fixing
|
|
34670
36003
|
--help, -h Show this help message
|
|
34671
36004
|
|
|
36005
|
+
Bash Tool Options:
|
|
36006
|
+
--enable-bash Enable bash command execution for system exploration
|
|
36007
|
+
--bash-allow <patterns> Additional bash command patterns to allow (comma-separated)
|
|
36008
|
+
--bash-deny <patterns> Additional bash command patterns to deny (comma-separated)
|
|
36009
|
+
--no-default-bash-allow Disable default bash allow list (use only custom patterns)
|
|
36010
|
+
--no-default-bash-deny Disable default bash deny list (use only custom patterns)
|
|
36011
|
+
--bash-timeout <ms> Bash command timeout in milliseconds (default: 120000)
|
|
36012
|
+
--bash-working-dir <path> Default working directory for bash commands
|
|
36013
|
+
|
|
34672
36014
|
Environment Variables:
|
|
34673
36015
|
ANTHROPIC_API_KEY Anthropic Claude API key
|
|
34674
36016
|
OPENAI_API_KEY OpenAI GPT API key
|
|
@@ -35005,6 +36347,40 @@ async function main() {
|
|
|
35005
36347
|
process.exit(1);
|
|
35006
36348
|
}
|
|
35007
36349
|
}
|
|
36350
|
+
let bashConfig = null;
|
|
36351
|
+
if (config.enableBash) {
|
|
36352
|
+
bashConfig = {};
|
|
36353
|
+
if (config.bashAllow) {
|
|
36354
|
+
bashConfig.allow = config.bashAllow.split(",").map((p3) => p3.trim()).filter((p3) => p3.length > 0);
|
|
36355
|
+
}
|
|
36356
|
+
if (config.bashDeny) {
|
|
36357
|
+
bashConfig.deny = config.bashDeny.split(",").map((p3) => p3.trim()).filter((p3) => p3.length > 0);
|
|
36358
|
+
}
|
|
36359
|
+
if (config.disableDefaultBashAllow) {
|
|
36360
|
+
bashConfig.disableDefaultAllow = true;
|
|
36361
|
+
}
|
|
36362
|
+
if (config.disableDefaultBashDeny) {
|
|
36363
|
+
bashConfig.disableDefaultDeny = true;
|
|
36364
|
+
}
|
|
36365
|
+
if (config.bashTimeout) {
|
|
36366
|
+
const timeout = parseInt(config.bashTimeout, 10);
|
|
36367
|
+
if (isNaN(timeout) || timeout < 1e3) {
|
|
36368
|
+
console.error("Error: Bash timeout must be a number >= 1000 milliseconds");
|
|
36369
|
+
process.exit(1);
|
|
36370
|
+
}
|
|
36371
|
+
bashConfig.timeout = timeout;
|
|
36372
|
+
}
|
|
36373
|
+
if (config.bashWorkingDir) {
|
|
36374
|
+
if (!existsSync5(config.bashWorkingDir)) {
|
|
36375
|
+
console.error(`Error: Bash working directory does not exist: ${config.bashWorkingDir}`);
|
|
36376
|
+
process.exit(1);
|
|
36377
|
+
}
|
|
36378
|
+
bashConfig.workingDirectory = config.bashWorkingDir;
|
|
36379
|
+
}
|
|
36380
|
+
if (config.verbose) {
|
|
36381
|
+
console.log("Bash command execution enabled");
|
|
36382
|
+
}
|
|
36383
|
+
}
|
|
35008
36384
|
const agentConfig2 = {
|
|
35009
36385
|
path: config.path,
|
|
35010
36386
|
allowedFolders: config.allowedFolders,
|
|
@@ -35015,7 +36391,9 @@ async function main() {
|
|
|
35015
36391
|
tracer: appTracer,
|
|
35016
36392
|
outline: config.outline,
|
|
35017
36393
|
maxResponseTokens: config.maxResponseTokens,
|
|
35018
|
-
disableMermaidValidation: config.noMermaidValidation
|
|
36394
|
+
disableMermaidValidation: config.noMermaidValidation,
|
|
36395
|
+
enableBash: config.enableBash,
|
|
36396
|
+
bashConfig
|
|
35019
36397
|
};
|
|
35020
36398
|
const agent = new ProbeAgent(agentConfig2);
|
|
35021
36399
|
let result;
|