@probelabs/visor 0.1.49 → 0.1.51
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/dist/ai-review-service.d.ts.map +1 -1
- package/dist/check-execution-engine.d.ts +1 -0
- package/dist/check-execution-engine.d.ts.map +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/index.js +2273 -304
- package/dist/liquid-extensions.d.ts +19 -0
- package/dist/liquid-extensions.d.ts.map +1 -0
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/providers/claude-code-check-provider.d.ts.map +1 -1
- package/dist/providers/command-check-provider.d.ts +19 -0
- package/dist/providers/command-check-provider.d.ts.map +1 -1
- package/dist/providers/http-check-provider.d.ts.map +1 -1
- package/dist/providers/http-client-provider.d.ts.map +1 -1
- package/dist/providers/http-input-provider.d.ts.map +1 -1
- package/dist/providers/log-check-provider.d.ts.map +1 -1
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/webhook-server.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
process.env.VISOR_VERSION = '0.1.
|
|
2
|
+
process.env.VISOR_VERSION = '0.1.51';
|
|
3
3
|
/******/ (() => { // webpackBootstrap
|
|
4
4
|
/******/ var __webpack_modules__ = ({
|
|
5
5
|
|
|
@@ -94138,11 +94138,12 @@ ${prContext}
|
|
|
94138
94138
|
*/
|
|
94139
94139
|
formatPRContext(prInfo) {
|
|
94140
94140
|
// Check if this is an issue (not a PR)
|
|
94141
|
-
const
|
|
94141
|
+
const prContextInfo = prInfo;
|
|
94142
|
+
const isIssue = prContextInfo.isIssue === true;
|
|
94142
94143
|
// Check if we should include code context (diffs)
|
|
94143
|
-
const isPRContext =
|
|
94144
|
+
const isPRContext = prContextInfo.isPRContext === true;
|
|
94144
94145
|
// In PR context, always include diffs. Otherwise check the flag.
|
|
94145
|
-
const includeCodeContext = isPRContext ||
|
|
94146
|
+
const includeCodeContext = isPRContext || prContextInfo.includeCodeContext !== false;
|
|
94146
94147
|
// Log the decision for transparency
|
|
94147
94148
|
const log = this.config.debug ? console.error : () => { };
|
|
94148
94149
|
if (isPRContext) {
|
|
@@ -94486,12 +94487,16 @@ ${prInfo.fullDiff ? this.escapeXml(prInfo.fullDiff) : ''}
|
|
|
94486
94487
|
if (this.config.provider) {
|
|
94487
94488
|
// Map claude-code to anthropic for ProbeAgent compatibility
|
|
94488
94489
|
// Map bedrock to anthropic temporarily until ProbeAgent adds bedrock type
|
|
94489
|
-
|
|
94490
|
-
|
|
94491
|
-
|
|
94492
|
-
|
|
94493
|
-
|
|
94494
|
-
|
|
94490
|
+
const providerOverride = this.config.provider === 'claude-code' || this.config.provider === 'bedrock'
|
|
94491
|
+
? 'anthropic'
|
|
94492
|
+
: this.config.provider === 'anthropic' ||
|
|
94493
|
+
this.config.provider === 'openai' ||
|
|
94494
|
+
this.config.provider === 'google'
|
|
94495
|
+
? this.config.provider
|
|
94496
|
+
: undefined;
|
|
94497
|
+
if (providerOverride) {
|
|
94498
|
+
options.provider = providerOverride;
|
|
94499
|
+
}
|
|
94495
94500
|
}
|
|
94496
94501
|
if (this.config.model) {
|
|
94497
94502
|
options.model = this.config.model;
|
|
@@ -95230,7 +95235,6 @@ class CheckExecutionEngine {
|
|
|
95230
95235
|
const result = await tasks[taskIndex]();
|
|
95231
95236
|
results[taskIndex] = { status: 'fulfilled', value: result };
|
|
95232
95237
|
// Check if we should stop due to fail-fast
|
|
95233
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
95234
95238
|
if (failFast && this.shouldFailFast(result)) {
|
|
95235
95239
|
shouldStop = true;
|
|
95236
95240
|
break;
|
|
@@ -95263,7 +95267,11 @@ class CheckExecutionEngine {
|
|
|
95263
95267
|
// Store config for use in filtering
|
|
95264
95268
|
this.config = config;
|
|
95265
95269
|
// Determine where to send log messages based on output format
|
|
95266
|
-
const logFn = outputFormat === 'json' || outputFormat === 'sarif'
|
|
95270
|
+
const logFn = outputFormat === 'json' || outputFormat === 'sarif'
|
|
95271
|
+
? debug
|
|
95272
|
+
? console.error
|
|
95273
|
+
: () => { }
|
|
95274
|
+
: console.log;
|
|
95267
95275
|
// Only output debug messages if debug mode is enabled
|
|
95268
95276
|
if (debug) {
|
|
95269
95277
|
logFn(`🔧 Debug: executeReviewChecks called with checks: ${JSON.stringify(checks)}`);
|
|
@@ -95385,7 +95393,11 @@ class CheckExecutionEngine {
|
|
|
95385
95393
|
*/
|
|
95386
95394
|
async executeGroupedChecks(prInfo, checks, timeout, config, outputFormat, debug, maxParallelism, failFast, tagFilter) {
|
|
95387
95395
|
// Determine where to send log messages based on output format
|
|
95388
|
-
const logFn = outputFormat === 'json' || outputFormat === 'sarif'
|
|
95396
|
+
const logFn = outputFormat === 'json' || outputFormat === 'sarif'
|
|
95397
|
+
? debug
|
|
95398
|
+
? console.error
|
|
95399
|
+
: () => { }
|
|
95400
|
+
: console.log;
|
|
95389
95401
|
// Only output debug messages if debug mode is enabled
|
|
95390
95402
|
if (debug) {
|
|
95391
95403
|
logFn(`🔧 Debug: executeGroupedChecks called with checks: ${JSON.stringify(checks)}`);
|
|
@@ -95465,6 +95477,7 @@ class CheckExecutionEngine {
|
|
|
95465
95477
|
// Pass any provider-specific config
|
|
95466
95478
|
...checkConfig,
|
|
95467
95479
|
};
|
|
95480
|
+
providerConfig.forEach = checkConfig.forEach;
|
|
95468
95481
|
const result = await provider.execute(prInfo, providerConfig);
|
|
95469
95482
|
// Render the check content using the appropriate template
|
|
95470
95483
|
const content = await this.renderCheckContent(checkName, result, checkConfig, prInfo);
|
|
@@ -95490,6 +95503,7 @@ class CheckExecutionEngine {
|
|
|
95490
95503
|
*/
|
|
95491
95504
|
async convertReviewSummaryToGroupedResults(reviewSummary, checks, config, prInfo) {
|
|
95492
95505
|
const groupedResults = {};
|
|
95506
|
+
const contentMap = reviewSummary.__contents;
|
|
95493
95507
|
// Process each check individually
|
|
95494
95508
|
for (const checkName of checks) {
|
|
95495
95509
|
const checkConfig = config?.checks?.[checkName];
|
|
@@ -95502,6 +95516,10 @@ class CheckExecutionEngine {
|
|
|
95502
95516
|
issues: checkIssues,
|
|
95503
95517
|
debug: reviewSummary.debug,
|
|
95504
95518
|
};
|
|
95519
|
+
if (contentMap?.[checkName]) {
|
|
95520
|
+
const summaryWithContent = checkSummary;
|
|
95521
|
+
summaryWithContent.content = contentMap[checkName];
|
|
95522
|
+
}
|
|
95505
95523
|
// Render content for this check
|
|
95506
95524
|
const content = await this.renderCheckContent(checkName, checkSummary, checkConfig, prInfo);
|
|
95507
95525
|
const checkResult = {
|
|
@@ -95583,11 +95601,15 @@ class CheckExecutionEngine {
|
|
|
95583
95601
|
* Render check content using the appropriate template
|
|
95584
95602
|
*/
|
|
95585
95603
|
async renderCheckContent(checkName, reviewSummary, checkConfig, _prInfo) {
|
|
95604
|
+
const directContent = reviewSummary.content;
|
|
95605
|
+
if (typeof directContent === 'string' && directContent.trim()) {
|
|
95606
|
+
return directContent.trim();
|
|
95607
|
+
}
|
|
95586
95608
|
// Import the liquid template system
|
|
95587
|
-
const {
|
|
95609
|
+
const { createExtendedLiquid } = await Promise.resolve().then(() => __importStar(__nccwpck_require__(33042)));
|
|
95588
95610
|
const fs = await Promise.resolve().then(() => __importStar(__nccwpck_require__(91943)));
|
|
95589
95611
|
const path = await Promise.resolve().then(() => __importStar(__nccwpck_require__(16928)));
|
|
95590
|
-
const liquid =
|
|
95612
|
+
const liquid = createExtendedLiquid({
|
|
95591
95613
|
trimTagLeft: false,
|
|
95592
95614
|
trimTagRight: false,
|
|
95593
95615
|
trimOutputLeft: false,
|
|
@@ -95768,6 +95790,7 @@ class CheckExecutionEngine {
|
|
|
95768
95790
|
const provider = this.providerRegistry.getProviderOrThrow(providerType);
|
|
95769
95791
|
this.setProviderWebhookContext(provider);
|
|
95770
95792
|
// Create provider config for this specific check
|
|
95793
|
+
const extendedCheckConfig = checkConfig;
|
|
95771
95794
|
const providerConfig = {
|
|
95772
95795
|
type: providerType,
|
|
95773
95796
|
prompt: checkConfig.prompt,
|
|
@@ -95778,9 +95801,11 @@ class CheckExecutionEngine {
|
|
|
95778
95801
|
checkName: checkName, // Add checkName for sessionID
|
|
95779
95802
|
eventContext: prInfo.eventContext, // Pass event context for templates
|
|
95780
95803
|
transform: checkConfig.transform,
|
|
95781
|
-
|
|
95782
|
-
|
|
95804
|
+
transform_js: checkConfig.transform_js,
|
|
95805
|
+
level: extendedCheckConfig.level,
|
|
95806
|
+
message: extendedCheckConfig.message,
|
|
95783
95807
|
env: checkConfig.env,
|
|
95808
|
+
forEach: checkConfig.forEach,
|
|
95784
95809
|
ai: {
|
|
95785
95810
|
timeout: timeout || 600000,
|
|
95786
95811
|
debug: debug,
|
|
@@ -95797,9 +95822,10 @@ class CheckExecutionEngine {
|
|
|
95797
95822
|
const depResult = results.get(depId);
|
|
95798
95823
|
dependencyResults.set(depId, depResult);
|
|
95799
95824
|
// Check if this dependency has forEach enabled
|
|
95800
|
-
|
|
95825
|
+
const depForEachResult = depResult;
|
|
95826
|
+
if (depForEachResult.isForEach && Array.isArray(depForEachResult.forEachItems)) {
|
|
95801
95827
|
isForEachDependent = true;
|
|
95802
|
-
forEachItems =
|
|
95828
|
+
forEachItems = depForEachResult.forEachItems;
|
|
95803
95829
|
forEachParentName = depId;
|
|
95804
95830
|
}
|
|
95805
95831
|
}
|
|
@@ -95836,17 +95862,22 @@ class CheckExecutionEngine {
|
|
|
95836
95862
|
log(`🔄 Debug: Check "${checkName}" depends on forEach check "${forEachParentName}", executing ${forEachItems.length} times`);
|
|
95837
95863
|
const allIssues = [];
|
|
95838
95864
|
const allOutputs = [];
|
|
95839
|
-
|
|
95840
|
-
|
|
95841
|
-
const item = forEachItems[itemIndex];
|
|
95865
|
+
const aggregatedContents = [];
|
|
95866
|
+
const itemTasks = forEachItems.map((item, itemIndex) => async () => {
|
|
95842
95867
|
// Create modified dependency results with current item
|
|
95843
95868
|
const forEachDependencyResults = new Map();
|
|
95844
95869
|
for (const [depName, depResult] of dependencyResults) {
|
|
95845
95870
|
if (depName === forEachParentName) {
|
|
95846
|
-
|
|
95847
|
-
|
|
95848
|
-
|
|
95871
|
+
const modifiedResult = {
|
|
95872
|
+
issues: [],
|
|
95873
|
+
output: item,
|
|
95874
|
+
};
|
|
95849
95875
|
forEachDependencyResults.set(depName, modifiedResult);
|
|
95876
|
+
const rawResult = {
|
|
95877
|
+
issues: [],
|
|
95878
|
+
output: forEachItems,
|
|
95879
|
+
};
|
|
95880
|
+
forEachDependencyResults.set(`${depName}-raw`, rawResult);
|
|
95850
95881
|
}
|
|
95851
95882
|
else {
|
|
95852
95883
|
forEachDependencyResults.set(depName, depResult);
|
|
@@ -95854,24 +95885,49 @@ class CheckExecutionEngine {
|
|
|
95854
95885
|
}
|
|
95855
95886
|
log(`🔄 Debug: Executing check "${checkName}" for item ${itemIndex + 1}/${forEachItems.length}`);
|
|
95856
95887
|
const itemResult = await provider.execute(prInfo, providerConfig, forEachDependencyResults, sessionInfo);
|
|
95857
|
-
|
|
95888
|
+
return { index: itemIndex, itemResult };
|
|
95889
|
+
});
|
|
95890
|
+
const forEachConcurrency = Math.max(1, Math.min(forEachItems.length, effectiveMaxParallelism));
|
|
95891
|
+
if (debug && forEachConcurrency > 1) {
|
|
95892
|
+
log(`🔄 Debug: Limiting forEach concurrency for check "${checkName}" to ${forEachConcurrency}`);
|
|
95893
|
+
}
|
|
95894
|
+
const forEachResults = await this.executeWithLimitedParallelism(itemTasks, forEachConcurrency, false);
|
|
95895
|
+
for (const result of forEachResults) {
|
|
95896
|
+
if (result.status === 'rejected') {
|
|
95897
|
+
throw result.reason;
|
|
95898
|
+
}
|
|
95899
|
+
const { itemResult } = result.value;
|
|
95858
95900
|
if (itemResult.issues) {
|
|
95859
95901
|
allIssues.push(...itemResult.issues);
|
|
95860
95902
|
}
|
|
95861
|
-
|
|
95862
|
-
if (
|
|
95863
|
-
allOutputs.push(
|
|
95903
|
+
const resultWithOutput = itemResult;
|
|
95904
|
+
if (resultWithOutput.output !== undefined) {
|
|
95905
|
+
allOutputs.push(resultWithOutput.output);
|
|
95906
|
+
}
|
|
95907
|
+
const itemContent = resultWithOutput.content;
|
|
95908
|
+
if (typeof itemContent === 'string' && itemContent.trim()) {
|
|
95909
|
+
aggregatedContents.push(itemContent.trim());
|
|
95864
95910
|
}
|
|
95865
95911
|
}
|
|
95912
|
+
const finalOutput = allOutputs.length > 0 ? allOutputs : undefined;
|
|
95866
95913
|
finalResult = {
|
|
95867
95914
|
issues: allIssues,
|
|
95868
|
-
|
|
95915
|
+
...(finalOutput !== undefined ? { output: finalOutput } : {}),
|
|
95869
95916
|
};
|
|
95917
|
+
if (aggregatedContents.length > 0) {
|
|
95918
|
+
finalResult.content =
|
|
95919
|
+
aggregatedContents.join('\n');
|
|
95920
|
+
}
|
|
95870
95921
|
log(`🔄 Debug: Completed forEach execution for check "${checkName}", total issues: ${allIssues.length}`);
|
|
95871
95922
|
}
|
|
95872
95923
|
else {
|
|
95873
95924
|
// Normal single execution
|
|
95874
95925
|
finalResult = await provider.execute(prInfo, providerConfig, dependencyResults, sessionInfo);
|
|
95926
|
+
if (process.env.DEBUG && checkConfig.forEach) {
|
|
95927
|
+
const finalResultWithOutput = finalResult;
|
|
95928
|
+
const outputPreview = JSON.stringify(finalResultWithOutput.output).slice(0, 200);
|
|
95929
|
+
console.log(`🔧 Debug: Check "${checkName}" provider returned:`, outputPreview);
|
|
95930
|
+
}
|
|
95875
95931
|
log(`🔧 Debug: Completed check: ${checkName}, issues found: ${(finalResult.issues || []).length}`);
|
|
95876
95932
|
}
|
|
95877
95933
|
// Add group, schema, template info and timestamp to issues from config
|
|
@@ -95913,28 +95969,39 @@ class CheckExecutionEngine {
|
|
|
95913
95969
|
if (result.status === 'fulfilled' && result.value.result && !result.value.error) {
|
|
95914
95970
|
const reviewResult = result.value.result;
|
|
95915
95971
|
// Handle forEach logic - process array outputs
|
|
95916
|
-
|
|
95917
|
-
|
|
95918
|
-
|
|
95919
|
-
|
|
95920
|
-
|
|
95921
|
-
|
|
95922
|
-
|
|
95923
|
-
|
|
95924
|
-
|
|
95925
|
-
|
|
95926
|
-
|
|
95927
|
-
|
|
95928
|
-
|
|
95972
|
+
const reviewSummaryWithOutput = reviewResult;
|
|
95973
|
+
if (checkConfig?.forEach && reviewSummaryWithOutput.output !== undefined) {
|
|
95974
|
+
if (process.env.DEBUG) {
|
|
95975
|
+
console.log(`🔧 Debug: Raw output for forEach check ${checkName}:`, Array.isArray(reviewSummaryWithOutput.output)
|
|
95976
|
+
? `array(${reviewSummaryWithOutput.output.length})`
|
|
95977
|
+
: typeof reviewSummaryWithOutput.output);
|
|
95978
|
+
}
|
|
95979
|
+
const rawOutput = reviewSummaryWithOutput.output;
|
|
95980
|
+
let normalizedOutput;
|
|
95981
|
+
if (Array.isArray(rawOutput)) {
|
|
95982
|
+
normalizedOutput = rawOutput;
|
|
95983
|
+
}
|
|
95984
|
+
else if (typeof rawOutput === 'string') {
|
|
95985
|
+
try {
|
|
95986
|
+
const parsed = JSON.parse(rawOutput);
|
|
95987
|
+
normalizedOutput = Array.isArray(parsed) ? parsed : [parsed];
|
|
95929
95988
|
}
|
|
95930
|
-
|
|
95931
|
-
|
|
95989
|
+
catch {
|
|
95990
|
+
normalizedOutput = [rawOutput];
|
|
95932
95991
|
}
|
|
95933
95992
|
}
|
|
95934
|
-
|
|
95993
|
+
else if (rawOutput === undefined || rawOutput === null) {
|
|
95994
|
+
normalizedOutput = [];
|
|
95995
|
+
}
|
|
95996
|
+
else {
|
|
95997
|
+
normalizedOutput = [rawOutput];
|
|
95998
|
+
}
|
|
95999
|
+
if (process.env.DEBUG) {
|
|
96000
|
+
console.log(`🔧 Debug: Check "${checkName}" forEach output:`, JSON.stringify(normalizedOutput).slice(0, 200));
|
|
96001
|
+
}
|
|
95935
96002
|
// Store the array for iteration by dependent checks
|
|
95936
|
-
|
|
95937
|
-
|
|
96003
|
+
reviewSummaryWithOutput.forEachItems = normalizedOutput;
|
|
96004
|
+
reviewSummaryWithOutput.isForEach = true;
|
|
95938
96005
|
}
|
|
95939
96006
|
results.set(checkName, reviewResult);
|
|
95940
96007
|
}
|
|
@@ -96177,6 +96244,7 @@ class CheckExecutionEngine {
|
|
|
96177
96244
|
aggregateDependencyAwareResults(results, dependencyGraph, debug, stoppedEarly) {
|
|
96178
96245
|
const aggregatedIssues = [];
|
|
96179
96246
|
const debugInfo = [];
|
|
96247
|
+
const contentMap = {};
|
|
96180
96248
|
// Add execution plan info
|
|
96181
96249
|
const stats = dependency_resolver_1.DependencyResolver.getExecutionStats(dependencyGraph);
|
|
96182
96250
|
const executionInfo = [
|
|
@@ -96209,9 +96277,16 @@ class CheckExecutionEngine {
|
|
|
96209
96277
|
}
|
|
96210
96278
|
// Issues are already prefixed and enriched with group/schema info
|
|
96211
96279
|
aggregatedIssues.push(...(result.issues || []));
|
|
96280
|
+
const resultSummary = result;
|
|
96281
|
+
const resultContent = resultSummary.content;
|
|
96282
|
+
if (typeof resultContent === 'string' && resultContent.trim()) {
|
|
96283
|
+
contentMap[checkName] = resultContent.trim();
|
|
96284
|
+
}
|
|
96212
96285
|
}
|
|
96213
96286
|
}
|
|
96214
|
-
|
|
96287
|
+
if (debug) {
|
|
96288
|
+
console.error(`🔧 Debug: Aggregated ${aggregatedIssues.length} issues from ${results.size} dependency-aware checks`);
|
|
96289
|
+
}
|
|
96215
96290
|
// Apply issue suppression filtering
|
|
96216
96291
|
const suppressionEnabled = this.config?.output?.suppressionEnabled !== false;
|
|
96217
96292
|
const issueFilter = new issue_filter_1.IssueFilter(suppressionEnabled);
|
|
@@ -96253,10 +96328,14 @@ class CheckExecutionEngine {
|
|
|
96253
96328
|
};
|
|
96254
96329
|
}
|
|
96255
96330
|
}
|
|
96256
|
-
|
|
96331
|
+
const summary = {
|
|
96257
96332
|
issues: filteredIssues,
|
|
96258
96333
|
debug: aggregatedDebug,
|
|
96259
96334
|
};
|
|
96335
|
+
if (Object.keys(contentMap).length > 0) {
|
|
96336
|
+
summary.__contents = contentMap;
|
|
96337
|
+
}
|
|
96338
|
+
return summary;
|
|
96260
96339
|
}
|
|
96261
96340
|
/**
|
|
96262
96341
|
* Aggregate results from parallel check execution (legacy method)
|
|
@@ -96326,7 +96405,9 @@ class CheckExecutionEngine {
|
|
|
96326
96405
|
});
|
|
96327
96406
|
}
|
|
96328
96407
|
});
|
|
96329
|
-
|
|
96408
|
+
if (debug) {
|
|
96409
|
+
console.error(`🔧 Debug: Aggregated ${aggregatedIssues.length} issues from ${results.length} checks`);
|
|
96410
|
+
}
|
|
96330
96411
|
// Apply issue suppression filtering
|
|
96331
96412
|
const suppressionEnabled = this.config?.output?.suppressionEnabled !== false;
|
|
96332
96413
|
const issueFilter = new issue_filter_1.IssueFilter(suppressionEnabled);
|
|
@@ -96546,14 +96627,36 @@ class CheckExecutionEngine {
|
|
|
96546
96627
|
/**
|
|
96547
96628
|
* Check if a task result should trigger fail-fast behavior
|
|
96548
96629
|
*/
|
|
96630
|
+
isFailFastCandidate(value) {
|
|
96631
|
+
if (typeof value !== 'object' || value === null) {
|
|
96632
|
+
return false;
|
|
96633
|
+
}
|
|
96634
|
+
const candidate = value;
|
|
96635
|
+
if (candidate.error !== undefined && typeof candidate.error !== 'string') {
|
|
96636
|
+
return false;
|
|
96637
|
+
}
|
|
96638
|
+
if (candidate.result !== undefined) {
|
|
96639
|
+
if (typeof candidate.result !== 'object' || candidate.result === null) {
|
|
96640
|
+
return false;
|
|
96641
|
+
}
|
|
96642
|
+
const issues = candidate.result.issues;
|
|
96643
|
+
if (issues !== undefined && !Array.isArray(issues)) {
|
|
96644
|
+
return false;
|
|
96645
|
+
}
|
|
96646
|
+
}
|
|
96647
|
+
return true;
|
|
96648
|
+
}
|
|
96549
96649
|
shouldFailFast(result) {
|
|
96550
|
-
|
|
96551
|
-
|
|
96650
|
+
if (!this.isFailFastCandidate(result)) {
|
|
96651
|
+
return false;
|
|
96652
|
+
}
|
|
96653
|
+
if (result.error) {
|
|
96552
96654
|
return true;
|
|
96553
96655
|
}
|
|
96554
96656
|
// If the result has a result with critical or error issues, it should fail fast
|
|
96555
|
-
|
|
96556
|
-
|
|
96657
|
+
const issues = result.result?.issues;
|
|
96658
|
+
if (Array.isArray(issues)) {
|
|
96659
|
+
return issues.some(issue => issue?.severity === 'error' || issue?.severity === 'critical');
|
|
96557
96660
|
}
|
|
96558
96661
|
return false;
|
|
96559
96662
|
}
|
|
@@ -96939,6 +97042,9 @@ async function main() {
|
|
|
96939
97042
|
const filteredArgv = process.argv.filter(arg => arg !== '--cli');
|
|
96940
97043
|
// Parse arguments using the CLI class
|
|
96941
97044
|
const options = cli.parseArgs(filteredArgv);
|
|
97045
|
+
const explicitChecks = options.checks.length > 0
|
|
97046
|
+
? new Set(options.checks.map(check => check.toString()))
|
|
97047
|
+
: null;
|
|
96942
97048
|
// Set environment variables early for proper logging in all modules
|
|
96943
97049
|
process.env.VISOR_OUTPUT_FORMAT = options.output;
|
|
96944
97050
|
process.env.VISOR_DEBUG = options.debug ? 'true' : 'false';
|
|
@@ -96992,7 +97098,7 @@ async function main() {
|
|
|
96992
97098
|
.catch(() => configManager.getDefaultConfig());
|
|
96993
97099
|
}
|
|
96994
97100
|
// Determine checks to run and validate check types early
|
|
96995
|
-
|
|
97101
|
+
let checksToRun = options.checks.length > 0 ? options.checks : Object.keys(config.checks || {});
|
|
96996
97102
|
// Validate that all requested checks exist in the configuration
|
|
96997
97103
|
const availableChecks = Object.keys(config.checks || {});
|
|
96998
97104
|
const invalidChecks = checksToRun.filter(check => !availableChecks.includes(check));
|
|
@@ -97000,8 +97106,28 @@ async function main() {
|
|
|
97000
97106
|
console.error(`❌ Error: No configuration found for check: ${invalidChecks[0]}`);
|
|
97001
97107
|
process.exit(1);
|
|
97002
97108
|
}
|
|
97109
|
+
// Include dependencies of requested checks
|
|
97110
|
+
const checksWithDependencies = new Set(checksToRun);
|
|
97111
|
+
const addDependencies = (checkName) => {
|
|
97112
|
+
const checkConfig = config.checks?.[checkName];
|
|
97113
|
+
if (checkConfig?.depends_on) {
|
|
97114
|
+
for (const dep of checkConfig.depends_on) {
|
|
97115
|
+
if (!checksWithDependencies.has(dep)) {
|
|
97116
|
+
checksWithDependencies.add(dep);
|
|
97117
|
+
addDependencies(dep); // Recursively add dependencies of dependencies
|
|
97118
|
+
}
|
|
97119
|
+
}
|
|
97120
|
+
}
|
|
97121
|
+
};
|
|
97122
|
+
// Add all dependencies
|
|
97123
|
+
for (const check of checksToRun) {
|
|
97124
|
+
addDependencies(check);
|
|
97125
|
+
}
|
|
97126
|
+
// Update checksToRun to include dependencies
|
|
97127
|
+
checksToRun = Array.from(checksWithDependencies);
|
|
97003
97128
|
// Use stderr for status messages when outputting formatted results to stdout
|
|
97004
|
-
|
|
97129
|
+
// Suppress all status messages when outputting JSON to avoid breaking parsers
|
|
97130
|
+
const logFn = options.output === 'json' ? () => { } : console.error;
|
|
97005
97131
|
// Determine if we should include code context (diffs)
|
|
97006
97132
|
// In CLI mode (local), we do smart detection. PR mode always includes context.
|
|
97007
97133
|
const isPRContext = false; // This is CLI mode, not GitHub Action
|
|
@@ -97047,14 +97173,14 @@ async function main() {
|
|
|
97047
97173
|
console.error('❌ Error: Not a git repository. Run "git init" to initialize a repository.');
|
|
97048
97174
|
process.exit(1);
|
|
97049
97175
|
}
|
|
97176
|
+
logFn('🔍 Visor - AI-powered code review tool');
|
|
97177
|
+
logFn(`Configuration version: ${config.version}`);
|
|
97178
|
+
logFn(`Configuration source: ${options.configPath || 'default search locations'}`);
|
|
97050
97179
|
// Check if there are any changes to analyze (only when code context is needed)
|
|
97051
97180
|
if (includeCodeContext && repositoryInfo.files.length === 0) {
|
|
97052
97181
|
console.error('❌ Error: No changes to analyze. Make some file changes first.');
|
|
97053
97182
|
process.exit(1);
|
|
97054
97183
|
}
|
|
97055
|
-
logFn('🔍 Visor - AI-powered code review tool');
|
|
97056
|
-
logFn(`Configuration version: ${config.version}`);
|
|
97057
|
-
logFn(`Configuration source: ${options.configPath || 'default search locations'}`);
|
|
97058
97184
|
// Show registered providers if in debug mode
|
|
97059
97185
|
if (options.debug) {
|
|
97060
97186
|
const { CheckProviderRegistry } = await Promise.resolve().then(() => __importStar(__nccwpck_require__(57140)));
|
|
@@ -97077,26 +97203,52 @@ async function main() {
|
|
|
97077
97203
|
// Convert repository info to PRInfo format
|
|
97078
97204
|
const prInfo = analyzer.toPRInfo(repositoryInfo, includeCodeContext);
|
|
97079
97205
|
// Store the includeCodeContext flag in prInfo for downstream use
|
|
97080
|
-
|
|
97206
|
+
const prInfoWithContext = prInfo;
|
|
97207
|
+
prInfoWithContext.includeCodeContext = includeCodeContext;
|
|
97081
97208
|
// Execute checks with proper parameters
|
|
97082
97209
|
const groupedResults = await engine.executeGroupedChecks(prInfo, checksToRun, options.timeout, config, options.output, options.debug || false, options.maxParallelism, options.failFast, tagFilter);
|
|
97210
|
+
const shouldFilterResults = explicitChecks && explicitChecks.size > 0 && !explicitChecks.has('all');
|
|
97211
|
+
const groupedResultsToUse = shouldFilterResults
|
|
97212
|
+
? Object.fromEntries(Object.entries(groupedResults)
|
|
97213
|
+
.map(([group, checkResults]) => [
|
|
97214
|
+
group,
|
|
97215
|
+
checkResults.filter(check => explicitChecks.has(check.checkName)),
|
|
97216
|
+
])
|
|
97217
|
+
.filter(([, checkResults]) => checkResults.length > 0))
|
|
97218
|
+
: groupedResults;
|
|
97219
|
+
if (shouldFilterResults) {
|
|
97220
|
+
for (const [group, checkResults] of Object.entries(groupedResults)) {
|
|
97221
|
+
for (const check of checkResults) {
|
|
97222
|
+
if (check.issues && check.issues.length > 0 && !explicitChecks.has(check.checkName)) {
|
|
97223
|
+
if (!groupedResultsToUse[group]) {
|
|
97224
|
+
groupedResultsToUse[group] = [];
|
|
97225
|
+
}
|
|
97226
|
+
const alreadyIncluded = groupedResultsToUse[group].some(existing => existing.checkName === check.checkName);
|
|
97227
|
+
if (!alreadyIncluded) {
|
|
97228
|
+
groupedResultsToUse[group].push(check);
|
|
97229
|
+
}
|
|
97230
|
+
}
|
|
97231
|
+
}
|
|
97232
|
+
}
|
|
97233
|
+
}
|
|
97234
|
+
const executedCheckNames = Array.from(new Set(Object.values(groupedResultsToUse).flatMap((checks) => checks.map(check => check.checkName))));
|
|
97083
97235
|
// Format output based on format type
|
|
97084
97236
|
let output;
|
|
97085
97237
|
if (options.output === 'json') {
|
|
97086
|
-
output = JSON.stringify(
|
|
97238
|
+
output = JSON.stringify(groupedResultsToUse, null, 2);
|
|
97087
97239
|
}
|
|
97088
97240
|
else if (options.output === 'sarif') {
|
|
97089
97241
|
// Build analysis result and format as SARIF
|
|
97090
97242
|
const analysisResult = {
|
|
97091
97243
|
repositoryInfo,
|
|
97092
97244
|
reviewSummary: {
|
|
97093
|
-
issues: Object.values(
|
|
97245
|
+
issues: Object.values(groupedResultsToUse)
|
|
97094
97246
|
.flatMap((r) => r.map((check) => check.issues || []).flat())
|
|
97095
97247
|
.flat(),
|
|
97096
97248
|
},
|
|
97097
97249
|
executionTime: 0,
|
|
97098
97250
|
timestamp: new Date().toISOString(),
|
|
97099
|
-
checksExecuted:
|
|
97251
|
+
checksExecuted: executedCheckNames,
|
|
97100
97252
|
};
|
|
97101
97253
|
output = output_formatters_1.OutputFormatters.formatAsSarif(analysisResult);
|
|
97102
97254
|
}
|
|
@@ -97105,13 +97257,13 @@ async function main() {
|
|
|
97105
97257
|
const analysisResult = {
|
|
97106
97258
|
repositoryInfo,
|
|
97107
97259
|
reviewSummary: {
|
|
97108
|
-
issues: Object.values(
|
|
97260
|
+
issues: Object.values(groupedResultsToUse)
|
|
97109
97261
|
.flatMap((r) => r.map((check) => check.issues || []).flat())
|
|
97110
97262
|
.flat(),
|
|
97111
97263
|
},
|
|
97112
97264
|
executionTime: 0,
|
|
97113
97265
|
timestamp: new Date().toISOString(),
|
|
97114
|
-
checksExecuted:
|
|
97266
|
+
checksExecuted: executedCheckNames,
|
|
97115
97267
|
};
|
|
97116
97268
|
output = output_formatters_1.OutputFormatters.formatAsMarkdown(analysisResult);
|
|
97117
97269
|
}
|
|
@@ -97120,19 +97272,19 @@ async function main() {
|
|
|
97120
97272
|
const analysisResult = {
|
|
97121
97273
|
repositoryInfo,
|
|
97122
97274
|
reviewSummary: {
|
|
97123
|
-
issues: Object.values(
|
|
97275
|
+
issues: Object.values(groupedResultsToUse)
|
|
97124
97276
|
.flatMap((r) => r.map((check) => check.issues || []).flat())
|
|
97125
97277
|
.flat(),
|
|
97126
97278
|
},
|
|
97127
97279
|
executionTime: 0,
|
|
97128
97280
|
timestamp: new Date().toISOString(),
|
|
97129
|
-
checksExecuted:
|
|
97281
|
+
checksExecuted: executedCheckNames,
|
|
97130
97282
|
};
|
|
97131
97283
|
output = output_formatters_1.OutputFormatters.formatAsTable(analysisResult, { showDetails: true });
|
|
97132
97284
|
}
|
|
97133
97285
|
console.log(output);
|
|
97134
97286
|
// Check for critical issues
|
|
97135
|
-
const allResults = Object.values(
|
|
97287
|
+
const allResults = Object.values(groupedResultsToUse).flat();
|
|
97136
97288
|
const criticalCount = allResults.reduce((sum, result) => {
|
|
97137
97289
|
const issues = result.issues || [];
|
|
97138
97290
|
return (sum + issues.filter((issue) => issue.severity === 'critical').length);
|
|
@@ -101355,6 +101507,108 @@ class IssueFilter {
|
|
|
101355
101507
|
exports.IssueFilter = IssueFilter;
|
|
101356
101508
|
|
|
101357
101509
|
|
|
101510
|
+
/***/ }),
|
|
101511
|
+
|
|
101512
|
+
/***/ 33042:
|
|
101513
|
+
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
101514
|
+
|
|
101515
|
+
"use strict";
|
|
101516
|
+
|
|
101517
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
101518
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
101519
|
+
};
|
|
101520
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
101521
|
+
exports.ReadFileTag = void 0;
|
|
101522
|
+
exports.configureLiquidWithExtensions = configureLiquidWithExtensions;
|
|
101523
|
+
exports.createExtendedLiquid = createExtendedLiquid;
|
|
101524
|
+
const liquidjs_1 = __nccwpck_require__(48694);
|
|
101525
|
+
const promises_1 = __importDefault(__nccwpck_require__(91943));
|
|
101526
|
+
const path_1 = __importDefault(__nccwpck_require__(16928));
|
|
101527
|
+
/**
|
|
101528
|
+
* Custom ReadFile tag for Liquid templates
|
|
101529
|
+
* Usage: {% readfile "path/to/file.txt" %}
|
|
101530
|
+
* or with variable: {% readfile filename %}
|
|
101531
|
+
*/
|
|
101532
|
+
class ReadFileTag extends liquidjs_1.Tag {
|
|
101533
|
+
filepath;
|
|
101534
|
+
constructor(token, remainTokens, liquid) {
|
|
101535
|
+
super(token, remainTokens, liquid);
|
|
101536
|
+
this.filepath = new liquidjs_1.Value(token.args, liquid);
|
|
101537
|
+
}
|
|
101538
|
+
*render(ctx, emitter) {
|
|
101539
|
+
const filePath = yield this.filepath.value(ctx, false);
|
|
101540
|
+
// Validate the path
|
|
101541
|
+
if (!filePath || typeof filePath !== 'string') {
|
|
101542
|
+
emitter.write('[Error: Invalid file path]');
|
|
101543
|
+
return;
|
|
101544
|
+
}
|
|
101545
|
+
// Security: Resolve path relative to project root to prevent directory traversal
|
|
101546
|
+
const projectRoot = process.cwd();
|
|
101547
|
+
const resolvedPath = path_1.default.resolve(projectRoot, filePath.toString());
|
|
101548
|
+
// Ensure the resolved path is within the project directory
|
|
101549
|
+
if (!resolvedPath.startsWith(projectRoot)) {
|
|
101550
|
+
emitter.write('[Error: File path escapes project directory]');
|
|
101551
|
+
return;
|
|
101552
|
+
}
|
|
101553
|
+
// Read the file content
|
|
101554
|
+
try {
|
|
101555
|
+
const content = yield promises_1.default.readFile(resolvedPath, 'utf-8');
|
|
101556
|
+
emitter.write(content);
|
|
101557
|
+
}
|
|
101558
|
+
catch (error) {
|
|
101559
|
+
// Handle file read errors gracefully
|
|
101560
|
+
const errorMessage = error instanceof Error
|
|
101561
|
+
? error.message
|
|
101562
|
+
: error?.code || 'Unknown error';
|
|
101563
|
+
emitter.write(`[Error reading file: ${errorMessage}]`);
|
|
101564
|
+
}
|
|
101565
|
+
}
|
|
101566
|
+
}
|
|
101567
|
+
exports.ReadFileTag = ReadFileTag;
|
|
101568
|
+
/**
|
|
101569
|
+
* Configure a Liquid instance with custom extensions
|
|
101570
|
+
*/
|
|
101571
|
+
function configureLiquidWithExtensions(liquid) {
|
|
101572
|
+
// Register the readfile tag
|
|
101573
|
+
liquid.registerTag('readfile', ReadFileTag);
|
|
101574
|
+
// Register parse_json filter to parse JSON strings into objects
|
|
101575
|
+
liquid.registerFilter('parse_json', (value) => {
|
|
101576
|
+
if (typeof value !== 'string') {
|
|
101577
|
+
return value;
|
|
101578
|
+
}
|
|
101579
|
+
try {
|
|
101580
|
+
return JSON.parse(value);
|
|
101581
|
+
}
|
|
101582
|
+
catch {
|
|
101583
|
+
// Return original value if parsing fails
|
|
101584
|
+
return value;
|
|
101585
|
+
}
|
|
101586
|
+
});
|
|
101587
|
+
// Register to_json filter as alias for json (for consistency)
|
|
101588
|
+
liquid.registerFilter('to_json', (value) => {
|
|
101589
|
+
try {
|
|
101590
|
+
return JSON.stringify(value);
|
|
101591
|
+
}
|
|
101592
|
+
catch {
|
|
101593
|
+
return '[Error: Unable to serialize to JSON]';
|
|
101594
|
+
}
|
|
101595
|
+
});
|
|
101596
|
+
}
|
|
101597
|
+
/**
|
|
101598
|
+
* Create a new Liquid instance with custom extensions
|
|
101599
|
+
*/
|
|
101600
|
+
function createExtendedLiquid(options = {}) {
|
|
101601
|
+
const liquid = new liquidjs_1.Liquid({
|
|
101602
|
+
cache: false,
|
|
101603
|
+
strictFilters: false,
|
|
101604
|
+
strictVariables: false,
|
|
101605
|
+
...options,
|
|
101606
|
+
});
|
|
101607
|
+
configureLiquidWithExtensions(liquid);
|
|
101608
|
+
return liquid;
|
|
101609
|
+
}
|
|
101610
|
+
|
|
101611
|
+
|
|
101358
101612
|
/***/ }),
|
|
101359
101613
|
|
|
101360
101614
|
/***/ 25508:
|
|
@@ -102190,7 +102444,7 @@ const check_provider_interface_1 = __nccwpck_require__(14131);
|
|
|
102190
102444
|
const ai_review_service_1 = __nccwpck_require__(51796);
|
|
102191
102445
|
const env_resolver_1 = __nccwpck_require__(58749);
|
|
102192
102446
|
const issue_filter_1 = __nccwpck_require__(36879);
|
|
102193
|
-
const
|
|
102447
|
+
const liquid_extensions_1 = __nccwpck_require__(33042);
|
|
102194
102448
|
const promises_1 = __importDefault(__nccwpck_require__(91943));
|
|
102195
102449
|
const path_1 = __importDefault(__nccwpck_require__(16928));
|
|
102196
102450
|
const claude_code_types_1 = __nccwpck_require__(21710);
|
|
@@ -102203,7 +102457,7 @@ class AICheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
102203
102457
|
constructor() {
|
|
102204
102458
|
super();
|
|
102205
102459
|
this.aiReviewService = new ai_review_service_1.AIReviewService();
|
|
102206
|
-
this.liquidEngine =
|
|
102460
|
+
this.liquidEngine = (0, liquid_extensions_1.createExtendedLiquid)();
|
|
102207
102461
|
}
|
|
102208
102462
|
getName() {
|
|
102209
102463
|
return 'ai';
|
|
@@ -102243,8 +102497,10 @@ class AICheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
102243
102497
|
}
|
|
102244
102498
|
}
|
|
102245
102499
|
// Validate check-level MCP servers if present
|
|
102246
|
-
|
|
102247
|
-
|
|
102500
|
+
const checkLevelMcpServers = cfg
|
|
102501
|
+
.ai_mcp_servers;
|
|
102502
|
+
if (checkLevelMcpServers) {
|
|
102503
|
+
if (!this.validateMcpServers(checkLevelMcpServers)) {
|
|
102248
102504
|
return false;
|
|
102249
102505
|
}
|
|
102250
102506
|
}
|
|
@@ -102262,10 +102518,10 @@ class AICheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
102262
102518
|
return false;
|
|
102263
102519
|
}
|
|
102264
102520
|
const config = serverConfig;
|
|
102265
|
-
if (
|
|
102521
|
+
if (typeof config.command !== 'string') {
|
|
102266
102522
|
return false;
|
|
102267
102523
|
}
|
|
102268
|
-
if (config.args && !Array.isArray(config.args)) {
|
|
102524
|
+
if (config.args !== undefined && !Array.isArray(config.args)) {
|
|
102269
102525
|
return false;
|
|
102270
102526
|
}
|
|
102271
102527
|
}
|
|
@@ -102504,9 +102760,10 @@ class AICheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
102504
102760
|
outputs: dependencyResults
|
|
102505
102761
|
? Object.fromEntries(Array.from(dependencyResults.entries()).map(([checkName, result]) => [
|
|
102506
102762
|
checkName,
|
|
102507
|
-
|
|
102508
|
-
|
|
102509
|
-
|
|
102763
|
+
(() => {
|
|
102764
|
+
const summary = result;
|
|
102765
|
+
return summary.output !== undefined ? summary.output : summary;
|
|
102766
|
+
})(),
|
|
102510
102767
|
]))
|
|
102511
102768
|
: {},
|
|
102512
102769
|
};
|
|
@@ -102532,7 +102789,7 @@ class AICheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
102532
102789
|
return tools;
|
|
102533
102790
|
}
|
|
102534
102791
|
const createSdkMcpServer = mcpModule.createSdkMcpServer || mcpModule.default?.createSdkMcpServer;
|
|
102535
|
-
if (createSdkMcpServer) {
|
|
102792
|
+
if (typeof createSdkMcpServer === 'function') {
|
|
102536
102793
|
for (const [serverName, serverConfig] of Object.entries(aiConfig.mcpServers)) {
|
|
102537
102794
|
try {
|
|
102538
102795
|
// Create MCP server instance
|
|
@@ -102543,8 +102800,8 @@ class AICheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
102543
102800
|
env: { ...process.env, ...serverConfig.env },
|
|
102544
102801
|
});
|
|
102545
102802
|
// Add server tools to available tools
|
|
102546
|
-
const serverTools = await server.listTools();
|
|
102547
|
-
tools.push(...serverTools.map(
|
|
102803
|
+
const serverTools = (await server.listTools());
|
|
102804
|
+
tools.push(...serverTools.map(tool => ({
|
|
102548
102805
|
name: tool.name,
|
|
102549
102806
|
server: serverName,
|
|
102550
102807
|
})));
|
|
@@ -102615,7 +102872,7 @@ class AICheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
102615
102872
|
// Setup MCP tools from multiple configuration levels
|
|
102616
102873
|
const mcpServers = {};
|
|
102617
102874
|
// 1. Start with global MCP servers (from visor config root)
|
|
102618
|
-
const globalConfig = config;
|
|
102875
|
+
const globalConfig = config;
|
|
102619
102876
|
if (globalConfig.ai_mcp_servers) {
|
|
102620
102877
|
Object.assign(mcpServers, globalConfig.ai_mcp_servers);
|
|
102621
102878
|
}
|
|
@@ -102928,10 +103185,13 @@ exports.ClaudeCodeCheckProvider = exports.ClaudeCodeAPIKeyMissingError = exports
|
|
|
102928
103185
|
const check_provider_interface_1 = __nccwpck_require__(14131);
|
|
102929
103186
|
const env_resolver_1 = __nccwpck_require__(58749);
|
|
102930
103187
|
const issue_filter_1 = __nccwpck_require__(36879);
|
|
102931
|
-
const
|
|
103188
|
+
const liquid_extensions_1 = __nccwpck_require__(33042);
|
|
102932
103189
|
const promises_1 = __importDefault(__nccwpck_require__(91943));
|
|
102933
103190
|
const path_1 = __importDefault(__nccwpck_require__(16928));
|
|
102934
103191
|
const claude_code_types_1 = __nccwpck_require__(21710);
|
|
103192
|
+
function isClaudeCodeConstructor(value) {
|
|
103193
|
+
return typeof value === 'function';
|
|
103194
|
+
}
|
|
102935
103195
|
/**
|
|
102936
103196
|
* Error thrown when Claude Code SDK is not installed
|
|
102937
103197
|
*/
|
|
@@ -102961,7 +103221,7 @@ class ClaudeCodeCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
102961
103221
|
claudeCodeClient = null;
|
|
102962
103222
|
constructor() {
|
|
102963
103223
|
super();
|
|
102964
|
-
this.liquidEngine =
|
|
103224
|
+
this.liquidEngine = (0, liquid_extensions_1.createExtendedLiquid)();
|
|
102965
103225
|
}
|
|
102966
103226
|
getName() {
|
|
102967
103227
|
return 'claude-code';
|
|
@@ -103026,8 +103286,8 @@ class ClaudeCodeCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103026
103286
|
if (!claudeCodeModule) {
|
|
103027
103287
|
throw new ClaudeCodeSDKNotInstalledError();
|
|
103028
103288
|
}
|
|
103029
|
-
const
|
|
103030
|
-
if (!
|
|
103289
|
+
const ClaudeCodeCtor = claudeCodeModule.ClaudeCode || claudeCodeModule.default?.ClaudeCode;
|
|
103290
|
+
if (!isClaudeCodeConstructor(ClaudeCodeCtor)) {
|
|
103031
103291
|
throw new Error('ClaudeCode class not found in @anthropic/claude-code-sdk');
|
|
103032
103292
|
}
|
|
103033
103293
|
// Initialize with API key from environment
|
|
@@ -103036,7 +103296,7 @@ class ClaudeCodeCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103036
103296
|
throw new ClaudeCodeAPIKeyMissingError();
|
|
103037
103297
|
}
|
|
103038
103298
|
try {
|
|
103039
|
-
const client = new
|
|
103299
|
+
const client = new ClaudeCodeCtor({
|
|
103040
103300
|
apiKey,
|
|
103041
103301
|
});
|
|
103042
103302
|
this.claudeCodeClient = client;
|
|
@@ -103067,7 +103327,7 @@ class ClaudeCodeCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103067
103327
|
return tools;
|
|
103068
103328
|
}
|
|
103069
103329
|
const createSdkMcpServer = mcpModule.createSdkMcpServer || mcpModule.default?.createSdkMcpServer;
|
|
103070
|
-
if (createSdkMcpServer) {
|
|
103330
|
+
if (typeof createSdkMcpServer === 'function') {
|
|
103071
103331
|
for (const [serverName, serverConfig] of Object.entries(config.mcpServers)) {
|
|
103072
103332
|
try {
|
|
103073
103333
|
// Create MCP server instance
|
|
@@ -103078,8 +103338,8 @@ class ClaudeCodeCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103078
103338
|
env: { ...process.env, ...serverConfig.env },
|
|
103079
103339
|
});
|
|
103080
103340
|
// Add server tools to available tools
|
|
103081
|
-
const serverTools = await server.listTools();
|
|
103082
|
-
tools.push(...serverTools.map(
|
|
103341
|
+
const serverTools = (await server.listTools());
|
|
103342
|
+
tools.push(...serverTools.map(tool => ({
|
|
103083
103343
|
name: tool.name,
|
|
103084
103344
|
server: serverName,
|
|
103085
103345
|
})));
|
|
@@ -103303,7 +103563,10 @@ class ClaudeCodeCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103303
103563
|
checkName,
|
|
103304
103564
|
// If the result has a direct output field, use it directly
|
|
103305
103565
|
// Otherwise, expose the entire result
|
|
103306
|
-
|
|
103566
|
+
(() => {
|
|
103567
|
+
const summary = result;
|
|
103568
|
+
return summary.output !== undefined ? summary.output : summary;
|
|
103569
|
+
})(),
|
|
103307
103570
|
]))
|
|
103308
103571
|
: {},
|
|
103309
103572
|
};
|
|
@@ -103385,7 +103648,6 @@ class ClaudeCodeCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103385
103648
|
}
|
|
103386
103649
|
// Parse the response
|
|
103387
103650
|
const result = this.parseStructuredResponse(response.content);
|
|
103388
|
-
// Add debug information if needed by casting to any
|
|
103389
103651
|
result.debug = {
|
|
103390
103652
|
prompt: processedPrompt,
|
|
103391
103653
|
rawResponse: response.content,
|
|
@@ -103399,7 +103661,7 @@ class ClaudeCodeCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103399
103661
|
errors: [],
|
|
103400
103662
|
checksExecuted: [config.checkName || 'claude-code-check'],
|
|
103401
103663
|
parallelExecution: false,
|
|
103402
|
-
timestamp: Date.
|
|
103664
|
+
timestamp: new Date().toISOString(),
|
|
103403
103665
|
// Claude Code specific debug info
|
|
103404
103666
|
sessionId: response.session_id,
|
|
103405
103667
|
turnCount: response.turn_count,
|
|
@@ -103590,8 +103852,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
103590
103852
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
103591
103853
|
exports.CommandCheckProvider = void 0;
|
|
103592
103854
|
const check_provider_interface_1 = __nccwpck_require__(14131);
|
|
103593
|
-
const liquidjs_1 = __nccwpck_require__(48694);
|
|
103594
103855
|
const sandboxjs_1 = __importDefault(__nccwpck_require__(29083));
|
|
103856
|
+
const liquid_extensions_1 = __nccwpck_require__(33042);
|
|
103595
103857
|
/**
|
|
103596
103858
|
* Check provider that executes shell commands and captures their output
|
|
103597
103859
|
* Supports JSON parsing and integration with forEach functionality
|
|
@@ -103601,7 +103863,7 @@ class CommandCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103601
103863
|
sandbox;
|
|
103602
103864
|
constructor() {
|
|
103603
103865
|
super();
|
|
103604
|
-
this.liquid =
|
|
103866
|
+
this.liquid = (0, liquid_extensions_1.createExtendedLiquid)({
|
|
103605
103867
|
cache: false,
|
|
103606
103868
|
strictFilters: false,
|
|
103607
103869
|
strictVariables: false,
|
|
@@ -103652,11 +103914,17 @@ class CommandCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103652
103914
|
outputs: this.buildOutputContext(dependencyResults),
|
|
103653
103915
|
env: this.getSafeEnvironmentVariables(),
|
|
103654
103916
|
};
|
|
103917
|
+
if (process.env.DEBUG) {
|
|
103918
|
+
console.log('🔧 Debug: Template outputs keys:', Object.keys(templateContext.outputs || {}));
|
|
103919
|
+
}
|
|
103655
103920
|
try {
|
|
103656
103921
|
// Render the command with Liquid templates if needed
|
|
103657
103922
|
let renderedCommand = command;
|
|
103658
103923
|
if (command.includes('{{') || command.includes('{%')) {
|
|
103659
|
-
renderedCommand = await this.
|
|
103924
|
+
renderedCommand = await this.renderCommandTemplate(command, templateContext);
|
|
103925
|
+
}
|
|
103926
|
+
if (process.env.DEBUG) {
|
|
103927
|
+
console.log('🔧 Debug: Rendered command:', renderedCommand);
|
|
103660
103928
|
}
|
|
103661
103929
|
// Prepare environment variables - convert all to strings
|
|
103662
103930
|
const scriptEnv = {};
|
|
@@ -103687,16 +103955,18 @@ class CommandCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103687
103955
|
if (stderr && process.env.DEBUG) {
|
|
103688
103956
|
console.error(`Command stderr: ${stderr}`);
|
|
103689
103957
|
}
|
|
103690
|
-
//
|
|
103691
|
-
|
|
103958
|
+
// Keep raw output for transforms
|
|
103959
|
+
const rawOutput = stdout.trim();
|
|
103960
|
+
// Try to parse output as JSON for default behavior
|
|
103961
|
+
let output = rawOutput;
|
|
103692
103962
|
try {
|
|
103693
103963
|
// Attempt to parse as JSON
|
|
103694
|
-
const parsed = JSON.parse(
|
|
103964
|
+
const parsed = JSON.parse(rawOutput);
|
|
103695
103965
|
output = parsed;
|
|
103696
103966
|
}
|
|
103697
103967
|
catch {
|
|
103698
103968
|
// If not JSON, keep as string
|
|
103699
|
-
output =
|
|
103969
|
+
output = rawOutput;
|
|
103700
103970
|
}
|
|
103701
103971
|
// Apply transform if specified (Liquid or JavaScript)
|
|
103702
103972
|
let finalOutput = output;
|
|
@@ -103705,7 +103975,7 @@ class CommandCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103705
103975
|
try {
|
|
103706
103976
|
const transformContext = {
|
|
103707
103977
|
...templateContext,
|
|
103708
|
-
output,
|
|
103978
|
+
output: output, // Use parsed output for Liquid (object if JSON, string otherwise)
|
|
103709
103979
|
};
|
|
103710
103980
|
const rendered = await this.liquid.parseAndRender(transform, transformContext);
|
|
103711
103981
|
// Try to parse the transformed result as JSON
|
|
@@ -103734,21 +104004,64 @@ class CommandCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103734
104004
|
// Then apply JavaScript transform if present
|
|
103735
104005
|
if (transformJs) {
|
|
103736
104006
|
try {
|
|
104007
|
+
// For transform_js, provide a JSON-smart wrapper that:
|
|
104008
|
+
// - behaves like a string when coerced (so JSON.parse(output) still works)
|
|
104009
|
+
// - exposes parsed JSON properties if stdout is valid JSON (so output.key works)
|
|
103737
104010
|
const jsContext = {
|
|
103738
|
-
output:
|
|
104011
|
+
output: this.makeJsonSmart(rawOutput),
|
|
103739
104012
|
pr: templateContext.pr,
|
|
103740
104013
|
files: templateContext.files,
|
|
103741
|
-
outputs: templateContext.outputs,
|
|
104014
|
+
outputs: this.makeOutputsJsonSmart(templateContext.outputs),
|
|
103742
104015
|
env: templateContext.env,
|
|
103743
|
-
// Helper functions
|
|
103744
|
-
JSON: JSON,
|
|
103745
104016
|
};
|
|
103746
104017
|
// Compile and execute the JavaScript expression
|
|
103747
|
-
|
|
103748
|
-
|
|
103749
|
-
|
|
103750
|
-
|
|
104018
|
+
// Use direct property access instead of destructuring to avoid syntax issues
|
|
104019
|
+
const trimmedTransform = transformJs.trim();
|
|
104020
|
+
let transformExpression;
|
|
104021
|
+
if (/return\s+/.test(trimmedTransform)) {
|
|
104022
|
+
transformExpression = `(() => {\n${trimmedTransform}\n})()`;
|
|
104023
|
+
}
|
|
104024
|
+
else {
|
|
104025
|
+
const lines = trimmedTransform.split('\n');
|
|
104026
|
+
if (lines.length > 1) {
|
|
104027
|
+
const lastLine = lines[lines.length - 1].trim();
|
|
104028
|
+
const remaining = lines.slice(0, -1).join('\n');
|
|
104029
|
+
if (lastLine && !lastLine.includes('}') && !lastLine.includes('{')) {
|
|
104030
|
+
const returnTarget = lastLine.replace(/;$/, '');
|
|
104031
|
+
transformExpression = `(() => {\n${remaining}\nreturn ${returnTarget};\n})()`;
|
|
104032
|
+
}
|
|
104033
|
+
else {
|
|
104034
|
+
transformExpression = `(${trimmedTransform})`;
|
|
104035
|
+
}
|
|
104036
|
+
}
|
|
104037
|
+
else {
|
|
104038
|
+
transformExpression = `(${trimmedTransform})`;
|
|
104039
|
+
}
|
|
104040
|
+
}
|
|
104041
|
+
const code = `
|
|
104042
|
+
const output = scope.output;
|
|
104043
|
+
const pr = scope.pr;
|
|
104044
|
+
const files = scope.files;
|
|
104045
|
+
const outputs = scope.outputs;
|
|
104046
|
+
const env = scope.env;
|
|
104047
|
+
return ${transformExpression};
|
|
104048
|
+
`;
|
|
104049
|
+
if (process.env.DEBUG) {
|
|
104050
|
+
console.log('🔧 Debug: JavaScript transform code:', code);
|
|
104051
|
+
console.log('🔧 Debug: JavaScript context:', jsContext);
|
|
104052
|
+
}
|
|
104053
|
+
const exec = this.sandbox.compile(code);
|
|
103751
104054
|
finalOutput = exec({ scope: jsContext }).run();
|
|
104055
|
+
if (process.env.DEBUG) {
|
|
104056
|
+
try {
|
|
104057
|
+
const preview = JSON.stringify(finalOutput);
|
|
104058
|
+
console.log('🔧 Debug: transform_js result:', typeof preview === 'string' ? preview.slice(0, 200) : String(preview).slice(0, 200));
|
|
104059
|
+
}
|
|
104060
|
+
catch {
|
|
104061
|
+
const preview = String(finalOutput);
|
|
104062
|
+
console.log('🔧 Debug: transform_js result:', preview.slice(0, 200));
|
|
104063
|
+
}
|
|
104064
|
+
}
|
|
103752
104065
|
}
|
|
103753
104066
|
catch (error) {
|
|
103754
104067
|
return {
|
|
@@ -103765,12 +104078,57 @@ class CommandCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103765
104078
|
};
|
|
103766
104079
|
}
|
|
103767
104080
|
}
|
|
103768
|
-
//
|
|
103769
|
-
|
|
103770
|
-
|
|
103771
|
-
|
|
103772
|
-
|
|
104081
|
+
// Extract structured issues when the command returns them (skip for forEach parents)
|
|
104082
|
+
let issues = [];
|
|
104083
|
+
let outputForDependents = finalOutput;
|
|
104084
|
+
let content;
|
|
104085
|
+
let extracted = null;
|
|
104086
|
+
const trimmedRawOutput = typeof rawOutput === 'string' ? rawOutput.trim() : undefined;
|
|
104087
|
+
const commandConfig = config;
|
|
104088
|
+
const isForEachParent = commandConfig.forEach === true;
|
|
104089
|
+
if (!isForEachParent) {
|
|
104090
|
+
extracted = this.extractIssuesFromOutput(finalOutput);
|
|
104091
|
+
if (!extracted && typeof finalOutput === 'string') {
|
|
104092
|
+
// Attempt to parse string output as JSON and extract issues again
|
|
104093
|
+
try {
|
|
104094
|
+
const parsed = JSON.parse(finalOutput);
|
|
104095
|
+
extracted = this.extractIssuesFromOutput(parsed);
|
|
104096
|
+
if (extracted) {
|
|
104097
|
+
issues = extracted.issues;
|
|
104098
|
+
outputForDependents = extracted.remainingOutput;
|
|
104099
|
+
}
|
|
104100
|
+
}
|
|
104101
|
+
catch {
|
|
104102
|
+
// Ignore JSON parse errors – leave output as-is
|
|
104103
|
+
}
|
|
104104
|
+
}
|
|
104105
|
+
else if (extracted) {
|
|
104106
|
+
issues = extracted.issues;
|
|
104107
|
+
outputForDependents = extracted.remainingOutput;
|
|
104108
|
+
}
|
|
104109
|
+
if (!issues.length && this.shouldTreatAsTextOutput(trimmedRawOutput)) {
|
|
104110
|
+
content = trimmedRawOutput;
|
|
104111
|
+
}
|
|
104112
|
+
else if (issues.length && typeof extracted?.remainingOutput === 'string') {
|
|
104113
|
+
const trimmed = extracted.remainingOutput.trim();
|
|
104114
|
+
if (trimmed) {
|
|
104115
|
+
content = trimmed;
|
|
104116
|
+
}
|
|
104117
|
+
}
|
|
104118
|
+
}
|
|
104119
|
+
if (!content && this.shouldTreatAsTextOutput(trimmedRawOutput) && !isForEachParent) {
|
|
104120
|
+
content = trimmedRawOutput;
|
|
104121
|
+
}
|
|
104122
|
+
// Return the output and issues as part of the review summary so dependent checks can use them
|
|
104123
|
+
const result = {
|
|
104124
|
+
issues,
|
|
104125
|
+
output: outputForDependents,
|
|
104126
|
+
...(content ? { content } : {}),
|
|
103773
104127
|
};
|
|
104128
|
+
if (process.env.DEBUG && transformJs) {
|
|
104129
|
+
console.log(`🔧 Debug: Command provider returning output:`, JSON.stringify(result.output).slice(0, 200));
|
|
104130
|
+
}
|
|
104131
|
+
return result;
|
|
103774
104132
|
}
|
|
103775
104133
|
catch (error) {
|
|
103776
104134
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
@@ -103796,10 +104154,92 @@ class CommandCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103796
104154
|
for (const [checkName, result] of dependencyResults) {
|
|
103797
104155
|
// If the result has a direct output field, use it directly
|
|
103798
104156
|
// Otherwise, expose the entire result as-is
|
|
103799
|
-
|
|
104157
|
+
const summary = result;
|
|
104158
|
+
const value = summary.output !== undefined ? summary.output : summary;
|
|
104159
|
+
outputs[checkName] = this.makeJsonSmart(value);
|
|
103800
104160
|
}
|
|
103801
104161
|
return outputs;
|
|
103802
104162
|
}
|
|
104163
|
+
/**
|
|
104164
|
+
* Wrap a value with JSON-smart behavior:
|
|
104165
|
+
* - If it's a JSON string, expose parsed properties via Proxy (e.g., value.key)
|
|
104166
|
+
* - When coerced to string (toString/valueOf/Symbol.toPrimitive), return the original raw string
|
|
104167
|
+
* - If parsing fails or value is not a string, return the value unchanged
|
|
104168
|
+
*/
|
|
104169
|
+
makeJsonSmart(value) {
|
|
104170
|
+
if (typeof value !== 'string') {
|
|
104171
|
+
return value;
|
|
104172
|
+
}
|
|
104173
|
+
const raw = value;
|
|
104174
|
+
let parsed;
|
|
104175
|
+
try {
|
|
104176
|
+
parsed = JSON.parse(raw);
|
|
104177
|
+
}
|
|
104178
|
+
catch {
|
|
104179
|
+
// Not JSON, return original string
|
|
104180
|
+
return raw;
|
|
104181
|
+
}
|
|
104182
|
+
// Use a boxed string so string methods still work via Proxy fallback
|
|
104183
|
+
const boxed = new String(raw);
|
|
104184
|
+
const handler = {
|
|
104185
|
+
get(target, prop, receiver) {
|
|
104186
|
+
if (prop === 'toString' || prop === 'valueOf') {
|
|
104187
|
+
return () => raw;
|
|
104188
|
+
}
|
|
104189
|
+
if (prop === Symbol.toPrimitive) {
|
|
104190
|
+
return () => raw;
|
|
104191
|
+
}
|
|
104192
|
+
if (parsed != null && (typeof parsed === 'object' || Array.isArray(parsed))) {
|
|
104193
|
+
if (prop in parsed) {
|
|
104194
|
+
return parsed[prop];
|
|
104195
|
+
}
|
|
104196
|
+
}
|
|
104197
|
+
return Reflect.get(target, prop, receiver);
|
|
104198
|
+
},
|
|
104199
|
+
has(_target, prop) {
|
|
104200
|
+
if (parsed != null && (typeof parsed === 'object' || Array.isArray(parsed))) {
|
|
104201
|
+
if (prop in parsed)
|
|
104202
|
+
return true;
|
|
104203
|
+
}
|
|
104204
|
+
return false;
|
|
104205
|
+
},
|
|
104206
|
+
ownKeys(_target) {
|
|
104207
|
+
if (parsed != null && (typeof parsed === 'object' || Array.isArray(parsed))) {
|
|
104208
|
+
try {
|
|
104209
|
+
return Reflect.ownKeys(parsed);
|
|
104210
|
+
}
|
|
104211
|
+
catch {
|
|
104212
|
+
return [];
|
|
104213
|
+
}
|
|
104214
|
+
}
|
|
104215
|
+
return [];
|
|
104216
|
+
},
|
|
104217
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
104218
|
+
if (parsed != null && (typeof parsed === 'object' || Array.isArray(parsed))) {
|
|
104219
|
+
const descriptor = Object.getOwnPropertyDescriptor(parsed, prop);
|
|
104220
|
+
if (descriptor)
|
|
104221
|
+
return descriptor;
|
|
104222
|
+
}
|
|
104223
|
+
return {
|
|
104224
|
+
configurable: true,
|
|
104225
|
+
enumerable: true,
|
|
104226
|
+
writable: false,
|
|
104227
|
+
value: undefined,
|
|
104228
|
+
};
|
|
104229
|
+
},
|
|
104230
|
+
};
|
|
104231
|
+
return new Proxy(boxed, handler);
|
|
104232
|
+
}
|
|
104233
|
+
/**
|
|
104234
|
+
* Recursively apply JSON-smart wrapper to outputs object values
|
|
104235
|
+
*/
|
|
104236
|
+
makeOutputsJsonSmart(outputs) {
|
|
104237
|
+
const wrapped = {};
|
|
104238
|
+
for (const [k, v] of Object.entries(outputs || {})) {
|
|
104239
|
+
wrapped[k] = this.makeJsonSmart(v);
|
|
104240
|
+
}
|
|
104241
|
+
return wrapped;
|
|
104242
|
+
}
|
|
103803
104243
|
getSafeEnvironmentVariables() {
|
|
103804
104244
|
const safeVars = {};
|
|
103805
104245
|
const allowedPrefixes = ['CI_', 'GITHUB_', 'RUNNER_', 'NODE_', 'npm_', 'PATH', 'HOME', 'USER'];
|
|
@@ -103838,6 +104278,190 @@ class CommandCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103838
104278
|
'Optional: Transform template for processing output',
|
|
103839
104279
|
];
|
|
103840
104280
|
}
|
|
104281
|
+
extractIssuesFromOutput(output) {
|
|
104282
|
+
if (output === null || output === undefined) {
|
|
104283
|
+
return null;
|
|
104284
|
+
}
|
|
104285
|
+
// If output is already a string, do not treat it as issues here (caller may try parsing JSON)
|
|
104286
|
+
if (typeof output === 'string') {
|
|
104287
|
+
return null;
|
|
104288
|
+
}
|
|
104289
|
+
if (Array.isArray(output)) {
|
|
104290
|
+
const issues = this.normalizeIssueArray(output);
|
|
104291
|
+
if (issues) {
|
|
104292
|
+
return { issues, remainingOutput: undefined };
|
|
104293
|
+
}
|
|
104294
|
+
return null;
|
|
104295
|
+
}
|
|
104296
|
+
if (typeof output === 'object') {
|
|
104297
|
+
const record = output;
|
|
104298
|
+
if (Array.isArray(record.issues)) {
|
|
104299
|
+
const issues = this.normalizeIssueArray(record.issues);
|
|
104300
|
+
if (!issues) {
|
|
104301
|
+
return null;
|
|
104302
|
+
}
|
|
104303
|
+
const remaining = { ...record };
|
|
104304
|
+
delete remaining.issues;
|
|
104305
|
+
const remainingKeys = Object.keys(remaining);
|
|
104306
|
+
const remainingOutput = remainingKeys.length > 0 ? remaining : undefined;
|
|
104307
|
+
return {
|
|
104308
|
+
issues,
|
|
104309
|
+
remainingOutput,
|
|
104310
|
+
};
|
|
104311
|
+
}
|
|
104312
|
+
const singleIssue = this.normalizeIssue(record);
|
|
104313
|
+
if (singleIssue) {
|
|
104314
|
+
return { issues: [singleIssue], remainingOutput: undefined };
|
|
104315
|
+
}
|
|
104316
|
+
}
|
|
104317
|
+
return null;
|
|
104318
|
+
}
|
|
104319
|
+
shouldTreatAsTextOutput(value) {
|
|
104320
|
+
if (!value) {
|
|
104321
|
+
return false;
|
|
104322
|
+
}
|
|
104323
|
+
const trimmed = value.trim();
|
|
104324
|
+
if (!trimmed) {
|
|
104325
|
+
return false;
|
|
104326
|
+
}
|
|
104327
|
+
// Heuristic: consider it JSON-like if it starts with { or [ and ends with } or ]
|
|
104328
|
+
const startsJson = (trimmed.startsWith('{') && trimmed.endsWith('}')) ||
|
|
104329
|
+
(trimmed.startsWith('[') && trimmed.endsWith(']'));
|
|
104330
|
+
return !startsJson;
|
|
104331
|
+
}
|
|
104332
|
+
normalizeIssueArray(values) {
|
|
104333
|
+
const normalized = [];
|
|
104334
|
+
for (const value of values) {
|
|
104335
|
+
const issue = this.normalizeIssue(value);
|
|
104336
|
+
if (!issue) {
|
|
104337
|
+
return null;
|
|
104338
|
+
}
|
|
104339
|
+
normalized.push(issue);
|
|
104340
|
+
}
|
|
104341
|
+
return normalized;
|
|
104342
|
+
}
|
|
104343
|
+
normalizeIssue(raw) {
|
|
104344
|
+
if (!raw || typeof raw !== 'object') {
|
|
104345
|
+
return null;
|
|
104346
|
+
}
|
|
104347
|
+
const data = raw;
|
|
104348
|
+
const message = this.toTrimmedString(data.message || data.text || data.description || data.summary);
|
|
104349
|
+
if (!message) {
|
|
104350
|
+
return null;
|
|
104351
|
+
}
|
|
104352
|
+
const allowedSeverities = new Set(['info', 'warning', 'error', 'critical']);
|
|
104353
|
+
const severityRaw = this.toTrimmedString(data.severity || data.level || data.priority);
|
|
104354
|
+
let severity = 'warning';
|
|
104355
|
+
if (severityRaw) {
|
|
104356
|
+
const lower = severityRaw.toLowerCase();
|
|
104357
|
+
if (allowedSeverities.has(lower)) {
|
|
104358
|
+
severity = lower;
|
|
104359
|
+
}
|
|
104360
|
+
else if (['fatal', 'high'].includes(lower)) {
|
|
104361
|
+
severity = 'error';
|
|
104362
|
+
}
|
|
104363
|
+
else if (['medium', 'moderate'].includes(lower)) {
|
|
104364
|
+
severity = 'warning';
|
|
104365
|
+
}
|
|
104366
|
+
else if (['low', 'minor'].includes(lower)) {
|
|
104367
|
+
severity = 'info';
|
|
104368
|
+
}
|
|
104369
|
+
}
|
|
104370
|
+
const allowedCategories = new Set([
|
|
104371
|
+
'security',
|
|
104372
|
+
'performance',
|
|
104373
|
+
'style',
|
|
104374
|
+
'logic',
|
|
104375
|
+
'documentation',
|
|
104376
|
+
]);
|
|
104377
|
+
const categoryRaw = this.toTrimmedString(data.category || data.type || data.group);
|
|
104378
|
+
let category = 'logic';
|
|
104379
|
+
if (categoryRaw && allowedCategories.has(categoryRaw.toLowerCase())) {
|
|
104380
|
+
category = categoryRaw.toLowerCase();
|
|
104381
|
+
}
|
|
104382
|
+
const file = this.toTrimmedString(data.file || data.path || data.filename) || 'system';
|
|
104383
|
+
const line = this.toNumber(data.line || data.startLine || data.lineNumber) ?? 0;
|
|
104384
|
+
const endLine = this.toNumber(data.endLine || data.end_line || data.stopLine);
|
|
104385
|
+
const suggestion = this.toTrimmedString(data.suggestion);
|
|
104386
|
+
const replacement = this.toTrimmedString(data.replacement);
|
|
104387
|
+
const ruleId = this.toTrimmedString(data.ruleId || data.rule || data.id || data.check) || 'command';
|
|
104388
|
+
return {
|
|
104389
|
+
file,
|
|
104390
|
+
line,
|
|
104391
|
+
endLine: endLine ?? undefined,
|
|
104392
|
+
ruleId,
|
|
104393
|
+
message,
|
|
104394
|
+
severity,
|
|
104395
|
+
category,
|
|
104396
|
+
suggestion: suggestion || undefined,
|
|
104397
|
+
replacement: replacement || undefined,
|
|
104398
|
+
};
|
|
104399
|
+
}
|
|
104400
|
+
toTrimmedString(value) {
|
|
104401
|
+
if (typeof value === 'string') {
|
|
104402
|
+
const trimmed = value.trim();
|
|
104403
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
104404
|
+
}
|
|
104405
|
+
if (value !== null && value !== undefined && typeof value.toString === 'function') {
|
|
104406
|
+
const converted = String(value).trim();
|
|
104407
|
+
return converted.length > 0 ? converted : null;
|
|
104408
|
+
}
|
|
104409
|
+
return null;
|
|
104410
|
+
}
|
|
104411
|
+
toNumber(value) {
|
|
104412
|
+
if (value === null || value === undefined) {
|
|
104413
|
+
return null;
|
|
104414
|
+
}
|
|
104415
|
+
const num = Number(value);
|
|
104416
|
+
if (Number.isFinite(num)) {
|
|
104417
|
+
return Math.trunc(num);
|
|
104418
|
+
}
|
|
104419
|
+
return null;
|
|
104420
|
+
}
|
|
104421
|
+
async renderCommandTemplate(template, context) {
|
|
104422
|
+
try {
|
|
104423
|
+
return await this.liquid.parseAndRender(template, context);
|
|
104424
|
+
}
|
|
104425
|
+
catch (error) {
|
|
104426
|
+
if (process.env.DEBUG) {
|
|
104427
|
+
console.warn('🔧 Debug: Liquid rendering failed, falling back to JS evaluation:', error);
|
|
104428
|
+
}
|
|
104429
|
+
return this.renderWithJsExpressions(template, context);
|
|
104430
|
+
}
|
|
104431
|
+
}
|
|
104432
|
+
renderWithJsExpressions(template, context) {
|
|
104433
|
+
const scope = {
|
|
104434
|
+
pr: context.pr,
|
|
104435
|
+
files: context.files,
|
|
104436
|
+
outputs: context.outputs,
|
|
104437
|
+
env: context.env,
|
|
104438
|
+
};
|
|
104439
|
+
const expressionRegex = /\{\{\s*([^{}]+?)\s*\}\}/g;
|
|
104440
|
+
return template.replace(expressionRegex, (_match, expr) => {
|
|
104441
|
+
const expression = String(expr).trim();
|
|
104442
|
+
if (!expression) {
|
|
104443
|
+
return '';
|
|
104444
|
+
}
|
|
104445
|
+
try {
|
|
104446
|
+
const evalCode = `
|
|
104447
|
+
const pr = scope.pr;
|
|
104448
|
+
const files = scope.files;
|
|
104449
|
+
const outputs = scope.outputs;
|
|
104450
|
+
const env = scope.env;
|
|
104451
|
+
return (${expression});
|
|
104452
|
+
`;
|
|
104453
|
+
const evaluator = this.sandbox.compile(evalCode);
|
|
104454
|
+
const result = evaluator({ scope }).run();
|
|
104455
|
+
return result === undefined || result === null ? '' : String(result);
|
|
104456
|
+
}
|
|
104457
|
+
catch (evaluationError) {
|
|
104458
|
+
if (process.env.DEBUG) {
|
|
104459
|
+
console.warn('🔧 Debug: Failed to evaluate expression:', expression, evaluationError);
|
|
104460
|
+
}
|
|
104461
|
+
return '';
|
|
104462
|
+
}
|
|
104463
|
+
});
|
|
104464
|
+
}
|
|
103841
104465
|
}
|
|
103842
104466
|
exports.CommandCheckProvider = CommandCheckProvider;
|
|
103843
104467
|
|
|
@@ -103853,7 +104477,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
103853
104477
|
exports.HttpCheckProvider = void 0;
|
|
103854
104478
|
const check_provider_interface_1 = __nccwpck_require__(14131);
|
|
103855
104479
|
const issue_filter_1 = __nccwpck_require__(36879);
|
|
103856
|
-
const
|
|
104480
|
+
const liquid_extensions_1 = __nccwpck_require__(33042);
|
|
103857
104481
|
/**
|
|
103858
104482
|
* Check provider that sends data to an HTTP endpoint, typically used as an output/notification provider
|
|
103859
104483
|
*/
|
|
@@ -103861,7 +104485,7 @@ class HttpCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
103861
104485
|
liquid;
|
|
103862
104486
|
constructor() {
|
|
103863
104487
|
super();
|
|
103864
|
-
this.liquid =
|
|
104488
|
+
this.liquid = (0, liquid_extensions_1.createExtendedLiquid)();
|
|
103865
104489
|
}
|
|
103866
104490
|
getName() {
|
|
103867
104491
|
return 'http';
|
|
@@ -104082,7 +104706,7 @@ exports.HttpCheckProvider = HttpCheckProvider;
|
|
|
104082
104706
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
104083
104707
|
exports.HttpClientProvider = void 0;
|
|
104084
104708
|
const check_provider_interface_1 = __nccwpck_require__(14131);
|
|
104085
|
-
const
|
|
104709
|
+
const liquid_extensions_1 = __nccwpck_require__(33042);
|
|
104086
104710
|
/**
|
|
104087
104711
|
* Check provider that fetches data from HTTP endpoints
|
|
104088
104712
|
*/
|
|
@@ -104090,7 +104714,7 @@ class HttpClientProvider extends check_provider_interface_1.CheckProvider {
|
|
|
104090
104714
|
liquid;
|
|
104091
104715
|
constructor() {
|
|
104092
104716
|
super();
|
|
104093
|
-
this.liquid =
|
|
104717
|
+
this.liquid = (0, liquid_extensions_1.createExtendedLiquid)();
|
|
104094
104718
|
}
|
|
104095
104719
|
getName() {
|
|
104096
104720
|
return 'http_client';
|
|
@@ -104311,7 +104935,7 @@ exports.HttpClientProvider = HttpClientProvider;
|
|
|
104311
104935
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
104312
104936
|
exports.HttpInputProvider = void 0;
|
|
104313
104937
|
const check_provider_interface_1 = __nccwpck_require__(14131);
|
|
104314
|
-
const
|
|
104938
|
+
const liquid_extensions_1 = __nccwpck_require__(33042);
|
|
104315
104939
|
/**
|
|
104316
104940
|
* Check provider that receives input from HTTP webhooks and makes it available to dependent checks
|
|
104317
104941
|
*/
|
|
@@ -104320,7 +104944,7 @@ class HttpInputProvider extends check_provider_interface_1.CheckProvider {
|
|
|
104320
104944
|
webhookContext;
|
|
104321
104945
|
constructor() {
|
|
104322
104946
|
super();
|
|
104323
|
-
this.liquid =
|
|
104947
|
+
this.liquid = (0, liquid_extensions_1.createExtendedLiquid)();
|
|
104324
104948
|
}
|
|
104325
104949
|
/**
|
|
104326
104950
|
* Set webhook context for accessing webhook data
|
|
@@ -104446,7 +105070,7 @@ exports.HttpInputProvider = HttpInputProvider;
|
|
|
104446
105070
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
104447
105071
|
exports.LogCheckProvider = void 0;
|
|
104448
105072
|
const check_provider_interface_1 = __nccwpck_require__(14131);
|
|
104449
|
-
const
|
|
105073
|
+
const liquid_extensions_1 = __nccwpck_require__(33042);
|
|
104450
105074
|
/**
|
|
104451
105075
|
* Check provider that outputs debugging and logging information.
|
|
104452
105076
|
* Useful for troubleshooting check workflows and understanding execution flow.
|
|
@@ -104455,7 +105079,7 @@ class LogCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
104455
105079
|
liquid;
|
|
104456
105080
|
constructor() {
|
|
104457
105081
|
super();
|
|
104458
|
-
this.liquid =
|
|
105082
|
+
this.liquid = (0, liquid_extensions_1.createExtendedLiquid)({
|
|
104459
105083
|
strictVariables: false,
|
|
104460
105084
|
strictFilters: false,
|
|
104461
105085
|
});
|
|
@@ -104542,7 +105166,8 @@ class LogCheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
104542
105166
|
issues: result.issues || [],
|
|
104543
105167
|
};
|
|
104544
105168
|
// Add outputs namespace for accessing dependency results directly
|
|
104545
|
-
|
|
105169
|
+
const summary = result;
|
|
105170
|
+
outputs[checkName] = summary.output !== undefined ? summary.output : summary;
|
|
104546
105171
|
}
|
|
104547
105172
|
context.dependencies = dependencies;
|
|
104548
105173
|
context.outputs = outputs;
|
|
@@ -105248,16 +105873,16 @@ class ConfigLoader {
|
|
|
105248
105873
|
const outputFormat = process.env.VISOR_OUTPUT_FORMAT;
|
|
105249
105874
|
const logFn = outputFormat === 'json' || outputFormat === 'sarif' ? console.error : console.log;
|
|
105250
105875
|
logFn(`⬇️ Fetching remote configuration from: ${url}`);
|
|
105876
|
+
const controller = new AbortController();
|
|
105877
|
+
const timeoutMs = this.options.timeout ?? 30000;
|
|
105878
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
105251
105879
|
try {
|
|
105252
|
-
const controller = new AbortController();
|
|
105253
|
-
const timeoutId = setTimeout(() => controller.abort(), this.options.timeout || 30000);
|
|
105254
105880
|
const response = await fetch(url, {
|
|
105255
105881
|
signal: controller.signal,
|
|
105256
105882
|
headers: {
|
|
105257
105883
|
'User-Agent': 'Visor/1.0',
|
|
105258
105884
|
},
|
|
105259
105885
|
});
|
|
105260
|
-
clearTimeout(timeoutId);
|
|
105261
105886
|
if (!response.ok) {
|
|
105262
105887
|
throw new Error(`Failed to fetch config: ${response.status} ${response.statusText}`);
|
|
105263
105888
|
}
|
|
@@ -105281,12 +105906,15 @@ class ConfigLoader {
|
|
|
105281
105906
|
catch (error) {
|
|
105282
105907
|
if (error instanceof Error) {
|
|
105283
105908
|
if (error.name === 'AbortError') {
|
|
105284
|
-
throw new Error(`Timeout fetching configuration from ${url} (${
|
|
105909
|
+
throw new Error(`Timeout fetching configuration from ${url} (${timeoutMs}ms)`);
|
|
105285
105910
|
}
|
|
105286
105911
|
throw new Error(`Failed to fetch remote configuration from ${url}: ${error.message}`);
|
|
105287
105912
|
}
|
|
105288
105913
|
throw error;
|
|
105289
105914
|
}
|
|
105915
|
+
finally {
|
|
105916
|
+
clearTimeout(timeoutId);
|
|
105917
|
+
}
|
|
105290
105918
|
}
|
|
105291
105919
|
/**
|
|
105292
105920
|
* Load bundled default configuration
|
|
@@ -125875,7 +126503,7 @@ function createMessagePreview(message, charsPerSide = 200) {
|
|
|
125875
126503
|
const end = message.substring(message.length - charsPerSide);
|
|
125876
126504
|
return `${start}...${end}`;
|
|
125877
126505
|
}
|
|
125878
|
-
var import_zod, searchSchema, querySchema, extractSchema, delegateSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, delegateToolDefinition, attemptCompletionToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, DEFAULT_VALID_TOOLS;
|
|
126506
|
+
var import_zod, searchSchema, querySchema, extractSchema, delegateSchema, bashSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, delegateToolDefinition, attemptCompletionToolDefinition, bashToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, bashDescription, DEFAULT_VALID_TOOLS;
|
|
125879
126507
|
var init_common = __esm({
|
|
125880
126508
|
"src/tools/common.js"() {
|
|
125881
126509
|
"use strict";
|
|
@@ -125907,6 +126535,12 @@ var init_common = __esm({
|
|
|
125907
126535
|
delegateSchema = import_zod.z.object({
|
|
125908
126536
|
task: import_zod.z.string().describe("The task to delegate to a subagent. Be specific about what needs to be accomplished.")
|
|
125909
126537
|
});
|
|
126538
|
+
bashSchema = import_zod.z.object({
|
|
126539
|
+
command: import_zod.z.string().describe("The bash command to execute"),
|
|
126540
|
+
workingDirectory: import_zod.z.string().optional().describe("Directory to execute the command in (optional)"),
|
|
126541
|
+
timeout: import_zod.z.number().optional().describe("Command timeout in milliseconds (optional)"),
|
|
126542
|
+
env: import_zod.z.record(import_zod.z.string()).optional().describe("Additional environment variables (optional)")
|
|
126543
|
+
});
|
|
125910
126544
|
attemptCompletionSchema = {
|
|
125911
126545
|
// Custom validation that requires result parameter but allows direct XML response
|
|
125912
126546
|
safeParse: (params) => {
|
|
@@ -126129,11 +126763,67 @@ Usage Example:
|
|
|
126129
126763
|
<attempt_completion>
|
|
126130
126764
|
I have refactored the search module according to the requirements and verified the tests pass. The module now uses the new BM25 ranking algorithm and has improved error handling.
|
|
126131
126765
|
</attempt_completion>
|
|
126766
|
+
`;
|
|
126767
|
+
bashToolDefinition = `
|
|
126768
|
+
## bash
|
|
126769
|
+
Description: Execute bash commands for system exploration and development tasks. This tool has built-in security with allow/deny lists. By default, only safe read-only commands are allowed for code exploration.
|
|
126770
|
+
|
|
126771
|
+
Parameters:
|
|
126772
|
+
- command: (required) The bash command to execute
|
|
126773
|
+
- workingDirectory: (optional) Directory to execute the command in
|
|
126774
|
+
- timeout: (optional) Command timeout in milliseconds
|
|
126775
|
+
- env: (optional) Additional environment variables as an object
|
|
126776
|
+
|
|
126777
|
+
Security: Commands are filtered through allow/deny lists for safety:
|
|
126778
|
+
- Allowed by default: ls, cat, git status, npm list, find, grep, etc.
|
|
126779
|
+
- Denied by default: rm -rf, sudo, npm install, dangerous system commands
|
|
126780
|
+
|
|
126781
|
+
Usage Examples:
|
|
126782
|
+
|
|
126783
|
+
<examples>
|
|
126784
|
+
|
|
126785
|
+
User: What files are in the src directory?
|
|
126786
|
+
<bash>
|
|
126787
|
+
<command>ls -la src/</command>
|
|
126788
|
+
</bash>
|
|
126789
|
+
|
|
126790
|
+
User: Show me the git status
|
|
126791
|
+
<bash>
|
|
126792
|
+
<command>git status</command>
|
|
126793
|
+
</bash>
|
|
126794
|
+
|
|
126795
|
+
User: Find all TypeScript files
|
|
126796
|
+
<bash>
|
|
126797
|
+
<command>find . -name "*.ts" -type f</command>
|
|
126798
|
+
</bash>
|
|
126799
|
+
|
|
126800
|
+
User: Check installed npm packages
|
|
126801
|
+
<bash>
|
|
126802
|
+
<command>npm list --depth=0</command>
|
|
126803
|
+
</bash>
|
|
126804
|
+
|
|
126805
|
+
User: Search for TODO comments in code
|
|
126806
|
+
<bash>
|
|
126807
|
+
<command>grep -r "TODO" src/</command>
|
|
126808
|
+
</bash>
|
|
126809
|
+
|
|
126810
|
+
User: Show recent git commits
|
|
126811
|
+
<bash>
|
|
126812
|
+
<command>git log --oneline -10</command>
|
|
126813
|
+
</bash>
|
|
126814
|
+
|
|
126815
|
+
User: Check system info
|
|
126816
|
+
<bash>
|
|
126817
|
+
<command>uname -a</command>
|
|
126818
|
+
</bash>
|
|
126819
|
+
|
|
126820
|
+
</examples>
|
|
126132
126821
|
`;
|
|
126133
126822
|
searchDescription = "Search code in the repository using Elasticsearch-like query syntax. Use this tool first for any code-related questions.";
|
|
126134
126823
|
queryDescription = "Search code using ast-grep structural pattern matching. Use this tool to find specific code structures like functions, classes, or methods.";
|
|
126135
126824
|
extractDescription = "Extract code blocks from files based on file paths and optional line numbers. Use this tool to see complete context after finding relevant files.";
|
|
126136
126825
|
delegateDescription = "Automatically delegate big distinct tasks to specialized probe subagents within the agentic loop. Used by AI agents to break down complex requests into focused, parallel tasks.";
|
|
126826
|
+
bashDescription = "Execute bash commands for system exploration and development tasks. Secure by default with built-in allow/deny lists.";
|
|
126137
126827
|
DEFAULT_VALID_TOOLS = [
|
|
126138
126828
|
"search",
|
|
126139
126829
|
"query",
|
|
@@ -126187,7 +126877,7 @@ async function delegate({ task, timeout = 300, debug = false, currentIteration =
|
|
|
126187
126877
|
console.error(`[DELEGATE] Using binary at: ${binaryPath}`);
|
|
126188
126878
|
console.error(`[DELEGATE] Command args: ${args.join(" ")}`);
|
|
126189
126879
|
}
|
|
126190
|
-
return new Promise((
|
|
126880
|
+
return new Promise((resolve4, reject) => {
|
|
126191
126881
|
const delegationSpan = tracer ? tracer.createDelegationSpan(sessionId, task) : null;
|
|
126192
126882
|
const process2 = (0, import_child_process5.spawn)(binaryPath, args, {
|
|
126193
126883
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -126252,7 +126942,7 @@ async function delegate({ task, timeout = 300, debug = false, currentIteration =
|
|
|
126252
126942
|
delegationSpan.end();
|
|
126253
126943
|
}
|
|
126254
126944
|
}
|
|
126255
|
-
|
|
126945
|
+
resolve4(response);
|
|
126256
126946
|
} else {
|
|
126257
126947
|
const errorMessage = stderr.trim() || `Delegate process failed with exit code ${code}`;
|
|
126258
126948
|
if (debug) {
|
|
@@ -126448,10 +127138,10 @@ var init_vercel = __esm({
|
|
|
126448
127138
|
let extractOptions = { path: extractPath };
|
|
126449
127139
|
if (input_content) {
|
|
126450
127140
|
const { writeFileSync: writeFileSync2, unlinkSync } = await Promise.resolve(/* import() */).then(__nccwpck_require__.t.bind(__nccwpck_require__, 79896, 23));
|
|
126451
|
-
const { join:
|
|
127141
|
+
const { join: join3 } = await Promise.resolve(/* import() */).then(__nccwpck_require__.t.bind(__nccwpck_require__, 16928, 23));
|
|
126452
127142
|
const { tmpdir } = await Promise.resolve(/* import() */).then(__nccwpck_require__.t.bind(__nccwpck_require__, 70857, 23));
|
|
126453
127143
|
const { randomUUID: randomUUID5 } = await Promise.resolve(/* import() */).then(__nccwpck_require__.t.bind(__nccwpck_require__, 76982, 23));
|
|
126454
|
-
tempFilePath =
|
|
127144
|
+
tempFilePath = join3(tmpdir(), `probe-extract-${randomUUID5()}.txt`);
|
|
126455
127145
|
writeFileSync2(tempFilePath, input_content);
|
|
126456
127146
|
if (debug) {
|
|
126457
127147
|
console.error(`Created temporary file for input content: ${tempFilePath}`);
|
|
@@ -126528,6 +127218,1248 @@ var init_vercel = __esm({
|
|
|
126528
127218
|
}
|
|
126529
127219
|
});
|
|
126530
127220
|
|
|
127221
|
+
// src/agent/bashDefaults.js
|
|
127222
|
+
var DEFAULT_ALLOW_PATTERNS, DEFAULT_DENY_PATTERNS;
|
|
127223
|
+
var init_bashDefaults = __esm({
|
|
127224
|
+
"src/agent/bashDefaults.js"() {
|
|
127225
|
+
"use strict";
|
|
127226
|
+
DEFAULT_ALLOW_PATTERNS = [
|
|
127227
|
+
// Basic navigation and listing
|
|
127228
|
+
"ls",
|
|
127229
|
+
"dir",
|
|
127230
|
+
"pwd",
|
|
127231
|
+
"cd",
|
|
127232
|
+
"cd:*",
|
|
127233
|
+
// File reading commands
|
|
127234
|
+
"cat",
|
|
127235
|
+
"cat:*",
|
|
127236
|
+
"head",
|
|
127237
|
+
"head:*",
|
|
127238
|
+
"tail",
|
|
127239
|
+
"tail:*",
|
|
127240
|
+
"less",
|
|
127241
|
+
"more",
|
|
127242
|
+
"view",
|
|
127243
|
+
// File information and metadata
|
|
127244
|
+
"file",
|
|
127245
|
+
"file:*",
|
|
127246
|
+
"stat",
|
|
127247
|
+
"stat:*",
|
|
127248
|
+
"wc",
|
|
127249
|
+
"wc:*",
|
|
127250
|
+
"du",
|
|
127251
|
+
"du:*",
|
|
127252
|
+
"df",
|
|
127253
|
+
"df:*",
|
|
127254
|
+
"realpath",
|
|
127255
|
+
"realpath:*",
|
|
127256
|
+
// Search and find commands (read-only) - find restricted to safe operations
|
|
127257
|
+
"find",
|
|
127258
|
+
"find:-name:*",
|
|
127259
|
+
"find:-type:*",
|
|
127260
|
+
"find:-size:*",
|
|
127261
|
+
"find:-mtime:*",
|
|
127262
|
+
"find:-newer:*",
|
|
127263
|
+
"find:-path:*",
|
|
127264
|
+
"find:-iname:*",
|
|
127265
|
+
"find:-maxdepth:*",
|
|
127266
|
+
"find:-mindepth:*",
|
|
127267
|
+
"find:-print",
|
|
127268
|
+
"grep",
|
|
127269
|
+
"grep:*",
|
|
127270
|
+
"egrep",
|
|
127271
|
+
"egrep:*",
|
|
127272
|
+
"fgrep",
|
|
127273
|
+
"fgrep:*",
|
|
127274
|
+
"rg",
|
|
127275
|
+
"rg:*",
|
|
127276
|
+
"ag",
|
|
127277
|
+
"ag:*",
|
|
127278
|
+
"ack",
|
|
127279
|
+
"ack:*",
|
|
127280
|
+
"which",
|
|
127281
|
+
"which:*",
|
|
127282
|
+
"whereis",
|
|
127283
|
+
"whereis:*",
|
|
127284
|
+
"locate",
|
|
127285
|
+
"locate:*",
|
|
127286
|
+
"type",
|
|
127287
|
+
"type:*",
|
|
127288
|
+
"command",
|
|
127289
|
+
"command:*",
|
|
127290
|
+
// Tree and structure visualization
|
|
127291
|
+
"tree",
|
|
127292
|
+
"tree:*",
|
|
127293
|
+
// Git read-only operations
|
|
127294
|
+
"git:status",
|
|
127295
|
+
"git:log",
|
|
127296
|
+
"git:log:*",
|
|
127297
|
+
"git:diff",
|
|
127298
|
+
"git:diff:*",
|
|
127299
|
+
"git:show",
|
|
127300
|
+
"git:show:*",
|
|
127301
|
+
"git:branch",
|
|
127302
|
+
"git:branch:*",
|
|
127303
|
+
"git:tag",
|
|
127304
|
+
"git:tag:*",
|
|
127305
|
+
"git:describe",
|
|
127306
|
+
"git:describe:*",
|
|
127307
|
+
"git:remote",
|
|
127308
|
+
"git:remote:*",
|
|
127309
|
+
"git:config:*",
|
|
127310
|
+
"git:blame",
|
|
127311
|
+
"git:blame:*",
|
|
127312
|
+
"git:shortlog",
|
|
127313
|
+
"git:reflog",
|
|
127314
|
+
"git:ls-files",
|
|
127315
|
+
"git:ls-tree",
|
|
127316
|
+
"git:rev-parse",
|
|
127317
|
+
"git:rev-list",
|
|
127318
|
+
"git:--version",
|
|
127319
|
+
"git:help",
|
|
127320
|
+
"git:help:*",
|
|
127321
|
+
// Package managers (information only)
|
|
127322
|
+
"npm:list",
|
|
127323
|
+
"npm:ls",
|
|
127324
|
+
"npm:view",
|
|
127325
|
+
"npm:info",
|
|
127326
|
+
"npm:show",
|
|
127327
|
+
"npm:outdated",
|
|
127328
|
+
"npm:audit",
|
|
127329
|
+
"npm:--version",
|
|
127330
|
+
"yarn:list",
|
|
127331
|
+
"yarn:info",
|
|
127332
|
+
"yarn:--version",
|
|
127333
|
+
"pnpm:list",
|
|
127334
|
+
"pnpm:--version",
|
|
127335
|
+
"pip:list",
|
|
127336
|
+
"pip:show",
|
|
127337
|
+
"pip:--version",
|
|
127338
|
+
"pip3:list",
|
|
127339
|
+
"pip3:show",
|
|
127340
|
+
"pip3:--version",
|
|
127341
|
+
"gem:list",
|
|
127342
|
+
"gem:--version",
|
|
127343
|
+
"bundle:list",
|
|
127344
|
+
"bundle:show",
|
|
127345
|
+
"bundle:--version",
|
|
127346
|
+
"composer:show",
|
|
127347
|
+
"composer:--version",
|
|
127348
|
+
// Language and runtime versions
|
|
127349
|
+
"node:--version",
|
|
127350
|
+
"node:-v",
|
|
127351
|
+
"python:--version",
|
|
127352
|
+
"python:-V",
|
|
127353
|
+
"python3:--version",
|
|
127354
|
+
"python3:-V",
|
|
127355
|
+
"ruby:--version",
|
|
127356
|
+
"ruby:-v",
|
|
127357
|
+
"go:version",
|
|
127358
|
+
"go:env",
|
|
127359
|
+
"go:list",
|
|
127360
|
+
"go:mod:graph",
|
|
127361
|
+
"rustc:--version",
|
|
127362
|
+
"cargo:--version",
|
|
127363
|
+
"cargo:tree",
|
|
127364
|
+
"cargo:metadata",
|
|
127365
|
+
"java:--version",
|
|
127366
|
+
"java:-version",
|
|
127367
|
+
"javac:--version",
|
|
127368
|
+
"mvn:--version",
|
|
127369
|
+
"gradle:--version",
|
|
127370
|
+
"php:--version",
|
|
127371
|
+
"dotnet:--version",
|
|
127372
|
+
"dotnet:list",
|
|
127373
|
+
// Database client versions (connection info only)
|
|
127374
|
+
"psql:--version",
|
|
127375
|
+
"mysql:--version",
|
|
127376
|
+
"redis-cli:--version",
|
|
127377
|
+
"mongo:--version",
|
|
127378
|
+
"sqlite3:--version",
|
|
127379
|
+
// System information
|
|
127380
|
+
"uname",
|
|
127381
|
+
"uname:*",
|
|
127382
|
+
"hostname",
|
|
127383
|
+
"whoami",
|
|
127384
|
+
"id",
|
|
127385
|
+
"groups",
|
|
127386
|
+
"date",
|
|
127387
|
+
"cal",
|
|
127388
|
+
"uptime",
|
|
127389
|
+
"w",
|
|
127390
|
+
"users",
|
|
127391
|
+
"sleep",
|
|
127392
|
+
"sleep:*",
|
|
127393
|
+
// Environment and shell
|
|
127394
|
+
"env",
|
|
127395
|
+
"printenv",
|
|
127396
|
+
"echo",
|
|
127397
|
+
"echo:*",
|
|
127398
|
+
"printf",
|
|
127399
|
+
"printf:*",
|
|
127400
|
+
"export",
|
|
127401
|
+
"export:*",
|
|
127402
|
+
"set",
|
|
127403
|
+
"unset",
|
|
127404
|
+
// Process information (read-only)
|
|
127405
|
+
"ps",
|
|
127406
|
+
"ps:*",
|
|
127407
|
+
"pgrep",
|
|
127408
|
+
"pgrep:*",
|
|
127409
|
+
"jobs",
|
|
127410
|
+
"top:-n:1",
|
|
127411
|
+
// Network information (read-only)
|
|
127412
|
+
"ifconfig",
|
|
127413
|
+
"ip:addr",
|
|
127414
|
+
"ip:link",
|
|
127415
|
+
"hostname:-I",
|
|
127416
|
+
"ping:-c:*",
|
|
127417
|
+
"traceroute",
|
|
127418
|
+
"nslookup",
|
|
127419
|
+
"dig",
|
|
127420
|
+
// Text processing and utilities (awk removed - too powerful)
|
|
127421
|
+
"sed:-n:*",
|
|
127422
|
+
"cut",
|
|
127423
|
+
"cut:*",
|
|
127424
|
+
"sort",
|
|
127425
|
+
"sort:*",
|
|
127426
|
+
"uniq",
|
|
127427
|
+
"uniq:*",
|
|
127428
|
+
"tr",
|
|
127429
|
+
"tr:*",
|
|
127430
|
+
"column",
|
|
127431
|
+
"column:*",
|
|
127432
|
+
"paste",
|
|
127433
|
+
"paste:*",
|
|
127434
|
+
"join",
|
|
127435
|
+
"join:*",
|
|
127436
|
+
"comm",
|
|
127437
|
+
"comm:*",
|
|
127438
|
+
"diff",
|
|
127439
|
+
"diff:*",
|
|
127440
|
+
"cmp",
|
|
127441
|
+
"cmp:*",
|
|
127442
|
+
"patch:--dry-run:*",
|
|
127443
|
+
// Hashing and encoding (read-only)
|
|
127444
|
+
"md5sum",
|
|
127445
|
+
"md5sum:*",
|
|
127446
|
+
"sha1sum",
|
|
127447
|
+
"sha1sum:*",
|
|
127448
|
+
"sha256sum",
|
|
127449
|
+
"sha256sum:*",
|
|
127450
|
+
"base64",
|
|
127451
|
+
"base64:-d",
|
|
127452
|
+
"od",
|
|
127453
|
+
"od:*",
|
|
127454
|
+
"hexdump",
|
|
127455
|
+
"hexdump:*",
|
|
127456
|
+
// Archive and compression (list/view only)
|
|
127457
|
+
"tar:-tf:*",
|
|
127458
|
+
"tar:-tzf:*",
|
|
127459
|
+
"unzip:-l:*",
|
|
127460
|
+
"zip:-l:*",
|
|
127461
|
+
"gzip:-l:*",
|
|
127462
|
+
"gunzip:-l:*",
|
|
127463
|
+
// Help and documentation
|
|
127464
|
+
"man",
|
|
127465
|
+
"man:*",
|
|
127466
|
+
"--help",
|
|
127467
|
+
"help",
|
|
127468
|
+
"info",
|
|
127469
|
+
"info:*",
|
|
127470
|
+
"whatis",
|
|
127471
|
+
"whatis:*",
|
|
127472
|
+
"apropos",
|
|
127473
|
+
"apropos:*",
|
|
127474
|
+
// Make (dry run and info)
|
|
127475
|
+
"make:-n",
|
|
127476
|
+
"make:--dry-run",
|
|
127477
|
+
"make:-p",
|
|
127478
|
+
"make:--print-data-base",
|
|
127479
|
+
// Docker (read-only operations)
|
|
127480
|
+
"docker:ps",
|
|
127481
|
+
"docker:images",
|
|
127482
|
+
"docker:version",
|
|
127483
|
+
"docker:info",
|
|
127484
|
+
"docker:logs:*",
|
|
127485
|
+
"docker:inspect:*",
|
|
127486
|
+
// Test runners (list/info only)
|
|
127487
|
+
"jest:--listTests",
|
|
127488
|
+
"mocha:--help",
|
|
127489
|
+
"pytest:--collect-only"
|
|
127490
|
+
];
|
|
127491
|
+
DEFAULT_DENY_PATTERNS = [
|
|
127492
|
+
// Dangerous file operations
|
|
127493
|
+
"rm:-rf",
|
|
127494
|
+
"rm:-f:/",
|
|
127495
|
+
"rm:/",
|
|
127496
|
+
"rm:-rf:*",
|
|
127497
|
+
"rmdir",
|
|
127498
|
+
"chmod:777",
|
|
127499
|
+
"chmod:-R:777",
|
|
127500
|
+
"chown",
|
|
127501
|
+
"chgrp",
|
|
127502
|
+
"dd",
|
|
127503
|
+
"dd:*",
|
|
127504
|
+
"shred",
|
|
127505
|
+
"shred:*",
|
|
127506
|
+
// Dangerous find operations that can execute arbitrary commands
|
|
127507
|
+
"find:-exec:*",
|
|
127508
|
+
"find:*:-exec:*",
|
|
127509
|
+
"find:-execdir:*",
|
|
127510
|
+
"find:*:-execdir:*",
|
|
127511
|
+
"find:-ok:*",
|
|
127512
|
+
"find:*:-ok:*",
|
|
127513
|
+
"find:-okdir:*",
|
|
127514
|
+
"find:*:-okdir:*",
|
|
127515
|
+
// Powerful scripting tools that can execute arbitrary commands
|
|
127516
|
+
"awk",
|
|
127517
|
+
"awk:*",
|
|
127518
|
+
"perl",
|
|
127519
|
+
"perl:*",
|
|
127520
|
+
"python:-c:*",
|
|
127521
|
+
"node:-e:*",
|
|
127522
|
+
// System administration and modification
|
|
127523
|
+
"sudo:*",
|
|
127524
|
+
"su",
|
|
127525
|
+
"su:*",
|
|
127526
|
+
"passwd",
|
|
127527
|
+
"adduser",
|
|
127528
|
+
"useradd",
|
|
127529
|
+
"userdel",
|
|
127530
|
+
"usermod",
|
|
127531
|
+
"groupadd",
|
|
127532
|
+
"groupdel",
|
|
127533
|
+
"visudo",
|
|
127534
|
+
// Package installation and removal
|
|
127535
|
+
"npm:install",
|
|
127536
|
+
"npm:i",
|
|
127537
|
+
"npm:uninstall",
|
|
127538
|
+
"npm:publish",
|
|
127539
|
+
"npm:unpublish",
|
|
127540
|
+
"npm:link",
|
|
127541
|
+
"npm:update",
|
|
127542
|
+
"yarn:install",
|
|
127543
|
+
"yarn:add",
|
|
127544
|
+
"yarn:remove",
|
|
127545
|
+
"yarn:upgrade",
|
|
127546
|
+
"pnpm:install",
|
|
127547
|
+
"pnpm:add",
|
|
127548
|
+
"pnpm:remove",
|
|
127549
|
+
"pip:install",
|
|
127550
|
+
"pip:uninstall",
|
|
127551
|
+
"pip:upgrade",
|
|
127552
|
+
"pip3:install",
|
|
127553
|
+
"pip3:uninstall",
|
|
127554
|
+
"pip3:upgrade",
|
|
127555
|
+
"gem:install",
|
|
127556
|
+
"gem:uninstall",
|
|
127557
|
+
"gem:update",
|
|
127558
|
+
"bundle:install",
|
|
127559
|
+
"bundle:update",
|
|
127560
|
+
"composer:install",
|
|
127561
|
+
"composer:update",
|
|
127562
|
+
"composer:remove",
|
|
127563
|
+
"apt:*",
|
|
127564
|
+
"apt-get:*",
|
|
127565
|
+
"yum:*",
|
|
127566
|
+
"dnf:*",
|
|
127567
|
+
"zypper:*",
|
|
127568
|
+
"brew:install",
|
|
127569
|
+
"brew:uninstall",
|
|
127570
|
+
"brew:upgrade",
|
|
127571
|
+
"conda:install",
|
|
127572
|
+
"conda:remove",
|
|
127573
|
+
"conda:update",
|
|
127574
|
+
// Service and system control
|
|
127575
|
+
"systemctl:*",
|
|
127576
|
+
"service:*",
|
|
127577
|
+
"chkconfig:*",
|
|
127578
|
+
"initctl:*",
|
|
127579
|
+
"upstart:*",
|
|
127580
|
+
// Network operations that could be dangerous
|
|
127581
|
+
"curl:-d:*",
|
|
127582
|
+
"curl:--data:*",
|
|
127583
|
+
"curl:-X:POST:*",
|
|
127584
|
+
"curl:-X:PUT:*",
|
|
127585
|
+
"wget:-O:/",
|
|
127586
|
+
"wget:--post-data:*",
|
|
127587
|
+
"ssh",
|
|
127588
|
+
"ssh:*",
|
|
127589
|
+
"scp",
|
|
127590
|
+
"scp:*",
|
|
127591
|
+
"sftp",
|
|
127592
|
+
"sftp:*",
|
|
127593
|
+
"rsync:*",
|
|
127594
|
+
"nc",
|
|
127595
|
+
"nc:*",
|
|
127596
|
+
"netcat",
|
|
127597
|
+
"netcat:*",
|
|
127598
|
+
"telnet",
|
|
127599
|
+
"telnet:*",
|
|
127600
|
+
"ftp",
|
|
127601
|
+
"ftp:*",
|
|
127602
|
+
// Process control and termination
|
|
127603
|
+
"kill",
|
|
127604
|
+
"kill:*",
|
|
127605
|
+
"killall",
|
|
127606
|
+
"killall:*",
|
|
127607
|
+
"pkill",
|
|
127608
|
+
"pkill:*",
|
|
127609
|
+
"nohup:*",
|
|
127610
|
+
"disown:*",
|
|
127611
|
+
// System control and shutdown
|
|
127612
|
+
"shutdown",
|
|
127613
|
+
"shutdown:*",
|
|
127614
|
+
"reboot",
|
|
127615
|
+
"halt",
|
|
127616
|
+
"poweroff",
|
|
127617
|
+
"init",
|
|
127618
|
+
"telinit",
|
|
127619
|
+
// Kernel and module operations
|
|
127620
|
+
"insmod",
|
|
127621
|
+
"insmod:*",
|
|
127622
|
+
"rmmod",
|
|
127623
|
+
"rmmod:*",
|
|
127624
|
+
"modprobe",
|
|
127625
|
+
"modprobe:*",
|
|
127626
|
+
"sysctl:-w:*",
|
|
127627
|
+
// Dangerous git operations
|
|
127628
|
+
"git:push",
|
|
127629
|
+
"git:push:*",
|
|
127630
|
+
"git:force",
|
|
127631
|
+
"git:reset:--hard:*",
|
|
127632
|
+
"git:clean:-fd",
|
|
127633
|
+
"git:rm:*",
|
|
127634
|
+
"git:commit",
|
|
127635
|
+
"git:merge",
|
|
127636
|
+
"git:rebase",
|
|
127637
|
+
"git:cherry-pick",
|
|
127638
|
+
"git:stash:drop",
|
|
127639
|
+
// File system mounting and partitioning
|
|
127640
|
+
"mount",
|
|
127641
|
+
"mount:*",
|
|
127642
|
+
"umount",
|
|
127643
|
+
"umount:*",
|
|
127644
|
+
"fdisk",
|
|
127645
|
+
"fdisk:*",
|
|
127646
|
+
"parted",
|
|
127647
|
+
"parted:*",
|
|
127648
|
+
"mkfs",
|
|
127649
|
+
"mkfs:*",
|
|
127650
|
+
"fsck",
|
|
127651
|
+
"fsck:*",
|
|
127652
|
+
// Cron and scheduling
|
|
127653
|
+
"crontab",
|
|
127654
|
+
"crontab:*",
|
|
127655
|
+
"at",
|
|
127656
|
+
"at:*",
|
|
127657
|
+
"batch",
|
|
127658
|
+
"batch:*",
|
|
127659
|
+
// Compression with potential overwrite
|
|
127660
|
+
"tar:-xf:*",
|
|
127661
|
+
"unzip",
|
|
127662
|
+
"unzip:*",
|
|
127663
|
+
"gzip:*",
|
|
127664
|
+
"gunzip:*",
|
|
127665
|
+
// Build and compilation that might modify files
|
|
127666
|
+
"make",
|
|
127667
|
+
"make:install",
|
|
127668
|
+
"make:clean",
|
|
127669
|
+
"cargo:build",
|
|
127670
|
+
"cargo:install",
|
|
127671
|
+
"npm:run:build",
|
|
127672
|
+
"yarn:build",
|
|
127673
|
+
"mvn:install",
|
|
127674
|
+
"gradle:build",
|
|
127675
|
+
// Docker operations that could modify state
|
|
127676
|
+
"docker:run",
|
|
127677
|
+
"docker:run:*",
|
|
127678
|
+
"docker:exec",
|
|
127679
|
+
"docker:exec:*",
|
|
127680
|
+
"docker:build",
|
|
127681
|
+
"docker:build:*",
|
|
127682
|
+
"docker:pull",
|
|
127683
|
+
"docker:push",
|
|
127684
|
+
"docker:rm",
|
|
127685
|
+
"docker:rmi",
|
|
127686
|
+
"docker:stop",
|
|
127687
|
+
"docker:start",
|
|
127688
|
+
// Database operations
|
|
127689
|
+
"mysql:-e:DROP",
|
|
127690
|
+
"psql:-c:DROP",
|
|
127691
|
+
"redis-cli:FLUSHALL",
|
|
127692
|
+
"mongo:--eval:*",
|
|
127693
|
+
// Text editors that could modify files
|
|
127694
|
+
"vi",
|
|
127695
|
+
"vi:*",
|
|
127696
|
+
"vim",
|
|
127697
|
+
"vim:*",
|
|
127698
|
+
"nano",
|
|
127699
|
+
"nano:*",
|
|
127700
|
+
"emacs",
|
|
127701
|
+
"emacs:*",
|
|
127702
|
+
"sed:-i:*",
|
|
127703
|
+
"perl:-i:*",
|
|
127704
|
+
// Potentially dangerous utilities
|
|
127705
|
+
"eval",
|
|
127706
|
+
"eval:*",
|
|
127707
|
+
"exec",
|
|
127708
|
+
"exec:*",
|
|
127709
|
+
"source",
|
|
127710
|
+
"source:*",
|
|
127711
|
+
"bash:-c:*",
|
|
127712
|
+
"sh:-c:*",
|
|
127713
|
+
"zsh:-c:*"
|
|
127714
|
+
];
|
|
127715
|
+
}
|
|
127716
|
+
});
|
|
127717
|
+
|
|
127718
|
+
// src/agent/bashCommandUtils.js
|
|
127719
|
+
function parseSimpleCommand(command) {
|
|
127720
|
+
if (!command || typeof command !== "string") {
|
|
127721
|
+
return {
|
|
127722
|
+
success: false,
|
|
127723
|
+
error: "Command must be a non-empty string",
|
|
127724
|
+
command: null,
|
|
127725
|
+
args: [],
|
|
127726
|
+
isComplex: false
|
|
127727
|
+
};
|
|
127728
|
+
}
|
|
127729
|
+
const trimmed = command.trim();
|
|
127730
|
+
if (!trimmed) {
|
|
127731
|
+
return {
|
|
127732
|
+
success: false,
|
|
127733
|
+
error: "Command cannot be empty",
|
|
127734
|
+
command: null,
|
|
127735
|
+
args: [],
|
|
127736
|
+
isComplex: false
|
|
127737
|
+
};
|
|
127738
|
+
}
|
|
127739
|
+
const complexPatterns = [
|
|
127740
|
+
/\|/,
|
|
127741
|
+
// Pipes
|
|
127742
|
+
/&&/,
|
|
127743
|
+
// Logical AND
|
|
127744
|
+
/\|\|/,
|
|
127745
|
+
// Logical OR
|
|
127746
|
+
/(?<!\\);/,
|
|
127747
|
+
// Command separator (but not escaped \;)
|
|
127748
|
+
/&$/,
|
|
127749
|
+
// Background execution
|
|
127750
|
+
/\$\(/,
|
|
127751
|
+
// Command substitution $()
|
|
127752
|
+
/`/,
|
|
127753
|
+
// Command substitution ``
|
|
127754
|
+
/>/,
|
|
127755
|
+
// Redirection >
|
|
127756
|
+
/</,
|
|
127757
|
+
// Redirection <
|
|
127758
|
+
/\*\*/,
|
|
127759
|
+
// Glob patterns (potentially dangerous)
|
|
127760
|
+
/^\s*\{.*,.*\}|\{.*\.\.\.*\}/
|
|
127761
|
+
// Brace expansion like {a,b} or {1..10} (but not find {} placeholders)
|
|
127762
|
+
];
|
|
127763
|
+
for (const pattern of complexPatterns) {
|
|
127764
|
+
if (pattern.test(trimmed)) {
|
|
127765
|
+
return {
|
|
127766
|
+
success: false,
|
|
127767
|
+
error: "Complex shell commands with pipes, operators, or redirections are not supported for security reasons",
|
|
127768
|
+
command: null,
|
|
127769
|
+
args: [],
|
|
127770
|
+
isComplex: true,
|
|
127771
|
+
detected: pattern.toString()
|
|
127772
|
+
};
|
|
127773
|
+
}
|
|
127774
|
+
}
|
|
127775
|
+
const args = [];
|
|
127776
|
+
let current = "";
|
|
127777
|
+
let inQuotes = false;
|
|
127778
|
+
let quoteChar = "";
|
|
127779
|
+
let escaped = false;
|
|
127780
|
+
for (let i3 = 0; i3 < trimmed.length; i3++) {
|
|
127781
|
+
const char = trimmed[i3];
|
|
127782
|
+
const nextChar = i3 + 1 < trimmed.length ? trimmed[i3 + 1] : "";
|
|
127783
|
+
if (escaped) {
|
|
127784
|
+
current += char;
|
|
127785
|
+
escaped = false;
|
|
127786
|
+
continue;
|
|
127787
|
+
}
|
|
127788
|
+
if (char === "\\" && !inQuotes) {
|
|
127789
|
+
escaped = true;
|
|
127790
|
+
continue;
|
|
127791
|
+
}
|
|
127792
|
+
if (!inQuotes && (char === '"' || char === "'")) {
|
|
127793
|
+
inQuotes = true;
|
|
127794
|
+
quoteChar = char;
|
|
127795
|
+
} else if (inQuotes && char === quoteChar) {
|
|
127796
|
+
inQuotes = false;
|
|
127797
|
+
quoteChar = "";
|
|
127798
|
+
} else if (!inQuotes && char === " ") {
|
|
127799
|
+
if (current.trim()) {
|
|
127800
|
+
args.push(current.trim());
|
|
127801
|
+
current = "";
|
|
127802
|
+
}
|
|
127803
|
+
} else {
|
|
127804
|
+
current += char;
|
|
127805
|
+
}
|
|
127806
|
+
}
|
|
127807
|
+
if (current.trim()) {
|
|
127808
|
+
args.push(current.trim());
|
|
127809
|
+
}
|
|
127810
|
+
if (inQuotes) {
|
|
127811
|
+
return {
|
|
127812
|
+
success: false,
|
|
127813
|
+
error: `Unclosed quote in command: ${quoteChar}`,
|
|
127814
|
+
command: null,
|
|
127815
|
+
args: [],
|
|
127816
|
+
isComplex: false
|
|
127817
|
+
};
|
|
127818
|
+
}
|
|
127819
|
+
if (args.length === 0) {
|
|
127820
|
+
return {
|
|
127821
|
+
success: false,
|
|
127822
|
+
error: "No command found after parsing",
|
|
127823
|
+
command: null,
|
|
127824
|
+
args: [],
|
|
127825
|
+
isComplex: false
|
|
127826
|
+
};
|
|
127827
|
+
}
|
|
127828
|
+
const [baseCommand, ...commandArgs] = args;
|
|
127829
|
+
return {
|
|
127830
|
+
success: true,
|
|
127831
|
+
error: null,
|
|
127832
|
+
command: baseCommand,
|
|
127833
|
+
args: commandArgs,
|
|
127834
|
+
fullArgs: args,
|
|
127835
|
+
isComplex: false,
|
|
127836
|
+
original: command
|
|
127837
|
+
};
|
|
127838
|
+
}
|
|
127839
|
+
function isComplexCommand(command) {
|
|
127840
|
+
const result = parseSimpleCommand(command);
|
|
127841
|
+
return result.isComplex;
|
|
127842
|
+
}
|
|
127843
|
+
function parseCommand(command) {
|
|
127844
|
+
const result = parseSimpleCommand(command);
|
|
127845
|
+
if (!result.success) {
|
|
127846
|
+
return {
|
|
127847
|
+
command: "",
|
|
127848
|
+
args: [],
|
|
127849
|
+
error: result.error,
|
|
127850
|
+
isComplex: result.isComplex
|
|
127851
|
+
};
|
|
127852
|
+
}
|
|
127853
|
+
return {
|
|
127854
|
+
command: result.command,
|
|
127855
|
+
args: result.args,
|
|
127856
|
+
error: null,
|
|
127857
|
+
isComplex: result.isComplex
|
|
127858
|
+
};
|
|
127859
|
+
}
|
|
127860
|
+
function parseCommandForExecution(command) {
|
|
127861
|
+
const result = parseSimpleCommand(command);
|
|
127862
|
+
if (!result.success) {
|
|
127863
|
+
return null;
|
|
127864
|
+
}
|
|
127865
|
+
return result.fullArgs;
|
|
127866
|
+
}
|
|
127867
|
+
var init_bashCommandUtils = __esm({
|
|
127868
|
+
"src/agent/bashCommandUtils.js"() {
|
|
127869
|
+
"use strict";
|
|
127870
|
+
}
|
|
127871
|
+
});
|
|
127872
|
+
|
|
127873
|
+
// src/agent/bashPermissions.js
|
|
127874
|
+
function matchesPattern(parsedCommand, pattern) {
|
|
127875
|
+
if (!parsedCommand || !pattern) return false;
|
|
127876
|
+
const { command, args } = parsedCommand;
|
|
127877
|
+
if (!command) return false;
|
|
127878
|
+
const patternParts = pattern.split(":");
|
|
127879
|
+
const commandName = patternParts[0];
|
|
127880
|
+
if (commandName === "*") {
|
|
127881
|
+
return true;
|
|
127882
|
+
} else if (commandName !== command) {
|
|
127883
|
+
return false;
|
|
127884
|
+
}
|
|
127885
|
+
if (patternParts.length === 1) {
|
|
127886
|
+
return true;
|
|
127887
|
+
}
|
|
127888
|
+
for (let i3 = 1; i3 < patternParts.length; i3++) {
|
|
127889
|
+
const patternArg = patternParts[i3];
|
|
127890
|
+
const argIndex = i3 - 1;
|
|
127891
|
+
if (patternArg === "*") {
|
|
127892
|
+
continue;
|
|
127893
|
+
}
|
|
127894
|
+
if (argIndex >= args.length) {
|
|
127895
|
+
return false;
|
|
127896
|
+
}
|
|
127897
|
+
const actualArg = args[argIndex];
|
|
127898
|
+
if (patternArg !== actualArg) {
|
|
127899
|
+
return false;
|
|
127900
|
+
}
|
|
127901
|
+
}
|
|
127902
|
+
return true;
|
|
127903
|
+
}
|
|
127904
|
+
function matchesAnyPattern(parsedCommand, patterns) {
|
|
127905
|
+
if (!patterns || patterns.length === 0) return false;
|
|
127906
|
+
return patterns.some((pattern) => matchesPattern(parsedCommand, pattern));
|
|
127907
|
+
}
|
|
127908
|
+
var BashPermissionChecker;
|
|
127909
|
+
var init_bashPermissions = __esm({
|
|
127910
|
+
"src/agent/bashPermissions.js"() {
|
|
127911
|
+
"use strict";
|
|
127912
|
+
init_bashDefaults();
|
|
127913
|
+
init_bashCommandUtils();
|
|
127914
|
+
BashPermissionChecker = class {
|
|
127915
|
+
/**
|
|
127916
|
+
* Create a permission checker
|
|
127917
|
+
* @param {Object} config - Configuration options
|
|
127918
|
+
* @param {string[]} [config.allow] - Additional allow patterns
|
|
127919
|
+
* @param {string[]} [config.deny] - Additional deny patterns
|
|
127920
|
+
* @param {boolean} [config.disableDefaultAllow] - Disable default allow list
|
|
127921
|
+
* @param {boolean} [config.disableDefaultDeny] - Disable default deny list
|
|
127922
|
+
* @param {boolean} [config.debug] - Enable debug logging
|
|
127923
|
+
*/
|
|
127924
|
+
constructor(config = {}) {
|
|
127925
|
+
this.debug = config.debug || false;
|
|
127926
|
+
this.allowPatterns = [];
|
|
127927
|
+
if (!config.disableDefaultAllow) {
|
|
127928
|
+
this.allowPatterns.push(...DEFAULT_ALLOW_PATTERNS);
|
|
127929
|
+
if (this.debug) {
|
|
127930
|
+
console.log(`[BashPermissions] Added ${DEFAULT_ALLOW_PATTERNS.length} default allow patterns`);
|
|
127931
|
+
}
|
|
127932
|
+
}
|
|
127933
|
+
if (config.allow && Array.isArray(config.allow)) {
|
|
127934
|
+
this.allowPatterns.push(...config.allow);
|
|
127935
|
+
if (this.debug) {
|
|
127936
|
+
console.log(`[BashPermissions] Added ${config.allow.length} custom allow patterns:`, config.allow);
|
|
127937
|
+
}
|
|
127938
|
+
}
|
|
127939
|
+
this.denyPatterns = [];
|
|
127940
|
+
if (!config.disableDefaultDeny) {
|
|
127941
|
+
this.denyPatterns.push(...DEFAULT_DENY_PATTERNS);
|
|
127942
|
+
if (this.debug) {
|
|
127943
|
+
console.log(`[BashPermissions] Added ${DEFAULT_DENY_PATTERNS.length} default deny patterns`);
|
|
127944
|
+
}
|
|
127945
|
+
}
|
|
127946
|
+
if (config.deny && Array.isArray(config.deny)) {
|
|
127947
|
+
this.denyPatterns.push(...config.deny);
|
|
127948
|
+
if (this.debug) {
|
|
127949
|
+
console.log(`[BashPermissions] Added ${config.deny.length} custom deny patterns:`, config.deny);
|
|
127950
|
+
}
|
|
127951
|
+
}
|
|
127952
|
+
if (this.debug) {
|
|
127953
|
+
console.log(`[BashPermissions] Total patterns - Allow: ${this.allowPatterns.length}, Deny: ${this.denyPatterns.length}`);
|
|
127954
|
+
}
|
|
127955
|
+
}
|
|
127956
|
+
/**
|
|
127957
|
+
* Check if a simple command is allowed (rejects complex commands for security)
|
|
127958
|
+
* @param {string} command - Command to check
|
|
127959
|
+
* @returns {Object} Permission result
|
|
127960
|
+
*/
|
|
127961
|
+
check(command) {
|
|
127962
|
+
if (!command || typeof command !== "string") {
|
|
127963
|
+
return {
|
|
127964
|
+
allowed: false,
|
|
127965
|
+
reason: "Invalid or empty command",
|
|
127966
|
+
command
|
|
127967
|
+
};
|
|
127968
|
+
}
|
|
127969
|
+
if (isComplexCommand(command)) {
|
|
127970
|
+
return {
|
|
127971
|
+
allowed: false,
|
|
127972
|
+
reason: "Complex shell commands with pipes, operators, or redirections are not supported for security reasons",
|
|
127973
|
+
command,
|
|
127974
|
+
isComplex: true
|
|
127975
|
+
};
|
|
127976
|
+
}
|
|
127977
|
+
const parsed = parseCommand(command);
|
|
127978
|
+
if (parsed.error) {
|
|
127979
|
+
return {
|
|
127980
|
+
allowed: false,
|
|
127981
|
+
reason: parsed.error,
|
|
127982
|
+
command
|
|
127983
|
+
};
|
|
127984
|
+
}
|
|
127985
|
+
if (!parsed.command) {
|
|
127986
|
+
return {
|
|
127987
|
+
allowed: false,
|
|
127988
|
+
reason: "No valid command found",
|
|
127989
|
+
command
|
|
127990
|
+
};
|
|
127991
|
+
}
|
|
127992
|
+
if (this.debug) {
|
|
127993
|
+
console.log(`[BashPermissions] Checking simple command: "${command}"`);
|
|
127994
|
+
console.log(`[BashPermissions] Parsed: ${parsed.command} with args: [${parsed.args.join(", ")}]`);
|
|
127995
|
+
}
|
|
127996
|
+
if (matchesAnyPattern(parsed, this.denyPatterns)) {
|
|
127997
|
+
const matchedPatterns = this.denyPatterns.filter((pattern) => matchesPattern(parsed, pattern));
|
|
127998
|
+
return {
|
|
127999
|
+
allowed: false,
|
|
128000
|
+
reason: `Command matches deny pattern: ${matchedPatterns[0]}`,
|
|
128001
|
+
command,
|
|
128002
|
+
parsed,
|
|
128003
|
+
matchedPatterns
|
|
128004
|
+
};
|
|
128005
|
+
}
|
|
128006
|
+
if (this.allowPatterns.length > 0) {
|
|
128007
|
+
if (!matchesAnyPattern(parsed, this.allowPatterns)) {
|
|
128008
|
+
return {
|
|
128009
|
+
allowed: false,
|
|
128010
|
+
reason: "Command not in allow list",
|
|
128011
|
+
command,
|
|
128012
|
+
parsed
|
|
128013
|
+
};
|
|
128014
|
+
}
|
|
128015
|
+
}
|
|
128016
|
+
const result = {
|
|
128017
|
+
allowed: true,
|
|
128018
|
+
command,
|
|
128019
|
+
parsed,
|
|
128020
|
+
isComplex: false
|
|
128021
|
+
};
|
|
128022
|
+
if (this.debug) {
|
|
128023
|
+
console.log(`[BashPermissions] ALLOWED - command passed all checks`);
|
|
128024
|
+
}
|
|
128025
|
+
return result;
|
|
128026
|
+
}
|
|
128027
|
+
/**
|
|
128028
|
+
* Get configuration summary
|
|
128029
|
+
* @returns {Object} Configuration info
|
|
128030
|
+
*/
|
|
128031
|
+
getConfig() {
|
|
128032
|
+
return {
|
|
128033
|
+
allowPatterns: this.allowPatterns.length,
|
|
128034
|
+
denyPatterns: this.denyPatterns.length,
|
|
128035
|
+
totalPatterns: this.allowPatterns.length + this.denyPatterns.length
|
|
128036
|
+
};
|
|
128037
|
+
}
|
|
128038
|
+
};
|
|
128039
|
+
}
|
|
128040
|
+
});
|
|
128041
|
+
|
|
128042
|
+
// src/agent/bashExecutor.js
|
|
128043
|
+
async function executeBashCommand(command, options = {}) {
|
|
128044
|
+
const {
|
|
128045
|
+
workingDirectory = process.cwd(),
|
|
128046
|
+
timeout = 12e4,
|
|
128047
|
+
// 2 minutes default
|
|
128048
|
+
env = {},
|
|
128049
|
+
maxBuffer = 10 * 1024 * 1024,
|
|
128050
|
+
// 10MB
|
|
128051
|
+
debug = false
|
|
128052
|
+
} = options;
|
|
128053
|
+
let cwd = workingDirectory;
|
|
128054
|
+
try {
|
|
128055
|
+
cwd = (0, import_path4.resolve)(cwd);
|
|
128056
|
+
if (!(0, import_fs.existsSync)(cwd)) {
|
|
128057
|
+
throw new Error(`Working directory does not exist: ${cwd}`);
|
|
128058
|
+
}
|
|
128059
|
+
} catch (error2) {
|
|
128060
|
+
return {
|
|
128061
|
+
success: false,
|
|
128062
|
+
error: `Invalid working directory: ${error2.message}`,
|
|
128063
|
+
stdout: "",
|
|
128064
|
+
stderr: "",
|
|
128065
|
+
exitCode: 1,
|
|
128066
|
+
command,
|
|
128067
|
+
workingDirectory: cwd,
|
|
128068
|
+
duration: 0
|
|
128069
|
+
};
|
|
128070
|
+
}
|
|
128071
|
+
const startTime = Date.now();
|
|
128072
|
+
if (debug) {
|
|
128073
|
+
console.log(`[BashExecutor] Executing command: "${command}"`);
|
|
128074
|
+
console.log(`[BashExecutor] Working directory: "${cwd}"`);
|
|
128075
|
+
console.log(`[BashExecutor] Timeout: ${timeout}ms`);
|
|
128076
|
+
}
|
|
128077
|
+
return new Promise((resolve4, reject) => {
|
|
128078
|
+
const processEnv = {
|
|
128079
|
+
...process.env,
|
|
128080
|
+
...env
|
|
128081
|
+
};
|
|
128082
|
+
const args = parseCommandForExecution(command);
|
|
128083
|
+
if (!args || args.length === 0) {
|
|
128084
|
+
resolve4({
|
|
128085
|
+
success: false,
|
|
128086
|
+
error: "Failed to parse command",
|
|
128087
|
+
stdout: "",
|
|
128088
|
+
stderr: "",
|
|
128089
|
+
exitCode: 1,
|
|
128090
|
+
command,
|
|
128091
|
+
workingDirectory: cwd,
|
|
128092
|
+
duration: Date.now() - startTime
|
|
128093
|
+
});
|
|
128094
|
+
return;
|
|
128095
|
+
}
|
|
128096
|
+
const [cmd, ...cmdArgs] = args;
|
|
128097
|
+
const child = (0, import_child_process6.spawn)(cmd, cmdArgs, {
|
|
128098
|
+
cwd,
|
|
128099
|
+
env: processEnv,
|
|
128100
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
128101
|
+
// stdin ignored, capture stdout/stderr
|
|
128102
|
+
shell: false,
|
|
128103
|
+
// For security
|
|
128104
|
+
windowsHide: true
|
|
128105
|
+
});
|
|
128106
|
+
let stdout = "";
|
|
128107
|
+
let stderr = "";
|
|
128108
|
+
let killed = false;
|
|
128109
|
+
let timeoutHandle;
|
|
128110
|
+
if (timeout > 0) {
|
|
128111
|
+
timeoutHandle = setTimeout(() => {
|
|
128112
|
+
if (!killed) {
|
|
128113
|
+
killed = true;
|
|
128114
|
+
child.kill("SIGTERM");
|
|
128115
|
+
setTimeout(() => {
|
|
128116
|
+
if (child.exitCode === null) {
|
|
128117
|
+
child.kill("SIGKILL");
|
|
128118
|
+
}
|
|
128119
|
+
}, 5e3);
|
|
128120
|
+
}
|
|
128121
|
+
}, timeout);
|
|
128122
|
+
}
|
|
128123
|
+
child.stdout.on("data", (data2) => {
|
|
128124
|
+
const chunk = data2.toString();
|
|
128125
|
+
if (stdout.length + chunk.length <= maxBuffer) {
|
|
128126
|
+
stdout += chunk;
|
|
128127
|
+
} else {
|
|
128128
|
+
if (!killed) {
|
|
128129
|
+
killed = true;
|
|
128130
|
+
child.kill("SIGTERM");
|
|
128131
|
+
}
|
|
128132
|
+
}
|
|
128133
|
+
});
|
|
128134
|
+
child.stderr.on("data", (data2) => {
|
|
128135
|
+
const chunk = data2.toString();
|
|
128136
|
+
if (stderr.length + chunk.length <= maxBuffer) {
|
|
128137
|
+
stderr += chunk;
|
|
128138
|
+
} else {
|
|
128139
|
+
if (!killed) {
|
|
128140
|
+
killed = true;
|
|
128141
|
+
child.kill("SIGTERM");
|
|
128142
|
+
}
|
|
128143
|
+
}
|
|
128144
|
+
});
|
|
128145
|
+
child.on("close", (code, signal) => {
|
|
128146
|
+
if (timeoutHandle) {
|
|
128147
|
+
clearTimeout(timeoutHandle);
|
|
128148
|
+
}
|
|
128149
|
+
const duration = Date.now() - startTime;
|
|
128150
|
+
if (debug) {
|
|
128151
|
+
console.log(`[BashExecutor] Command completed - Code: ${code}, Signal: ${signal}, Duration: ${duration}ms`);
|
|
128152
|
+
console.log(`[BashExecutor] Stdout length: ${stdout.length}, Stderr length: ${stderr.length}`);
|
|
128153
|
+
}
|
|
128154
|
+
let success = true;
|
|
128155
|
+
let error2 = "";
|
|
128156
|
+
if (killed) {
|
|
128157
|
+
success = false;
|
|
128158
|
+
if (stdout.length + stderr.length > maxBuffer) {
|
|
128159
|
+
error2 = `Command output exceeded maximum buffer size (${maxBuffer} bytes)`;
|
|
128160
|
+
} else {
|
|
128161
|
+
error2 = `Command timed out after ${timeout}ms`;
|
|
128162
|
+
}
|
|
128163
|
+
} else if (code !== 0) {
|
|
128164
|
+
success = false;
|
|
128165
|
+
error2 = `Command exited with code ${code}`;
|
|
128166
|
+
}
|
|
128167
|
+
resolve4({
|
|
128168
|
+
success,
|
|
128169
|
+
error: error2,
|
|
128170
|
+
stdout: stdout.trim(),
|
|
128171
|
+
stderr: stderr.trim(),
|
|
128172
|
+
exitCode: code,
|
|
128173
|
+
signal,
|
|
128174
|
+
command,
|
|
128175
|
+
workingDirectory: cwd,
|
|
128176
|
+
duration,
|
|
128177
|
+
killed
|
|
128178
|
+
});
|
|
128179
|
+
});
|
|
128180
|
+
child.on("error", (error2) => {
|
|
128181
|
+
if (timeoutHandle) {
|
|
128182
|
+
clearTimeout(timeoutHandle);
|
|
128183
|
+
}
|
|
128184
|
+
if (debug) {
|
|
128185
|
+
console.log(`[BashExecutor] Spawn error:`, error2);
|
|
128186
|
+
}
|
|
128187
|
+
resolve4({
|
|
128188
|
+
success: false,
|
|
128189
|
+
error: `Failed to execute command: ${error2.message}`,
|
|
128190
|
+
stdout: "",
|
|
128191
|
+
stderr: "",
|
|
128192
|
+
exitCode: 1,
|
|
128193
|
+
command,
|
|
128194
|
+
workingDirectory: cwd,
|
|
128195
|
+
duration: Date.now() - startTime
|
|
128196
|
+
});
|
|
128197
|
+
});
|
|
128198
|
+
});
|
|
128199
|
+
}
|
|
128200
|
+
function formatExecutionResult(result, includeMetadata = false) {
|
|
128201
|
+
if (!result) {
|
|
128202
|
+
return "No result available";
|
|
128203
|
+
}
|
|
128204
|
+
let output = "";
|
|
128205
|
+
if (includeMetadata) {
|
|
128206
|
+
output += `Command: ${result.command}
|
|
128207
|
+
`;
|
|
128208
|
+
output += `Working directory: ${result.workingDirectory}
|
|
128209
|
+
`;
|
|
128210
|
+
output += `Duration: ${result.duration}ms
|
|
128211
|
+
`;
|
|
128212
|
+
output += `Exit Code: ${result.exitCode}
|
|
128213
|
+
`;
|
|
128214
|
+
if (result.signal) {
|
|
128215
|
+
output += `Signal: ${result.signal}
|
|
128216
|
+
`;
|
|
128217
|
+
}
|
|
128218
|
+
output += "\n";
|
|
128219
|
+
}
|
|
128220
|
+
if (result.stdout) {
|
|
128221
|
+
if (includeMetadata) {
|
|
128222
|
+
output += "--- STDOUT ---\n";
|
|
128223
|
+
}
|
|
128224
|
+
output += result.stdout;
|
|
128225
|
+
if (includeMetadata && result.stderr) {
|
|
128226
|
+
output += "\n";
|
|
128227
|
+
}
|
|
128228
|
+
}
|
|
128229
|
+
if (result.stderr) {
|
|
128230
|
+
if (includeMetadata) {
|
|
128231
|
+
if (result.stdout) output += "\n";
|
|
128232
|
+
output += "--- STDERR ---\n";
|
|
128233
|
+
} else if (result.stdout) {
|
|
128234
|
+
output += "\n--- STDERR ---\n";
|
|
128235
|
+
}
|
|
128236
|
+
output += result.stderr;
|
|
128237
|
+
}
|
|
128238
|
+
if (!result.success && result.error && !result.stderr) {
|
|
128239
|
+
if (output) output += "\n";
|
|
128240
|
+
output += `Error: ${result.error}`;
|
|
128241
|
+
}
|
|
128242
|
+
if (!result.success && result.exitCode !== void 0 && result.exitCode !== 0) {
|
|
128243
|
+
if (output) output += "\n";
|
|
128244
|
+
output += `Exit code: ${result.exitCode}`;
|
|
128245
|
+
}
|
|
128246
|
+
return output || (result.success ? "Command completed successfully (no output)" : "Command failed (no output)");
|
|
128247
|
+
}
|
|
128248
|
+
function validateExecutionOptions(options = {}) {
|
|
128249
|
+
const errors = [];
|
|
128250
|
+
const warnings = [];
|
|
128251
|
+
if (options.timeout !== void 0) {
|
|
128252
|
+
if (typeof options.timeout !== "number" || options.timeout < 0) {
|
|
128253
|
+
errors.push("timeout must be a non-negative number");
|
|
128254
|
+
} else if (options.timeout > 6e5) {
|
|
128255
|
+
warnings.push("timeout is very high (>10 minutes)");
|
|
128256
|
+
}
|
|
128257
|
+
}
|
|
128258
|
+
if (options.maxBuffer !== void 0) {
|
|
128259
|
+
if (typeof options.maxBuffer !== "number" || options.maxBuffer < 1024) {
|
|
128260
|
+
errors.push("maxBuffer must be at least 1024 bytes");
|
|
128261
|
+
} else if (options.maxBuffer > 100 * 1024 * 1024) {
|
|
128262
|
+
warnings.push("maxBuffer is very high (>100MB)");
|
|
128263
|
+
}
|
|
128264
|
+
}
|
|
128265
|
+
if (options.workingDirectory) {
|
|
128266
|
+
if (typeof options.workingDirectory !== "string") {
|
|
128267
|
+
errors.push("workingDirectory must be a string");
|
|
128268
|
+
} else if (!(0, import_fs.existsSync)(options.workingDirectory)) {
|
|
128269
|
+
errors.push(`workingDirectory does not exist: ${options.workingDirectory}`);
|
|
128270
|
+
}
|
|
128271
|
+
}
|
|
128272
|
+
if (options.env && typeof options.env !== "object") {
|
|
128273
|
+
errors.push("env must be an object");
|
|
128274
|
+
}
|
|
128275
|
+
return {
|
|
128276
|
+
valid: errors.length === 0,
|
|
128277
|
+
errors,
|
|
128278
|
+
warnings
|
|
128279
|
+
};
|
|
128280
|
+
}
|
|
128281
|
+
var import_child_process6, import_path4, import_fs;
|
|
128282
|
+
var init_bashExecutor = __esm({
|
|
128283
|
+
"src/agent/bashExecutor.js"() {
|
|
128284
|
+
"use strict";
|
|
128285
|
+
import_child_process6 = __nccwpck_require__(35317);
|
|
128286
|
+
import_path4 = __nccwpck_require__(16928);
|
|
128287
|
+
import_fs = __nccwpck_require__(79896);
|
|
128288
|
+
init_bashCommandUtils();
|
|
128289
|
+
}
|
|
128290
|
+
});
|
|
128291
|
+
|
|
128292
|
+
// src/tools/bash.js
|
|
128293
|
+
var import_ai2, import_path5, bashTool;
|
|
128294
|
+
var init_bash = __esm({
|
|
128295
|
+
"src/tools/bash.js"() {
|
|
128296
|
+
"use strict";
|
|
128297
|
+
import_ai2 = __nccwpck_require__(86619);
|
|
128298
|
+
import_path5 = __nccwpck_require__(16928);
|
|
128299
|
+
init_bashPermissions();
|
|
128300
|
+
init_bashExecutor();
|
|
128301
|
+
bashTool = (options = {}) => {
|
|
128302
|
+
const {
|
|
128303
|
+
bashConfig = {},
|
|
128304
|
+
debug = false,
|
|
128305
|
+
defaultPath,
|
|
128306
|
+
allowedFolders = []
|
|
128307
|
+
} = options;
|
|
128308
|
+
const permissionChecker = new BashPermissionChecker({
|
|
128309
|
+
allow: bashConfig.allow,
|
|
128310
|
+
deny: bashConfig.deny,
|
|
128311
|
+
disableDefaultAllow: bashConfig.disableDefaultAllow,
|
|
128312
|
+
disableDefaultDeny: bashConfig.disableDefaultDeny,
|
|
128313
|
+
debug
|
|
128314
|
+
});
|
|
128315
|
+
const getDefaultWorkingDirectory = () => {
|
|
128316
|
+
if (bashConfig.workingDirectory) {
|
|
128317
|
+
return bashConfig.workingDirectory;
|
|
128318
|
+
}
|
|
128319
|
+
if (defaultPath) {
|
|
128320
|
+
return defaultPath;
|
|
128321
|
+
}
|
|
128322
|
+
if (allowedFolders && allowedFolders.length > 0) {
|
|
128323
|
+
return allowedFolders[0];
|
|
128324
|
+
}
|
|
128325
|
+
return process.cwd();
|
|
128326
|
+
};
|
|
128327
|
+
return (0, import_ai2.tool)({
|
|
128328
|
+
name: "bash",
|
|
128329
|
+
description: `Execute bash commands for system exploration and development tasks.
|
|
128330
|
+
|
|
128331
|
+
Security: This tool has built-in security with allow/deny lists. By default, only safe read-only commands are allowed for code exploration.
|
|
128332
|
+
|
|
128333
|
+
Parameters:
|
|
128334
|
+
- command: (required) The bash command to execute
|
|
128335
|
+
- workingDirectory: (optional) Directory to execute command in
|
|
128336
|
+
- timeout: (optional) Command timeout in milliseconds
|
|
128337
|
+
- env: (optional) Additional environment variables
|
|
128338
|
+
|
|
128339
|
+
Examples of allowed commands by default:
|
|
128340
|
+
- File exploration: ls, cat, head, tail, find, grep
|
|
128341
|
+
- Git operations: git status, git log, git diff, git show
|
|
128342
|
+
- Package info: npm list, pip list, cargo --version
|
|
128343
|
+
- System info: whoami, pwd, uname, date
|
|
128344
|
+
|
|
128345
|
+
Dangerous commands are blocked by default (rm -rf, sudo, npm install, etc.)`,
|
|
128346
|
+
inputSchema: {
|
|
128347
|
+
type: "object",
|
|
128348
|
+
properties: {
|
|
128349
|
+
command: {
|
|
128350
|
+
type: "string",
|
|
128351
|
+
description: "The bash command to execute"
|
|
128352
|
+
},
|
|
128353
|
+
workingDirectory: {
|
|
128354
|
+
type: "string",
|
|
128355
|
+
description: "Directory to execute the command in (optional)"
|
|
128356
|
+
},
|
|
128357
|
+
timeout: {
|
|
128358
|
+
type: "number",
|
|
128359
|
+
description: "Command timeout in milliseconds (optional)",
|
|
128360
|
+
minimum: 1e3,
|
|
128361
|
+
maximum: 6e5
|
|
128362
|
+
},
|
|
128363
|
+
env: {
|
|
128364
|
+
type: "object",
|
|
128365
|
+
description: "Additional environment variables (optional)",
|
|
128366
|
+
additionalProperties: {
|
|
128367
|
+
type: "string"
|
|
128368
|
+
}
|
|
128369
|
+
}
|
|
128370
|
+
},
|
|
128371
|
+
required: ["command"],
|
|
128372
|
+
additionalProperties: false
|
|
128373
|
+
},
|
|
128374
|
+
execute: async ({ command, workingDirectory, timeout, env }) => {
|
|
128375
|
+
try {
|
|
128376
|
+
if (command === null || command === void 0 || typeof command !== "string") {
|
|
128377
|
+
return "Error: Command is required and must be a string";
|
|
128378
|
+
}
|
|
128379
|
+
if (command.trim().length === 0) {
|
|
128380
|
+
return "Error: Command cannot be empty";
|
|
128381
|
+
}
|
|
128382
|
+
const permissionResult = permissionChecker.check(command.trim());
|
|
128383
|
+
if (!permissionResult.allowed) {
|
|
128384
|
+
if (debug) {
|
|
128385
|
+
console.log(`[BashTool] Permission denied for command: "${command}"`);
|
|
128386
|
+
console.log(`[BashTool] Reason: ${permissionResult.reason}`);
|
|
128387
|
+
}
|
|
128388
|
+
return `Permission denied: ${permissionResult.reason}
|
|
128389
|
+
|
|
128390
|
+
This command is not allowed by the current security policy.
|
|
128391
|
+
|
|
128392
|
+
Common reasons:
|
|
128393
|
+
1. The command is in the deny list (potentially dangerous)
|
|
128394
|
+
2. The command is not in the allow list (not a recognized safe command)
|
|
128395
|
+
|
|
128396
|
+
If you believe this command should be allowed, you can:
|
|
128397
|
+
- Use the --bash-allow option to add specific patterns
|
|
128398
|
+
- Use the --no-default-bash-deny flag to remove default restrictions (not recommended)
|
|
128399
|
+
|
|
128400
|
+
For code exploration, try these safe alternatives:
|
|
128401
|
+
- ls, cat, head, tail for file operations
|
|
128402
|
+
- find, grep, rg for searching
|
|
128403
|
+
- git status, git log, git show for git operations
|
|
128404
|
+
- npm list, pip list for package information`;
|
|
128405
|
+
}
|
|
128406
|
+
const workingDir = workingDirectory || getDefaultWorkingDirectory();
|
|
128407
|
+
if (allowedFolders && allowedFolders.length > 0) {
|
|
128408
|
+
const resolvedWorkingDir = (0, import_path5.resolve)(workingDir);
|
|
128409
|
+
const isAllowed = allowedFolders.some((folder) => {
|
|
128410
|
+
const resolvedFolder = (0, import_path5.resolve)(folder);
|
|
128411
|
+
return resolvedWorkingDir.startsWith(resolvedFolder);
|
|
128412
|
+
});
|
|
128413
|
+
if (!isAllowed) {
|
|
128414
|
+
return `Error: Working directory "${workingDir}" is not within allowed folders: ${allowedFolders.join(", ")}`;
|
|
128415
|
+
}
|
|
128416
|
+
}
|
|
128417
|
+
const executionOptions = {
|
|
128418
|
+
workingDirectory: workingDir,
|
|
128419
|
+
timeout: timeout || bashConfig.timeout || 12e4,
|
|
128420
|
+
env: { ...bashConfig.env, ...env },
|
|
128421
|
+
maxBuffer: bashConfig.maxBuffer,
|
|
128422
|
+
debug
|
|
128423
|
+
};
|
|
128424
|
+
const validation = validateExecutionOptions(executionOptions);
|
|
128425
|
+
if (!validation.valid) {
|
|
128426
|
+
return `Error: Invalid execution options: ${validation.errors.join(", ")}`;
|
|
128427
|
+
}
|
|
128428
|
+
if (validation.warnings.length > 0 && debug) {
|
|
128429
|
+
console.log("[BashTool] Warnings:", validation.warnings);
|
|
128430
|
+
}
|
|
128431
|
+
if (debug) {
|
|
128432
|
+
console.log(`[BashTool] Executing command: "${command}"`);
|
|
128433
|
+
console.log(`[BashTool] Working directory: "${workingDir}"`);
|
|
128434
|
+
console.log(`[BashTool] Timeout: ${executionOptions.timeout}ms`);
|
|
128435
|
+
}
|
|
128436
|
+
const result = await executeBashCommand(command.trim(), executionOptions);
|
|
128437
|
+
if (debug) {
|
|
128438
|
+
console.log(`[BashTool] Command completed - Success: ${result.success}, Duration: ${result.duration}ms`);
|
|
128439
|
+
}
|
|
128440
|
+
const formattedResult = formatExecutionResult(result, debug);
|
|
128441
|
+
if (!result.success) {
|
|
128442
|
+
let errorInfo = `
|
|
128443
|
+
|
|
128444
|
+
Command failed with exit code ${result.exitCode}`;
|
|
128445
|
+
if (result.killed) {
|
|
128446
|
+
errorInfo += ` (${result.error})`;
|
|
128447
|
+
}
|
|
128448
|
+
return formattedResult + errorInfo;
|
|
128449
|
+
}
|
|
128450
|
+
return formattedResult;
|
|
128451
|
+
} catch (error2) {
|
|
128452
|
+
if (debug) {
|
|
128453
|
+
console.error("[BashTool] Execution error:", error2);
|
|
128454
|
+
}
|
|
128455
|
+
return `Error executing bash command: ${error2.message}`;
|
|
128456
|
+
}
|
|
128457
|
+
}
|
|
128458
|
+
});
|
|
128459
|
+
};
|
|
128460
|
+
}
|
|
128461
|
+
});
|
|
128462
|
+
|
|
126531
128463
|
// src/tools/langchain.js
|
|
126532
128464
|
function createSearchTool() {
|
|
126533
128465
|
return {
|
|
@@ -126745,6 +128677,10 @@ __export(tools_exports, {
|
|
|
126745
128677
|
DEFAULT_SYSTEM_MESSAGE: () => DEFAULT_SYSTEM_MESSAGE,
|
|
126746
128678
|
attemptCompletionSchema: () => attemptCompletionSchema,
|
|
126747
128679
|
attemptCompletionToolDefinition: () => attemptCompletionToolDefinition,
|
|
128680
|
+
bashDescription: () => bashDescription,
|
|
128681
|
+
bashSchema: () => bashSchema,
|
|
128682
|
+
bashTool: () => bashTool,
|
|
128683
|
+
bashToolDefinition: () => bashToolDefinition,
|
|
126748
128684
|
createExtractTool: () => createExtractTool,
|
|
126749
128685
|
createQueryTool: () => createQueryTool,
|
|
126750
128686
|
createSearchTool: () => createSearchTool,
|
|
@@ -126765,16 +128701,19 @@ var init_tools = __esm({
|
|
|
126765
128701
|
"src/tools/index.js"() {
|
|
126766
128702
|
"use strict";
|
|
126767
128703
|
init_vercel();
|
|
128704
|
+
init_bash();
|
|
126768
128705
|
init_langchain();
|
|
126769
128706
|
init_common();
|
|
126770
128707
|
init_system_message();
|
|
126771
128708
|
init_vercel();
|
|
128709
|
+
init_bash();
|
|
126772
128710
|
init_system_message();
|
|
126773
128711
|
tools = {
|
|
126774
128712
|
searchTool: searchTool(),
|
|
126775
128713
|
queryTool: queryTool(),
|
|
126776
128714
|
extractTool: extractTool(),
|
|
126777
128715
|
delegateTool: delegateTool(),
|
|
128716
|
+
bashTool: bashTool(),
|
|
126778
128717
|
DEFAULT_SYSTEM_MESSAGE
|
|
126779
128718
|
};
|
|
126780
128719
|
}
|
|
@@ -126787,10 +128726,10 @@ async function listFilesByLevel(options) {
|
|
|
126787
128726
|
maxFiles = 100,
|
|
126788
128727
|
respectGitignore = true
|
|
126789
128728
|
} = options;
|
|
126790
|
-
if (!
|
|
128729
|
+
if (!import_fs2.default.existsSync(directory)) {
|
|
126791
128730
|
throw new Error(`Directory does not exist: ${directory}`);
|
|
126792
128731
|
}
|
|
126793
|
-
const gitDirExists =
|
|
128732
|
+
const gitDirExists = import_fs2.default.existsSync(import_path6.default.join(directory, ".git"));
|
|
126794
128733
|
if (gitDirExists && respectGitignore) {
|
|
126795
128734
|
try {
|
|
126796
128735
|
return await listFilesUsingGit(directory, maxFiles);
|
|
@@ -126805,8 +128744,8 @@ async function listFilesUsingGit(directory, maxFiles) {
|
|
|
126805
128744
|
const { stdout } = await execAsync4("git ls-files", { cwd: directory });
|
|
126806
128745
|
const files = stdout.split("\n").filter(Boolean);
|
|
126807
128746
|
const sortedFiles = files.sort((a3, b3) => {
|
|
126808
|
-
const depthA = a3.split(
|
|
126809
|
-
const depthB = b3.split(
|
|
128747
|
+
const depthA = a3.split(import_path6.default.sep).length;
|
|
128748
|
+
const depthB = b3.split(import_path6.default.sep).length;
|
|
126810
128749
|
return depthA - depthB;
|
|
126811
128750
|
});
|
|
126812
128751
|
return sortedFiles.slice(0, maxFiles);
|
|
@@ -126821,19 +128760,19 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
|
|
|
126821
128760
|
while (queue.length > 0 && result.length < maxFiles) {
|
|
126822
128761
|
const { dir, level } = queue.shift();
|
|
126823
128762
|
try {
|
|
126824
|
-
const entries =
|
|
128763
|
+
const entries = import_fs2.default.readdirSync(dir, { withFileTypes: true });
|
|
126825
128764
|
const files = entries.filter((entry) => entry.isFile());
|
|
126826
128765
|
for (const file of files) {
|
|
126827
128766
|
if (result.length >= maxFiles) break;
|
|
126828
|
-
const filePath =
|
|
126829
|
-
const relativePath =
|
|
128767
|
+
const filePath = import_path6.default.join(dir, file.name);
|
|
128768
|
+
const relativePath = import_path6.default.relative(directory, filePath);
|
|
126830
128769
|
if (shouldIgnore(relativePath, ignorePatterns)) continue;
|
|
126831
128770
|
result.push(relativePath);
|
|
126832
128771
|
}
|
|
126833
128772
|
const dirs = entries.filter((entry) => entry.isDirectory());
|
|
126834
128773
|
for (const subdir of dirs) {
|
|
126835
|
-
const subdirPath =
|
|
126836
|
-
const relativeSubdirPath =
|
|
128774
|
+
const subdirPath = import_path6.default.join(dir, subdir.name);
|
|
128775
|
+
const relativeSubdirPath = import_path6.default.relative(directory, subdirPath);
|
|
126837
128776
|
if (shouldIgnore(relativeSubdirPath, ignorePatterns)) continue;
|
|
126838
128777
|
if (subdir.name === "node_modules" || subdir.name === ".git") continue;
|
|
126839
128778
|
queue.push({ dir: subdirPath, level: level + 1 });
|
|
@@ -126845,12 +128784,12 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
|
|
|
126845
128784
|
return result;
|
|
126846
128785
|
}
|
|
126847
128786
|
function loadGitignorePatterns(directory) {
|
|
126848
|
-
const gitignorePath =
|
|
126849
|
-
if (!
|
|
128787
|
+
const gitignorePath = import_path6.default.join(directory, ".gitignore");
|
|
128788
|
+
if (!import_fs2.default.existsSync(gitignorePath)) {
|
|
126850
128789
|
return [];
|
|
126851
128790
|
}
|
|
126852
128791
|
try {
|
|
126853
|
-
const content =
|
|
128792
|
+
const content = import_fs2.default.readFileSync(gitignorePath, "utf8");
|
|
126854
128793
|
return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
126855
128794
|
} catch (error2) {
|
|
126856
128795
|
console.error(`Warning: Could not read .gitignore: ${error2.message}`);
|
|
@@ -126868,15 +128807,15 @@ function shouldIgnore(filePath, ignorePatterns) {
|
|
|
126868
128807
|
}
|
|
126869
128808
|
return false;
|
|
126870
128809
|
}
|
|
126871
|
-
var
|
|
128810
|
+
var import_fs2, import_path6, import_util5, import_child_process7, execAsync4;
|
|
126872
128811
|
var init_file_lister = __esm({
|
|
126873
128812
|
"src/utils/file-lister.js"() {
|
|
126874
128813
|
"use strict";
|
|
126875
|
-
|
|
126876
|
-
|
|
128814
|
+
import_fs2 = __toESM(__nccwpck_require__(79896), 1);
|
|
128815
|
+
import_path6 = __toESM(__nccwpck_require__(16928), 1);
|
|
126877
128816
|
import_util5 = __nccwpck_require__(39023);
|
|
126878
|
-
|
|
126879
|
-
execAsync4 = (0, import_util5.promisify)(
|
|
128817
|
+
import_child_process7 = __nccwpck_require__(35317);
|
|
128818
|
+
execAsync4 = (0, import_util5.promisify)(import_child_process7.exec);
|
|
126880
128819
|
}
|
|
126881
128820
|
});
|
|
126882
128821
|
|
|
@@ -129031,7 +130970,7 @@ var require_headStream = __commonJS({
|
|
|
129031
130970
|
if ((0, stream_type_check_1.isReadableStream)(stream)) {
|
|
129032
130971
|
return (0, headStream_browser_1.headStream)(stream, bytes);
|
|
129033
130972
|
}
|
|
129034
|
-
return new Promise((
|
|
130973
|
+
return new Promise((resolve4, reject) => {
|
|
129035
130974
|
const collector = new Collector();
|
|
129036
130975
|
collector.limit = bytes;
|
|
129037
130976
|
stream.pipe(collector);
|
|
@@ -129042,7 +130981,7 @@ var require_headStream = __commonJS({
|
|
|
129042
130981
|
collector.on("error", reject);
|
|
129043
130982
|
collector.on("finish", function() {
|
|
129044
130983
|
const bytes2 = new Uint8Array(Buffer.concat(this.buffers));
|
|
129045
|
-
|
|
130984
|
+
resolve4(bytes2);
|
|
129046
130985
|
});
|
|
129047
130986
|
});
|
|
129048
130987
|
};
|
|
@@ -129300,21 +131239,21 @@ var require_dist_cjs15 = __commonJS({
|
|
|
129300
131239
|
let sendBody = true;
|
|
129301
131240
|
if (expect === "100-continue") {
|
|
129302
131241
|
sendBody = await Promise.race([
|
|
129303
|
-
new Promise((
|
|
129304
|
-
timeoutId = Number(timing.setTimeout(() =>
|
|
131242
|
+
new Promise((resolve4) => {
|
|
131243
|
+
timeoutId = Number(timing.setTimeout(() => resolve4(true), Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
|
|
129305
131244
|
}),
|
|
129306
|
-
new Promise((
|
|
131245
|
+
new Promise((resolve4) => {
|
|
129307
131246
|
httpRequest.on("continue", () => {
|
|
129308
131247
|
timing.clearTimeout(timeoutId);
|
|
129309
|
-
|
|
131248
|
+
resolve4(true);
|
|
129310
131249
|
});
|
|
129311
131250
|
httpRequest.on("response", () => {
|
|
129312
131251
|
timing.clearTimeout(timeoutId);
|
|
129313
|
-
|
|
131252
|
+
resolve4(false);
|
|
129314
131253
|
});
|
|
129315
131254
|
httpRequest.on("error", () => {
|
|
129316
131255
|
timing.clearTimeout(timeoutId);
|
|
129317
|
-
|
|
131256
|
+
resolve4(false);
|
|
129318
131257
|
});
|
|
129319
131258
|
})
|
|
129320
131259
|
]);
|
|
@@ -129350,13 +131289,13 @@ var require_dist_cjs15 = __commonJS({
|
|
|
129350
131289
|
constructor(options) {
|
|
129351
131290
|
this.socketWarningTimestamp = 0;
|
|
129352
131291
|
this.metadata = { handlerProtocol: "http/1.1" };
|
|
129353
|
-
this.configProvider = new Promise((
|
|
131292
|
+
this.configProvider = new Promise((resolve4, reject) => {
|
|
129354
131293
|
if (typeof options === "function") {
|
|
129355
131294
|
options().then((_options) => {
|
|
129356
|
-
|
|
131295
|
+
resolve4(this.resolveDefaultConfig(_options));
|
|
129357
131296
|
}).catch(reject);
|
|
129358
131297
|
} else {
|
|
129359
|
-
|
|
131298
|
+
resolve4(this.resolveDefaultConfig(options));
|
|
129360
131299
|
}
|
|
129361
131300
|
});
|
|
129362
131301
|
}
|
|
@@ -129440,7 +131379,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
129440
131379
|
return new Promise((_resolve, _reject) => {
|
|
129441
131380
|
let writeRequestBodyPromise = void 0;
|
|
129442
131381
|
const timeouts = [];
|
|
129443
|
-
const
|
|
131382
|
+
const resolve4 = /* @__PURE__ */ __name(async (arg) => {
|
|
129444
131383
|
await writeRequestBodyPromise;
|
|
129445
131384
|
timeouts.forEach(timing.clearTimeout);
|
|
129446
131385
|
_resolve(arg);
|
|
@@ -129510,7 +131449,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
129510
131449
|
headers: getTransformedHeaders(res.headers),
|
|
129511
131450
|
body: res
|
|
129512
131451
|
});
|
|
129513
|
-
|
|
131452
|
+
resolve4({ response: httpResponse });
|
|
129514
131453
|
});
|
|
129515
131454
|
req.on("error", (err) => {
|
|
129516
131455
|
if (NODEJS_TIMEOUT_ERROR_CODES.includes(err.code)) {
|
|
@@ -129699,13 +131638,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
129699
131638
|
constructor(options) {
|
|
129700
131639
|
this.metadata = { handlerProtocol: "h2" };
|
|
129701
131640
|
this.connectionManager = new NodeHttp2ConnectionManager({});
|
|
129702
|
-
this.configProvider = new Promise((
|
|
131641
|
+
this.configProvider = new Promise((resolve4, reject) => {
|
|
129703
131642
|
if (typeof options === "function") {
|
|
129704
131643
|
options().then((opts) => {
|
|
129705
|
-
|
|
131644
|
+
resolve4(opts || {});
|
|
129706
131645
|
}).catch(reject);
|
|
129707
131646
|
} else {
|
|
129708
|
-
|
|
131647
|
+
resolve4(options || {});
|
|
129709
131648
|
}
|
|
129710
131649
|
});
|
|
129711
131650
|
}
|
|
@@ -129738,7 +131677,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
129738
131677
|
return new Promise((_resolve, _reject) => {
|
|
129739
131678
|
let fulfilled = false;
|
|
129740
131679
|
let writeRequestBodyPromise = void 0;
|
|
129741
|
-
const
|
|
131680
|
+
const resolve4 = /* @__PURE__ */ __name(async (arg) => {
|
|
129742
131681
|
await writeRequestBodyPromise;
|
|
129743
131682
|
_resolve(arg);
|
|
129744
131683
|
}, "resolve");
|
|
@@ -129794,7 +131733,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
129794
131733
|
body: req
|
|
129795
131734
|
});
|
|
129796
131735
|
fulfilled = true;
|
|
129797
|
-
|
|
131736
|
+
resolve4({ response: httpResponse });
|
|
129798
131737
|
if (disableConcurrentStreams) {
|
|
129799
131738
|
session.close();
|
|
129800
131739
|
this.connectionManager.deleteSession(authority, session);
|
|
@@ -129883,7 +131822,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
129883
131822
|
if (isReadableStreamInstance(stream)) {
|
|
129884
131823
|
return collectReadableStream(stream);
|
|
129885
131824
|
}
|
|
129886
|
-
return new Promise((
|
|
131825
|
+
return new Promise((resolve4, reject) => {
|
|
129887
131826
|
const collector = new Collector();
|
|
129888
131827
|
stream.pipe(collector);
|
|
129889
131828
|
stream.on("error", (err) => {
|
|
@@ -129893,7 +131832,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
129893
131832
|
collector.on("error", reject);
|
|
129894
131833
|
collector.on("finish", function() {
|
|
129895
131834
|
const bytes = new Uint8Array(Buffer.concat(this.bufferedBytes));
|
|
129896
|
-
|
|
131835
|
+
resolve4(bytes);
|
|
129897
131836
|
});
|
|
129898
131837
|
});
|
|
129899
131838
|
}, "streamCollector");
|
|
@@ -129958,7 +131897,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
129958
131897
|
}
|
|
129959
131898
|
__name(createRequest, "createRequest");
|
|
129960
131899
|
function requestTimeout(timeoutInMs = 0) {
|
|
129961
|
-
return new Promise((
|
|
131900
|
+
return new Promise((resolve4, reject) => {
|
|
129962
131901
|
if (timeoutInMs) {
|
|
129963
131902
|
setTimeout(() => {
|
|
129964
131903
|
const timeoutError = new Error(`Request did not complete within ${timeoutInMs} ms`);
|
|
@@ -130085,7 +132024,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
130085
132024
|
];
|
|
130086
132025
|
if (abortSignal) {
|
|
130087
132026
|
raceOfPromises.push(
|
|
130088
|
-
new Promise((
|
|
132027
|
+
new Promise((resolve4, reject) => {
|
|
130089
132028
|
const onAbort = /* @__PURE__ */ __name(() => {
|
|
130090
132029
|
const abortError = new Error("Request aborted");
|
|
130091
132030
|
abortError.name = "AbortError";
|
|
@@ -130153,7 +132092,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
130153
132092
|
}
|
|
130154
132093
|
__name(collectStream, "collectStream");
|
|
130155
132094
|
function readToBase64(blob) {
|
|
130156
|
-
return new Promise((
|
|
132095
|
+
return new Promise((resolve4, reject) => {
|
|
130157
132096
|
const reader = new FileReader();
|
|
130158
132097
|
reader.onloadend = () => {
|
|
130159
132098
|
if (reader.readyState !== 2) {
|
|
@@ -130162,7 +132101,7 @@ var require_dist_cjs16 = __commonJS({
|
|
|
130162
132101
|
const result = reader.result ?? "";
|
|
130163
132102
|
const commaIndex = result.indexOf(",");
|
|
130164
132103
|
const dataOffset = commaIndex > -1 ? commaIndex + 1 : result.length;
|
|
130165
|
-
|
|
132104
|
+
resolve4(result.substring(dataOffset));
|
|
130166
132105
|
};
|
|
130167
132106
|
reader.onabort = () => reject(new Error("Read aborted"));
|
|
130168
132107
|
reader.onerror = () => reject(reader.error);
|
|
@@ -130649,9 +132588,10 @@ var TypeRegistry;
|
|
|
130649
132588
|
var init_TypeRegistry = __esm({
|
|
130650
132589
|
"node_modules/@smithy/core/dist-es/submodules/schema/TypeRegistry.js"() {
|
|
130651
132590
|
TypeRegistry = class _TypeRegistry {
|
|
130652
|
-
constructor(namespace, schemas = /* @__PURE__ */ new Map()) {
|
|
132591
|
+
constructor(namespace, schemas = /* @__PURE__ */ new Map(), exceptions = /* @__PURE__ */ new Map()) {
|
|
130653
132592
|
this.namespace = namespace;
|
|
130654
132593
|
this.schemas = schemas;
|
|
132594
|
+
this.exceptions = exceptions;
|
|
130655
132595
|
}
|
|
130656
132596
|
static for(namespace) {
|
|
130657
132597
|
if (!_TypeRegistry.registries.has(namespace)) {
|
|
@@ -130661,8 +132601,7 @@ var init_TypeRegistry = __esm({
|
|
|
130661
132601
|
}
|
|
130662
132602
|
register(shapeId, schema) {
|
|
130663
132603
|
const qualifiedName = this.normalizeShapeId(shapeId);
|
|
130664
|
-
|
|
130665
|
-
registry.schemas.set(qualifiedName, schema);
|
|
132604
|
+
this.schemas.set(qualifiedName, schema);
|
|
130666
132605
|
}
|
|
130667
132606
|
getSchema(shapeId) {
|
|
130668
132607
|
const id = this.normalizeShapeId(shapeId);
|
|
@@ -130671,6 +132610,12 @@ var init_TypeRegistry = __esm({
|
|
|
130671
132610
|
}
|
|
130672
132611
|
return this.schemas.get(id);
|
|
130673
132612
|
}
|
|
132613
|
+
registerError(errorSchema, ctor) {
|
|
132614
|
+
this.exceptions.set(errorSchema, ctor);
|
|
132615
|
+
}
|
|
132616
|
+
getErrorCtor(errorSchema) {
|
|
132617
|
+
return this.exceptions.get(errorSchema);
|
|
132618
|
+
}
|
|
130674
132619
|
getBaseException() {
|
|
130675
132620
|
for (const [id, schema] of this.schemas.entries()) {
|
|
130676
132621
|
if (id.startsWith("smithy.ts.sdk.synthetic.") && id.endsWith("ServiceException")) {
|
|
@@ -130682,9 +132627,9 @@ var init_TypeRegistry = __esm({
|
|
|
130682
132627
|
find(predicate) {
|
|
130683
132628
|
return [...this.schemas.values()].find(predicate);
|
|
130684
132629
|
}
|
|
130685
|
-
|
|
130686
|
-
_TypeRegistry.registries.delete(this.namespace);
|
|
132630
|
+
clear() {
|
|
130687
132631
|
this.schemas.clear();
|
|
132632
|
+
this.exceptions.clear();
|
|
130688
132633
|
}
|
|
130689
132634
|
normalizeShapeId(shapeId) {
|
|
130690
132635
|
if (shapeId.includes("#")) {
|
|
@@ -130832,7 +132777,7 @@ var init_ErrorSchema = __esm({
|
|
|
130832
132777
|
traits,
|
|
130833
132778
|
memberNames,
|
|
130834
132779
|
memberList,
|
|
130835
|
-
ctor
|
|
132780
|
+
ctor: null
|
|
130836
132781
|
});
|
|
130837
132782
|
}
|
|
130838
132783
|
});
|
|
@@ -131801,11 +133746,11 @@ function __metadata(metadataKey, metadataValue) {
|
|
|
131801
133746
|
}
|
|
131802
133747
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
131803
133748
|
function adopt(value) {
|
|
131804
|
-
return value instanceof P ? value : new P(function(
|
|
131805
|
-
|
|
133749
|
+
return value instanceof P ? value : new P(function(resolve4) {
|
|
133750
|
+
resolve4(value);
|
|
131806
133751
|
});
|
|
131807
133752
|
}
|
|
131808
|
-
return new (P || (P = Promise))(function(
|
|
133753
|
+
return new (P || (P = Promise))(function(resolve4, reject) {
|
|
131809
133754
|
function fulfilled(value) {
|
|
131810
133755
|
try {
|
|
131811
133756
|
step(generator.next(value));
|
|
@@ -131821,7 +133766,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
131821
133766
|
}
|
|
131822
133767
|
}
|
|
131823
133768
|
function step(result) {
|
|
131824
|
-
result.done ?
|
|
133769
|
+
result.done ? resolve4(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
131825
133770
|
}
|
|
131826
133771
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
131827
133772
|
});
|
|
@@ -132012,14 +133957,14 @@ function __asyncValues(o3) {
|
|
|
132012
133957
|
}, i3);
|
|
132013
133958
|
function verb(n3) {
|
|
132014
133959
|
i3[n3] = o3[n3] && function(v3) {
|
|
132015
|
-
return new Promise(function(
|
|
132016
|
-
v3 = o3[n3](v3), settle(
|
|
133960
|
+
return new Promise(function(resolve4, reject) {
|
|
133961
|
+
v3 = o3[n3](v3), settle(resolve4, reject, v3.done, v3.value);
|
|
132017
133962
|
});
|
|
132018
133963
|
};
|
|
132019
133964
|
}
|
|
132020
|
-
function settle(
|
|
133965
|
+
function settle(resolve4, reject, d3, v3) {
|
|
132021
133966
|
Promise.resolve(v3).then(function(v4) {
|
|
132022
|
-
|
|
133967
|
+
resolve4({ value: v4, done: d3 });
|
|
132023
133968
|
}, reject);
|
|
132024
133969
|
}
|
|
132025
133970
|
}
|
|
@@ -136990,16 +138935,18 @@ var init_SmithyRpcV2CborProtocol = __esm({
|
|
|
136990
138935
|
if (dataObject.Message) {
|
|
136991
138936
|
dataObject.message = dataObject.Message;
|
|
136992
138937
|
}
|
|
136993
|
-
const
|
|
138938
|
+
const synthetic = TypeRegistry.for("smithy.ts.sdk.synthetic." + namespace);
|
|
138939
|
+
const baseExceptionSchema = synthetic.getBaseException();
|
|
136994
138940
|
if (baseExceptionSchema) {
|
|
136995
|
-
const
|
|
136996
|
-
throw Object.assign(new
|
|
138941
|
+
const ErrorCtor2 = synthetic.getErrorCtor(baseExceptionSchema);
|
|
138942
|
+
throw Object.assign(new ErrorCtor2({ name: errorName }), errorMetadata, dataObject);
|
|
136997
138943
|
}
|
|
136998
138944
|
throw Object.assign(new Error(errorName), errorMetadata, dataObject);
|
|
136999
138945
|
}
|
|
137000
138946
|
const ns = NormalizedSchema.of(errorSchema);
|
|
138947
|
+
const ErrorCtor = registry.getErrorCtor(errorSchema);
|
|
137001
138948
|
const message = dataObject.message ?? dataObject.Message ?? "Unknown";
|
|
137002
|
-
const exception = new
|
|
138949
|
+
const exception = new ErrorCtor(message);
|
|
137003
138950
|
const output = {};
|
|
137004
138951
|
for (const [name14, member] of ns.structIterator()) {
|
|
137005
138952
|
output[name14] = this.deserializer.readValue(member, dataObject[name14]);
|
|
@@ -142665,7 +144612,7 @@ var require_dist_cjs37 = __commonJS({
|
|
|
142665
144612
|
);
|
|
142666
144613
|
}
|
|
142667
144614
|
waitForReady(socket, connectionTimeout) {
|
|
142668
|
-
return new Promise((
|
|
144615
|
+
return new Promise((resolve4, reject) => {
|
|
142669
144616
|
const timeout = setTimeout(() => {
|
|
142670
144617
|
this.removeNotUsableSockets(socket.url);
|
|
142671
144618
|
reject({
|
|
@@ -142676,7 +144623,7 @@ var require_dist_cjs37 = __commonJS({
|
|
|
142676
144623
|
}, connectionTimeout);
|
|
142677
144624
|
socket.onopen = () => {
|
|
142678
144625
|
clearTimeout(timeout);
|
|
142679
|
-
|
|
144626
|
+
resolve4();
|
|
142680
144627
|
};
|
|
142681
144628
|
});
|
|
142682
144629
|
}
|
|
@@ -142685,10 +144632,10 @@ var require_dist_cjs37 = __commonJS({
|
|
|
142685
144632
|
let socketErrorOccurred = false;
|
|
142686
144633
|
let reject = /* @__PURE__ */ __name(() => {
|
|
142687
144634
|
}, "reject");
|
|
142688
|
-
let
|
|
144635
|
+
let resolve4 = /* @__PURE__ */ __name(() => {
|
|
142689
144636
|
}, "resolve");
|
|
142690
144637
|
socket.onmessage = (event) => {
|
|
142691
|
-
|
|
144638
|
+
resolve4({
|
|
142692
144639
|
done: false,
|
|
142693
144640
|
value: new Uint8Array(event.data)
|
|
142694
144641
|
});
|
|
@@ -142704,7 +144651,7 @@ var require_dist_cjs37 = __commonJS({
|
|
|
142704
144651
|
if (streamError) {
|
|
142705
144652
|
reject(streamError);
|
|
142706
144653
|
} else {
|
|
142707
|
-
|
|
144654
|
+
resolve4({
|
|
142708
144655
|
done: true,
|
|
142709
144656
|
value: void 0
|
|
142710
144657
|
// unchecked because done=true.
|
|
@@ -142715,7 +144662,7 @@ var require_dist_cjs37 = __commonJS({
|
|
|
142715
144662
|
[Symbol.asyncIterator]: () => ({
|
|
142716
144663
|
next: /* @__PURE__ */ __name(() => {
|
|
142717
144664
|
return new Promise((_resolve, _reject) => {
|
|
142718
|
-
|
|
144665
|
+
resolve4 = _resolve;
|
|
142719
144666
|
reject = _reject;
|
|
142720
144667
|
});
|
|
142721
144668
|
}, "next")
|
|
@@ -143238,13 +145185,13 @@ var require_dist_cjs42 = __commonJS({
|
|
|
143238
145185
|
...data2.default && { default: data2.default }
|
|
143239
145186
|
}
|
|
143240
145187
|
), "getConfigData");
|
|
143241
|
-
var
|
|
145188
|
+
var import_path11 = __nccwpck_require__(16928);
|
|
143242
145189
|
var import_getHomeDir = require_getHomeDir();
|
|
143243
145190
|
var ENV_CONFIG_PATH = "AWS_CONFIG_FILE";
|
|
143244
|
-
var getConfigFilepath = /* @__PURE__ */ __name(() => process.env[ENV_CONFIG_PATH] || (0,
|
|
145191
|
+
var getConfigFilepath = /* @__PURE__ */ __name(() => process.env[ENV_CONFIG_PATH] || (0, import_path11.join)((0, import_getHomeDir.getHomeDir)(), ".aws", "config"), "getConfigFilepath");
|
|
143245
145192
|
var import_getHomeDir2 = require_getHomeDir();
|
|
143246
145193
|
var ENV_CREDENTIALS_PATH = "AWS_SHARED_CREDENTIALS_FILE";
|
|
143247
|
-
var getCredentialsFilepath = /* @__PURE__ */ __name(() => process.env[ENV_CREDENTIALS_PATH] || (0,
|
|
145194
|
+
var getCredentialsFilepath = /* @__PURE__ */ __name(() => process.env[ENV_CREDENTIALS_PATH] || (0, import_path11.join)((0, import_getHomeDir2.getHomeDir)(), ".aws", "credentials"), "getCredentialsFilepath");
|
|
143248
145195
|
var import_getHomeDir3 = require_getHomeDir();
|
|
143249
145196
|
var prefixKeyRegex = /^([\w-]+)\s(["'])?([\w-@\+\.%:/]+)\2$/;
|
|
143250
145197
|
var profileNameBlockList = ["__proto__", "profile __proto__"];
|
|
@@ -143302,11 +145249,11 @@ var require_dist_cjs42 = __commonJS({
|
|
|
143302
145249
|
const relativeHomeDirPrefix = "~/";
|
|
143303
145250
|
let resolvedFilepath = filepath;
|
|
143304
145251
|
if (filepath.startsWith(relativeHomeDirPrefix)) {
|
|
143305
|
-
resolvedFilepath = (0,
|
|
145252
|
+
resolvedFilepath = (0, import_path11.join)(homeDir, filepath.slice(2));
|
|
143306
145253
|
}
|
|
143307
145254
|
let resolvedConfigFilepath = configFilepath;
|
|
143308
145255
|
if (configFilepath.startsWith(relativeHomeDirPrefix)) {
|
|
143309
|
-
resolvedConfigFilepath = (0,
|
|
145256
|
+
resolvedConfigFilepath = (0, import_path11.join)(homeDir, configFilepath.slice(2));
|
|
143310
145257
|
}
|
|
143311
145258
|
const parsedFiles = await Promise.all([
|
|
143312
145259
|
(0, import_slurpFile.slurpFile)(resolvedConfigFilepath, {
|
|
@@ -143961,7 +145908,7 @@ var require_dist_cjs46 = __commonJS({
|
|
|
143961
145908
|
this.refillTokenBucket();
|
|
143962
145909
|
if (amount > this.currentCapacity) {
|
|
143963
145910
|
const delay = (amount - this.currentCapacity) / this.fillRate * 1e3;
|
|
143964
|
-
await new Promise((
|
|
145911
|
+
await new Promise((resolve4) => _DefaultRateLimiter.setTimeoutFn(resolve4, delay));
|
|
143965
145912
|
}
|
|
143966
145913
|
this.currentCapacity = this.currentCapacity - amount;
|
|
143967
145914
|
}
|
|
@@ -144352,7 +146299,7 @@ var require_dist_cjs47 = __commonJS({
|
|
|
144352
146299
|
const delayFromResponse = getDelayFromRetryAfterHeader(err.$response);
|
|
144353
146300
|
const delay = Math.max(delayFromResponse || 0, delayFromDecider);
|
|
144354
146301
|
totalDelay += delay;
|
|
144355
|
-
await new Promise((
|
|
146302
|
+
await new Promise((resolve4) => setTimeout(resolve4, delay));
|
|
144356
146303
|
continue;
|
|
144357
146304
|
}
|
|
144358
146305
|
if (!err.$metadata) {
|
|
@@ -144512,7 +146459,7 @@ var require_dist_cjs47 = __commonJS({
|
|
|
144512
146459
|
attempts = retryToken.getRetryCount();
|
|
144513
146460
|
const delay = retryToken.getRetryDelay();
|
|
144514
146461
|
totalRetryDelay += delay;
|
|
144515
|
-
await new Promise((
|
|
146462
|
+
await new Promise((resolve4) => setTimeout(resolve4, delay));
|
|
144516
146463
|
}
|
|
144517
146464
|
}
|
|
144518
146465
|
} else {
|
|
@@ -144855,7 +146802,7 @@ var require_dist_cjs49 = __commonJS({
|
|
|
144855
146802
|
var import_buffer = __nccwpck_require__(20181);
|
|
144856
146803
|
var import_http = __nccwpck_require__(58611);
|
|
144857
146804
|
function httpRequest(options) {
|
|
144858
|
-
return new Promise((
|
|
146805
|
+
return new Promise((resolve4, reject) => {
|
|
144859
146806
|
const req = (0, import_http.request)({
|
|
144860
146807
|
method: "GET",
|
|
144861
146808
|
...options,
|
|
@@ -144884,7 +146831,7 @@ var require_dist_cjs49 = __commonJS({
|
|
|
144884
146831
|
chunks.push(chunk);
|
|
144885
146832
|
});
|
|
144886
146833
|
res.on("end", () => {
|
|
144887
|
-
|
|
146834
|
+
resolve4(import_buffer.Buffer.concat(chunks));
|
|
144888
146835
|
req.destroy();
|
|
144889
146836
|
});
|
|
144890
146837
|
});
|
|
@@ -145319,7 +147266,7 @@ var require_retry_wrapper = __commonJS({
|
|
|
145319
147266
|
try {
|
|
145320
147267
|
return await toRetry();
|
|
145321
147268
|
} catch (e3) {
|
|
145322
|
-
await new Promise((
|
|
147269
|
+
await new Promise((resolve4) => setTimeout(resolve4, delayMs));
|
|
145323
147270
|
}
|
|
145324
147271
|
}
|
|
145325
147272
|
return await toRetry();
|
|
@@ -145763,7 +147710,7 @@ var require_dist_cjs53 = __commonJS({
|
|
|
145763
147710
|
calculateBodyLength: () => calculateBodyLength3
|
|
145764
147711
|
});
|
|
145765
147712
|
module2.exports = __toCommonJS2(index_exports2);
|
|
145766
|
-
var
|
|
147713
|
+
var import_fs8 = __nccwpck_require__(79896);
|
|
145767
147714
|
var calculateBodyLength3 = /* @__PURE__ */ __name((body) => {
|
|
145768
147715
|
if (!body) {
|
|
145769
147716
|
return 0;
|
|
@@ -145777,9 +147724,9 @@ var require_dist_cjs53 = __commonJS({
|
|
|
145777
147724
|
} else if (typeof body.start === "number" && typeof body.end === "number") {
|
|
145778
147725
|
return body.end + 1 - body.start;
|
|
145779
147726
|
} else if (typeof body.path === "string" || Buffer.isBuffer(body.path)) {
|
|
145780
|
-
return (0,
|
|
147727
|
+
return (0, import_fs8.lstatSync)(body.path).size;
|
|
145781
147728
|
} else if (typeof body.fd === "number") {
|
|
145782
|
-
return (0,
|
|
147729
|
+
return (0, import_fs8.fstatSync)(body.fd).size;
|
|
145783
147730
|
}
|
|
145784
147731
|
throw new Error(`Body Length computation failed for ${body}`);
|
|
145785
147732
|
}, "calculateBodyLength");
|
|
@@ -147817,8 +149764,8 @@ var require_dist_cjs57 = __commonJS({
|
|
|
147817
149764
|
}
|
|
147818
149765
|
}, "validateTokenKey");
|
|
147819
149766
|
var import_shared_ini_file_loader = require_dist_cjs42();
|
|
147820
|
-
var
|
|
147821
|
-
var { writeFile } =
|
|
149767
|
+
var import_fs8 = __nccwpck_require__(79896);
|
|
149768
|
+
var { writeFile } = import_fs8.promises;
|
|
147822
149769
|
var writeSSOTokenToFile = /* @__PURE__ */ __name((id, ssoToken) => {
|
|
147823
149770
|
const tokenFilepath = (0, import_shared_ini_file_loader.getSSOTokenFilepath)(id);
|
|
147824
149771
|
const tokenString = JSON.stringify(ssoToken, null, 2);
|
|
@@ -149460,7 +151407,7 @@ var require_dist_cjs59 = __commonJS({
|
|
|
149460
151407
|
module2.exports = __toCommonJS2(index_exports2);
|
|
149461
151408
|
var import_property_provider2 = require_dist_cjs24();
|
|
149462
151409
|
var import_shared_ini_file_loader = require_dist_cjs42();
|
|
149463
|
-
var
|
|
151410
|
+
var import_child_process9 = __nccwpck_require__(35317);
|
|
149464
151411
|
var import_util7 = __nccwpck_require__(39023);
|
|
149465
151412
|
var import_client7 = (init_client(), __toCommonJS(client_exports));
|
|
149466
151413
|
var getValidatedProcessCredentials = /* @__PURE__ */ __name((profileName, data2, profiles) => {
|
|
@@ -149497,7 +151444,7 @@ var require_dist_cjs59 = __commonJS({
|
|
|
149497
151444
|
if (profiles[profileName]) {
|
|
149498
151445
|
const credentialProcess = profile["credential_process"];
|
|
149499
151446
|
if (credentialProcess !== void 0) {
|
|
149500
|
-
const execPromise = (0, import_util7.promisify)(import_shared_ini_file_loader.externalDataInterceptor?.getTokenRecord?.().exec ??
|
|
151447
|
+
const execPromise = (0, import_util7.promisify)(import_shared_ini_file_loader.externalDataInterceptor?.getTokenRecord?.().exec ?? import_child_process9.exec);
|
|
149501
151448
|
try {
|
|
149502
151449
|
const { stdout } = await execPromise(credentialProcess);
|
|
149503
151450
|
let data2;
|
|
@@ -150236,7 +152183,7 @@ var require_dist_cjs64 = __commonJS({
|
|
|
150236
152183
|
streamEnded = true;
|
|
150237
152184
|
});
|
|
150238
152185
|
while (!generationEnded) {
|
|
150239
|
-
const value = await new Promise((
|
|
152186
|
+
const value = await new Promise((resolve4) => setTimeout(() => resolve4(records.shift()), 0));
|
|
150240
152187
|
if (value) {
|
|
150241
152188
|
yield value;
|
|
150242
152189
|
}
|
|
@@ -153613,16 +155560,16 @@ function prepareTools(mode) {
|
|
|
153613
155560
|
}
|
|
153614
155561
|
const toolWarnings = [];
|
|
153615
155562
|
const bedrockTools = [];
|
|
153616
|
-
for (const
|
|
153617
|
-
if (
|
|
153618
|
-
toolWarnings.push({ type: "unsupported-tool", tool:
|
|
155563
|
+
for (const tool3 of tools2) {
|
|
155564
|
+
if (tool3.type === "provider-defined") {
|
|
155565
|
+
toolWarnings.push({ type: "unsupported-tool", tool: tool3 });
|
|
153619
155566
|
} else {
|
|
153620
155567
|
bedrockTools.push({
|
|
153621
155568
|
toolSpec: {
|
|
153622
|
-
name:
|
|
153623
|
-
description:
|
|
155569
|
+
name: tool3.name,
|
|
155570
|
+
description: tool3.description,
|
|
153624
155571
|
inputSchema: {
|
|
153625
|
-
json:
|
|
155572
|
+
json: tool3.parameters
|
|
153626
155573
|
}
|
|
153627
155574
|
}
|
|
153628
155575
|
});
|
|
@@ -154633,8 +156580,8 @@ function checkAttemptCompleteRecovery(cleanedXmlString, validTools = []) {
|
|
|
154633
156580
|
function hasOtherToolTags(xmlString, validTools = []) {
|
|
154634
156581
|
const defaultTools = ["search", "query", "extract", "listFiles", "searchFiles", "implement", "attempt_completion"];
|
|
154635
156582
|
const toolsToCheck = validTools.length > 0 ? validTools : defaultTools;
|
|
154636
|
-
for (const
|
|
154637
|
-
if (
|
|
156583
|
+
for (const tool3 of toolsToCheck) {
|
|
156584
|
+
if (tool3 !== "attempt_completion" && xmlString.includes(`<${tool3}`)) {
|
|
154638
156585
|
return true;
|
|
154639
156586
|
}
|
|
154640
156587
|
}
|
|
@@ -154662,12 +156609,16 @@ var init_xmlParsingUtils = __esm({
|
|
|
154662
156609
|
|
|
154663
156610
|
// src/agent/tools.js
|
|
154664
156611
|
function createTools(configOptions) {
|
|
154665
|
-
|
|
156612
|
+
const tools2 = {
|
|
154666
156613
|
searchTool: searchTool(configOptions),
|
|
154667
156614
|
queryTool: queryTool(configOptions),
|
|
154668
156615
|
extractTool: extractTool(configOptions),
|
|
154669
156616
|
delegateTool: delegateTool(configOptions)
|
|
154670
156617
|
};
|
|
156618
|
+
if (configOptions.enableBash) {
|
|
156619
|
+
tools2.bashTool = bashTool(configOptions);
|
|
156620
|
+
}
|
|
156621
|
+
return tools2;
|
|
154671
156622
|
}
|
|
154672
156623
|
function parseXmlToolCallWithThinking(xmlString, validTools) {
|
|
154673
156624
|
const { cleanedXmlString, recoveryResult } = processXmlWithThinkingAndRecovery(xmlString, validTools);
|
|
@@ -154811,26 +156762,33 @@ function createWrappedTools(baseTools) {
|
|
|
154811
156762
|
baseTools.delegateTool.execute
|
|
154812
156763
|
);
|
|
154813
156764
|
}
|
|
156765
|
+
if (baseTools.bashTool) {
|
|
156766
|
+
wrappedTools.bashToolInstance = wrapToolWithEmitter(
|
|
156767
|
+
baseTools.bashTool,
|
|
156768
|
+
"bash",
|
|
156769
|
+
baseTools.bashTool.execute
|
|
156770
|
+
);
|
|
156771
|
+
}
|
|
154814
156772
|
return wrappedTools;
|
|
154815
156773
|
}
|
|
154816
|
-
var
|
|
156774
|
+
var import_child_process8, import_util6, import_crypto4, import_events, import_fs3, import_fs4, import_path7, import_glob, toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
|
|
154817
156775
|
var init_probeTool = __esm({
|
|
154818
156776
|
"src/agent/probeTool.js"() {
|
|
154819
156777
|
"use strict";
|
|
154820
156778
|
init_index();
|
|
154821
|
-
|
|
156779
|
+
import_child_process8 = __nccwpck_require__(35317);
|
|
154822
156780
|
import_util6 = __nccwpck_require__(39023);
|
|
154823
156781
|
import_crypto4 = __nccwpck_require__(76982);
|
|
154824
156782
|
import_events = __nccwpck_require__(24434);
|
|
154825
|
-
|
|
154826
|
-
|
|
154827
|
-
|
|
156783
|
+
import_fs3 = __toESM(__nccwpck_require__(79896), 1);
|
|
156784
|
+
import_fs4 = __nccwpck_require__(79896);
|
|
156785
|
+
import_path7 = __toESM(__nccwpck_require__(16928), 1);
|
|
154828
156786
|
import_glob = __nccwpck_require__(21363);
|
|
154829
156787
|
toolCallEmitter = new import_events.EventEmitter();
|
|
154830
156788
|
activeToolExecutions = /* @__PURE__ */ new Map();
|
|
154831
|
-
wrapToolWithEmitter = (
|
|
156789
|
+
wrapToolWithEmitter = (tool3, toolName, baseExecute) => {
|
|
154832
156790
|
return {
|
|
154833
|
-
...
|
|
156791
|
+
...tool3,
|
|
154834
156792
|
// Spread schema, description etc.
|
|
154835
156793
|
execute: async (params) => {
|
|
154836
156794
|
const debug = process.env.DEBUG === "1";
|
|
@@ -154912,9 +156870,9 @@ var init_probeTool = __esm({
|
|
|
154912
156870
|
execute: async (params) => {
|
|
154913
156871
|
const { directory = ".", workingDirectory } = params;
|
|
154914
156872
|
const baseCwd = workingDirectory || process.cwd();
|
|
154915
|
-
const secureBaseDir =
|
|
154916
|
-
const targetDir =
|
|
154917
|
-
if (!targetDir.startsWith(secureBaseDir +
|
|
156873
|
+
const secureBaseDir = import_path7.default.resolve(baseCwd);
|
|
156874
|
+
const targetDir = import_path7.default.resolve(secureBaseDir, directory);
|
|
156875
|
+
if (!targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
|
|
154918
156876
|
throw new Error("Path traversal attempt detected. Access denied.");
|
|
154919
156877
|
}
|
|
154920
156878
|
try {
|
|
@@ -154937,9 +156895,9 @@ var init_probeTool = __esm({
|
|
|
154937
156895
|
throw new Error("Pattern is required for file search");
|
|
154938
156896
|
}
|
|
154939
156897
|
const baseCwd = workingDirectory || process.cwd();
|
|
154940
|
-
const secureBaseDir =
|
|
154941
|
-
const targetDir =
|
|
154942
|
-
if (!targetDir.startsWith(secureBaseDir +
|
|
156898
|
+
const secureBaseDir = import_path7.default.resolve(baseCwd);
|
|
156899
|
+
const targetDir = import_path7.default.resolve(secureBaseDir, directory);
|
|
156900
|
+
if (!targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
|
|
154943
156901
|
throw new Error("Path traversal attempt detected. Access denied.");
|
|
154944
156902
|
}
|
|
154945
156903
|
try {
|
|
@@ -154971,7 +156929,7 @@ function createMockProvider() {
|
|
|
154971
156929
|
provider: "mock",
|
|
154972
156930
|
// Mock the doGenerate method used by Vercel AI SDK
|
|
154973
156931
|
doGenerate: async ({ messages, tools: tools2 }) => {
|
|
154974
|
-
await new Promise((
|
|
156932
|
+
await new Promise((resolve4) => setTimeout(resolve4, 10));
|
|
154975
156933
|
return {
|
|
154976
156934
|
text: "This is a mock response for testing",
|
|
154977
156935
|
toolCalls: [],
|
|
@@ -155546,7 +157504,7 @@ ${decodedContent}
|
|
|
155546
157504
|
}
|
|
155547
157505
|
if (needsQuoting(content)) {
|
|
155548
157506
|
wasFixed = true;
|
|
155549
|
-
const safeContent = content.replace(/"/g, "'");
|
|
157507
|
+
const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
|
|
155550
157508
|
return `["${safeContent}"]`;
|
|
155551
157509
|
}
|
|
155552
157510
|
return match;
|
|
@@ -155559,7 +157517,7 @@ ${decodedContent}
|
|
|
155559
157517
|
}
|
|
155560
157518
|
if (needsQuoting(content)) {
|
|
155561
157519
|
wasFixed = true;
|
|
155562
|
-
const safeContent = content.replace(/"/g, "'");
|
|
157520
|
+
const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
|
|
155563
157521
|
return `{"${safeContent}"}`;
|
|
155564
157522
|
}
|
|
155565
157523
|
return match;
|
|
@@ -155729,7 +157687,7 @@ ${fixedContent}
|
|
|
155729
157687
|
}
|
|
155730
157688
|
if (needsQuoting(content)) {
|
|
155731
157689
|
wasFixed = true;
|
|
155732
|
-
const safeContent = content.replace(/"/g, "'");
|
|
157690
|
+
const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
|
|
155733
157691
|
return `["${safeContent}"]`;
|
|
155734
157692
|
}
|
|
155735
157693
|
return match;
|
|
@@ -155742,7 +157700,7 @@ ${fixedContent}
|
|
|
155742
157700
|
}
|
|
155743
157701
|
if (needsQuoting(content)) {
|
|
155744
157702
|
wasFixed = true;
|
|
155745
|
-
const safeContent = content.replace(/"/g, "'");
|
|
157703
|
+
const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
|
|
155746
157704
|
return `{"${safeContent}"}`;
|
|
155747
157705
|
}
|
|
155748
157706
|
return match;
|
|
@@ -156142,11 +158100,11 @@ function loadMCPConfigurationFromPath(configPath) {
|
|
|
156142
158100
|
if (!configPath) {
|
|
156143
158101
|
throw new Error("Config path is required");
|
|
156144
158102
|
}
|
|
156145
|
-
if (!(0,
|
|
158103
|
+
if (!(0, import_fs5.existsSync)(configPath)) {
|
|
156146
158104
|
throw new Error(`MCP configuration file not found: ${configPath}`);
|
|
156147
158105
|
}
|
|
156148
158106
|
try {
|
|
156149
|
-
const content = (0,
|
|
158107
|
+
const content = (0, import_fs5.readFileSync)(configPath, "utf8");
|
|
156150
158108
|
const config = JSON.parse(content);
|
|
156151
158109
|
if (process.env.DEBUG === "1") {
|
|
156152
158110
|
console.error(`[MCP] Loaded configuration from: ${configPath}`);
|
|
@@ -156161,19 +158119,19 @@ function loadMCPConfiguration() {
|
|
|
156161
158119
|
// Environment variable path
|
|
156162
158120
|
process.env.MCP_CONFIG_PATH,
|
|
156163
158121
|
// Local project paths
|
|
156164
|
-
(0,
|
|
156165
|
-
(0,
|
|
158122
|
+
(0, import_path8.join)(process.cwd(), ".mcp", "config.json"),
|
|
158123
|
+
(0, import_path8.join)(process.cwd(), "mcp.config.json"),
|
|
156166
158124
|
// Home directory paths
|
|
156167
|
-
(0,
|
|
156168
|
-
(0,
|
|
158125
|
+
(0, import_path8.join)((0, import_os3.homedir)(), ".config", "probe", "mcp.json"),
|
|
158126
|
+
(0, import_path8.join)((0, import_os3.homedir)(), ".mcp", "config.json"),
|
|
156169
158127
|
// Claude-style config location
|
|
156170
|
-
(0,
|
|
158128
|
+
(0, import_path8.join)((0, import_os3.homedir)(), "Library", "Application Support", "Claude", "mcp_config.json")
|
|
156171
158129
|
].filter(Boolean);
|
|
156172
158130
|
let config = null;
|
|
156173
158131
|
for (const configPath of configPaths) {
|
|
156174
|
-
if ((0,
|
|
158132
|
+
if ((0, import_fs5.existsSync)(configPath)) {
|
|
156175
158133
|
try {
|
|
156176
|
-
const content = (0,
|
|
158134
|
+
const content = (0, import_fs5.readFileSync)(configPath, "utf8");
|
|
156177
158135
|
config = JSON.parse(content);
|
|
156178
158136
|
if (process.env.DEBUG === "1") {
|
|
156179
158137
|
console.error(`[MCP] Loaded configuration from: ${configPath}`);
|
|
@@ -156269,22 +158227,22 @@ function parseEnabledServers(config) {
|
|
|
156269
158227
|
}
|
|
156270
158228
|
return servers;
|
|
156271
158229
|
}
|
|
156272
|
-
var
|
|
158230
|
+
var import_fs5, import_path8, import_os3, import_url4, __filename4, __dirname4, DEFAULT_CONFIG;
|
|
156273
158231
|
var init_config = __esm({
|
|
156274
158232
|
"src/agent/mcp/config.js"() {
|
|
156275
158233
|
"use strict";
|
|
156276
|
-
|
|
156277
|
-
|
|
158234
|
+
import_fs5 = __nccwpck_require__(79896);
|
|
158235
|
+
import_path8 = __nccwpck_require__(16928);
|
|
156278
158236
|
import_os3 = __nccwpck_require__(70857);
|
|
156279
158237
|
import_url4 = __nccwpck_require__(87016);
|
|
156280
158238
|
__filename4 = (0, import_url4.fileURLToPath)("file:///");
|
|
156281
|
-
__dirname4 = (0,
|
|
158239
|
+
__dirname4 = (0, import_path8.dirname)(__filename4);
|
|
156282
158240
|
DEFAULT_CONFIG = {
|
|
156283
158241
|
mcpServers: {
|
|
156284
158242
|
// Example probe server configuration
|
|
156285
158243
|
"probe-local": {
|
|
156286
158244
|
command: "node",
|
|
156287
|
-
args: [(0,
|
|
158245
|
+
args: [(0, import_path8.join)(__dirname4, "../../../examples/chat/mcpServer.js")],
|
|
156288
158246
|
transport: "stdio",
|
|
156289
158247
|
enabled: false
|
|
156290
158248
|
},
|
|
@@ -156441,12 +158399,12 @@ var init_client2 = __esm({
|
|
|
156441
158399
|
});
|
|
156442
158400
|
const toolsResponse = await client.listTools();
|
|
156443
158401
|
if (toolsResponse && toolsResponse.tools) {
|
|
156444
|
-
for (const
|
|
156445
|
-
const qualifiedName = `${name14}_${
|
|
158402
|
+
for (const tool3 of toolsResponse.tools) {
|
|
158403
|
+
const qualifiedName = `${name14}_${tool3.name}`;
|
|
156446
158404
|
this.tools.set(qualifiedName, {
|
|
156447
|
-
...
|
|
158405
|
+
...tool3,
|
|
156448
158406
|
serverName: name14,
|
|
156449
|
-
originalName:
|
|
158407
|
+
originalName: tool3.name
|
|
156450
158408
|
});
|
|
156451
158409
|
if (this.debug) {
|
|
156452
158410
|
console.error(`[MCP] Registered tool: ${qualifiedName}`);
|
|
@@ -156468,20 +158426,20 @@ var init_client2 = __esm({
|
|
|
156468
158426
|
* @param {Object} args - Tool arguments
|
|
156469
158427
|
*/
|
|
156470
158428
|
async callTool(toolName, args) {
|
|
156471
|
-
const
|
|
156472
|
-
if (!
|
|
158429
|
+
const tool3 = this.tools.get(toolName);
|
|
158430
|
+
if (!tool3) {
|
|
156473
158431
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
156474
158432
|
}
|
|
156475
|
-
const clientInfo = this.clients.get(
|
|
158433
|
+
const clientInfo = this.clients.get(tool3.serverName);
|
|
156476
158434
|
if (!clientInfo) {
|
|
156477
|
-
throw new Error(`Server ${
|
|
158435
|
+
throw new Error(`Server ${tool3.serverName} not connected`);
|
|
156478
158436
|
}
|
|
156479
158437
|
try {
|
|
156480
158438
|
if (this.debug) {
|
|
156481
158439
|
console.error(`[MCP] Calling ${toolName} with args:`, args);
|
|
156482
158440
|
}
|
|
156483
158441
|
const result = await clientInfo.client.callTool({
|
|
156484
|
-
name:
|
|
158442
|
+
name: tool3.originalName,
|
|
156485
158443
|
arguments: args
|
|
156486
158444
|
});
|
|
156487
158445
|
return result;
|
|
@@ -156496,11 +158454,11 @@ var init_client2 = __esm({
|
|
|
156496
158454
|
*/
|
|
156497
158455
|
getTools() {
|
|
156498
158456
|
const tools2 = {};
|
|
156499
|
-
for (const [name14,
|
|
158457
|
+
for (const [name14, tool3] of this.tools.entries()) {
|
|
156500
158458
|
tools2[name14] = {
|
|
156501
|
-
description:
|
|
156502
|
-
inputSchema:
|
|
156503
|
-
serverName:
|
|
158459
|
+
description: tool3.description,
|
|
158460
|
+
inputSchema: tool3.inputSchema,
|
|
158461
|
+
serverName: tool3.serverName
|
|
156504
158462
|
};
|
|
156505
158463
|
}
|
|
156506
158464
|
return tools2;
|
|
@@ -156511,10 +158469,10 @@ var init_client2 = __esm({
|
|
|
156511
158469
|
*/
|
|
156512
158470
|
getVercelTools() {
|
|
156513
158471
|
const tools2 = {};
|
|
156514
|
-
for (const [name14,
|
|
158472
|
+
for (const [name14, tool3] of this.tools.entries()) {
|
|
156515
158473
|
tools2[name14] = {
|
|
156516
|
-
description:
|
|
156517
|
-
inputSchema:
|
|
158474
|
+
description: tool3.description,
|
|
158475
|
+
inputSchema: tool3.inputSchema,
|
|
156518
158476
|
execute: async (args) => {
|
|
156519
158477
|
const result = await this.callTool(name14, args);
|
|
156520
158478
|
if (result.content && result.content[0]) {
|
|
@@ -156551,9 +158509,9 @@ var init_client2 = __esm({
|
|
|
156551
158509
|
});
|
|
156552
158510
|
|
|
156553
158511
|
// src/agent/mcp/xmlBridge.js
|
|
156554
|
-
function mcpToolToXmlDefinition(name14,
|
|
156555
|
-
const description =
|
|
156556
|
-
const inputSchema =
|
|
158512
|
+
function mcpToolToXmlDefinition(name14, tool3) {
|
|
158513
|
+
const description = tool3.description || "MCP tool";
|
|
158514
|
+
const inputSchema = tool3.inputSchema || tool3.parameters || {};
|
|
156557
158515
|
let paramDocs = "";
|
|
156558
158516
|
if (inputSchema.properties) {
|
|
156559
158517
|
paramDocs = "\n\nParameters (provide as JSON object):";
|
|
@@ -156713,8 +158671,8 @@ var init_xmlBridge = __esm({
|
|
|
156713
158671
|
const result = await this.mcpManager.initialize(mcpConfigs);
|
|
156714
158672
|
const vercelTools = this.mcpManager.getVercelTools();
|
|
156715
158673
|
this.mcpTools = vercelTools;
|
|
156716
|
-
for (const [name14,
|
|
156717
|
-
this.xmlDefinitions[name14] = mcpToolToXmlDefinition(name14,
|
|
158674
|
+
for (const [name14, tool3] of Object.entries(vercelTools)) {
|
|
158675
|
+
this.xmlDefinitions[name14] = mcpToolToXmlDefinition(name14, tool3);
|
|
156718
158676
|
}
|
|
156719
158677
|
if (this.debug) {
|
|
156720
158678
|
console.error(`[MCP] Loaded ${Object.keys(vercelTools).length} MCP tools from ${result.connected} server(s)`);
|
|
@@ -156751,12 +158709,12 @@ var init_xmlBridge = __esm({
|
|
|
156751
158709
|
if (this.debug) {
|
|
156752
158710
|
console.error(`[MCP] Executing MCP tool: ${toolName} with params:`, params);
|
|
156753
158711
|
}
|
|
156754
|
-
const
|
|
156755
|
-
if (!
|
|
158712
|
+
const tool3 = this.mcpTools[toolName];
|
|
158713
|
+
if (!tool3) {
|
|
156756
158714
|
throw new Error(`Unknown MCP tool: ${toolName}`);
|
|
156757
158715
|
}
|
|
156758
158716
|
try {
|
|
156759
|
-
const result = await
|
|
158717
|
+
const result = await tool3.execute(params);
|
|
156760
158718
|
return {
|
|
156761
158719
|
success: true,
|
|
156762
158720
|
toolName,
|
|
@@ -156808,7 +158766,7 @@ var ProbeAgent_exports = {};
|
|
|
156808
158766
|
__export(ProbeAgent_exports, {
|
|
156809
158767
|
ProbeAgent: () => ProbeAgent
|
|
156810
158768
|
});
|
|
156811
|
-
var import_anthropic, import_openai, import_google,
|
|
158769
|
+
var import_anthropic, import_openai, import_google, import_ai3, import_crypto5, import_events2, import_fs6, import_promises, import_path9, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, SUPPORTED_IMAGE_EXTENSIONS, MAX_IMAGE_FILE_SIZE, ProbeAgent;
|
|
156812
158770
|
var init_ProbeAgent = __esm({
|
|
156813
158771
|
"src/agent/ProbeAgent.js"() {
|
|
156814
158772
|
"use strict";
|
|
@@ -156816,12 +158774,12 @@ var init_ProbeAgent = __esm({
|
|
|
156816
158774
|
import_openai = __nccwpck_require__(87635);
|
|
156817
158775
|
import_google = __nccwpck_require__(30260);
|
|
156818
158776
|
init_dist3();
|
|
156819
|
-
|
|
158777
|
+
import_ai3 = __nccwpck_require__(86619);
|
|
156820
158778
|
import_crypto5 = __nccwpck_require__(76982);
|
|
156821
158779
|
import_events2 = __nccwpck_require__(24434);
|
|
156822
|
-
|
|
158780
|
+
import_fs6 = __nccwpck_require__(79896);
|
|
156823
158781
|
import_promises = __nccwpck_require__(91943);
|
|
156824
|
-
|
|
158782
|
+
import_path9 = __nccwpck_require__(16928);
|
|
156825
158783
|
init_tokenCounter();
|
|
156826
158784
|
init_tools2();
|
|
156827
158785
|
init_common();
|
|
@@ -156865,6 +158823,8 @@ var init_ProbeAgent = __esm({
|
|
|
156865
158823
|
this.outline = !!options.outline;
|
|
156866
158824
|
this.maxResponseTokens = options.maxResponseTokens || parseInt(process.env.MAX_RESPONSE_TOKENS || "0", 10) || null;
|
|
156867
158825
|
this.disableMermaidValidation = !!options.disableMermaidValidation;
|
|
158826
|
+
this.enableBash = !!options.enableBash;
|
|
158827
|
+
this.bashConfig = options.bashConfig || {};
|
|
156868
158828
|
if (options.allowedFolders && Array.isArray(options.allowedFolders)) {
|
|
156869
158829
|
this.allowedFolders = options.allowedFolders;
|
|
156870
158830
|
} else if (options.path) {
|
|
@@ -156908,7 +158868,9 @@ var init_ProbeAgent = __esm({
|
|
|
156908
158868
|
debug: this.debug,
|
|
156909
158869
|
defaultPath: this.allowedFolders.length > 0 ? this.allowedFolders[0] : process.cwd(),
|
|
156910
158870
|
allowedFolders: this.allowedFolders,
|
|
156911
|
-
outline: this.outline
|
|
158871
|
+
outline: this.outline,
|
|
158872
|
+
enableBash: this.enableBash,
|
|
158873
|
+
bashConfig: this.bashConfig
|
|
156912
158874
|
};
|
|
156913
158875
|
const baseTools = createTools(configOptions);
|
|
156914
158876
|
const wrappedTools = createWrappedTools(baseTools);
|
|
@@ -156920,6 +158882,9 @@ var init_ProbeAgent = __esm({
|
|
|
156920
158882
|
listFiles: listFilesToolInstance,
|
|
156921
158883
|
searchFiles: searchFilesToolInstance
|
|
156922
158884
|
};
|
|
158885
|
+
if (this.enableBash && wrappedTools.bashToolInstance) {
|
|
158886
|
+
this.toolImplementations.bash = wrappedTools.bashToolInstance;
|
|
158887
|
+
}
|
|
156923
158888
|
this.wrappedTools = wrappedTools;
|
|
156924
158889
|
}
|
|
156925
158890
|
/**
|
|
@@ -157106,13 +159071,13 @@ var init_ProbeAgent = __esm({
|
|
|
157106
159071
|
const allowedDirs = this.allowedFolders && this.allowedFolders.length > 0 ? this.allowedFolders : [process.cwd()];
|
|
157107
159072
|
let absolutePath;
|
|
157108
159073
|
let isPathAllowed = false;
|
|
157109
|
-
if ((0,
|
|
159074
|
+
if ((0, import_path9.isAbsolute)(imagePath)) {
|
|
157110
159075
|
absolutePath = imagePath;
|
|
157111
|
-
isPathAllowed = allowedDirs.some((dir) => absolutePath.startsWith((0,
|
|
159076
|
+
isPathAllowed = allowedDirs.some((dir) => absolutePath.startsWith((0, import_path9.resolve)(dir)));
|
|
157112
159077
|
} else {
|
|
157113
159078
|
for (const dir of allowedDirs) {
|
|
157114
|
-
const resolvedPath3 = (0,
|
|
157115
|
-
if (resolvedPath3.startsWith((0,
|
|
159079
|
+
const resolvedPath3 = (0, import_path9.resolve)(dir, imagePath);
|
|
159080
|
+
if (resolvedPath3.startsWith((0, import_path9.resolve)(dir))) {
|
|
157116
159081
|
absolutePath = resolvedPath3;
|
|
157117
159082
|
isPathAllowed = true;
|
|
157118
159083
|
break;
|
|
@@ -157607,7 +159572,7 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
157607
159572
|
try {
|
|
157608
159573
|
const executeAIRequest = async () => {
|
|
157609
159574
|
const messagesForAI = this.prepareMessagesWithImages(currentMessages);
|
|
157610
|
-
const result = await (0,
|
|
159575
|
+
const result = await (0, import_ai3.streamText)({
|
|
157611
159576
|
model: this.provider(this.model),
|
|
157612
159577
|
messages: messagesForAI,
|
|
157613
159578
|
maxTokens: maxResponseTokens,
|
|
@@ -158284,12 +160249,12 @@ function initializeSimpleTelemetryFromOptions(options) {
|
|
|
158284
160249
|
});
|
|
158285
160250
|
return telemetry;
|
|
158286
160251
|
}
|
|
158287
|
-
var
|
|
160252
|
+
var import_fs7, import_path10, SimpleTelemetry, SimpleAppTracer;
|
|
158288
160253
|
var init_simpleTelemetry = __esm({
|
|
158289
160254
|
"src/agent/simpleTelemetry.js"() {
|
|
158290
160255
|
"use strict";
|
|
158291
|
-
|
|
158292
|
-
|
|
160256
|
+
import_fs7 = __nccwpck_require__(79896);
|
|
160257
|
+
import_path10 = __nccwpck_require__(16928);
|
|
158293
160258
|
SimpleTelemetry = class {
|
|
158294
160259
|
constructor(options = {}) {
|
|
158295
160260
|
this.serviceName = options.serviceName || "probe-agent";
|
|
@@ -158303,11 +160268,11 @@ var init_simpleTelemetry = __esm({
|
|
|
158303
160268
|
}
|
|
158304
160269
|
initializeFileExporter() {
|
|
158305
160270
|
try {
|
|
158306
|
-
const dir = (0,
|
|
158307
|
-
if (!(0,
|
|
158308
|
-
(0,
|
|
160271
|
+
const dir = (0, import_path10.dirname)(this.filePath);
|
|
160272
|
+
if (!(0, import_fs7.existsSync)(dir)) {
|
|
160273
|
+
(0, import_fs7.mkdirSync)(dir, { recursive: true });
|
|
158309
160274
|
}
|
|
158310
|
-
this.stream = (0,
|
|
160275
|
+
this.stream = (0, import_fs7.createWriteStream)(this.filePath, { flags: "a" });
|
|
158311
160276
|
this.stream.on("error", (error2) => {
|
|
158312
160277
|
console.error(`[SimpleTelemetry] Stream error: ${error2.message}`);
|
|
158313
160278
|
});
|
|
@@ -158368,20 +160333,20 @@ var init_simpleTelemetry = __esm({
|
|
|
158368
160333
|
}
|
|
158369
160334
|
async flush() {
|
|
158370
160335
|
if (this.stream) {
|
|
158371
|
-
return new Promise((
|
|
158372
|
-
this.stream.once("drain",
|
|
160336
|
+
return new Promise((resolve4) => {
|
|
160337
|
+
this.stream.once("drain", resolve4);
|
|
158373
160338
|
if (!this.stream.writableNeedDrain) {
|
|
158374
|
-
|
|
160339
|
+
resolve4();
|
|
158375
160340
|
}
|
|
158376
160341
|
});
|
|
158377
160342
|
}
|
|
158378
160343
|
}
|
|
158379
160344
|
async shutdown() {
|
|
158380
160345
|
if (this.stream) {
|
|
158381
|
-
return new Promise((
|
|
160346
|
+
return new Promise((resolve4) => {
|
|
158382
160347
|
this.stream.end(() => {
|
|
158383
160348
|
console.log(`[SimpleTelemetry] File stream closed: ${this.filePath}`);
|
|
158384
|
-
|
|
160349
|
+
resolve4();
|
|
158385
160350
|
});
|
|
158386
160351
|
});
|
|
158387
160352
|
}
|
|
@@ -158508,6 +160473,9 @@ __export(index_exports, {
|
|
|
158508
160473
|
SimpleTelemetry: () => SimpleTelemetry,
|
|
158509
160474
|
attemptCompletionSchema: () => attemptCompletionSchema,
|
|
158510
160475
|
attemptCompletionToolDefinition: () => attemptCompletionToolDefinition,
|
|
160476
|
+
bashSchema: () => bashSchema,
|
|
160477
|
+
bashTool: () => bashTool,
|
|
160478
|
+
bashToolDefinition: () => bashToolDefinition,
|
|
158511
160479
|
delegate: () => delegate,
|
|
158512
160480
|
delegateSchema: () => delegateSchema,
|
|
158513
160481
|
delegateTool: () => delegateTool,
|
|
@@ -158544,6 +160512,7 @@ var init_index = __esm({
|
|
|
158544
160512
|
init_system_message();
|
|
158545
160513
|
init_common();
|
|
158546
160514
|
init_vercel();
|
|
160515
|
+
init_bash();
|
|
158547
160516
|
init_ProbeAgent();
|
|
158548
160517
|
init_simpleTelemetry();
|
|
158549
160518
|
}
|