@probelabs/visor 0.1.113 → 0.1.122

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.
Files changed (120) hide show
  1. package/defaults/workflow-builder.tests.yaml +363 -0
  2. package/defaults/workflow-builder.yaml +720 -0
  3. package/dist/ai-review-service.d.ts.map +1 -1
  4. package/dist/cli-main.d.ts.map +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/defaults/workflow-builder.tests.yaml +363 -0
  7. package/dist/defaults/workflow-builder.yaml +720 -0
  8. package/dist/docs/workflow-creation-guide.md +1274 -0
  9. package/dist/frontends/slack-frontend.d.ts +3 -0
  10. package/dist/frontends/slack-frontend.d.ts.map +1 -1
  11. package/dist/generated/config-schema.d.ts +14 -6
  12. package/dist/generated/config-schema.d.ts.map +1 -1
  13. package/dist/generated/config-schema.json +14 -6
  14. package/dist/index.js +36879 -13895
  15. package/dist/logger.d.ts +9 -0
  16. package/dist/logger.d.ts.map +1 -1
  17. package/dist/mcp-server.d.ts +4 -4
  18. package/dist/output/traces/{run-2026-01-21T12-31-10-108Z.ndjson → run-2026-01-28T13-56-32-263Z.ndjson} +84 -84
  19. package/dist/output/traces/run-2026-01-28T13-57-13-140Z.ndjson +1357 -0
  20. package/dist/providers/ai-check-provider.d.ts.map +1 -1
  21. package/dist/providers/check-provider.interface.d.ts +15 -1
  22. package/dist/providers/check-provider.interface.d.ts.map +1 -1
  23. package/dist/providers/command-check-provider.d.ts.map +1 -1
  24. package/dist/providers/git-checkout-provider.d.ts.map +1 -1
  25. package/dist/sdk/{check-provider-registry-534KL5HT.mjs → check-provider-registry-JMNLGIMJ.mjs} +11 -11
  26. package/dist/sdk/{chunk-AIVFBIS4.mjs → chunk-35NT3725.mjs} +30 -10
  27. package/dist/sdk/chunk-35NT3725.mjs.map +1 -0
  28. package/dist/sdk/{chunk-AGIZJ4UZ.mjs → chunk-3NMLT3YS.mjs} +42 -8
  29. package/dist/sdk/chunk-3NMLT3YS.mjs.map +1 -0
  30. package/dist/sdk/{chunk-AK6BVWIT.mjs → chunk-7GUAFV6L.mjs} +2 -2
  31. package/dist/sdk/{chunk-QY2XYPEV.mjs → chunk-CUNPH6TR.mjs} +18 -10
  32. package/dist/sdk/chunk-CUNPH6TR.mjs.map +1 -0
  33. package/dist/sdk/{chunk-HTOKWMPO.mjs → chunk-HQL734ZI.mjs} +2 -2
  34. package/dist/sdk/{chunk-7UK3NIIT.mjs → chunk-IHZOSIF4.mjs} +2 -2
  35. package/dist/sdk/{chunk-AUT26LHW.mjs → chunk-J2QWVDXK.mjs} +2 -2
  36. package/dist/sdk/{chunk-QR7MOMJH.mjs → chunk-J6EVEXC2.mjs} +2 -2
  37. package/dist/sdk/{chunk-SIWNBRTK.mjs → chunk-SWEEZ5D5.mjs} +3 -3
  38. package/dist/sdk/{chunk-23L3QRYX.mjs → chunk-VPEQOQ7G.mjs} +279 -70
  39. package/dist/sdk/chunk-VPEQOQ7G.mjs.map +1 -0
  40. package/dist/sdk/{command-executor-TYUV6HUS.mjs → command-executor-Q7MHJKZJ.mjs} +3 -3
  41. package/dist/sdk/{config-YNC2EOOT.mjs → config-MK4XTU45.mjs} +3 -3
  42. package/dist/sdk/{failure-condition-evaluator-YGTF2GHG.mjs → failure-condition-evaluator-HB35XRLZ.mjs} +4 -4
  43. package/dist/sdk/{github-frontend-SIAEOCON.mjs → github-frontend-6Q4BISZX.mjs} +4 -4
  44. package/dist/sdk/{host-DXUYTNMU.mjs → host-P5NQICP7.mjs} +3 -3
  45. package/dist/sdk/{liquid-extensions-PKWCKK7E.mjs → liquid-extensions-DFDEBMUI.mjs} +4 -4
  46. package/dist/sdk/{memory-store-XGBB7LX7.mjs → memory-store-RW5N2NGJ.mjs} +3 -3
  47. package/dist/sdk/{prompt-state-YRJY6QAL.mjs → prompt-state-EZYOUG75.mjs} +3 -3
  48. package/dist/sdk/{renderer-schema-LPKN5UJS.mjs → renderer-schema-CKFB5NDB.mjs} +2 -2
  49. package/dist/sdk/{routing-6N45MJ4F.mjs → routing-KZ345OFG.mjs} +5 -5
  50. package/dist/sdk/sdk.d.mts +19 -1
  51. package/dist/sdk/sdk.d.ts +19 -1
  52. package/dist/sdk/sdk.js +421 -75
  53. package/dist/sdk/sdk.js.map +1 -1
  54. package/dist/sdk/sdk.mjs +35 -18
  55. package/dist/sdk/sdk.mjs.map +1 -1
  56. package/dist/sdk/{slack-frontend-BVKW3GD5.mjs → slack-frontend-J442FJWZ.mjs} +61 -3
  57. package/dist/sdk/slack-frontend-J442FJWZ.mjs.map +1 -0
  58. package/dist/sdk/{workflow-registry-R6KSACFR.mjs → workflow-registry-6LZKCWHP.mjs} +3 -3
  59. package/dist/state-machine/context/build-engine-context.d.ts.map +1 -1
  60. package/dist/state-machine/dispatch/history-snapshot.d.ts.map +1 -1
  61. package/dist/state-machine/runner.d.ts.map +1 -1
  62. package/dist/state-machine/states/level-dispatch.d.ts.map +1 -1
  63. package/dist/state-machine/states/routing.d.ts.map +1 -1
  64. package/dist/state-machine/states/wave-planning.d.ts.map +1 -1
  65. package/dist/ter-u14b.json +17826 -0
  66. package/dist/ter-u14n.json +17826 -0
  67. package/dist/test-runner/index.d.ts.map +1 -1
  68. package/dist/traces/{run-2026-01-21T12-31-10-108Z.ndjson → run-2026-01-28T13-56-32-263Z.ndjson} +84 -84
  69. package/dist/traces/run-2026-01-28T13-57-13-140Z.ndjson +1357 -0
  70. package/dist/tui.d.ts +51 -0
  71. package/dist/tui.d.ts.map +1 -0
  72. package/dist/types/cli.d.ts +10 -0
  73. package/dist/types/cli.d.ts.map +1 -1
  74. package/dist/types/config.d.ts +4 -0
  75. package/dist/types/config.d.ts.map +1 -1
  76. package/dist/types/engine.d.ts +3 -0
  77. package/dist/types/engine.d.ts.map +1 -1
  78. package/dist/usr/fonts/AUTHORS +1 -0
  79. package/dist/usr/fonts/LICENSE +94 -0
  80. package/dist/usr/fonts/README +340 -0
  81. package/dist/usr/fonts/ter-u14b.json +17826 -0
  82. package/dist/usr/fonts/ter-u14n.json +17826 -0
  83. package/dist/usr/linux +0 -0
  84. package/dist/usr/windows-ansi +0 -0
  85. package/dist/usr/xterm +0 -0
  86. package/dist/usr/xterm-256color +0 -0
  87. package/dist/usr/xterm.termcap +243 -0
  88. package/dist/usr/xterm.terminfo +1977 -0
  89. package/dist/utils/workspace-manager.d.ts +2 -0
  90. package/dist/utils/workspace-manager.d.ts.map +1 -1
  91. package/dist/utils/worktree-manager.d.ts +5 -0
  92. package/dist/utils/worktree-manager.d.ts.map +1 -1
  93. package/dist/xterm +0 -0
  94. package/dist/xterm.termcap +243 -0
  95. package/package.json +9 -7
  96. package/dist/output/traces/run-2026-01-21T12-32-04-510Z.ndjson +0 -1067
  97. package/dist/sdk/chunk-23L3QRYX.mjs.map +0 -1
  98. package/dist/sdk/chunk-AGIZJ4UZ.mjs.map +0 -1
  99. package/dist/sdk/chunk-AIVFBIS4.mjs.map +0 -1
  100. package/dist/sdk/chunk-QY2XYPEV.mjs.map +0 -1
  101. package/dist/sdk/slack-frontend-BVKW3GD5.mjs.map +0 -1
  102. package/dist/traces/run-2026-01-21T12-32-04-510Z.ndjson +0 -1067
  103. /package/dist/sdk/{check-provider-registry-534KL5HT.mjs.map → check-provider-registry-JMNLGIMJ.mjs.map} +0 -0
  104. /package/dist/sdk/{chunk-AK6BVWIT.mjs.map → chunk-7GUAFV6L.mjs.map} +0 -0
  105. /package/dist/sdk/{chunk-HTOKWMPO.mjs.map → chunk-HQL734ZI.mjs.map} +0 -0
  106. /package/dist/sdk/{chunk-7UK3NIIT.mjs.map → chunk-IHZOSIF4.mjs.map} +0 -0
  107. /package/dist/sdk/{chunk-AUT26LHW.mjs.map → chunk-J2QWVDXK.mjs.map} +0 -0
  108. /package/dist/sdk/{chunk-QR7MOMJH.mjs.map → chunk-J6EVEXC2.mjs.map} +0 -0
  109. /package/dist/sdk/{chunk-SIWNBRTK.mjs.map → chunk-SWEEZ5D5.mjs.map} +0 -0
  110. /package/dist/sdk/{command-executor-TYUV6HUS.mjs.map → command-executor-Q7MHJKZJ.mjs.map} +0 -0
  111. /package/dist/sdk/{config-YNC2EOOT.mjs.map → config-MK4XTU45.mjs.map} +0 -0
  112. /package/dist/sdk/{failure-condition-evaluator-YGTF2GHG.mjs.map → failure-condition-evaluator-HB35XRLZ.mjs.map} +0 -0
  113. /package/dist/sdk/{github-frontend-SIAEOCON.mjs.map → github-frontend-6Q4BISZX.mjs.map} +0 -0
  114. /package/dist/sdk/{host-DXUYTNMU.mjs.map → host-P5NQICP7.mjs.map} +0 -0
  115. /package/dist/sdk/{liquid-extensions-PKWCKK7E.mjs.map → liquid-extensions-DFDEBMUI.mjs.map} +0 -0
  116. /package/dist/sdk/{memory-store-XGBB7LX7.mjs.map → memory-store-RW5N2NGJ.mjs.map} +0 -0
  117. /package/dist/sdk/{prompt-state-YRJY6QAL.mjs.map → prompt-state-EZYOUG75.mjs.map} +0 -0
  118. /package/dist/sdk/{renderer-schema-LPKN5UJS.mjs.map → renderer-schema-CKFB5NDB.mjs.map} +0 -0
  119. /package/dist/sdk/{routing-6N45MJ4F.mjs.map → routing-KZ345OFG.mjs.map} +0 -0
  120. /package/dist/sdk/{workflow-registry-R6KSACFR.mjs.map → workflow-registry-6LZKCWHP.mjs.map} +0 -0
