@probelabs/visor 0.1.72 → 0.1.73

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.
@@ -7,8 +7,10 @@ export interface AnalysisResult {
7
7
  executionTime: number;
8
8
  timestamp: string;
9
9
  checksExecuted: string[];
10
+ executionStatistics?: import('./check-execution-engine').ExecutionStatistics;
10
11
  debug?: DebugInfo;
11
12
  failureConditions?: FailureConditionResult[];
13
+ isCodeReview?: boolean;
12
14
  }
13
15
  export interface DebugInfo {
14
16
  provider?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/output-formatters.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EAMd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,iBAAiB,CAAC;IAClC,aAAa,EAAE,aAAa,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,iBAAiB,CAAC,EAAE,sBAAsB,EAAE,CAAC;CAC9C;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,KAAK,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,qBAAa,gBAAgB;IAC3B;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,sBAA2B,GAAG,MAAM;IA2K1F;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,sBAA2B,GAAG,MAAM;IAoCzF;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,GAAE,sBAA2B,GAAG,MAAM;IAmI3F;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,sBAA2B,GAAG,MAAM;IAuN7F,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAqBtC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAc7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAsBpC,OAAO,CAAC,MAAM,CAAC,cAAc;IAU7B,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAUjC,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAU/B,OAAO,CAAC,MAAM,CAAC,YAAY;IAK3B,OAAO,CAAC,MAAM,CAAC,QAAQ;CAmBxB"}
1
+ {"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/output-formatters.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EAMd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,iBAAiB,CAAC;IAClC,aAAa,EAAE,aAAa,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,mBAAmB,CAAC,EAAE,OAAO,0BAA0B,EAAE,mBAAmB,CAAC;IAC7E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,iBAAiB,CAAC,EAAE,sBAAsB,EAAE,CAAC;IAC7C,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,KAAK,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,qBAAa,gBAAgB;IAC3B;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,sBAA2B,GAAG,MAAM;IA8L1F;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,sBAA2B,GAAG,MAAM;IAoCzF;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,GAAE,sBAA2B,GAAG,MAAM;IAmI3F;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,sBAA2B,GAAG,MAAM;IAuN7F,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAqBtC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAc7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAsBpC,OAAO,CAAC,MAAM,CAAC,cAAc;IAU7B,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAUjC,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAU/B,OAAO,CAAC,MAAM,CAAC,YAAY;IAK3B,OAAO,CAAC,MAAM,CAAC,QAAQ;CAmBxB"}
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  CheckExecutionEngine
3
- } from "./chunk-J355UUEI.mjs";
3
+ } from "./chunk-NINHE4RF.mjs";
4
4
  import "./chunk-FIL2OGF6.mjs";
5
5
  import "./chunk-WMJKH4XE.mjs";
6
6
  export {
7
7
  CheckExecutionEngine
8
8
  };
