@probelabs/visor 0.1.78 → 0.1.80

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/sdk/sdk.js CHANGED
@@ -4173,7 +4173,19 @@ var init_command_check_provider = __esm({
4173
4173
  const parsed = JSON.parse(rawOutput);
4174
4174
  output = parsed;
4175
4175
  } catch {
4176
- output = rawOutput;
4176
+ const extracted2 = this.extractJsonFromEnd(rawOutput);
4177
+ if (extracted2) {
4178
+ try {
4179
+ output = JSON.parse(extracted2);
4180
+ logger.debug(
4181
+ `\u{1F527} Debug: Extracted and parsed JSON from end of output (${extracted2.length} chars from ${rawOutput.length} total)`
4182
+ );
4183
+ } catch {
4184
+ output = rawOutput;
4185
+ }
4186
+ } else {
4187
+ output = rawOutput;
4188
+ }
4177
4189
  }
4178
4190
  let finalOutput = output;
4179
4191
  if (transform) {
@@ -4392,6 +4404,7 @@ ${stderrOutput}` : `Command execution failed: ${errorMessage}`;
4392
4404
  * - If it's a JSON string, expose parsed properties via Proxy (e.g., value.key)
4393
4405
  * - When coerced to string (toString/valueOf/Symbol.toPrimitive), return the original raw string
4394
4406
  * - If parsing fails or value is not a string, return the value unchanged
4407
+ * - Attempts to extract JSON from the end of the output if full parse fails
4395
4408
  */
4396
4409
  makeJsonSmart(value) {
4397
4410
  if (typeof value !== "string") {
@@ -4402,7 +4415,19 @@ ${stderrOutput}` : `Command execution failed: ${errorMessage}`;
4402
4415
  try {
4403
4416
  parsed = JSON.parse(raw);
4404
4417
  } catch {
4405
- return raw;
4418
+ const jsonMatch = this.extractJsonFromEnd(raw);
4419
+ if (jsonMatch) {
4420
+ try {
4421
+ parsed = JSON.parse(jsonMatch);
4422
+ logger.debug(
4423
+ `\u{1F527} Debug: Extracted JSON from end of output (${jsonMatch.length} chars from ${raw.length} total)`
4424
+ );
4425
+ } catch {
4426
+ return raw;
4427
+ }
4428
+ } else {
4429
+ return raw;
4430
+ }
4406
4431
  }
4407
4432
  const boxed = new String(raw);
4408
4433
  const handler = {
@@ -4451,6 +4476,24 @@ ${stderrOutput}` : `Command execution failed: ${errorMessage}`;
4451
4476
  };
4452
4477
  return new Proxy(boxed, handler);
4453
4478
  }
4479
+ /**
4480
+ * Extract JSON from the end of a string that may contain logs/debug output
4481
+ * Looks for the last occurrence of { or [ and tries to parse from there
4482
+ */
4483
+ extractJsonFromEnd(text) {
4484
+ const lines = text.split("\n");
4485
+ for (let i = lines.length - 1; i >= 0; i--) {
4486
+ const trimmed = lines[i].trim();
4487
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
4488
+ const candidate = lines.slice(i).join("\n");
4489
+ const trimmedCandidate = candidate.trim();
4490
+ if (trimmedCandidate.startsWith("{") && trimmedCandidate.endsWith("}") || trimmedCandidate.startsWith("[") && trimmedCandidate.endsWith("]")) {
4491
+ return trimmedCandidate;
4492
+ }
4493
+ }
4494
+ }
4495
+ return null;
4496
+ }
4454
4497
  /**
4455
4498
  * Recursively apply JSON-smart wrapper to outputs object values
4456
4499
  */
@@ -7257,11 +7300,15 @@ ${expr}
7257
7300
  for (const depId of directDeps) {
7258
7301
  const depRes = results.get(depId);
7259
7302
  if (!depRes) continue;
7260
- const hasFatalCommandFailure = (depRes.issues || []).some((issue) => {
7303
+ const wasSkipped = (depRes.issues || []).some((issue) => {
7304
+ const id = issue.ruleId || "";
7305
+ return id.endsWith("/__skipped");
7306
+ });
7307
+ const hasFatalFailure = (depRes.issues || []).some((issue) => {
7261
7308
  const id = issue.ruleId || "";
7262
- return id.endsWith("/command/execution_error") || id.endsWith("/command/transform_js_error") || id.endsWith("/command/transform_error");
7309
+ return id === "command/execution_error" || id.endsWith("/command/execution_error") || id === "command/transform_js_error" || id.endsWith("/command/transform_js_error") || id === "command/transform_error" || id.endsWith("/command/transform_error") || id.endsWith("/forEach/iteration_error");
7263
7310
  });
7264
- if (hasFatalCommandFailure) failedDeps.push(depId);
7311
+ if (wasSkipped || hasFatalFailure) failedDeps.push(depId);
7265
7312
  }
7266
7313
  if (failedDeps.length > 0) {
7267
7314
  this.recordSkip(checkName, "dependency_failed");
@@ -7327,7 +7374,9 @@ ${expr}
7327
7374
  `\u{1F504} Debug: Check "${checkName}" depends on forEach check "${forEachParentName}", executing ${forEachItems.length} times`
7328
7375
  );
7329
7376
  }
7330
- logger.info(` Processing ${forEachItems.length} items...`);
7377
+ logger.info(
7378
+ ` forEach: processing ${forEachItems.length} items from "${forEachParentName}"...`
7379
+ );
7331
7380
  const allIssues = [];
7332
7381
  const allOutputs = [];
7333
7382
  const aggregatedContents = [];
@@ -7404,11 +7453,16 @@ ${expr}
7404
7453
  parent: forEachParentName
7405
7454
  }
7406
7455
  );
7456
+ const hadFatalError = (itemResult.issues || []).some((issue) => {
7457
+ const id = issue.ruleId || "";
7458
+ return id === "command/execution_error" || id.endsWith("/command/execution_error") || id === "command/transform_js_error" || id.endsWith("/command/transform_js_error") || id === "command/transform_error" || id.endsWith("/command/transform_error");
7459
+ });
7407
7460
  const iterationDuration = (Date.now() - iterationStart) / 1e3;
7408
7461
  this.recordIterationComplete(
7409
7462
  checkName,
7410
7463
  iterationStart,
7411
- true,
7464
+ !hadFatalError,
7465
+ // Success if no fatal errors
7412
7466
  itemResult.issues || [],
7413
7467
  itemResult.output
7414
7468
  );
@@ -7433,7 +7487,22 @@ ${expr}
7433
7487
  );
7434
7488
  for (const result of forEachResults) {
7435
7489
  if (result.status === "rejected") {
7436
- throw result.reason;
7490
+ const error = result.reason;
7491
+ const errorMessage = error instanceof Error ? error.message : String(error);
7492
+ allIssues.push({
7493
+ ruleId: `${checkName}/forEach/iteration_error`,
7494
+ severity: "error",
7495
+ category: "logic",
7496
+ message: `forEach iteration failed: ${errorMessage}`,
7497
+ file: "",
7498
+ line: 0
7499
+ });
7500
+ if (debug) {
7501
+ log2(
7502
+ `\u{1F504} Debug: forEach iteration for check "${checkName}" failed: ${errorMessage}`
7503
+ );
7504
+ }
7505
+ continue;
7437
7506
  }
7438
7507
  if (result.value.skipped) {
7439
7508
  continue;
@@ -7501,10 +7570,15 @@ ${expr}
7501
7570
  debug,
7502
7571
  results
7503
7572
  );
7573
+ const hadFatalError = (finalResult.issues || []).some((issue) => {
7574
+ const id = issue.ruleId || "";
7575
+ return id === "command/execution_error" || id.endsWith("/command/execution_error") || id === "command/transform_js_error" || id.endsWith("/command/transform_js_error") || id === "command/transform_error" || id.endsWith("/command/transform_error");
7576
+ });
7504
7577
  this.recordIterationComplete(
7505
7578
  checkName,
7506
7579
  checkStartTime,
7507
- true,
7580
+ !hadFatalError,
7581
+ // Success if no fatal errors
7508
7582
  finalResult.issues || [],
7509
7583
  finalResult.output
7510
7584
  );
@@ -7592,8 +7666,20 @@ ${expr}
7592
7666
  if (result.status === "fulfilled" && result.value.result && !result.value.error) {
7593
7667
  if (result.value.skipped) {
7594
7668
  if (debug) {
7595
- log2(`\u{1F527} Debug: Not storing result for skipped check "${checkName}"`);
7669
+ log2(`\u{1F527} Debug: Storing skip marker for skipped check "${checkName}"`);
7596
7670
  }
7671
+ results.set(checkName, {
7672
+ issues: [
7673
+ {
7674
+ ruleId: `${checkName}/__skipped`,
7675
+ severity: "info",
7676
+ category: "logic",
7677
+ message: "Check was skipped",
7678
+ file: "",
7679
+ line: 0
7680
+ }
7681
+ ]
7682
+ });
7597
7683
  continue;
7598
7684
  }
7599
7685
  const reviewResult = result.value.result;
@@ -7618,6 +7704,7 @@ ${expr}
7618
7704
  } else {
7619
7705
  normalizedOutput = [rawOutput];
7620
7706
  }
7707
+ logger.info(` Found ${normalizedOutput.length} items for forEach iteration`);
7621
7708
  try {
7622
7709
  const preview = JSON.stringify(normalizedOutput);
7623
7710
  logger.debug(
@@ -7922,7 +8009,10 @@ ${expr}
7922
8009
  `\u2705 Check "${checkName}" completed: ${(result.issues || []).length} issues found (level ${executionGroup.level})`
7923
8010
  );
7924
8011
  }
7925
- aggregatedIssues.push(...result.issues || []);
8012
+ const nonInternalIssues = (result.issues || []).filter(
8013
+ (issue) => !issue.ruleId?.endsWith("/__skipped")
8014
+ );
8015
+ aggregatedIssues.push(...nonInternalIssues);
7926
8016
  const resultSummary = result;
7927
8017
  const resultContent = resultSummary.content;
7928
8018
  if (typeof resultContent === "string" && resultContent.trim()) {