@@ -6,21 +6,21 @@ import {
6
6
  import {
7
7
  commandExecutor,
8
8
  init_command_executor
9
- } from "./chunk-AUT26LHW.mjs";
9
+ } from "./chunk-J2QWVDXK.mjs";
10
10
  import {
11
11
  getPromptStateManager,
12
12
  init_prompt_state
13
- } from "./chunk-HTOKWMPO.mjs";
13
+ } from "./chunk-HQL734ZI.mjs";
14
14
  import {
15
15
  DependencyResolver,
16
16
  WorkflowRegistry,
17
17
  init_dependency_resolver,
18
18
  init_workflow_registry
19
- } from "./chunk-QR7MOMJH.mjs";
19
+ } from "./chunk-J6EVEXC2.mjs";
20
20
  import {
21
21
  config_exports,
22
22
  init_config
23
- } from "./chunk-QY2XYPEV.mjs";
23
+ } from "./chunk-CUNPH6TR.mjs";
24
24
  import {
25
25
  checkLoopBudget,
26
26
  evaluateGoto,
@@ -28,11 +28,11 @@ import {
28
28
  init_routing,
29
29
  init_snapshot_store,
30
30
  snapshot_store_exports
31
- } from "./chunk-AIVFBIS4.mjs";
31
+ } from "./chunk-35NT3725.mjs";
32
32
  import {
33
33
  FailureConditionEvaluator,
34
34
  init_failure_condition_evaluator
35
- } from "./chunk-SIWNBRTK.mjs";
35
+ } from "./chunk-SWEEZ5D5.mjs";
36
36
  import {
37
37
  compileAndRun,
38
38
  createSecureSandbox,
@@ -55,7 +55,7 @@ import {
55
55
  import {
56
56
  createExtendedLiquid,
57
57
  init_liquid_extensions
58
- } from "./chunk-AK6BVWIT.mjs";
58
+ } from "./chunk-7GUAFV6L.mjs";
59
59
  import {
60
60
  createPermissionHelpers,
61
61
  detectLocalMode,
@@ -66,11 +66,11 @@ import {
66
66
  MemoryStore,
67
67
  init_memory_store,
68
68
  memory_store_exports
69
- } from "./chunk-7UK3NIIT.mjs";
69
+ } from "./chunk-IHZOSIF4.mjs";
70
70
  import {
71
71
  init_logger,
72
72
  logger
73
- } from "./chunk-AGIZJ4UZ.mjs";
73
+ } from "./chunk-3NMLT3YS.mjs";
74
74
  import {
75
75
  context,
76
76
  init_lazy_otel,
@@ -352,8 +352,8 @@ var init_ai_review_service = __esm({
352
352
  sessionRegistry;
353
353
  constructor(config = {}) {
354
354
  this.config = {
355
- timeout: 6e5,
356
- // Increased timeout to 10 minutes for AI responses
355
+ timeout: 12e5,
356
+ // Increased timeout to 20 minutes for AI responses
357
357
  ...config
358
358
  };
359
359
  this.sessionRegistry = SessionRegistry.getInstance();
@@ -448,12 +448,10 @@ var init_ai_review_service = __esm({
448
448
  }
449
449
  }
450
450
  if (!this.config.apiKey) {
451
- const errorMessage = "No API key configured. Please set GOOGLE_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY environment variable, or configure AWS credentials for Bedrock (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY).";
451
+ log("\u26A0\uFE0F No API key configured - ProbeAgent will attempt CLI fallback (claude-code/codex)");
452
452
  if (debugInfo) {
453
- debugInfo.errors = [errorMessage];
454
- debugInfo.rawResponse = "API call attempted in debug without API key (test mode)";
455
- } else {
456
- throw new Error(errorMessage);
453
+ debugInfo.errors = debugInfo.errors || [];
454
+ debugInfo.errors.push("No API key configured - attempting CLI fallback");
457
455
  }
458
456
  }
459
457
  }
@@ -1605,6 +1603,9 @@ ${"=".repeat(60)}
1605
1603
  options.model = this.config.model;
1606
1604
  }
1607
1605
  const agent = new ProbeAgent(options);
1606
+ if (typeof agent.initialize === "function") {
1607
+ await agent.initialize();
1608
+ }
1608
1609
  log("\u{1F680} Calling ProbeAgent...");
1609
1610
  let schemaString = void 0;
1610
1611
  let effectiveSchema = typeof schema === "object" ? "custom" : schema;
@@ -3763,10 +3764,18 @@ var init_ai_check_provider = __esm({
3763
3764
  if (info && typeof info.workspacePath === "string") {
3764
3765
  workspaceRoot = info.workspacePath;
3765
3766
  mainProjectPath = info.mainProjectPath;
3766
- folders.push(info.workspacePath);
3767
3767
  }
3768
3768
  } catch {
3769
3769
  }
3770
+ if (mainProjectPath) {
3771
+ folders.push(mainProjectPath);
3772
+ logger.debug(
3773
+ `[AI Provider] Including main project FIRST in allowedFolders: ${mainProjectPath}`
3774
+ );
3775
+ }
3776
+ if (workspaceRoot) {
3777
+ folders.push(workspaceRoot);
3778
+ }
3770
3779
  const projectPaths = [];
3771
3780
  try {
3772
3781
  const projects = workspace.listProjects?.() || [];
@@ -3778,27 +3787,16 @@ var init_ai_check_provider = __esm({
3778
3787
  }
3779
3788
  } catch {
3780
3789
  }
3781
- if (projectPaths.length === 0 && mainProjectPath) {
3782
- folders.push(mainProjectPath);
3783
- logger.debug(
3784
- `[AI Provider] No external projects - including main project as fallback: ${mainProjectPath}`
3785
- );
3786
- } else if (mainProjectPath) {
3787
- logger.debug(
3788
- `[AI Provider] Excluding main project (visor) from allowedFolders: ${mainProjectPath}`
3789
- );
3790
- }
3791
3790
  const unique = Array.from(new Set(folders.filter((p) => typeof p === "string" && p)));
3792
3791
  if (unique.length > 0 && workspaceRoot) {
3793
3792
  aiConfig.allowedFolders = unique;
3794
- aiConfig.path = workspaceRoot;
3795
- aiConfig.cwd = workspaceRoot;
3796
- aiConfig.workspacePath = workspaceRoot;
3793
+ const aiCwd = mainProjectPath || workspaceRoot;
3794
+ aiConfig.path = aiCwd;
3795
+ aiConfig.cwd = aiCwd;
3796
+ aiConfig.workspacePath = aiCwd;
3797
3797
  logger.debug(`[AI Provider] Workspace isolation enabled:`);
3798
- logger.debug(`[AI Provider] workspaceRoot (cwd): ${workspaceRoot}`);
3799
- logger.debug(
3800
- `[AI Provider] mainProjectPath (excluded unless fallback): ${mainProjectPath || "N/A"}`
3801
- );
3798
+ logger.debug(`[AI Provider] cwd (mainProjectPath): ${aiCwd}`);
3799
+ logger.debug(`[AI Provider] workspaceRoot: ${workspaceRoot}`);
3802
3800
  logger.debug(`[AI Provider] allowedFolders: ${JSON.stringify(unique)}`);
3803
3801
  }
3804
3802
  } else if (parentCtx && typeof parentCtx.workingDirectory === "string") {
@@ -3966,10 +3964,15 @@ ${processedPrompt}` : processedPrompt;
3966
3964
  const stepName = config.checkName || "unknown";
3967
3965
  const mock = sessionInfo?.hooks?.mockForStep?.(String(stepName));
3968
3966
  if (mock !== void 0) {
3969
- if (mock && typeof mock === "object" && ("issues" in mock || "content" in mock)) {
3970
- return mock;
3971
- }
3972
- return { issues: [], output: mock };
3967
+ const ms = mock;
3968
+ const issuesArr = Array.isArray(ms?.issues) ? ms.issues : [];
3969
+ const out = ms && typeof ms === "object" && "output" in ms ? ms.output : ms;
3970
+ const summary = {
3971
+ issues: issuesArr,
3972
+ output: out,
3973
+ ...typeof ms?.content === "string" ? { content: String(ms.content) } : {}
3974
+ };
3975
+ return summary;
3973
3976
  }
3974
3977
  } catch {
3975
3978
  }
@@ -6428,7 +6431,17 @@ var init_command_check_provider = __esm({
6428
6431
  }
6429
6432
  try {
6430
6433
  const stepName = config.checkName || "unknown";
6434
+ if (process.env.VISOR_DEBUG === "true") {
6435
+ logger.debug(
6436
+ `[Command] Mock check: stepName=${stepName}, context=${!!context2}, hooks=${!!context2?.hooks}, mockForStep=${!!context2?.hooks?.mockForStep}`
6437
+ );
6438
+ }
6431
6439
  const rawMock = context2?.hooks?.mockForStep?.(String(stepName));
6440
+ if (process.env.VISOR_DEBUG === "true") {
6441
+ logger.debug(
6442
+ `[Command] Mock result: ${rawMock !== void 0 ? "found" : "not found"}, value=${JSON.stringify(rawMock)?.slice(0, 200)}`
6443
+ );
6444
+ }
6432
6445
  if (rawMock !== void 0) {
6433
6446
  let mock;
6434
6447
  if (typeof rawMock === "number") {
@@ -6453,6 +6466,16 @@ var init_command_check_provider = __esm({
6453
6466
  out = mock;
6454
6467
  }
6455
6468
  const code = isCommandMock ? typeof m.exit_code === "number" ? m.exit_code : typeof m.exit === "number" ? m.exit : 0 : 0;
6469
+ let outputWithMeta;
6470
+ if (isCommandMock) {
6471
+ if (out && typeof out === "object" && !Array.isArray(out)) {
6472
+ outputWithMeta = { ...out, exit_code: code };
6473
+ } else {
6474
+ outputWithMeta = { value: out, exit_code: code };
6475
+ }
6476
+ } else {
6477
+ outputWithMeta = out;
6478
+ }
6456
6479
  if (code !== 0) {
6457
6480
  return {
6458
6481
  issues: [
@@ -6465,10 +6488,10 @@ var init_command_check_provider = __esm({
6465
6488
  category: "logic"
6466
6489
  }
6467
6490
  ],
6468
- output: out
6491
+ output: outputWithMeta
6469
6492
  };
6470
6493
  }
6471
- return { issues: [], output: out };
6494
+ return { issues: [], output: outputWithMeta };
6472
6495
  }
6473
6496
  } catch {
6474
6497
  }
@@ -10476,22 +10499,41 @@ async function handleWavePlanning(context2, state, transition) {
10476
10499
  if (gotoEvent) {
10477
10500
  eventOverrides.set(target, gotoEvent);
10478
10501
  }
10502
+ const sourceCheck = request.sourceCheck;
10503
+ if (sourceCheck && request.origin === "run") {
10504
+ if (!state.allowedFailedDeps) {
10505
+ state.allowedFailedDeps = /* @__PURE__ */ new Map();
10506
+ }
10507
+ const allowedSet = state.allowedFailedDeps.get(target) || /* @__PURE__ */ new Set();
10508
+ allowedSet.add(sourceCheck);
10509
+ state.allowedFailedDeps.set(target, allowedSet);
10510
+ if (context2.debug) {
10511
+ logger.info(
10512
+ `[WavePlanning] Allowing ${target} to run despite failed dependency ${sourceCheck}`
10513
+ );
10514
+ }
10515
+ }
10516
+ const origin = request.origin;
10479
10517
  const dependencies = findTransitiveDependencies(target, context2);
10480
10518
  for (const dep of dependencies) {
10481
10519
  const stats = state.stats.get(dep);
10482
10520
  const hasSucceeded = !!stats && (stats.successfulRuns || 0) > 0;
10521
+ const hasRun = !!stats && (stats.totalRuns || 0) > 0;
10522
+ if (origin === "run" && hasRun) {
10523
+ continue;
10524
+ }
10483
10525
  if (!hasSucceeded) {
10484
10526
  checksToRun.add(dep);
10485
10527
  }
10486
10528
  }
10487
10529
  let shouldIncludeDependents = true;
10488
10530
  try {
10489
- const origin = request.origin;
10531
+ const origin2 = request.origin;
10490
10532
  const cfg = context2.config.checks?.[target];
10491
10533
  const targetType = String(cfg?.type || "").toLowerCase();
10492
10534
  const execCtx = context2.executionContext || {};
10493
10535
  const hasWebhook = !!execCtx.webhookContext;
10494
- if (hasWebhook && (origin === "goto" || origin === "goto_js") && targetType === "human-input") {
10536
+ if (hasWebhook && (origin2 === "goto" || origin2 === "goto_js") && targetType === "human-input") {
10495
10537
  shouldIncludeDependents = false;
10496
10538
  }
10497
10539
  } catch {
@@ -10829,8 +10871,15 @@ var history_snapshot_exports = {};
10829
10871
  __export(history_snapshot_exports, {
10830
10872
  buildOutputHistoryFromJournal: () => buildOutputHistoryFromJournal
10831
10873
  });
10874
+ function getHistoryLimit() {
10875
+ const raw = process.env.VISOR_TEST_HISTORY_LIMIT || process.env.VISOR_OUTPUT_HISTORY_LIMIT;
10876
+ if (!raw) return void 0;
10877
+ const n = parseInt(raw, 10);
10878
+ return Number.isFinite(n) && n > 0 ? n : void 0;
10879
+ }
10832
10880
  function buildOutputHistoryFromJournal(context2) {
10833
10881
  const outputHistory = /* @__PURE__ */ new Map();
10882
+ const limit = getHistoryLimit();
10834
10883
  try {
10835
10884
  const snapshot = context2.journal.beginSnapshot();
10836
10885
  const allEntries = context2.journal.readVisible(context2.sessionId, snapshot, void 0);
@@ -10852,7 +10901,13 @@ function buildOutputHistoryFromJournal(context2) {
10852
10901
  }
10853
10902
  } catch {
10854
10903
  }
10855
- if (payload !== void 0) outputHistory.get(checkId).push(payload);
10904
+ if (payload !== void 0) {
10905
+ const arr = outputHistory.get(checkId);
10906
+ arr.push(payload);
10907
+ if (limit && arr.length > limit) {
10908
+ arr.splice(0, arr.length - limit);
10909
+ }
10910
+ }
10856
10911
  }
10857
10912
  } catch (error) {
10858
10913
  logger.debug(`[LevelDispatch] Error building output history: ${error}`);
@@ -10981,7 +11036,7 @@ var init_dependency_gating = __esm({
10981
11036
  // src/state-machine/dispatch/template-renderer.ts
10982
11037
  async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
10983
11038
  try {
10984
- const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-PKWCKK7E.mjs");
11039
+ const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-DFDEBMUI.mjs");
10985
11040
  const fs8 = await import("fs/promises");
10986
11041
  const path9 = await import("path");
10987
11042
  const schemaRaw = checkConfig.schema || "plain";
@@ -11274,7 +11329,7 @@ async function executeCheckWithForEachItems(checkId, forEachParent, forEachItems
11274
11329
  __outputHistory: outputHistory,
11275
11330
  ai: {
11276
11331
  ...checkConfig.ai || {},
11277
- timeout: checkConfig.ai?.timeout || 6e5,
11332
+ timeout: checkConfig.ai?.timeout || 12e5,
11278
11333
  debug: !!context2.debug
11279
11334
  }
11280
11335
  };
@@ -11754,7 +11809,7 @@ async function executeInvocation(item, context2, scope, prInfo, dependencyResult
11754
11809
  __outputHistory: outputHistory,
11755
11810
  ai: {
11756
11811
  ...stepConfig.ai || {},
11757
- timeout: stepConfig.ai?.timeout || 6e5,
11812
+ timeout: stepConfig.ai?.timeout || 12e5,
11758
11813
  debug: !!context2.debug
11759
11814
  }
11760
11815
  };
@@ -12230,7 +12285,7 @@ async function executeSingleCheck(checkId, context2, state, emitEvent, transitio
12230
12285
  __outputHistory: outputHistory,
12231
12286
  ai: {
12232
12287
  ...checkConfig.ai || {},
12233
- timeout: checkConfig.ai?.timeout || 6e5,
12288
+ timeout: checkConfig.ai?.timeout || 12e5,
12234
12289
  debug: !!context2.debug
12235
12290
  }
12236
12291
  };
@@ -12540,8 +12595,15 @@ function recordOnFinishRoutingEvent(args) {
12540
12595
  if (args.gotoEvent) attrs.goto_event = args.gotoEvent;
12541
12596
  addEvent("visor.routing", attrs);
12542
12597
  }
12598
+ function getHistoryLimit2() {
12599
+ const raw = process.env.VISOR_TEST_HISTORY_LIMIT || process.env.VISOR_OUTPUT_HISTORY_LIMIT;
12600
+ if (!raw) return void 0;
12601
+ const n = parseInt(raw, 10);
12602
+ return Number.isFinite(n) && n > 0 ? n : void 0;
12603
+ }
12543
12604
  function buildOutputHistoryFromJournal2(context2) {
12544
12605
  const outputHistory = /* @__PURE__ */ new Map();
12606
+ const limit = getHistoryLimit2();
12545
12607
  try {
12546
12608
  const snapshot = context2.journal.beginSnapshot();
12547
12609
  const allEntries = context2.journal.readVisible(context2.sessionId, snapshot, void 0);
@@ -12551,7 +12613,13 @@ function buildOutputHistoryFromJournal2(context2) {
12551
12613
  outputHistory.set(checkId, []);
12552
12614
  }
12553
12615
  const payload = entry.result.output !== void 0 ? entry.result.output : entry.result;
12554
- if (payload !== void 0) outputHistory.get(checkId).push(payload);
12616
+ if (payload !== void 0) {
12617
+ const arr = outputHistory.get(checkId);
12618
+ arr.push(payload);
12619
+ if (limit && arr.length > limit) {
12620
+ arr.splice(0, arr.length - limit);
12621
+ }
12622
+ }
12555
12623
  }
12556
12624
  } catch (error) {
12557
12625
  logger.debug(`[LevelDispatch] Error building output history: ${error}`);
@@ -12964,7 +13032,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
12964
13032
  __outputHistory: outputHistory,
12965
13033
  ai: {
12966
13034
  ...checkConfig.ai || {},
12967
- timeout: checkConfig.ai?.timeout || 6e5,
13035
+ timeout: checkConfig.ai?.timeout || 12e5,
12968
13036
  debug: !!context2.debug
12969
13037
  }
12970
13038
  };
@@ -13177,7 +13245,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
13177
13245
  let schemaObj = (typeof checkConfig.schema === "object" ? checkConfig.schema : void 0) || checkConfig.output_schema;
13178
13246
  if (!schemaObj && typeof checkConfig.schema === "string") {
13179
13247
  try {
13180
- const { loadRendererSchema } = await import("./renderer-schema-LPKN5UJS.mjs");
13248
+ const { loadRendererSchema } = await import("./renderer-schema-CKFB5NDB.mjs");
13181
13249
  schemaObj = await loadRendererSchema(checkConfig.schema);
13182
13250
  } catch {
13183
13251
  }
@@ -13510,7 +13578,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
13510
13578
  }
13511
13579
  }
13512
13580
  try {
13513
- const { evaluateTransitions } = await import("./routing-6N45MJ4F.mjs");
13581
+ const { evaluateTransitions } = await import("./routing-KZ345OFG.mjs");
13514
13582
  const transTarget = await evaluateTransitions(
13515
13583
  onFinish.transitions,
13516
13584
  forEachParent,
@@ -13570,7 +13638,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
13570
13638
  `[LevelDispatch] Error evaluating on_finish transitions for ${forEachParent}: ${e instanceof Error ? e.message : String(e)}`
13571
13639
  );
13572
13640
  }
13573
- const { evaluateGoto: evaluateGoto2 } = await import("./routing-6N45MJ4F.mjs");
13641
+ const { evaluateGoto: evaluateGoto2 } = await import("./routing-KZ345OFG.mjs");
13574
13642
  if (context2.debug) {
13575
13643
  logger.info(
13576
13644
  `[LevelDispatch] Evaluating on_finish.goto_js for forEach parent: ${forEachParent}`
@@ -13740,10 +13808,20 @@ async function executeSingleCheck2(checkId, context2, state, emitEvent, transiti
13740
13808
  const dependencies = checkConfig?.depends_on || [];
13741
13809
  const depList = Array.isArray(dependencies) ? dependencies : [dependencies];
13742
13810
  const failedChecks = state.failedChecks;
13811
+ const allowedFailedDeps = state.allowedFailedDeps?.get(checkId);
13743
13812
  const tokens = depList.filter(Boolean);
13744
13813
  const groupSatisfied = (token) => {
13745
13814
  const options = token.includes("|") ? token.split("|").map((s) => s.trim()).filter(Boolean) : [token];
13746
13815
  for (const opt of options) {
13816
+ const isAllowedFailedDep = !!(allowedFailedDeps && allowedFailedDeps.has(opt));
13817
+ if (isAllowedFailedDep) {
13818
+ if (context2.debug) {
13819
+ logger.info(
13820
+ `[LevelDispatch] Allowing ${checkId} to run despite failed dependency ${opt} (on_fail.run)`
13821
+ );
13822
+ }
13823
+ return true;
13824
+ }
13747
13825
  const depCfg = context2.config.checks?.[opt];
13748
13826
  const cont = !!(depCfg && depCfg.continue_on_failure === true);
13749
13827
  const st = state.stats.get(opt);
@@ -13982,7 +14060,7 @@ async function executeSingleCheck2(checkId, context2, state, emitEvent, transiti
13982
14060
  checksMeta,
13983
14061
  ai: {
13984
14062
  ...checkConfig2.ai || {},
13985
- timeout: checkConfig2.ai?.timeout || 6e5,
14063
+ timeout: checkConfig2.ai?.timeout || 12e5,
13986
14064
  debug: !!context2.debug
13987
14065
  }
13988
14066
  };
@@ -14155,7 +14233,7 @@ async function executeSingleCheck2(checkId, context2, state, emitEvent, transiti
14155
14233
  let schemaObj = (typeof checkConfig2.schema === "object" ? checkConfig2.schema : void 0) || checkConfig2.output_schema;
14156
14234
  if (!schemaObj && typeof checkConfig2.schema === "string") {
14157
14235
  try {
14158
- const { loadRendererSchema } = await import("./renderer-schema-LPKN5UJS.mjs");
14236
+ const { loadRendererSchema } = await import("./renderer-schema-CKFB5NDB.mjs");
14159
14237
  schemaObj = await loadRendererSchema(checkConfig2.schema);
14160
14238
  } catch {
14161
14239
  }
@@ -14697,7 +14775,7 @@ function updateStats2(results, state, isForEachIteration = false) {
14697
14775
  }
14698
14776
  async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
14699
14777
  try {
14700
- const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-PKWCKK7E.mjs");
14778
+ const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-DFDEBMUI.mjs");
14701
14779
  const fs8 = await import("fs/promises");
14702
14780
  const path9 = await import("path");
14703
14781
  const schemaRaw = checkConfig.schema || "plain";
@@ -15056,6 +15134,25 @@ var init_runner = __esm({
15056
15134
  }
15057
15135
  } catch {
15058
15136
  }
15137
+ if (event.type === "CheckCompleted") {
15138
+ try {
15139
+ const hook = this.context.executionContext?.hooks?.onCheckComplete;
15140
+ if (typeof hook === "function") {
15141
+ const checkConfig = this.context.config?.checks?.[event.checkId];
15142
+ hook({
15143
+ checkId: event.checkId,
15144
+ result: event.result,
15145
+ checkConfig: checkConfig ? {
15146
+ type: checkConfig.type,
15147
+ group: checkConfig.group,
15148
+ criticality: checkConfig.criticality,
15149
+ schema: checkConfig.schema
15150
+ } : void 0
15151
+ });
15152
+ }
15153
+ } catch {
15154
+ }
15155
+ }
15059
15156
  if (this.context.debug && event.type !== "StateTransition") {
15060
15157
  logger.debug(`[StateMachine] Event: ${event.type}`);
15061
15158
  }
@@ -16093,25 +16190,76 @@ var init_worktree_manager = __esm({
16093
16190
  }
16094
16191
  if (fs7.existsSync(worktreePath)) {
16095
16192
  logger.debug(`Worktree already exists: ${worktreePath}`);
16096
- if (options.clean) {
16097
- logger.debug(`Cleaning existing worktree`);
16098
- await this.cleanWorktree(worktreePath);
16099
- }
16100
16193
  const metadata2 = await this.loadMetadata(worktreePath);
16101
16194
  if (metadata2) {
16102
- this.activeWorktrees.set(worktreeId, metadata2);
16103
- return {
16104
- id: worktreeId,
16105
- path: worktreePath,
16106
- ref: metadata2.ref,
16107
- commit: metadata2.commit,
16108
- metadata: metadata2,
16109
- locked: false
16110
- };
16195
+ if (metadata2.ref === ref) {
16196
+ if (options.clean) {
16197
+ logger.debug(`Cleaning existing worktree`);
16198
+ await this.cleanWorktree(worktreePath);
16199
+ }
16200
+ this.activeWorktrees.set(worktreeId, metadata2);
16201
+ return {
16202
+ id: worktreeId,
16203
+ path: worktreePath,
16204
+ ref: metadata2.ref,
16205
+ commit: metadata2.commit,
16206
+ metadata: metadata2,
16207
+ locked: false
16208
+ };
16209
+ } else {
16210
+ logger.info(
16211
+ `Worktree exists with different ref (${metadata2.ref} -> ${ref}), updating...`
16212
+ );
16213
+ try {
16214
+ const bareRepoPath2 = metadata2.bare_repo_path || await this.getOrCreateBareRepo(
16215
+ repository,
16216
+ repoUrl,
16217
+ options.token,
16218
+ options.fetchDepth,
16219
+ options.cloneTimeoutMs
16220
+ );
16221
+ await this.fetchRef(bareRepoPath2, ref);
16222
+ const newCommit = await this.getCommitShaForRef(bareRepoPath2, ref);
16223
+ const checkoutCmd = `git -C ${this.escapeShellArg(worktreePath)} checkout --detach ${this.escapeShellArg(newCommit)}`;
16224
+ const checkoutResult = await this.executeGitCommand(checkoutCmd, { timeout: 6e4 });
16225
+ if (checkoutResult.exitCode !== 0) {
16226
+ throw new Error(`Failed to checkout new ref: ${checkoutResult.stderr}`);
16227
+ }
16228
+ const updatedMetadata = {
16229
+ ...metadata2,
16230
+ ref,
16231
+ commit: newCommit,
16232
+ created_at: (/* @__PURE__ */ new Date()).toISOString()
16233
+ };
16234
+ await this.saveMetadata(worktreePath, updatedMetadata);
16235
+ if (options.clean) {
16236
+ logger.debug(`Cleaning updated worktree`);
16237
+ await this.cleanWorktree(worktreePath);
16238
+ }
16239
+ this.activeWorktrees.set(worktreeId, updatedMetadata);
16240
+ logger.info(`Successfully updated worktree to ${ref} (${newCommit})`);
16241
+ return {
16242
+ id: worktreeId,
16243
+ path: worktreePath,
16244
+ ref,
16245
+ commit: newCommit,
16246
+ metadata: updatedMetadata,
16247
+ locked: false
16248
+ };
16249
+ } catch (error) {
16250
+ const errorMessage = error instanceof Error ? error.message : String(error);
16251
+ logger.warn(`Failed to update worktree, will recreate: ${errorMessage}`);
16252
+ await fsp.rm(worktreePath, { recursive: true, force: true });
16253
+ }
16254
+ }
16255
+ } else {
16256
+ logger.info(`Removing stale directory (no metadata): ${worktreePath}`);
16257
+ await fsp.rm(worktreePath, { recursive: true, force: true });
16111
16258
  }
16112
16259
  }
16113
16260
  await this.fetchRef(bareRepoPath, ref);
16114
16261
  const commit = await this.getCommitShaForRef(bareRepoPath, ref);
16262
+ await this.pruneWorktrees(bareRepoPath);
16115
16263
  logger.info(`Creating worktree for ${repository}@${ref} (${commit})`);
16116
16264
  const createCmd = `git -C ${this.escapeShellArg(
16117
16265
  bareRepoPath
@@ -16144,6 +16292,20 @@ var init_worktree_manager = __esm({
16144
16292
  locked: false
16145
16293
  };
16146
16294
  }
16295
+ /**
16296
+ * Prune stale worktree entries from a bare repository.
16297
+ * This removes entries for worktrees whose directories no longer exist.
16298
+ */
16299
+ async pruneWorktrees(bareRepoPath) {
16300
+ logger.debug(`Pruning stale worktrees for ${bareRepoPath}`);
16301
+ const pruneCmd = `git -C ${this.escapeShellArg(bareRepoPath)} worktree prune`;
16302
+ const result = await this.executeGitCommand(pruneCmd, { timeout: 1e4 });
16303
+ if (result.exitCode !== 0) {
16304
+ logger.warn(`Failed to prune worktrees: ${result.stderr}`);
16305
+ } else {
16306
+ logger.debug(`Successfully pruned stale worktrees`);
16307
+ }
16308
+ }
16147
16309
  /**
16148
16310
  * Fetch a specific ref in bare repository
16149
16311
  */
@@ -16504,6 +16666,53 @@ var init_git_checkout_provider = __esm({
16504
16666
  async execute(prInfo, config, dependencyResults, context2) {
16505
16667
  const checkoutConfig = config;
16506
16668
  const issues = [];
16669
+ try {
16670
+ const stepName = config.checkName || "git-checkout";
16671
+ if (process.env.VISOR_DEBUG === "true") {
16672
+ logger.debug(
16673
+ `[GitCheckout] Mock check: stepName=${stepName}, context=${!!context2}, hooks=${!!context2?.hooks}, mockForStep=${!!context2?.hooks?.mockForStep}`
16674
+ );
16675
+ }
16676
+ const mock = context2?.hooks?.mockForStep?.(String(stepName));
16677
+ if (process.env.VISOR_DEBUG === "true") {
16678
+ logger.debug(
16679
+ `[GitCheckout] Mock result: ${mock !== void 0 ? "found" : "not found"}, value=${JSON.stringify(mock)}`
16680
+ );
16681
+ }
16682
+ if (mock !== void 0) {
16683
+ if (mock && typeof mock === "object") {
16684
+ const mockOutput = mock;
16685
+ if (mockOutput.success === false) {
16686
+ const errorMsg = String(mockOutput.error || "Mocked checkout failure");
16687
+ if (process.env.VISOR_DEBUG === "true") {
16688
+ logger.debug(`[GitCheckout] Returning mock failure: ${errorMsg}`);
16689
+ }
16690
+ return {
16691
+ issues: [
16692
+ {
16693
+ file: "git-checkout",
16694
+ line: 0,
16695
+ ruleId: "git-checkout/error",
16696
+ message: `Failed to checkout code: ${errorMsg}`,
16697
+ severity: "error",
16698
+ category: "logic"
16699
+ }
16700
+ ],
16701
+ output: mockOutput
16702
+ };
16703
+ }
16704
+ if (process.env.VISOR_DEBUG === "true") {
16705
+ logger.debug(`[GitCheckout] Returning mock success: ${JSON.stringify(mockOutput)}`);
16706
+ }
16707
+ return { issues: [], output: mockOutput };
16708
+ }
16709
+ if (process.env.VISOR_DEBUG === "true") {
16710
+ logger.debug(`[GitCheckout] Returning primitive mock: ${String(mock)}`);
16711
+ }
16712
+ return { issues: [], output: { success: true, path: String(mock) } };
16713
+ }
16714
+ } catch {
16715
+ }
16507
16716
  try {
16508
16717
  const templateContext = this.buildTemplateContext(
16509
16718
  prInfo,
@@ -16658,7 +16867,7 @@ var init_git_checkout_provider = __esm({
16658
16867
  }
16659
16868
  async isAvailable() {
16660
16869
  try {
16661
- const { commandExecutor: commandExecutor2 } = await import("./command-executor-TYUV6HUS.mjs");
16870
+ const { commandExecutor: commandExecutor2 } = await import("./command-executor-Q7MHJKZJ.mjs");
16662
16871
  const result = await commandExecutor2.execute("git --version", { timeout: 5e3 });
16663
16872
  return result.exitCode === 0;
16664
16873
  } catch (_error) {
@@ -16869,4 +17078,4 @@ export {
16869
17078
  StateMachineRunner,
16870
17079
  init_runner
16871
17080
  };
16872
- //# sourceMappingURL=chunk-23L3QRYX.mjs.map
17081
+ //# sourceMappingURL=chunk-VPEQOQ7G.mjs.map