9
- //# sourceMappingURL=check-execution-engine-RXV4MUD2.mjs.map
9
+ //# sourceMappingURL=check-execution-engine-75SSXUBP.mjs.map
@@ -1493,9 +1493,9 @@ var PRReviewer = class {
1493
1493
  async reviewPR(owner, repo, prNumber, prInfo, options = {}) {
1494
1494
  const { debug = false, config, checks } = options;
1495
1495
  if (config && checks && checks.length > 0) {
1496
- const { CheckExecutionEngine: CheckExecutionEngine2 } = await import("./check-execution-engine-RXV4MUD2.mjs");
1496
+ const { CheckExecutionEngine: CheckExecutionEngine2 } = await import("./check-execution-engine-75SSXUBP.mjs");
1497
1497
  const engine = new CheckExecutionEngine2();
1498
- const groupedResults = await engine.executeGroupedChecks(
1498
+ const { results } = await engine.executeGroupedChecks(
1499
1499
  prInfo,
1500
1500
  checks,
1501
1501
  void 0,
@@ -1503,7 +1503,7 @@ var PRReviewer = class {
1503
1503
  void 0,
1504
1504
  debug
1505
1505
  );
1506
- return groupedResults;
1506
+ return results;
1507
1507
  }
1508
1508
  throw new Error(
1509
1509
  "No configuration provided. Please create a .visor.yaml file with check definitions. Built-in prompts have been removed - all checks must be explicitly configured."
@@ -5746,6 +5746,7 @@ var CheckExecutionEngine = class _CheckExecutionEngine {
5746
5746
  config;
5747
5747
  webhookContext;
5748
5748
  routingSandbox;
5749
+ executionStats = /* @__PURE__ */ new Map();
5749
5750
  constructor(workingDirectory) {
5750
5751
  this.workingDirectory = workingDirectory || process.cwd();
5751
5752
  this.gitAnalyzer = new GitRepositoryAnalyzer(this.workingDirectory);
@@ -6284,12 +6285,14 @@ ${expr}
6284
6285
  apiCallDetails: reviewSummary.debug.apiCallDetails
6285
6286
  };
6286
6287
  }
6288
+ const executionStatistics = this.buildExecutionStatistics();
6287
6289
  return {
6288
6290
  repositoryInfo,
6289
6291
  reviewSummary,
6290
6292
  executionTime,
6291
6293
  timestamp,
6292
6294
  checksExecuted: filteredChecks,
6295
+ executionStatistics,
6293
6296
  debug: debugInfo
6294
6297
  };
6295
6298
  } catch (error) {
@@ -6482,7 +6485,7 @@ ${expr}
6482
6485
  });
6483
6486
  }
6484
6487
  /**
6485
- * Execute review checks and return grouped results for new architecture
6488
+ * Execute review checks and return grouped results with statistics for new architecture
6486
6489
  */
6487
6490
  async executeGroupedChecks(prInfo, checks, timeout, config, outputFormat, debug, maxParallelism, failFast, tagFilter) {
6488
6491
  const logFn = outputFormat === "json" || outputFormat === "sarif" ? debug ? console.error : () => {
@@ -6512,7 +6515,10 @@ ${expr}
6512
6515
  checks = tagFilteredChecks;
6513
6516
  if (checks.length === 0) {
6514
6517
  logger.warn("\u26A0\uFE0F No checks remain after tag filtering");
6515
- return {};
6518
+ return {
6519
+ results: {},
6520
+ statistics: this.buildExecutionStatistics()
6521
+ };
6516
6522
  }
6517
6523
  if (!config?.checks) {
6518
6524
  throw new Error("Config with check definitions required for grouped execution");
@@ -6552,9 +6558,15 @@ ${expr}
6552
6558
  );
6553
6559
  const groupedResults = {};
6554
6560
  groupedResults[checkResult.group] = [checkResult];
6555
- return groupedResults;
6561
+ return {
6562
+ results: groupedResults,
6563
+ statistics: this.buildExecutionStatistics()
6564
+ };
6556
6565
  }
6557
- return {};
6566
+ return {
6567
+ results: {},
6568
+ statistics: this.buildExecutionStatistics()
6569
+ };
6558
6570
  }
6559
6571
  /**
6560
6572
  * Execute single check and return grouped result
@@ -6600,7 +6612,7 @@ ${expr}
6600
6612
  };
6601
6613
  }
6602
6614
  /**
6603
- * Execute multiple checks with dependency awareness - return grouped results
6615
+ * Execute multiple checks with dependency awareness - return grouped results with statistics
6604
6616
  */
6605
6617
  async executeGroupedDependencyAwareChecks(prInfo, checks, timeout, config, logFn, debug, maxParallelism, failFast) {
6606
6618
  const reviewSummary = await this.executeDependencyAwareChecks(
@@ -6613,7 +6625,17 @@ ${expr}
6613
6625
  maxParallelism,
6614
6626
  failFast
6615
6627
  );
6616
- return await this.convertReviewSummaryToGroupedResults(reviewSummary, checks, config, prInfo);
6628
+ const executionStatistics = this.buildExecutionStatistics();
6629
+ const groupedResults = await this.convertReviewSummaryToGroupedResults(
6630
+ reviewSummary,
6631
+ checks,
6632
+ config,
6633
+ prInfo
6634
+ );
6635
+ return {
6636
+ results: groupedResults,
6637
+ statistics: executionStatistics
6638
+ };
6617
6639
  }
6618
6640
  /**
6619
6641
  * Convert ReviewSummary to GroupedCheckResults
@@ -6876,9 +6898,9 @@ ${expr}
6876
6898
  let shouldStopExecution = false;
6877
6899
  let completedChecksCount = 0;
6878
6900
  const totalChecksCount = stats.totalChecks;
6879
- let skippedChecksCount = 0;
6880
- let failedChecksCount = 0;
6881
- const executionStartTime = Date.now();
6901
+ for (const checkName of checks) {
6902
+ this.initializeCheckStats(checkName);
6903
+ }
6882
6904
  for (let levelIndex = 0; levelIndex < dependencyGraph.executionOrder.length && !shouldStopExecution; levelIndex++) {
6883
6905
  const executionGroup = dependencyGraph.executionOrder[levelIndex];
6884
6906
  const checksInLevel = executionGroup.parallel;
@@ -7008,11 +7030,13 @@ ${expr}
7008
7030
  }
7009
7031
  let finalResult;
7010
7032
  if (isForEachDependent && forEachParentName) {
7033
+ this.recordForEachPreview(checkName, forEachItems);
7011
7034
  if (debug) {
7012
7035
  log2(
7013
7036
  `\u{1F504} Debug: Check "${checkName}" depends on forEach check "${forEachParentName}", executing ${forEachItems.length} times`
7014
7037
  );
7015
7038
  }
7039
+ logger.info(` Processing ${forEachItems.length} items...`);
7016
7040
  const allIssues = [];
7017
7041
  const allOutputs = [];
7018
7042
  const aggregatedContents = [];
@@ -7069,6 +7093,7 @@ ${expr}
7069
7093
  `\u{1F504} Debug: Executing check "${checkName}" for item ${itemIndex + 1}/${forEachItems.length}`
7070
7094
  );
7071
7095
  }
7096
+ const iterationStart = this.recordIterationStart(checkName);
7072
7097
  const itemResult = await this.executeWithRouting(
7073
7098
  checkName,
7074
7099
  checkConfig,
@@ -7088,6 +7113,17 @@ ${expr}
7088
7113
  parent: forEachParentName
7089
7114
  }
7090
7115
  );
7116
+ const iterationDuration = (Date.now() - iterationStart) / 1e3;
7117
+ this.recordIterationComplete(
7118
+ checkName,
7119
+ iterationStart,
7120
+ true,
7121
+ itemResult.issues || [],
7122
+ itemResult.output
7123
+ );
7124
+ logger.info(
7125
+ ` \u2714 ${itemIndex + 1}/${forEachItems.length} (${iterationDuration.toFixed(1)}s)`
7126
+ );
7091
7127
  return { index: itemIndex, itemResult };
7092
7128
  });
7093
7129
  const forEachConcurrency = Math.max(
@@ -7149,8 +7185,8 @@ ${expr}
7149
7185
  debug
7150
7186
  );
7151
7187
  if (!shouldRun) {
7152
- skippedChecksCount++;
7153
- logger.info(`\u23ED Skipping check: ${checkName} (if condition evaluated to false)`);
7188
+ this.recordSkip(checkName, "if_condition", checkConfig.if);
7189
+ logger.info(`\u23ED Skipped (if: ${this.truncate(checkConfig.if, 40)})`);
7154
7190
  return {
7155
7191
  checkName,
7156
7192
  error: null,
@@ -7174,6 +7210,13 @@ ${expr}
7174
7210
  debug,
7175
7211
  results
7176
7212
  );
7213
+ this.recordIterationComplete(
7214
+ checkName,
7215
+ checkStartTime,
7216
+ true,
7217
+ finalResult.issues || [],
7218
+ finalResult.output
7219
+ );
7177
7220
  if (checkConfig.forEach) {
7178
7221
  try {
7179
7222
  const finalResultWithOutput = finalResult;
@@ -7203,7 +7246,22 @@ ${expr}
7203
7246
  };
7204
7247
  const checkDuration = ((Date.now() - checkStartTime) / 1e3).toFixed(1);
7205
7248
  const issueCount = enrichedIssues.length;
7206
- if (issueCount > 0) {
7249
+ const checkStats = this.executionStats.get(checkName);
7250
+ if (checkStats && checkStats.totalRuns > 1) {
7251
+ if (issueCount > 0) {
7252
+ logger.success(
7253
+ `Check complete: ${checkName} (${checkDuration}s) - ${checkStats.totalRuns} runs, ${issueCount} issue${issueCount === 1 ? "" : "s"}`
7254
+ );
7255
+ } else {
7256
+ logger.success(
7257
+ `Check complete: ${checkName} (${checkDuration}s) - ${checkStats.totalRuns} runs`
7258
+ );
7259
+ }
7260
+ } else if (checkStats && checkStats.outputsProduced && checkStats.outputsProduced > 0) {
7261
+ logger.success(
7262
+ `Check complete: ${checkName} (${checkDuration}s) - ${checkStats.outputsProduced} items`
7263
+ );
7264
+ } else if (issueCount > 0) {
7207
7265
  logger.success(
7208
7266
  `Check complete: ${checkName} (${checkDuration}s) - ${issueCount} issue${issueCount === 1 ? "" : "s"} found`
7209
7267
  );
@@ -7216,9 +7274,10 @@ ${expr}
7216
7274
  result: enrichedResult
7217
7275
  };
7218
7276
  } catch (error) {
7219
- failedChecksCount++;
7220
7277
  const errorMessage = error instanceof Error ? error.message : String(error);
7221
7278
  const checkDuration = ((Date.now() - checkStartTime) / 1e3).toFixed(1);
7279
+ this.recordError(checkName, error instanceof Error ? error : new Error(String(error)));
7280
+ this.recordIterationComplete(checkName, checkStartTime, false, [], void 0);
7222
7281
  logger.error(`\u2716 Check failed: ${checkName} (${checkDuration}s) - ${errorMessage}`);
7223
7282
  if (debug) {
7224
7283
  log2(`\u{1F527} Debug: Error in check ${checkName}: ${errorMessage}`);
@@ -7326,19 +7385,13 @@ ${expr}
7326
7385
  }
7327
7386
  }
7328
7387
  }
7329
- const executionDuration = ((Date.now() - executionStartTime) / 1e3).toFixed(1);
7330
- const successfulChecks = totalChecksCount - failedChecksCount - skippedChecksCount;
7331
- logger.info("");
7332
- logger.step(`Execution complete (${executionDuration}s)`);
7333
- logger.info(` \u2714 Successful: ${successfulChecks}/${totalChecksCount}`);
7334
- if (skippedChecksCount > 0) {
7335
- logger.info(` \u23ED Skipped: ${skippedChecksCount}`);
7336
- }
7337
- if (failedChecksCount > 0) {
7338
- logger.info(` \u2716 Failed: ${failedChecksCount}`);
7388
+ const executionStatistics = this.buildExecutionStatistics();
7389
+ if (logFn === console.log) {
7390
+ this.logExecutionSummary(executionStatistics);
7339
7391
  }
7340
7392
  if (shouldStopExecution) {
7341
- logger.warn(` \u26A0\uFE0F Execution stopped early due to fail-fast`);
7393
+ logger.info("");
7394
+ logger.warn(`\u26A0\uFE0F Execution stopped early due to fail-fast`);
7342
7395
  }
7343
7396
  if (debug) {
7344
7397
  if (shouldStopExecution) {
@@ -8293,9 +8346,223 @@ ${result.value.result.debug.rawResponse}`;
8293
8346
  }
8294
8347
  return "pr_updated";
8295
8348
  }
8349
+ /**
8350
+ * Initialize execution statistics for a check
8351
+ */
8352
+ initializeCheckStats(checkName) {
8353
+ this.executionStats.set(checkName, {
8354
+ checkName,
8355
+ totalRuns: 0,
8356
+ successfulRuns: 0,
8357
+ failedRuns: 0,
8358
+ skipped: false,
8359
+ totalDuration: 0,
8360
+ issuesFound: 0,
8361
+ issuesBySeverity: {
8362
+ critical: 0,
8363
+ error: 0,
8364
+ warning: 0,
8365
+ info: 0
8366
+ },
8367
+ perIterationDuration: []
8368
+ });
8369
+ }
8370
+ /**
8371
+ * Record the start of a check iteration
8372
+ * Returns the start timestamp for duration tracking
8373
+ */
8374
+ recordIterationStart(_checkName) {
8375
+ return Date.now();
8376
+ }
8377
+ /**
8378
+ * Record completion of a check iteration
8379
+ */
8380
+ recordIterationComplete(checkName, startTime, success, issues, output) {
8381
+ const stats = this.executionStats.get(checkName);
8382
+ if (!stats) return;
8383
+ const duration = Date.now() - startTime;
8384
+ stats.totalRuns++;
8385
+ if (success) {
8386
+ stats.successfulRuns++;
8387
+ } else {
8388
+ stats.failedRuns++;
8389
+ }
8390
+ stats.totalDuration += duration;
8391
+ stats.perIterationDuration.push(duration);
8392
+ for (const issue of issues) {
8393
+ stats.issuesFound++;
8394
+ if (issue.severity === "critical") stats.issuesBySeverity.critical++;
8395
+ else if (issue.severity === "error") stats.issuesBySeverity.error++;
8396
+ else if (issue.severity === "warning") stats.issuesBySeverity.warning++;
8397
+ else if (issue.severity === "info") stats.issuesBySeverity.info++;
8398
+ }
8399
+ if (output !== void 0) {
8400
+ stats.outputsProduced = (stats.outputsProduced || 0) + 1;
8401
+ }
8402
+ }
8403
+ /**
8404
+ * Record that a check was skipped
8405
+ */
8406
+ recordSkip(checkName, reason, condition) {
8407
+ const stats = this.executionStats.get(checkName);
8408
+ if (!stats) return;
8409
+ stats.skipped = true;
8410
+ stats.skipReason = reason;
8411
+ if (condition) {
8412
+ stats.skipCondition = condition;
8413
+ }
8414
+ }
8415
+ /**
8416
+ * Record forEach preview items
8417
+ */
8418
+ recordForEachPreview(checkName, items) {
8419
+ const stats = this.executionStats.get(checkName);
8420
+ if (!stats || !items.length) return;
8421
+ const preview = items.slice(0, 3).map((item) => {
8422
+ const str = typeof item === "string" ? item : JSON.stringify(item);
8423
+ return str.length > 50 ? str.substring(0, 47) + "..." : str;
8424
+ });
8425
+ if (items.length > 3) {
8426
+ preview.push(`...${items.length - 3} more`);
8427
+ }
8428
+ stats.forEachPreview = preview;
8429
+ }
8430
+ /**
8431
+ * Record an error for a check
8432
+ */
8433
+ recordError(checkName, error) {
8434
+ const stats = this.executionStats.get(checkName);
8435
+ if (!stats) return;
8436
+ stats.errorMessage = error instanceof Error ? error.message : String(error);
8437
+ }
8438
+ /**
8439
+ * Build the final execution statistics object
8440
+ */
8441
+ buildExecutionStatistics() {
8442
+ const checks = Array.from(this.executionStats.values());
8443
+ const totalExecutions = checks.reduce((sum, s) => sum + s.totalRuns, 0);
8444
+ const successfulExecutions = checks.reduce((sum, s) => sum + s.successfulRuns, 0);
8445
+ const failedExecutions = checks.reduce((sum, s) => sum + s.failedRuns, 0);
8446
+ const skippedChecks = checks.filter((s) => s.skipped).length;
8447
+ const totalDuration = checks.reduce((sum, s) => sum + s.totalDuration, 0);
8448
+ return {
8449
+ totalChecksConfigured: checks.length,
8450
+ totalExecutions,
8451
+ successfulExecutions,
8452
+ failedExecutions,
8453
+ skippedChecks,
8454
+ totalDuration,
8455
+ checks
8456
+ };
8457
+ }
8458
+ /**
8459
+ * Truncate a string to max length with ellipsis
8460
+ */
8461
+ truncate(str, maxLen) {
8462
+ if (str.length <= maxLen) return str;
8463
+ return str.substring(0, maxLen - 3) + "...";
8464
+ }
8465
+ /**
8466
+ * Format the Status column for execution summary table
8467
+ */
8468
+ formatStatusColumn(stats) {
8469
+ if (stats.skipped) {
8470
+ if (stats.skipReason === "if_condition") return "\u23ED if";
8471
+ if (stats.skipReason === "fail_fast") return "\u23ED ff";
8472
+ if (stats.skipReason === "dependency_failed") return "\u23ED dep";
8473
+ return "\u23ED";
8474
+ }
8475
+ if (stats.totalRuns === 0) return "-";
8476
+ const symbol = stats.failedRuns === 0 ? "\u2714" : stats.successfulRuns === 0 ? "\u2716" : "\u2714/\u2716";
8477
+ if (stats.totalRuns > 1) {
8478
+ if (stats.failedRuns > 0 && stats.successfulRuns > 0) {
8479
+ return `${symbol} ${stats.successfulRuns}/${stats.totalRuns}`;
8480
+ } else {
8481
+ return `${symbol} \xD7${stats.totalRuns}`;
8482
+ }
8483
+ }
8484
+ return symbol;
8485
+ }
8486
+ /**
8487
+ * Format the Details column for execution summary table
8488
+ */
8489
+ formatDetailsColumn(stats) {
8490
+ const parts = [];
8491
+ if (stats.outputsProduced && stats.outputsProduced > 0) {
8492
+ parts.push(`\u2192${stats.outputsProduced}`);
8493
+ }
8494
+ if (stats.issuesBySeverity.critical > 0) {
8495
+ parts.push(`${stats.issuesBySeverity.critical}\u{1F534}`);
8496
+ }
8497
+ if (stats.issuesBySeverity.warning > 0) {
8498
+ parts.push(`${stats.issuesBySeverity.warning}\u26A0\uFE0F`);
8499
+ }
8500
+ if (stats.issuesBySeverity.info > 0 && stats.issuesBySeverity.critical === 0 && stats.issuesBySeverity.warning === 0) {
8501
+ parts.push(`${stats.issuesBySeverity.info}\u{1F4A1}`);
8502
+ }
8503
+ if (stats.errorMessage) {
8504
+ parts.push(this.truncate(stats.errorMessage, 20));
8505
+ } else if (stats.skipCondition) {
8506
+ parts.push(this.truncate(stats.skipCondition, 20));
8507
+ }
8508
+ return parts.join(" ");
8509
+ }
8510
+ /**
8511
+ * Log the execution summary table
8512
+ */
8513
+ logExecutionSummary(stats) {
8514
+ const totalIssues = stats.checks.reduce((sum, s) => sum + s.issuesFound, 0);
8515
+ const criticalIssues = stats.checks.reduce((sum, s) => sum + s.issuesBySeverity.critical, 0);
8516
+ const warningIssues = stats.checks.reduce((sum, s) => sum + s.issuesBySeverity.warning, 0);
8517
+ const durationSec = (stats.totalDuration / 1e3).toFixed(1);
8518
+ const summaryTable = new (__require("cli-table3"))({
8519
+ style: {
8520
+ head: [],
8521
+ border: []
8522
+ },
8523
+ colWidths: [41]
8524
+ });
8525
+ summaryTable.push(
8526
+ [`Execution Complete (${durationSec}s)`],
8527
+ [`Checks: ${stats.totalChecksConfigured} configured \u2192 ${stats.totalExecutions} executions`],
8528
+ [
8529
+ `Status: ${stats.successfulExecutions} \u2714 \u2502 ${stats.failedExecutions} \u2716 \u2502 ${stats.skippedChecks} \u23ED`
8530
+ ]
8531
+ );
8532
+ if (totalIssues > 0) {
8533
+ let issuesLine = `Issues: ${totalIssues} total`;
8534
+ if (criticalIssues > 0) issuesLine += ` (${criticalIssues} \u{1F534}`;
8535
+ if (warningIssues > 0) issuesLine += `${criticalIssues > 0 ? " " : " ("}${warningIssues} \u26A0\uFE0F)`;
8536
+ else if (criticalIssues > 0) issuesLine += ")";
8537
+ summaryTable.push([issuesLine]);
8538
+ }
8539
+ logger.info("");
8540
+ logger.info(summaryTable.toString());
8541
+ logger.info("");
8542
+ logger.info("Check Details:");
8543
+ const detailsTable = new (__require("cli-table3"))({
8544
+ head: ["Check", "Duration", "Status", "Details"],
8545
+ colWidths: [21, 10, 10, 21],
8546
+ style: {
8547
+ head: ["cyan"],
8548
+ border: ["grey"]
8549
+ }
8550
+ });
8551
+ for (const checkStats of stats.checks) {
8552
+ const duration = checkStats.skipped ? "-" : `${(checkStats.totalDuration / 1e3).toFixed(1)}s`;
8553
+ const status = this.formatStatusColumn(checkStats);
8554
+ const details = this.formatDetailsColumn(checkStats);
8555
+ detailsTable.push([checkStats.checkName, duration, status, details]);
8556
+ }
8557
+ logger.info(detailsTable.toString());
8558
+ logger.info("");
8559
+ logger.info(
8560
+ "Legend: \u2714=success \u2502 \u2716=failed \u2502 \u23ED=skipped \u2502 \xD7N=iterations \u2502 \u2192N=outputs \u2502 N\u{1F534}=critical \u2502 N\u26A0\uFE0F=warnings"
8561
+ );
8562
+ }
8296
8563
  };
8297
8564
 
8298
8565
  export {
8299
8566
  CheckExecutionEngine
8300
8567
  };
8301
- //# sourceMappingURL=chunk-J355UUEI.mjs.map
8568
+ //# sourceMappingURL=chunk-NINHE4RF.mjs.map