@probelabs/visor 0.1.72 → 0.1.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -0
- package/action.yml +5 -1
- package/dist/check-execution-engine.d.ts +92 -3
- package/dist/check-execution-engine.d.ts.map +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/index.js +546 -74
- package/dist/output-formatters.d.ts +2 -0
- package/dist/output-formatters.d.ts.map +1 -1
- package/dist/sdk/{check-execution-engine-RXV4MUD2.mjs → check-execution-engine-75SSXUBP.mjs} +2 -2
- package/dist/sdk/{chunk-J355UUEI.mjs → chunk-NINHE4RF.mjs} +295 -28
- package/dist/sdk/chunk-NINHE4RF.mjs.map +1 -0
- package/dist/sdk/sdk.d.mts +99 -60
- package/dist/sdk/sdk.d.ts +99 -60
- package/dist/sdk/sdk.js +293 -26
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +1 -1
- package/package.json +3 -3
- package/dist/sdk/chunk-J355UUEI.mjs.map +0 -1
- /package/dist/sdk/{check-execution-engine-RXV4MUD2.mjs.map → check-execution-engine-75SSXUBP.mjs.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
process.env.VISOR_VERSION = '0.1.
|
|
3
|
-
process.env.PROBE_VERSION = '0.6.0-
|
|
2
|
+
process.env.VISOR_VERSION = '0.1.74';
|
|
3
|
+
process.env.PROBE_VERSION = '0.6.0-rc117';
|
|
4
4
|
/******/ (() => { // webpackBootstrap
|
|
5
5
|
/******/ var __webpack_modules__ = ({
|
|
6
6
|
|
|
@@ -95099,6 +95099,7 @@ class CheckExecutionEngine {
|
|
|
95099
95099
|
config;
|
|
95100
95100
|
webhookContext;
|
|
95101
95101
|
routingSandbox;
|
|
95102
|
+
executionStats = new Map();
|
|
95102
95103
|
constructor(workingDirectory) {
|
|
95103
95104
|
this.workingDirectory = workingDirectory || process.cwd();
|
|
95104
95105
|
this.gitAnalyzer = new git_repository_analyzer_1.GitRepositoryAnalyzer(this.workingDirectory);
|
|
@@ -95660,12 +95661,15 @@ class CheckExecutionEngine {
|
|
|
95660
95661
|
apiCallDetails: reviewSummary.debug.apiCallDetails,
|
|
95661
95662
|
};
|
|
95662
95663
|
}
|
|
95664
|
+
// Build execution statistics
|
|
95665
|
+
const executionStatistics = this.buildExecutionStatistics();
|
|
95663
95666
|
return {
|
|
95664
95667
|
repositoryInfo,
|
|
95665
95668
|
reviewSummary,
|
|
95666
95669
|
executionTime,
|
|
95667
95670
|
timestamp,
|
|
95668
95671
|
checksExecuted: filteredChecks,
|
|
95672
|
+
executionStatistics,
|
|
95669
95673
|
debug: debugInfo,
|
|
95670
95674
|
};
|
|
95671
95675
|
}
|
|
@@ -95861,7 +95865,7 @@ class CheckExecutionEngine {
|
|
|
95861
95865
|
});
|
|
95862
95866
|
}
|
|
95863
95867
|
/**
|
|
95864
|
-
* Execute review checks and return grouped results for new architecture
|
|
95868
|
+
* Execute review checks and return grouped results with statistics for new architecture
|
|
95865
95869
|
*/
|
|
95866
95870
|
async executeGroupedChecks(prInfo, checks, timeout, config, outputFormat, debug, maxParallelism, failFast, tagFilter) {
|
|
95867
95871
|
// Determine where to send log messages based on output format
|
|
@@ -95890,7 +95894,10 @@ class CheckExecutionEngine {
|
|
|
95890
95894
|
// Check if we have any checks left after filtering
|
|
95891
95895
|
if (checks.length === 0) {
|
|
95892
95896
|
logger_1.logger.warn('⚠️ No checks remain after tag filtering');
|
|
95893
|
-
return {
|
|
95897
|
+
return {
|
|
95898
|
+
results: {},
|
|
95899
|
+
statistics: this.buildExecutionStatistics(),
|
|
95900
|
+
};
|
|
95894
95901
|
}
|
|
95895
95902
|
if (!config?.checks) {
|
|
95896
95903
|
throw new Error('Config with check definitions required for grouped execution');
|
|
@@ -95914,10 +95921,16 @@ class CheckExecutionEngine {
|
|
|
95914
95921
|
const checkResult = await this.executeSingleGroupedCheck(prInfo, checks[0], timeout, config, logFn, debug);
|
|
95915
95922
|
const groupedResults = {};
|
|
95916
95923
|
groupedResults[checkResult.group] = [checkResult];
|
|
95917
|
-
return
|
|
95924
|
+
return {
|
|
95925
|
+
results: groupedResults,
|
|
95926
|
+
statistics: this.buildExecutionStatistics(),
|
|
95927
|
+
};
|
|
95918
95928
|
}
|
|
95919
95929
|
// No checks to execute
|
|
95920
|
-
return {
|
|
95930
|
+
return {
|
|
95931
|
+
results: {},
|
|
95932
|
+
statistics: this.buildExecutionStatistics(),
|
|
95933
|
+
};
|
|
95921
95934
|
}
|
|
95922
95935
|
/**
|
|
95923
95936
|
* Execute single check and return grouped result
|
|
@@ -95962,13 +95975,19 @@ class CheckExecutionEngine {
|
|
|
95962
95975
|
};
|
|
95963
95976
|
}
|
|
95964
95977
|
/**
|
|
95965
|
-
* Execute multiple checks with dependency awareness - return grouped results
|
|
95978
|
+
* Execute multiple checks with dependency awareness - return grouped results with statistics
|
|
95966
95979
|
*/
|
|
95967
95980
|
async executeGroupedDependencyAwareChecks(prInfo, checks, timeout, config, logFn, debug, maxParallelism, failFast) {
|
|
95968
95981
|
// Use the existing dependency-aware execution logic
|
|
95969
95982
|
const reviewSummary = await this.executeDependencyAwareChecks(prInfo, checks, timeout, config, logFn, debug, maxParallelism, failFast);
|
|
95983
|
+
// Build execution statistics
|
|
95984
|
+
const executionStatistics = this.buildExecutionStatistics();
|
|
95970
95985
|
// Convert the flat ReviewSummary to grouped CheckResults
|
|
95971
|
-
|
|
95986
|
+
const groupedResults = await this.convertReviewSummaryToGroupedResults(reviewSummary, checks, config, prInfo);
|
|
95987
|
+
return {
|
|
95988
|
+
results: groupedResults,
|
|
95989
|
+
statistics: executionStatistics,
|
|
95990
|
+
};
|
|
95972
95991
|
}
|
|
95973
95992
|
/**
|
|
95974
95993
|
* Convert ReviewSummary to GroupedCheckResults
|
|
@@ -96281,9 +96300,10 @@ class CheckExecutionEngine {
|
|
|
96281
96300
|
let shouldStopExecution = false;
|
|
96282
96301
|
let completedChecksCount = 0;
|
|
96283
96302
|
const totalChecksCount = stats.totalChecks;
|
|
96284
|
-
|
|
96285
|
-
|
|
96286
|
-
|
|
96303
|
+
// Initialize execution statistics for all checks
|
|
96304
|
+
for (const checkName of checks) {
|
|
96305
|
+
this.initializeCheckStats(checkName);
|
|
96306
|
+
}
|
|
96287
96307
|
for (let levelIndex = 0; levelIndex < dependencyGraph.executionOrder.length && !shouldStopExecution; levelIndex++) {
|
|
96288
96308
|
const executionGroup = dependencyGraph.executionOrder[levelIndex];
|
|
96289
96309
|
// Check if any checks in this level require session reuse - if so, force sequential execution
|
|
@@ -96416,9 +96436,13 @@ class CheckExecutionEngine {
|
|
|
96416
96436
|
// Handle forEach dependent execution
|
|
96417
96437
|
let finalResult;
|
|
96418
96438
|
if (isForEachDependent && forEachParentName) {
|
|
96439
|
+
// Record forEach preview items
|
|
96440
|
+
this.recordForEachPreview(checkName, forEachItems);
|
|
96419
96441
|
if (debug) {
|
|
96420
96442
|
log(`🔄 Debug: Check "${checkName}" depends on forEach check "${forEachParentName}", executing ${forEachItems.length} times`);
|
|
96421
96443
|
}
|
|
96444
|
+
// Log forEach processing start
|
|
96445
|
+
logger_1.logger.info(` Processing ${forEachItems.length} items...`);
|
|
96422
96446
|
const allIssues = [];
|
|
96423
96447
|
const allOutputs = [];
|
|
96424
96448
|
const aggregatedContents = [];
|
|
@@ -96479,6 +96503,8 @@ class CheckExecutionEngine {
|
|
|
96479
96503
|
if (debug) {
|
|
96480
96504
|
log(`🔄 Debug: Executing check "${checkName}" for item ${itemIndex + 1}/${forEachItems.length}`);
|
|
96481
96505
|
}
|
|
96506
|
+
// Track iteration start
|
|
96507
|
+
const iterationStart = this.recordIterationStart(checkName);
|
|
96482
96508
|
// Execute with retry/routing semantics per item
|
|
96483
96509
|
const itemResult = await this.executeWithRouting(checkName, checkConfig, provider, providerConfig, prInfo, forEachDependencyResults, sessionInfo, config, dependencyGraph, debug, results,
|
|
96484
96510
|
/*foreachContext*/ {
|
|
@@ -96486,6 +96512,11 @@ class CheckExecutionEngine {
|
|
|
96486
96512
|
total: forEachItems.length,
|
|
96487
96513
|
parent: forEachParentName,
|
|
96488
96514
|
});
|
|
96515
|
+
// Record iteration completion
|
|
96516
|
+
const iterationDuration = (Date.now() - iterationStart) / 1000;
|
|
96517
|
+
this.recordIterationComplete(checkName, iterationStart, true, itemResult.issues || [], itemResult.output);
|
|
96518
|
+
// Log iteration progress
|
|
96519
|
+
logger_1.logger.info(` ✔ ${itemIndex + 1}/${forEachItems.length} (${iterationDuration.toFixed(1)}s)`);
|
|
96489
96520
|
return { index: itemIndex, itemResult };
|
|
96490
96521
|
});
|
|
96491
96522
|
const forEachConcurrency = Math.max(1, Math.min(forEachItems.length, effectiveMaxParallelism));
|
|
@@ -96537,8 +96568,9 @@ class CheckExecutionEngine {
|
|
|
96537
96568
|
if (checkConfig.if) {
|
|
96538
96569
|
const shouldRun = await this.evaluateCheckCondition(checkName, checkConfig.if, prInfo, results, debug);
|
|
96539
96570
|
if (!shouldRun) {
|
|
96540
|
-
|
|
96541
|
-
|
|
96571
|
+
// Record skip with condition
|
|
96572
|
+
this.recordSkip(checkName, 'if_condition', checkConfig.if);
|
|
96573
|
+
logger_1.logger.info(`⏭ Skipped (if: ${this.truncate(checkConfig.if, 40)})`);
|
|
96542
96574
|
return {
|
|
96543
96575
|
checkName,
|
|
96544
96576
|
error: null,
|
|
@@ -96551,6 +96583,8 @@ class CheckExecutionEngine {
|
|
|
96551
96583
|
}
|
|
96552
96584
|
// Execute with retry/routing semantics
|
|
96553
96585
|
finalResult = await this.executeWithRouting(checkName, checkConfig, provider, providerConfig, prInfo, dependencyResults, sessionInfo, config, dependencyGraph, debug, results);
|
|
96586
|
+
// Record normal (non-forEach) execution
|
|
96587
|
+
this.recordIterationComplete(checkName, checkStartTime, true, finalResult.issues || [], finalResult.output);
|
|
96554
96588
|
if (checkConfig.forEach) {
|
|
96555
96589
|
try {
|
|
96556
96590
|
const finalResultWithOutput = finalResult;
|
|
@@ -96581,7 +96615,20 @@ class CheckExecutionEngine {
|
|
|
96581
96615
|
};
|
|
96582
96616
|
const checkDuration = ((Date.now() - checkStartTime) / 1000).toFixed(1);
|
|
96583
96617
|
const issueCount = enrichedIssues.length;
|
|
96584
|
-
|
|
96618
|
+
const checkStats = this.executionStats.get(checkName);
|
|
96619
|
+
// Enhanced completion message with forEach stats
|
|
96620
|
+
if (checkStats && checkStats.totalRuns > 1) {
|
|
96621
|
+
if (issueCount > 0) {
|
|
96622
|
+
logger_1.logger.success(`Check complete: ${checkName} (${checkDuration}s) - ${checkStats.totalRuns} runs, ${issueCount} issue${issueCount === 1 ? '' : 's'}`);
|
|
96623
|
+
}
|
|
96624
|
+
else {
|
|
96625
|
+
logger_1.logger.success(`Check complete: ${checkName} (${checkDuration}s) - ${checkStats.totalRuns} runs`);
|
|
96626
|
+
}
|
|
96627
|
+
}
|
|
96628
|
+
else if (checkStats && checkStats.outputsProduced && checkStats.outputsProduced > 0) {
|
|
96629
|
+
logger_1.logger.success(`Check complete: ${checkName} (${checkDuration}s) - ${checkStats.outputsProduced} items`);
|
|
96630
|
+
}
|
|
96631
|
+
else if (issueCount > 0) {
|
|
96585
96632
|
logger_1.logger.success(`Check complete: ${checkName} (${checkDuration}s) - ${issueCount} issue${issueCount === 1 ? '' : 's'} found`);
|
|
96586
96633
|
}
|
|
96587
96634
|
else {
|
|
@@ -96594,9 +96641,11 @@ class CheckExecutionEngine {
|
|
|
96594
96641
|
};
|
|
96595
96642
|
}
|
|
96596
96643
|
catch (error) {
|
|
96597
|
-
failedChecksCount++;
|
|
96598
96644
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
96599
96645
|
const checkDuration = ((Date.now() - checkStartTime) / 1000).toFixed(1);
|
|
96646
|
+
// Record error in stats
|
|
96647
|
+
this.recordError(checkName, error instanceof Error ? error : new Error(String(error)));
|
|
96648
|
+
this.recordIterationComplete(checkName, checkStartTime, false, [], undefined);
|
|
96600
96649
|
logger_1.logger.error(`✖ Check failed: ${checkName} (${checkDuration}s) - ${errorMessage}`);
|
|
96601
96650
|
if (debug) {
|
|
96602
96651
|
log(`🔧 Debug: Error in check ${checkName}: ${errorMessage}`);
|
|
@@ -96714,20 +96763,18 @@ class CheckExecutionEngine {
|
|
|
96714
96763
|
}
|
|
96715
96764
|
}
|
|
96716
96765
|
}
|
|
96717
|
-
//
|
|
96718
|
-
const
|
|
96719
|
-
|
|
96720
|
-
|
|
96721
|
-
|
|
96722
|
-
|
|
96723
|
-
|
|
96724
|
-
logger_1.logger.info(` ⏭ Skipped: ${skippedChecksCount}`);
|
|
96725
|
-
}
|
|
96726
|
-
if (failedChecksCount > 0) {
|
|
96727
|
-
logger_1.logger.info(` ✖ Failed: ${failedChecksCount}`);
|
|
96766
|
+
// Build and log final execution summary
|
|
96767
|
+
const executionStatistics = this.buildExecutionStatistics();
|
|
96768
|
+
// Show detailed summary table (only if logFn outputs to console)
|
|
96769
|
+
// Skip when output format is JSON/SARIF to avoid polluting structured output
|
|
96770
|
+
// Check if logFn is console.log (not a no-op or console.error)
|
|
96771
|
+
if (logFn === console.log) {
|
|
96772
|
+
this.logExecutionSummary(executionStatistics);
|
|
96728
96773
|
}
|
|
96774
|
+
// Add warning if execution stopped early
|
|
96729
96775
|
if (shouldStopExecution) {
|
|
96730
|
-
logger_1.logger.
|
|
96776
|
+
logger_1.logger.info('');
|
|
96777
|
+
logger_1.logger.warn(`⚠️ Execution stopped early due to fail-fast`);
|
|
96731
96778
|
}
|
|
96732
96779
|
if (debug) {
|
|
96733
96780
|
if (shouldStopExecution) {
|
|
@@ -97666,6 +97713,251 @@ class CheckExecutionEngine {
|
|
|
97666
97713
|
// events, which don't generate PRInfo objects in the first place.
|
|
97667
97714
|
return 'pr_updated';
|
|
97668
97715
|
}
|
|
97716
|
+
/**
|
|
97717
|
+
* Initialize execution statistics for a check
|
|
97718
|
+
*/
|
|
97719
|
+
initializeCheckStats(checkName) {
|
|
97720
|
+
this.executionStats.set(checkName, {
|
|
97721
|
+
checkName,
|
|
97722
|
+
totalRuns: 0,
|
|
97723
|
+
successfulRuns: 0,
|
|
97724
|
+
failedRuns: 0,
|
|
97725
|
+
skipped: false,
|
|
97726
|
+
totalDuration: 0,
|
|
97727
|
+
issuesFound: 0,
|
|
97728
|
+
issuesBySeverity: {
|
|
97729
|
+
critical: 0,
|
|
97730
|
+
error: 0,
|
|
97731
|
+
warning: 0,
|
|
97732
|
+
info: 0,
|
|
97733
|
+
},
|
|
97734
|
+
perIterationDuration: [],
|
|
97735
|
+
});
|
|
97736
|
+
}
|
|
97737
|
+
/**
|
|
97738
|
+
* Record the start of a check iteration
|
|
97739
|
+
* Returns the start timestamp for duration tracking
|
|
97740
|
+
*/
|
|
97741
|
+
recordIterationStart(_checkName) {
|
|
97742
|
+
return Date.now();
|
|
97743
|
+
}
|
|
97744
|
+
/**
|
|
97745
|
+
* Record completion of a check iteration
|
|
97746
|
+
*/
|
|
97747
|
+
recordIterationComplete(checkName, startTime, success, issues, output) {
|
|
97748
|
+
const stats = this.executionStats.get(checkName);
|
|
97749
|
+
if (!stats)
|
|
97750
|
+
return;
|
|
97751
|
+
const duration = Date.now() - startTime;
|
|
97752
|
+
stats.totalRuns++;
|
|
97753
|
+
if (success) {
|
|
97754
|
+
stats.successfulRuns++;
|
|
97755
|
+
}
|
|
97756
|
+
else {
|
|
97757
|
+
stats.failedRuns++;
|
|
97758
|
+
}
|
|
97759
|
+
stats.totalDuration += duration;
|
|
97760
|
+
stats.perIterationDuration.push(duration);
|
|
97761
|
+
// Count issues by severity
|
|
97762
|
+
for (const issue of issues) {
|
|
97763
|
+
stats.issuesFound++;
|
|
97764
|
+
if (issue.severity === 'critical')
|
|
97765
|
+
stats.issuesBySeverity.critical++;
|
|
97766
|
+
else if (issue.severity === 'error')
|
|
97767
|
+
stats.issuesBySeverity.error++;
|
|
97768
|
+
else if (issue.severity === 'warning')
|
|
97769
|
+
stats.issuesBySeverity.warning++;
|
|
97770
|
+
else if (issue.severity === 'info')
|
|
97771
|
+
stats.issuesBySeverity.info++;
|
|
97772
|
+
}
|
|
97773
|
+
// Track outputs produced
|
|
97774
|
+
if (output !== undefined) {
|
|
97775
|
+
stats.outputsProduced = (stats.outputsProduced || 0) + 1;
|
|
97776
|
+
}
|
|
97777
|
+
}
|
|
97778
|
+
/**
|
|
97779
|
+
* Record that a check was skipped
|
|
97780
|
+
*/
|
|
97781
|
+
recordSkip(checkName, reason, condition) {
|
|
97782
|
+
const stats = this.executionStats.get(checkName);
|
|
97783
|
+
if (!stats)
|
|
97784
|
+
return;
|
|
97785
|
+
stats.skipped = true;
|
|
97786
|
+
stats.skipReason = reason;
|
|
97787
|
+
if (condition) {
|
|
97788
|
+
stats.skipCondition = condition;
|
|
97789
|
+
}
|
|
97790
|
+
}
|
|
97791
|
+
/**
|
|
97792
|
+
* Record forEach preview items
|
|
97793
|
+
*/
|
|
97794
|
+
recordForEachPreview(checkName, items) {
|
|
97795
|
+
const stats = this.executionStats.get(checkName);
|
|
97796
|
+
if (!stats || !items.length)
|
|
97797
|
+
return;
|
|
97798
|
+
// Store preview of first 3 items
|
|
97799
|
+
const preview = items.slice(0, 3).map(item => {
|
|
97800
|
+
const str = typeof item === 'string' ? item : JSON.stringify(item);
|
|
97801
|
+
return str.length > 50 ? str.substring(0, 47) + '...' : str;
|
|
97802
|
+
});
|
|
97803
|
+
if (items.length > 3) {
|
|
97804
|
+
preview.push(`...${items.length - 3} more`);
|
|
97805
|
+
}
|
|
97806
|
+
stats.forEachPreview = preview;
|
|
97807
|
+
}
|
|
97808
|
+
/**
|
|
97809
|
+
* Record an error for a check
|
|
97810
|
+
*/
|
|
97811
|
+
recordError(checkName, error) {
|
|
97812
|
+
const stats = this.executionStats.get(checkName);
|
|
97813
|
+
if (!stats)
|
|
97814
|
+
return;
|
|
97815
|
+
stats.errorMessage = error instanceof Error ? error.message : String(error);
|
|
97816
|
+
}
|
|
97817
|
+
/**
|
|
97818
|
+
* Build the final execution statistics object
|
|
97819
|
+
*/
|
|
97820
|
+
buildExecutionStatistics() {
|
|
97821
|
+
const checks = Array.from(this.executionStats.values());
|
|
97822
|
+
const totalExecutions = checks.reduce((sum, s) => sum + s.totalRuns, 0);
|
|
97823
|
+
const successfulExecutions = checks.reduce((sum, s) => sum + s.successfulRuns, 0);
|
|
97824
|
+
const failedExecutions = checks.reduce((sum, s) => sum + s.failedRuns, 0);
|
|
97825
|
+
const skippedChecks = checks.filter(s => s.skipped).length;
|
|
97826
|
+
const totalDuration = checks.reduce((sum, s) => sum + s.totalDuration, 0);
|
|
97827
|
+
return {
|
|
97828
|
+
totalChecksConfigured: checks.length,
|
|
97829
|
+
totalExecutions,
|
|
97830
|
+
successfulExecutions,
|
|
97831
|
+
failedExecutions,
|
|
97832
|
+
skippedChecks,
|
|
97833
|
+
totalDuration,
|
|
97834
|
+
checks,
|
|
97835
|
+
};
|
|
97836
|
+
}
|
|
97837
|
+
/**
|
|
97838
|
+
* Truncate a string to max length with ellipsis
|
|
97839
|
+
*/
|
|
97840
|
+
truncate(str, maxLen) {
|
|
97841
|
+
if (str.length <= maxLen)
|
|
97842
|
+
return str;
|
|
97843
|
+
return str.substring(0, maxLen - 3) + '...';
|
|
97844
|
+
}
|
|
97845
|
+
/**
|
|
97846
|
+
* Format the Status column for execution summary table
|
|
97847
|
+
*/
|
|
97848
|
+
formatStatusColumn(stats) {
|
|
97849
|
+
if (stats.skipped) {
|
|
97850
|
+
if (stats.skipReason === 'if_condition')
|
|
97851
|
+
return '⏭ if';
|
|
97852
|
+
if (stats.skipReason === 'fail_fast')
|
|
97853
|
+
return '⏭ ff';
|
|
97854
|
+
if (stats.skipReason === 'dependency_failed')
|
|
97855
|
+
return '⏭ dep';
|
|
97856
|
+
return '⏭';
|
|
97857
|
+
}
|
|
97858
|
+
if (stats.totalRuns === 0)
|
|
97859
|
+
return '-';
|
|
97860
|
+
const symbol = stats.failedRuns === 0 ? '✔' : stats.successfulRuns === 0 ? '✖' : '✔/✖';
|
|
97861
|
+
// Show iteration count if > 1
|
|
97862
|
+
if (stats.totalRuns > 1) {
|
|
97863
|
+
if (stats.failedRuns > 0 && stats.successfulRuns > 0) {
|
|
97864
|
+
// Partial success
|
|
97865
|
+
return `${symbol} ${stats.successfulRuns}/${stats.totalRuns}`;
|
|
97866
|
+
}
|
|
97867
|
+
else {
|
|
97868
|
+
// All success or all failed
|
|
97869
|
+
return `${symbol} ×${stats.totalRuns}`;
|
|
97870
|
+
}
|
|
97871
|
+
}
|
|
97872
|
+
return symbol;
|
|
97873
|
+
}
|
|
97874
|
+
/**
|
|
97875
|
+
* Format the Details column for execution summary table
|
|
97876
|
+
*/
|
|
97877
|
+
formatDetailsColumn(stats) {
|
|
97878
|
+
const parts = [];
|
|
97879
|
+
// Outputs produced (forEach)
|
|
97880
|
+
if (stats.outputsProduced && stats.outputsProduced > 0) {
|
|
97881
|
+
parts.push(`→${stats.outputsProduced}`);
|
|
97882
|
+
}
|
|
97883
|
+
// Critical issues
|
|
97884
|
+
if (stats.issuesBySeverity.critical > 0) {
|
|
97885
|
+
parts.push(`${stats.issuesBySeverity.critical}🔴`);
|
|
97886
|
+
}
|
|
97887
|
+
// Warnings
|
|
97888
|
+
if (stats.issuesBySeverity.warning > 0) {
|
|
97889
|
+
parts.push(`${stats.issuesBySeverity.warning}⚠️`);
|
|
97890
|
+
}
|
|
97891
|
+
// Info (only if no critical/warnings)
|
|
97892
|
+
if (stats.issuesBySeverity.info > 0 &&
|
|
97893
|
+
stats.issuesBySeverity.critical === 0 &&
|
|
97894
|
+
stats.issuesBySeverity.warning === 0) {
|
|
97895
|
+
parts.push(`${stats.issuesBySeverity.info}💡`);
|
|
97896
|
+
}
|
|
97897
|
+
// Error message or skip condition
|
|
97898
|
+
if (stats.errorMessage) {
|
|
97899
|
+
parts.push(this.truncate(stats.errorMessage, 20));
|
|
97900
|
+
}
|
|
97901
|
+
else if (stats.skipCondition) {
|
|
97902
|
+
parts.push(this.truncate(stats.skipCondition, 20));
|
|
97903
|
+
}
|
|
97904
|
+
return parts.join(' ');
|
|
97905
|
+
}
|
|
97906
|
+
/**
|
|
97907
|
+
* Log the execution summary table
|
|
97908
|
+
*/
|
|
97909
|
+
logExecutionSummary(stats) {
|
|
97910
|
+
const totalIssues = stats.checks.reduce((sum, s) => sum + s.issuesFound, 0);
|
|
97911
|
+
const criticalIssues = stats.checks.reduce((sum, s) => sum + s.issuesBySeverity.critical, 0);
|
|
97912
|
+
const warningIssues = stats.checks.reduce((sum, s) => sum + s.issuesBySeverity.warning, 0);
|
|
97913
|
+
const durationSec = (stats.totalDuration / 1000).toFixed(1);
|
|
97914
|
+
// Summary box
|
|
97915
|
+
const summaryTable = new (__nccwpck_require__(25832))({
|
|
97916
|
+
style: {
|
|
97917
|
+
head: [],
|
|
97918
|
+
border: [],
|
|
97919
|
+
},
|
|
97920
|
+
colWidths: [41],
|
|
97921
|
+
});
|
|
97922
|
+
summaryTable.push([`Execution Complete (${durationSec}s)`], [`Checks: ${stats.totalChecksConfigured} configured → ${stats.totalExecutions} executions`], [
|
|
97923
|
+
`Status: ${stats.successfulExecutions} ✔ │ ${stats.failedExecutions} ✖ │ ${stats.skippedChecks} ⏭`,
|
|
97924
|
+
]);
|
|
97925
|
+
if (totalIssues > 0) {
|
|
97926
|
+
let issuesLine = `Issues: ${totalIssues} total`;
|
|
97927
|
+
if (criticalIssues > 0)
|
|
97928
|
+
issuesLine += ` (${criticalIssues} 🔴`;
|
|
97929
|
+
if (warningIssues > 0)
|
|
97930
|
+
issuesLine += `${criticalIssues > 0 ? ' ' : ' ('}${warningIssues} ⚠️)`;
|
|
97931
|
+
else if (criticalIssues > 0)
|
|
97932
|
+
issuesLine += ')';
|
|
97933
|
+
summaryTable.push([issuesLine]);
|
|
97934
|
+
}
|
|
97935
|
+
logger_1.logger.info('');
|
|
97936
|
+
logger_1.logger.info(summaryTable.toString());
|
|
97937
|
+
// Details table
|
|
97938
|
+
logger_1.logger.info('');
|
|
97939
|
+
logger_1.logger.info('Check Details:');
|
|
97940
|
+
const detailsTable = new (__nccwpck_require__(25832))({
|
|
97941
|
+
head: ['Check', 'Duration', 'Status', 'Details'],
|
|
97942
|
+
colWidths: [21, 10, 10, 21],
|
|
97943
|
+
style: {
|
|
97944
|
+
head: ['cyan'],
|
|
97945
|
+
border: ['grey'],
|
|
97946
|
+
},
|
|
97947
|
+
});
|
|
97948
|
+
for (const checkStats of stats.checks) {
|
|
97949
|
+
const duration = checkStats.skipped
|
|
97950
|
+
? '-'
|
|
97951
|
+
: `${(checkStats.totalDuration / 1000).toFixed(1)}s`;
|
|
97952
|
+
const status = this.formatStatusColumn(checkStats);
|
|
97953
|
+
const details = this.formatDetailsColumn(checkStats);
|
|
97954
|
+
detailsTable.push([checkStats.checkName, duration, status, details]);
|
|
97955
|
+
}
|
|
97956
|
+
logger_1.logger.info(detailsTable.toString());
|
|
97957
|
+
// Legend
|
|
97958
|
+
logger_1.logger.info('');
|
|
97959
|
+
logger_1.logger.info('Legend: ✔=success │ ✖=failed │ ⏭=skipped │ ×N=iterations │ →N=outputs │ N🔴=critical │ N⚠️=warnings');
|
|
97960
|
+
}
|
|
97669
97961
|
}
|
|
97670
97962
|
exports.CheckExecutionEngine = CheckExecutionEngine;
|
|
97671
97963
|
|
|
@@ -97752,7 +98044,15 @@ async function main() {
|
|
|
97752
98044
|
console.log(cli.getVersion());
|
|
97753
98045
|
process.exit(0);
|
|
97754
98046
|
}
|
|
98047
|
+
// Configure logger based on output format and verbosity
|
|
98048
|
+
logger_1.logger.configure({
|
|
98049
|
+
outputFormat: options.output,
|
|
98050
|
+
debug: options.debug,
|
|
98051
|
+
verbose: options.verbose,
|
|
98052
|
+
quiet: options.quiet,
|
|
98053
|
+
});
|
|
97755
98054
|
// Print runtime banner (info level): Visor + Probe versions
|
|
98055
|
+
// Banner is automatically suppressed for JSON/SARIF by logger configuration
|
|
97756
98056
|
try {
|
|
97757
98057
|
const visorVersion = process.env.VISOR_VERSION || ((__nccwpck_require__(8330)/* .version */ .rE) ?? 'dev');
|
|
97758
98058
|
let probeVersion = process.env.PROBE_VERSION || 'unknown';
|
|
@@ -97920,7 +98220,9 @@ async function main() {
|
|
|
97920
98220
|
const prInfoWithContext = prInfo;
|
|
97921
98221
|
prInfoWithContext.includeCodeContext = includeCodeContext;
|
|
97922
98222
|
// Execute checks with proper parameters
|
|
97923
|
-
const
|
|
98223
|
+
const executionResult = await engine.executeGroupedChecks(prInfo, checksToRun, options.timeout, config, options.output, options.debug || false, options.maxParallelism, options.failFast, tagFilter);
|
|
98224
|
+
// Extract results and statistics from the execution result
|
|
98225
|
+
const { results: groupedResults, statistics: executionStatistics } = executionResult;
|
|
97924
98226
|
const shouldFilterResults = explicitChecks && explicitChecks.size > 0 && !explicitChecks.has('all');
|
|
97925
98227
|
const groupedResultsToUse = shouldFilterResults
|
|
97926
98228
|
? Object.fromEntries(Object.entries(groupedResults)
|
|
@@ -97945,7 +98247,8 @@ async function main() {
|
|
|
97945
98247
|
}
|
|
97946
98248
|
}
|
|
97947
98249
|
}
|
|
97948
|
-
|
|
98250
|
+
// Get executed check names
|
|
98251
|
+
const executedCheckNames = Array.from(new Set(Object.entries(groupedResultsToUse).flatMap(([, checks]) => checks.map(check => check.checkName))));
|
|
97949
98252
|
// Format output based on format type
|
|
97950
98253
|
logger_1.logger.step(`Formatting results as ${options.output}`);
|
|
97951
98254
|
let output;
|
|
@@ -97958,12 +98261,14 @@ async function main() {
|
|
|
97958
98261
|
repositoryInfo,
|
|
97959
98262
|
reviewSummary: {
|
|
97960
98263
|
issues: Object.values(groupedResultsToUse)
|
|
97961
|
-
.flatMap(
|
|
98264
|
+
.flatMap(checks => checks.flatMap(check => check.issues || []))
|
|
97962
98265
|
.flat(),
|
|
97963
98266
|
},
|
|
97964
98267
|
executionTime: 0,
|
|
97965
98268
|
timestamp: new Date().toISOString(),
|
|
97966
98269
|
checksExecuted: executedCheckNames,
|
|
98270
|
+
executionStatistics,
|
|
98271
|
+
isCodeReview: includeCodeContext,
|
|
97967
98272
|
};
|
|
97968
98273
|
output = output_formatters_1.OutputFormatters.formatAsSarif(analysisResult);
|
|
97969
98274
|
}
|
|
@@ -97973,12 +98278,14 @@ async function main() {
|
|
|
97973
98278
|
repositoryInfo,
|
|
97974
98279
|
reviewSummary: {
|
|
97975
98280
|
issues: Object.values(groupedResultsToUse)
|
|
97976
|
-
.flatMap(
|
|
98281
|
+
.flatMap(checks => checks.flatMap(check => check.issues || []))
|
|
97977
98282
|
.flat(),
|
|
97978
98283
|
},
|
|
97979
98284
|
executionTime: 0,
|
|
97980
98285
|
timestamp: new Date().toISOString(),
|
|
97981
98286
|
checksExecuted: executedCheckNames,
|
|
98287
|
+
executionStatistics,
|
|
98288
|
+
isCodeReview: includeCodeContext,
|
|
97982
98289
|
};
|
|
97983
98290
|
output = output_formatters_1.OutputFormatters.formatAsMarkdown(analysisResult);
|
|
97984
98291
|
}
|
|
@@ -97988,12 +98295,14 @@ async function main() {
|
|
|
97988
98295
|
repositoryInfo,
|
|
97989
98296
|
reviewSummary: {
|
|
97990
98297
|
issues: Object.values(groupedResultsToUse)
|
|
97991
|
-
.flatMap(
|
|
98298
|
+
.flatMap(checks => checks.flatMap(check => check.issues || []))
|
|
97992
98299
|
.flat(),
|
|
97993
98300
|
},
|
|
97994
98301
|
executionTime: 0,
|
|
97995
98302
|
timestamp: new Date().toISOString(),
|
|
97996
98303
|
checksExecuted: executedCheckNames,
|
|
98304
|
+
executionStatistics,
|
|
98305
|
+
isCodeReview: includeCodeContext,
|
|
97997
98306
|
};
|
|
97998
98307
|
output = output_formatters_1.OutputFormatters.formatAsTable(analysisResult, { showDetails: true });
|
|
97999
98308
|
}
|
|
@@ -98014,7 +98323,7 @@ async function main() {
|
|
|
98014
98323
|
console.log(output);
|
|
98015
98324
|
}
|
|
98016
98325
|
// Summarize execution (stderr only; suppressed in JSON/SARIF unless verbose/debug)
|
|
98017
|
-
const allResults = Object.values(groupedResultsToUse).
|
|
98326
|
+
const allResults = Object.values(groupedResultsToUse).flatMap(checks => checks);
|
|
98018
98327
|
const allIssues = allResults.flatMap((r) => r.issues || []);
|
|
98019
98328
|
const counts = allIssues.reduce((acc, issue) => {
|
|
98020
98329
|
const sev = (issue.severity || 'info').toLowerCase();
|
|
@@ -98168,6 +98477,7 @@ class CLI {
|
|
|
98168
98477
|
.option('--no-remote-extends', 'Disable loading configurations from remote URLs')
|
|
98169
98478
|
.option('--enable-code-context', 'Force include code diffs in analysis (CLI mode)')
|
|
98170
98479
|
.option('--disable-code-context', 'Force exclude code diffs from analysis (CLI mode)')
|
|
98480
|
+
.option('--mode <mode>', 'Run mode (cli|github-actions). Default: cli')
|
|
98171
98481
|
.addHelpText('after', this.getExamplesText())
|
|
98172
98482
|
.exitOverride(); // Prevent automatic process.exit for better error handling
|
|
98173
98483
|
// Add validation for options
|
|
@@ -98210,6 +98520,7 @@ class CLI {
|
|
|
98210
98520
|
.option('--allowed-remote-patterns <patterns>', 'Comma-separated list of allowed URL prefixes for remote config extends (e.g., "https://github.com/,https://raw.githubusercontent.com/")')
|
|
98211
98521
|
.option('--enable-code-context', 'Force include code diffs in analysis (CLI mode)')
|
|
98212
98522
|
.option('--disable-code-context', 'Force exclude code diffs from analysis (CLI mode)')
|
|
98523
|
+
.option('--mode <mode>', 'Run mode (cli|github-actions). Default: cli')
|
|
98213
98524
|
.allowUnknownOption(false)
|
|
98214
98525
|
.allowExcessArguments(false) // Don't allow positional arguments
|
|
98215
98526
|
.addHelpText('after', this.getExamplesText())
|
|
@@ -98340,6 +98651,7 @@ class CLI {
|
|
|
98340
98651
|
.option('--exclude-tags <tags>', 'Exclude checks with these tags (comma-separated)')
|
|
98341
98652
|
.option('--enable-code-context', 'Force include code diffs in analysis (CLI mode)')
|
|
98342
98653
|
.option('--disable-code-context', 'Force exclude code diffs from analysis (CLI mode)')
|
|
98654
|
+
.option('--mode <mode>', 'Run mode (cli|github-actions). Default: cli')
|
|
98343
98655
|
.addHelpText('after', this.getExamplesText());
|
|
98344
98656
|
// Get the basic help and append examples manually if addHelpText doesn't work
|
|
98345
98657
|
const basicHelp = tempProgram.helpInformation();
|
|
@@ -101537,14 +101849,15 @@ async function handleIssueEvent(octokit, owner, repo, context, inputs, config, c
|
|
|
101537
101849
|
const { CheckExecutionEngine } = await Promise.resolve().then(() => __importStar(__nccwpck_require__(80299)));
|
|
101538
101850
|
const engine = new CheckExecutionEngine();
|
|
101539
101851
|
try {
|
|
101540
|
-
const
|
|
101852
|
+
const executionResult = await engine.executeGroupedChecks(prInfo, checksToRun, undefined, // timeout
|
|
101541
101853
|
config, undefined, // outputFormat
|
|
101542
101854
|
inputs.debug === 'true');
|
|
101855
|
+
const { results } = executionResult;
|
|
101543
101856
|
// Format and post results as a comment on the issue
|
|
101544
|
-
if (Object.keys(
|
|
101857
|
+
if (Object.keys(results).length > 0) {
|
|
101545
101858
|
let commentBody = '';
|
|
101546
101859
|
// Directly use check content without adding extra headers
|
|
101547
|
-
for (const checks of Object.values(
|
|
101860
|
+
for (const checks of Object.values(results)) {
|
|
101548
101861
|
for (const check of checks) {
|
|
101549
101862
|
if (check.content && check.content.trim()) {
|
|
101550
101863
|
commentBody += `${check.content}\n\n`;
|
|
@@ -101803,7 +102116,7 @@ async function handleIssueComment(octokit, owner, repo, context, inputs, actionC
|
|
|
101803
102116
|
console.log('📝 Skipping comment (comment-on-pr is disabled)');
|
|
101804
102117
|
}
|
|
101805
102118
|
// Calculate total check results from grouped results
|
|
101806
|
-
const totalChecks = Object.values(groupedResults).
|
|
102119
|
+
const totalChecks = Object.values(groupedResults).flatMap(checks => checks).length;
|
|
101807
102120
|
(0, core_1.setOutput)('checks-executed', totalChecks.toString());
|
|
101808
102121
|
}
|
|
101809
102122
|
break;
|
|
@@ -102123,7 +102436,7 @@ async function completeGitHubChecks(octokit, owner, repo, checkRunMap, groupedRe
|
|
|
102123
102436
|
*/
|
|
102124
102437
|
function extractIssuesFromGroupedResults(groupedResults) {
|
|
102125
102438
|
const issues = [];
|
|
102126
|
-
for (const
|
|
102439
|
+
for (const checkResults of Object.values(groupedResults)) {
|
|
102127
102440
|
for (const checkResult of checkResults) {
|
|
102128
102441
|
const { checkName, content } = checkResult;
|
|
102129
102442
|
// First, check if structured issues are available
|
|
@@ -102152,7 +102465,7 @@ function extractIssuesFromGroupedResults(groupedResults) {
|
|
|
102152
102465
|
message: message.trim(),
|
|
102153
102466
|
severity,
|
|
102154
102467
|
category: 'logic', // Default category since we can't parse this from content
|
|
102155
|
-
group:
|
|
102468
|
+
group: checkResult.group,
|
|
102156
102469
|
timestamp: Date.now(),
|
|
102157
102470
|
};
|
|
102158
102471
|
issues.push(issue);
|
|
@@ -102284,15 +102597,31 @@ async function markCheckAsFailed(checkService, owner, repo, checkRunId, checkNam
|
|
|
102284
102597
|
// Only execute if not in test environment
|
|
102285
102598
|
if (process.env.NODE_ENV !== 'test' && process.env.JEST_WORKER_ID === undefined) {
|
|
102286
102599
|
(() => {
|
|
102287
|
-
//
|
|
102288
|
-
//
|
|
102289
|
-
const
|
|
102290
|
-
|
|
102291
|
-
|
|
102600
|
+
// Explicit, argument-driven mode selection. No auto-detection of GitHub Actions.
|
|
102601
|
+
// Priority order: --mode flag > VISOR_MODE env > INPUT_MODE env > default 'cli'.
|
|
102602
|
+
const argv = process.argv;
|
|
102603
|
+
let modeFromArg;
|
|
102604
|
+
for (let i = 0; i < argv.length; i++) {
|
|
102605
|
+
const arg = argv[i];
|
|
102606
|
+
if (arg === '--mode' && i + 1 < argv.length) {
|
|
102607
|
+
modeFromArg = argv[i + 1];
|
|
102608
|
+
break;
|
|
102609
|
+
}
|
|
102610
|
+
else if (arg.startsWith('--mode=')) {
|
|
102611
|
+
modeFromArg = arg.split('=')[1];
|
|
102612
|
+
break;
|
|
102613
|
+
}
|
|
102614
|
+
}
|
|
102615
|
+
const mode = (modeFromArg || process.env.VISOR_MODE || process.env.INPUT_MODE || 'cli')
|
|
102616
|
+
.toString()
|
|
102617
|
+
.toLowerCase();
|
|
102618
|
+
const isGitHubMode = mode === 'github-actions' || mode === 'github';
|
|
102619
|
+
if (isGitHubMode) {
|
|
102620
|
+
// Run in GitHub Action mode explicitly
|
|
102292
102621
|
run();
|
|
102293
102622
|
}
|
|
102294
102623
|
else {
|
|
102295
|
-
//
|
|
102624
|
+
// Default to CLI mode
|
|
102296
102625
|
Promise.resolve().then(() => __importStar(__nccwpck_require__(10091))).then(({ main }) => {
|
|
102297
102626
|
main().catch(error => {
|
|
102298
102627
|
console.error('CLI execution failed:', error);
|
|
@@ -102716,19 +103045,35 @@ class OutputFormatters {
|
|
|
102716
103045
|
const issues = result.reviewSummary.issues || [];
|
|
102717
103046
|
const totalIssues = issues.length;
|
|
102718
103047
|
const criticalIssues = issues.filter(i => i.severity === 'critical').length;
|
|
102719
|
-
//
|
|
102720
|
-
const
|
|
102721
|
-
|
|
102722
|
-
|
|
102723
|
-
|
|
102724
|
-
|
|
102725
|
-
|
|
102726
|
-
|
|
102727
|
-
|
|
102728
|
-
|
|
102729
|
-
|
|
102730
|
-
|
|
102731
|
-
|
|
103048
|
+
// Check if this is a code review context
|
|
103049
|
+
const isCodeReview = result.isCodeReview || issues.some(i => i.schema === 'code-review');
|
|
103050
|
+
// Only show "Analysis Summary" table for code review contexts or when there are issues
|
|
103051
|
+
// For other contexts, the execution statistics table already provides summary
|
|
103052
|
+
if (isCodeReview || totalIssues > 0) {
|
|
103053
|
+
// Summary table
|
|
103054
|
+
const summaryTable = new cli_table3_1.default({
|
|
103055
|
+
head: ['Metric', 'Value'],
|
|
103056
|
+
colWidths: [25, 30],
|
|
103057
|
+
style: {
|
|
103058
|
+
head: ['cyan', 'bold'],
|
|
103059
|
+
border: ['grey'],
|
|
103060
|
+
},
|
|
103061
|
+
});
|
|
103062
|
+
// Add issue metrics
|
|
103063
|
+
summaryTable.push(['Total Issues', totalIssues.toString()]);
|
|
103064
|
+
if (criticalIssues > 0) {
|
|
103065
|
+
summaryTable.push(['Critical Issues', criticalIssues.toString()]);
|
|
103066
|
+
}
|
|
103067
|
+
// Add code-review specific metrics if in code review context
|
|
103068
|
+
if (isCodeReview && result.repositoryInfo.files.length > 0) {
|
|
103069
|
+
summaryTable.push(['Files Analyzed', result.repositoryInfo.files.length.toString()], ['Total Additions', result.repositoryInfo.totalAdditions.toString()], ['Total Deletions', result.repositoryInfo.totalDeletions.toString()]);
|
|
103070
|
+
}
|
|
103071
|
+
// Always show execution time and checks executed
|
|
103072
|
+
summaryTable.push(['Execution Time', `${result.executionTime}ms`], ['Checks Executed', result.checksExecuted.join(', ')]);
|
|
103073
|
+
output += 'Analysis Summary\n';
|
|
103074
|
+
output += summaryTable.toString() + '\n';
|
|
103075
|
+
output += '\n';
|
|
103076
|
+
}
|
|
102732
103077
|
// Issues by category table
|
|
102733
103078
|
if (issues.length > 0) {
|
|
102734
103079
|
if (groupByCategory) {
|
|
@@ -106563,8 +106908,8 @@ class PRReviewer {
|
|
|
106563
106908
|
if (config && checks && checks.length > 0) {
|
|
106564
106909
|
const { CheckExecutionEngine } = await Promise.resolve().then(() => __importStar(__nccwpck_require__(80299)));
|
|
106565
106910
|
const engine = new CheckExecutionEngine();
|
|
106566
|
-
const
|
|
106567
|
-
return
|
|
106911
|
+
const { results } = await engine.executeGroupedChecks(prInfo, checks, undefined, config, undefined, debug);
|
|
106912
|
+
return results;
|
|
106568
106913
|
}
|
|
106569
106914
|
throw new Error('No configuration provided. Please create a .visor.yaml file with check definitions. ' +
|
|
106570
106915
|
'Built-in prompts have been removed - all checks must be explicitly configured.');
|
|
@@ -156734,14 +157079,53 @@ var init_probeTool = __esm({
|
|
|
156734
157079
|
if (!targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
|
|
156735
157080
|
throw new Error("Path traversal attempt detected. Access denied.");
|
|
156736
157081
|
}
|
|
157082
|
+
const debug = process.env.DEBUG === "1";
|
|
157083
|
+
if (debug) {
|
|
157084
|
+
console.log(`[DEBUG] Listing files in directory: ${targetDir}`);
|
|
157085
|
+
}
|
|
156737
157086
|
try {
|
|
156738
|
-
const files = await
|
|
156739
|
-
|
|
156740
|
-
|
|
156741
|
-
|
|
156742
|
-
|
|
157087
|
+
const files = await import_fs4.promises.readdir(targetDir, { withFileTypes: true });
|
|
157088
|
+
const formatSize = (size) => {
|
|
157089
|
+
if (size < 1024) return `${size}B`;
|
|
157090
|
+
if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)}K`;
|
|
157091
|
+
if (size < 1024 * 1024 * 1024) return `${(size / (1024 * 1024)).toFixed(1)}M`;
|
|
157092
|
+
return `${(size / (1024 * 1024 * 1024)).toFixed(1)}G`;
|
|
157093
|
+
};
|
|
157094
|
+
const entries = await Promise.all(files.map(async (file) => {
|
|
157095
|
+
const isDirectory = file.isDirectory();
|
|
157096
|
+
const fullPath = import_path7.default.join(targetDir, file.name);
|
|
157097
|
+
let size = 0;
|
|
157098
|
+
try {
|
|
157099
|
+
const stats = await import_fs4.promises.stat(fullPath);
|
|
157100
|
+
size = stats.size;
|
|
157101
|
+
} catch (statError) {
|
|
157102
|
+
if (debug) {
|
|
157103
|
+
console.log(`[DEBUG] Could not stat file ${file.name}:`, statError.message);
|
|
157104
|
+
}
|
|
157105
|
+
}
|
|
157106
|
+
return {
|
|
157107
|
+
name: file.name,
|
|
157108
|
+
isDirectory,
|
|
157109
|
+
size
|
|
157110
|
+
};
|
|
157111
|
+
}));
|
|
157112
|
+
entries.sort((a3, b3) => {
|
|
157113
|
+
if (a3.isDirectory && !b3.isDirectory) return -1;
|
|
157114
|
+
if (!a3.isDirectory && b3.isDirectory) return 1;
|
|
157115
|
+
return a3.name.localeCompare(b3.name);
|
|
156743
157116
|
});
|
|
156744
|
-
|
|
157117
|
+
const formatted = entries.map((entry) => {
|
|
157118
|
+
const type = entry.isDirectory ? "dir " : "file";
|
|
157119
|
+
const sizeStr = formatSize(entry.size).padStart(8);
|
|
157120
|
+
return `${type} ${sizeStr} ${entry.name}`;
|
|
157121
|
+
});
|
|
157122
|
+
if (debug) {
|
|
157123
|
+
console.log(`[DEBUG] Found ${entries.length} files/directories in ${targetDir}`);
|
|
157124
|
+
}
|
|
157125
|
+
const header = `${targetDir}:
|
|
157126
|
+
`;
|
|
157127
|
+
const output = header + formatted.join("\n");
|
|
157128
|
+
return output;
|
|
156745
157129
|
} catch (error2) {
|
|
156746
157130
|
throw new Error(`Failed to list files: ${error2.message}`);
|
|
156747
157131
|
}
|
|
@@ -156759,6 +157143,9 @@ var init_probeTool = __esm({
|
|
|
156759
157143
|
if (!targetDir.startsWith(secureBaseDir + import_path7.default.sep) && targetDir !== secureBaseDir) {
|
|
156760
157144
|
throw new Error("Path traversal attempt detected. Access denied.");
|
|
156761
157145
|
}
|
|
157146
|
+
if (pattern.includes("**/**") || pattern.split("*").length > 10) {
|
|
157147
|
+
throw new Error("Pattern too complex. Please use a simpler glob pattern.");
|
|
157148
|
+
}
|
|
156762
157149
|
try {
|
|
156763
157150
|
const options = {
|
|
156764
157151
|
cwd: targetDir,
|
|
@@ -156768,7 +157155,17 @@ var init_probeTool = __esm({
|
|
|
156768
157155
|
if (!recursive) {
|
|
156769
157156
|
options.deep = 1;
|
|
156770
157157
|
}
|
|
156771
|
-
const
|
|
157158
|
+
const timeoutPromise = new Promise((_2, reject2) => {
|
|
157159
|
+
setTimeout(() => reject2(new Error("Search operation timed out after 10 seconds")), 1e4);
|
|
157160
|
+
});
|
|
157161
|
+
const files = await Promise.race([
|
|
157162
|
+
(0, import_glob.glob)(pattern, options),
|
|
157163
|
+
timeoutPromise
|
|
157164
|
+
]);
|
|
157165
|
+
const maxResults = 1e3;
|
|
157166
|
+
if (files.length > maxResults) {
|
|
157167
|
+
return files.slice(0, maxResults);
|
|
157168
|
+
}
|
|
156772
157169
|
return files;
|
|
156773
157170
|
} catch (error2) {
|
|
156774
157171
|
throw new Error(`Failed to search files: ${error2.message}`);
|
|
@@ -184172,8 +184569,8 @@ When presented with a broken Mermaid diagram, analyze it thoroughly and provide
|
|
|
184172
184569
|
debug: this.options.debug,
|
|
184173
184570
|
tracer: this.options.tracer,
|
|
184174
184571
|
allowEdit: this.options.allowEdit,
|
|
184175
|
-
maxIterations:
|
|
184176
|
-
//
|
|
184572
|
+
maxIterations: 10,
|
|
184573
|
+
// Allow more iterations for mermaid fixing to handle complex diagrams
|
|
184177
184574
|
disableMermaidValidation: true
|
|
184178
184575
|
// CRITICAL: Disable mermaid validation in nested agent to prevent infinite recursion
|
|
184179
184576
|
});
|
|
@@ -185073,6 +185470,18 @@ var init_ProbeAgent = __esm({
|
|
|
185073
185470
|
this.toolImplementations.bash = wrappedTools.bashToolInstance;
|
|
185074
185471
|
}
|
|
185075
185472
|
this.wrappedTools = wrappedTools;
|
|
185473
|
+
if (this.debug) {
|
|
185474
|
+
console.error("\n[DEBUG] ========================================");
|
|
185475
|
+
console.error("[DEBUG] ProbeAgent Tools Initialized");
|
|
185476
|
+
console.error("[DEBUG] Session ID:", this.sessionId);
|
|
185477
|
+
console.error("[DEBUG] Available tools:");
|
|
185478
|
+
for (const toolName of Object.keys(this.toolImplementations)) {
|
|
185479
|
+
console.error(`[DEBUG] - ${toolName}`);
|
|
185480
|
+
}
|
|
185481
|
+
console.error("[DEBUG] Allowed folders:", this.allowedFolders);
|
|
185482
|
+
console.error("[DEBUG] Outline mode:", this.outline);
|
|
185483
|
+
console.error("[DEBUG] ========================================\n");
|
|
185484
|
+
}
|
|
185076
185485
|
}
|
|
185077
185486
|
/**
|
|
185078
185487
|
* Initialize the AI model based on available API keys and forced provider setting
|
|
@@ -185843,12 +186252,28 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
185843
186252
|
const { type } = parsedTool;
|
|
185844
186253
|
if (type === "mcp" && this.mcpBridge && this.mcpBridge.isMcpTool(toolName)) {
|
|
185845
186254
|
try {
|
|
185846
|
-
if (this.debug)
|
|
186255
|
+
if (this.debug) {
|
|
186256
|
+
console.error(`
|
|
186257
|
+
[DEBUG] ========================================`);
|
|
186258
|
+
console.error(`[DEBUG] Executing MCP tool: ${toolName}`);
|
|
186259
|
+
console.error(`[DEBUG] Arguments:`);
|
|
186260
|
+
for (const [key, value] of Object.entries(params)) {
|
|
186261
|
+
const displayValue = typeof value === "string" && value.length > 100 ? value.substring(0, 100) + "..." : value;
|
|
186262
|
+
console.error(`[DEBUG] ${key}: ${JSON.stringify(displayValue)}`);
|
|
186263
|
+
}
|
|
186264
|
+
console.error(`[DEBUG] ========================================
|
|
186265
|
+
`);
|
|
186266
|
+
}
|
|
185847
186267
|
const executionResult = await this.mcpBridge.mcpTools[toolName].execute(params);
|
|
185848
186268
|
const toolResultContent = typeof executionResult === "string" ? executionResult : JSON.stringify(executionResult, null, 2);
|
|
185849
|
-
const preview = createMessagePreview(toolResultContent);
|
|
185850
186269
|
if (this.debug) {
|
|
185851
|
-
|
|
186270
|
+
const preview = toolResultContent.length > 500 ? toolResultContent.substring(0, 500) + "..." : toolResultContent;
|
|
186271
|
+
console.error(`[DEBUG] ========================================`);
|
|
186272
|
+
console.error(`[DEBUG] MCP tool '${toolName}' completed successfully`);
|
|
186273
|
+
console.error(`[DEBUG] Result preview:`);
|
|
186274
|
+
console.error(preview);
|
|
186275
|
+
console.error(`[DEBUG] ========================================
|
|
186276
|
+
`);
|
|
185852
186277
|
}
|
|
185853
186278
|
currentMessages.push({ role: "user", content: `<tool_result>
|
|
185854
186279
|
${toolResultContent}
|
|
@@ -185856,7 +186281,13 @@ ${toolResultContent}
|
|
|
185856
186281
|
} catch (error2) {
|
|
185857
186282
|
console.error(`Error executing MCP tool ${toolName}:`, error2);
|
|
185858
186283
|
const toolResultContent = `Error executing MCP tool ${toolName}: ${error2.message}`;
|
|
185859
|
-
if (this.debug)
|
|
186284
|
+
if (this.debug) {
|
|
186285
|
+
console.error(`[DEBUG] ========================================`);
|
|
186286
|
+
console.error(`[DEBUG] MCP tool '${toolName}' failed with error:`);
|
|
186287
|
+
console.error(`[DEBUG] ${error2.message}`);
|
|
186288
|
+
console.error(`[DEBUG] ========================================
|
|
186289
|
+
`);
|
|
186290
|
+
}
|
|
185860
186291
|
currentMessages.push({ role: "user", content: `<tool_result>
|
|
185861
186292
|
${toolResultContent}
|
|
185862
186293
|
</tool_result>` });
|
|
@@ -185868,6 +186299,18 @@ ${toolResultContent}
|
|
|
185868
186299
|
sessionId: this.sessionId,
|
|
185869
186300
|
workingDirectory: this.allowedFolders && this.allowedFolders[0] || process.cwd()
|
|
185870
186301
|
};
|
|
186302
|
+
if (this.debug) {
|
|
186303
|
+
console.error(`
|
|
186304
|
+
[DEBUG] ========================================`);
|
|
186305
|
+
console.error(`[DEBUG] Executing tool: ${toolName}`);
|
|
186306
|
+
console.error(`[DEBUG] Arguments:`);
|
|
186307
|
+
for (const [key, value] of Object.entries(params)) {
|
|
186308
|
+
const displayValue = typeof value === "string" && value.length > 100 ? value.substring(0, 100) + "..." : value;
|
|
186309
|
+
console.error(`[DEBUG] ${key}: ${JSON.stringify(displayValue)}`);
|
|
186310
|
+
}
|
|
186311
|
+
console.error(`[DEBUG] ========================================
|
|
186312
|
+
`);
|
|
186313
|
+
}
|
|
185871
186314
|
this.events.emit("toolCall", {
|
|
185872
186315
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
185873
186316
|
name: toolName,
|
|
@@ -185909,6 +186352,15 @@ ${toolResultContent}
|
|
|
185909
186352
|
} else {
|
|
185910
186353
|
toolResult = await executeToolCall();
|
|
185911
186354
|
}
|
|
186355
|
+
if (this.debug) {
|
|
186356
|
+
const resultPreview = typeof toolResult === "string" ? toolResult.length > 500 ? toolResult.substring(0, 500) + "..." : toolResult : toolResult ? JSON.stringify(toolResult, null, 2).substring(0, 500) + "..." : "No Result";
|
|
186357
|
+
console.error(`[DEBUG] ========================================`);
|
|
186358
|
+
console.error(`[DEBUG] Tool '${toolName}' completed successfully`);
|
|
186359
|
+
console.error(`[DEBUG] Result preview:`);
|
|
186360
|
+
console.error(resultPreview);
|
|
186361
|
+
console.error(`[DEBUG] ========================================
|
|
186362
|
+
`);
|
|
186363
|
+
}
|
|
185912
186364
|
this.events.emit("toolCall", {
|
|
185913
186365
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
185914
186366
|
name: toolName,
|
|
@@ -185917,6 +186369,13 @@ ${toolResultContent}
|
|
|
185917
186369
|
status: "completed"
|
|
185918
186370
|
});
|
|
185919
186371
|
} catch (toolError) {
|
|
186372
|
+
if (this.debug) {
|
|
186373
|
+
console.error(`[DEBUG] ========================================`);
|
|
186374
|
+
console.error(`[DEBUG] Tool '${toolName}' failed with error:`);
|
|
186375
|
+
console.error(`[DEBUG] ${toolError.message}`);
|
|
186376
|
+
console.error(`[DEBUG] ========================================
|
|
186377
|
+
`);
|
|
186378
|
+
}
|
|
185920
186379
|
this.events.emit("toolCall", {
|
|
185921
186380
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
185922
186381
|
name: toolName,
|
|
@@ -185966,6 +186425,16 @@ Error: Unknown tool '${toolName}'. Available tools: ${allAvailableTools.join(",
|
|
|
185966
186425
|
}
|
|
185967
186426
|
}
|
|
185968
186427
|
} else {
|
|
186428
|
+
const hasMermaidCodeBlock = /```mermaid\s*\n[\s\S]*?\n```/.test(assistantResponseContent);
|
|
186429
|
+
const hasNoSchemaOrTools = !options.schema && validTools.length === 0;
|
|
186430
|
+
if (hasMermaidCodeBlock && hasNoSchemaOrTools) {
|
|
186431
|
+
finalResult = assistantResponseContent;
|
|
186432
|
+
completionAttempted = true;
|
|
186433
|
+
if (this.debug) {
|
|
186434
|
+
console.error(`[DEBUG] Accepting mermaid code block as valid completion (no schema, no tools)`);
|
|
186435
|
+
}
|
|
186436
|
+
break;
|
|
186437
|
+
}
|
|
185969
186438
|
currentMessages.push({ role: "assistant", content: assistantResponseContent });
|
|
185970
186439
|
let reminderContent;
|
|
185971
186440
|
if (options.schema) {
|
|
@@ -186679,12 +187148,14 @@ __export(index_exports, {
|
|
|
186679
187148
|
getBinaryPath: () => getBinaryPath,
|
|
186680
187149
|
initializeSimpleTelemetryFromOptions: () => initializeSimpleTelemetryFromOptions,
|
|
186681
187150
|
listFilesByLevel: () => listFilesByLevel,
|
|
187151
|
+
listFilesToolInstance: () => listFilesToolInstance,
|
|
186682
187152
|
parseXmlToolCall: () => parseXmlToolCall,
|
|
186683
187153
|
query: () => query,
|
|
186684
187154
|
querySchema: () => querySchema,
|
|
186685
187155
|
queryTool: () => queryTool,
|
|
186686
187156
|
queryToolDefinition: () => queryToolDefinition,
|
|
186687
187157
|
search: () => search,
|
|
187158
|
+
searchFilesToolInstance: () => searchFilesToolInstance,
|
|
186688
187159
|
searchSchema: () => searchSchema,
|
|
186689
187160
|
searchTool: () => searchTool,
|
|
186690
187161
|
searchToolDefinition: () => searchToolDefinition,
|
|
@@ -186707,6 +187178,7 @@ var init_index = __esm({
|
|
|
186707
187178
|
init_bash();
|
|
186708
187179
|
init_ProbeAgent();
|
|
186709
187180
|
init_simpleTelemetry();
|
|
187181
|
+
init_probeTool();
|
|
186710
187182
|
}
|
|
186711
187183
|
});
|
|
186712
187184
|
init_index();
|
|
@@ -216788,7 +217260,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"application/1d-interleaved-parityfec
|
|
|
216788
217260
|
/***/ ((module) => {
|
|
216789
217261
|
|
|
216790
217262
|
"use strict";
|
|
216791
|
-
module.exports = {"rE":"0.1.
|
|
217263
|
+
module.exports = {"rE":"0.1.74"};
|
|
216792
217264
|
|
|
216793
217265
|
/***/ })
|
|
216794
217266
|
|