@probelabs/visor 0.1.178 → 0.1.179

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 (94) hide show
  1. package/defaults/assistant.yaml +38 -16
  2. package/defaults/skills/code-explorer.yaml +8 -8
  3. package/dist/agent-protocol/tasks-cli-handler.d.ts.map +1 -1
  4. package/dist/agent-protocol/track-execution.d.ts.map +1 -1
  5. package/dist/defaults/assistant.yaml +38 -16
  6. package/dist/defaults/skills/code-explorer.yaml +8 -8
  7. package/dist/frontends/slack-frontend.d.ts +6 -0
  8. package/dist/frontends/slack-frontend.d.ts.map +1 -1
  9. package/dist/index.js +305 -87
  10. package/dist/output/traces/{run-2026-03-11T06-33-05-398Z.ndjson → run-2026-03-11T13-57-13-250Z.ndjson} +96 -96
  11. package/dist/output/traces/{run-2026-03-11T06-33-47-884Z.ndjson → run-2026-03-11T13-57-55-455Z.ndjson} +1932 -1932
  12. package/dist/providers/ai-check-provider.d.ts.map +1 -1
  13. package/dist/sdk/{a2a-frontend-WYBMBBYG.mjs → a2a-frontend-HKPCABGG.mjs} +2 -2
  14. package/dist/sdk/{a2a-frontend-U3PTNCLR.mjs → a2a-frontend-KJFLIZJT.mjs} +2 -2
  15. package/dist/sdk/{check-provider-registry-3DZOXYIA.mjs → check-provider-registry-EXP6DYGL.mjs} +5 -5
  16. package/dist/sdk/{check-provider-registry-T5J3H2N7.mjs → check-provider-registry-SYAHJMWJ.mjs} +5 -5
  17. package/dist/sdk/{check-provider-registry-ZX76MY2L.mjs → check-provider-registry-WKVXEZXA.mjs} +5 -5
  18. package/dist/sdk/{chunk-AK64Y6Y2.mjs → chunk-BFQUKQQI.mjs} +163 -124
  19. package/dist/sdk/chunk-BFQUKQQI.mjs.map +1 -0
  20. package/dist/sdk/{chunk-6YGCACBF.mjs → chunk-CHARL3TY.mjs} +2 -2
  21. package/dist/sdk/{chunk-6YGCACBF.mjs.map → chunk-CHARL3TY.mjs.map} +1 -1
  22. package/dist/sdk/{chunk-4ECMTCOM.mjs → chunk-DMUBFE4V.mjs} +2 -2
  23. package/dist/sdk/{chunk-B7XHSG3L.mjs → chunk-FTPLYUQ3.mjs} +163 -124
  24. package/dist/sdk/chunk-FTPLYUQ3.mjs.map +1 -0
  25. package/dist/sdk/{chunk-ANEKFNAS.mjs → chunk-JTRN5AR7.mjs} +163 -124
  26. package/dist/sdk/chunk-JTRN5AR7.mjs.map +1 -0
  27. package/dist/sdk/{chunk-ENSZDV3O.mjs → chunk-NNL5M6QR.mjs} +3 -3
  28. package/dist/sdk/{chunk-CDRKH5HH.mjs → chunk-OYHDBTKY.mjs} +2 -2
  29. package/dist/sdk/{chunk-KG6PM4OL.mjs → chunk-WSPF7FAK.mjs} +3 -3
  30. package/dist/sdk/{chunk-KG6PM4OL.mjs.map → chunk-WSPF7FAK.mjs.map} +1 -1
  31. package/dist/sdk/{chunk-WZS4ARZB.mjs → chunk-ZJYQMNPA.mjs} +3 -3
  32. package/dist/sdk/{failure-condition-evaluator-P3MS5DRL.mjs → failure-condition-evaluator-CBJ2DP4X.mjs} +3 -3
  33. package/dist/sdk/{failure-condition-evaluator-MMPKQGUA.mjs → failure-condition-evaluator-V2YGFRKO.mjs} +3 -3
  34. package/dist/sdk/{github-frontend-7RLEBJWG.mjs → github-frontend-4LM4NAZK.mjs} +3 -3
  35. package/dist/sdk/{github-frontend-QTKOYB56.mjs → github-frontend-VGU6PNQH.mjs} +3 -3
  36. package/dist/sdk/{host-I2TBBKD5.mjs → host-AMJG7BIE.mjs} +4 -4
  37. package/dist/sdk/{host-SE3MQHWG.mjs → host-XXPPPC76.mjs} +4 -4
  38. package/dist/sdk/{routing-2X6QF5IW.mjs → routing-W6AUOIGF.mjs} +4 -4
  39. package/dist/sdk/{routing-QHXBQS6X.mjs → routing-YAYBIVPL.mjs} +4 -4
  40. package/dist/sdk/{schedule-tool-R6JJIDZ6.mjs → schedule-tool-BVWTYA2Y.mjs} +5 -5
  41. package/dist/sdk/{schedule-tool-W4SQ334O.mjs → schedule-tool-OIVJDIDK.mjs} +5 -5
  42. package/dist/sdk/{schedule-tool-MKT5FZ6J.mjs → schedule-tool-T3PAV4N3.mjs} +5 -5
  43. package/dist/sdk/{schedule-tool-handler-AOMZV3Q3.mjs → schedule-tool-handler-AYJP3FGI.mjs} +5 -5
  44. package/dist/sdk/{schedule-tool-handler-MPJFLH4J.mjs → schedule-tool-handler-SJF4ZKSB.mjs} +5 -5
  45. package/dist/sdk/{schedule-tool-handler-WY7WCFE5.mjs → schedule-tool-handler-VOCVDJSM.mjs} +5 -5
  46. package/dist/sdk/sdk.js +214 -138
  47. package/dist/sdk/sdk.js.map +1 -1
  48. package/dist/sdk/sdk.mjs +4 -4
  49. package/dist/sdk/{slack-frontend-XKSIOUXB.mjs → slack-frontend-OWD7BSWF.mjs} +22 -3
  50. package/dist/sdk/slack-frontend-OWD7BSWF.mjs.map +1 -0
  51. package/dist/sdk/{trace-helpers-4ADQ4GB3.mjs → trace-helpers-FZAVMGTD.mjs} +2 -2
  52. package/dist/sdk/{trace-helpers-K47ZVJSU.mjs → trace-helpers-QL2B75AK.mjs} +2 -2
  53. package/dist/sdk/{track-execution-XTCZBUWX.mjs → track-execution-2Q66SXBZ.mjs} +20 -2
  54. package/dist/sdk/{track-execution-XTCZBUWX.mjs.map → track-execution-2Q66SXBZ.mjs.map} +1 -1
  55. package/dist/sdk/{workflow-check-provider-WHZP7BDF.mjs → workflow-check-provider-IXW6BMQA.mjs} +5 -5
  56. package/dist/sdk/{workflow-check-provider-WZN3B2S2.mjs → workflow-check-provider-JW43OGRQ.mjs} +5 -5
  57. package/dist/sdk/{workflow-check-provider-A3YH2UZJ.mjs → workflow-check-provider-ZG2JHKBH.mjs} +5 -5
  58. package/dist/traces/{run-2026-03-11T06-33-05-398Z.ndjson → run-2026-03-11T13-57-13-250Z.ndjson} +96 -96
  59. package/dist/traces/{run-2026-03-11T06-33-47-884Z.ndjson → run-2026-03-11T13-57-55-455Z.ndjson} +1932 -1932
  60. package/dist/utils/workspace-manager.d.ts +2 -0
  61. package/dist/utils/workspace-manager.d.ts.map +1 -1
  62. package/package.json +2 -2
  63. package/dist/sdk/chunk-AK64Y6Y2.mjs.map +0 -1
  64. package/dist/sdk/chunk-ANEKFNAS.mjs.map +0 -1
  65. package/dist/sdk/chunk-B7XHSG3L.mjs.map +0 -1
  66. package/dist/sdk/slack-frontend-XKSIOUXB.mjs.map +0 -1
  67. /package/dist/sdk/{a2a-frontend-U3PTNCLR.mjs.map → a2a-frontend-HKPCABGG.mjs.map} +0 -0
  68. /package/dist/sdk/{a2a-frontend-WYBMBBYG.mjs.map → a2a-frontend-KJFLIZJT.mjs.map} +0 -0
  69. /package/dist/sdk/{check-provider-registry-3DZOXYIA.mjs.map → check-provider-registry-EXP6DYGL.mjs.map} +0 -0
  70. /package/dist/sdk/{check-provider-registry-T5J3H2N7.mjs.map → check-provider-registry-SYAHJMWJ.mjs.map} +0 -0
  71. /package/dist/sdk/{check-provider-registry-ZX76MY2L.mjs.map → check-provider-registry-WKVXEZXA.mjs.map} +0 -0
  72. /package/dist/sdk/{chunk-4ECMTCOM.mjs.map → chunk-DMUBFE4V.mjs.map} +0 -0
  73. /package/dist/sdk/{chunk-ENSZDV3O.mjs.map → chunk-NNL5M6QR.mjs.map} +0 -0
  74. /package/dist/sdk/{chunk-CDRKH5HH.mjs.map → chunk-OYHDBTKY.mjs.map} +0 -0
  75. /package/dist/sdk/{chunk-WZS4ARZB.mjs.map → chunk-ZJYQMNPA.mjs.map} +0 -0
  76. /package/dist/sdk/{failure-condition-evaluator-MMPKQGUA.mjs.map → failure-condition-evaluator-CBJ2DP4X.mjs.map} +0 -0
  77. /package/dist/sdk/{failure-condition-evaluator-P3MS5DRL.mjs.map → failure-condition-evaluator-V2YGFRKO.mjs.map} +0 -0
  78. /package/dist/sdk/{github-frontend-7RLEBJWG.mjs.map → github-frontend-4LM4NAZK.mjs.map} +0 -0
  79. /package/dist/sdk/{github-frontend-QTKOYB56.mjs.map → github-frontend-VGU6PNQH.mjs.map} +0 -0
  80. /package/dist/sdk/{host-I2TBBKD5.mjs.map → host-AMJG7BIE.mjs.map} +0 -0
  81. /package/dist/sdk/{host-SE3MQHWG.mjs.map → host-XXPPPC76.mjs.map} +0 -0
  82. /package/dist/sdk/{routing-2X6QF5IW.mjs.map → routing-W6AUOIGF.mjs.map} +0 -0
  83. /package/dist/sdk/{routing-QHXBQS6X.mjs.map → routing-YAYBIVPL.mjs.map} +0 -0
  84. /package/dist/sdk/{schedule-tool-MKT5FZ6J.mjs.map → schedule-tool-BVWTYA2Y.mjs.map} +0 -0
  85. /package/dist/sdk/{schedule-tool-R6JJIDZ6.mjs.map → schedule-tool-OIVJDIDK.mjs.map} +0 -0
  86. /package/dist/sdk/{schedule-tool-W4SQ334O.mjs.map → schedule-tool-T3PAV4N3.mjs.map} +0 -0
  87. /package/dist/sdk/{schedule-tool-handler-AOMZV3Q3.mjs.map → schedule-tool-handler-AYJP3FGI.mjs.map} +0 -0
  88. /package/dist/sdk/{schedule-tool-handler-MPJFLH4J.mjs.map → schedule-tool-handler-SJF4ZKSB.mjs.map} +0 -0
  89. /package/dist/sdk/{schedule-tool-handler-WY7WCFE5.mjs.map → schedule-tool-handler-VOCVDJSM.mjs.map} +0 -0
  90. /package/dist/sdk/{trace-helpers-4ADQ4GB3.mjs.map → trace-helpers-FZAVMGTD.mjs.map} +0 -0
  91. /package/dist/sdk/{trace-helpers-K47ZVJSU.mjs.map → trace-helpers-QL2B75AK.mjs.map} +0 -0
  92. /package/dist/sdk/{workflow-check-provider-A3YH2UZJ.mjs.map → workflow-check-provider-IXW6BMQA.mjs.map} +0 -0
  93. /package/dist/sdk/{workflow-check-provider-WHZP7BDF.mjs.map → workflow-check-provider-JW43OGRQ.mjs.map} +0 -0
  94. /package/dist/sdk/{workflow-check-provider-WZN3B2S2.mjs.map → workflow-check-provider-ZG2JHKBH.mjs.map} +0 -0
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- process.env.VISOR_VERSION = '0.1.178';
3
- process.env.PROBE_VERSION = '0.6.0-rc293';
4
- process.env.VISOR_COMMIT_SHA = '79fcc6344e1ab954501ff6a7f9614a0372019b2b';
5
- process.env.VISOR_COMMIT_SHORT = '79fcc6344';
2
+ process.env.VISOR_VERSION = '0.1.179';
3
+ process.env.PROBE_VERSION = '0.6.0-rc294';
4
+ process.env.VISOR_COMMIT_SHA = 'c2ec610fc6c00b8e34666b8dad089ca3cf06bbf5';
5
+ process.env.VISOR_COMMIT_SHORT = 'c2ec610f';
6
6
  /******/ (() => { // webpackBootstrap
7
7
  /******/ var __webpack_modules__ = ({
8
8
 
@@ -299882,6 +299882,19 @@ async function handleShow(positional, flags) {
299882
299882
  if (match.run_id)
299883
299883
  detailTable.push({ 'Run ID': match.run_id });
299884
299884
  detailTable.push({ Input: match.request_message });
299885
+ // Show AI response from status_message (recorded on completion/failure)
299886
+ const fullTask = store.getTask(match.id);
299887
+ if (fullTask?.status?.message) {
299888
+ const parts = fullTask.status.message.parts ?? [];
299889
+ const textPart = parts.find((p) => typeof p.text === 'string');
299890
+ if (textPart) {
299891
+ const responseText = textPart.text;
299892
+ // Truncate long responses for display
299893
+ const maxLen = 500;
299894
+ const display = responseText.length > maxLen ? responseText.slice(0, maxLen) + '...' : responseText;
299895
+ detailTable.push({ Response: display });
299896
+ }
299897
+ }
299885
299898
  // Show metadata
299886
299899
  const meta = match.metadata;
299887
299900
  const metaKeys = Object.keys(meta).filter(k => k !== 'source');
@@ -300057,10 +300070,35 @@ async function trackExecution(opts, executor) {
300057
300070
  logger_1.logger.info(`[TaskTracking] Task ${task.id} started (source=${source}, workflow=${workflowId || '-'}, instance=${instanceId})`);
300058
300071
  try {
300059
300072
  const result = await executor();
300073
+ // Extract AI response text from the result using the same pattern as Slack frontend:
300074
+ // result.reviewSummary.history has check outputs, look for output.text in any check
300075
+ let responseText = 'Execution completed';
300076
+ try {
300077
+ const history = result?.reviewSummary?.history;
300078
+ if (history) {
300079
+ // Look through check outputs for a text response (e.g., generate-response)
300080
+ for (const outputs of Object.values(history)) {
300081
+ if (!Array.isArray(outputs))
300082
+ continue;
300083
+ for (const out of outputs) {
300084
+ const text = out?.text;
300085
+ if (typeof text === 'string' && text.trim().length > 0) {
300086
+ responseText = text.trim();
300087
+ break;
300088
+ }
300089
+ }
300090
+ if (responseText !== 'Execution completed')
300091
+ break;
300092
+ }
300093
+ }
300094
+ }
300095
+ catch {
300096
+ // ignore extraction errors
300097
+ }
300060
300098
  const completedMsg = {
300061
300099
  message_id: crypto_1.default.randomUUID(),
300062
300100
  role: 'agent',
300063
- parts: [{ text: 'Execution completed' }],
300101
+ parts: [{ text: responseText }],
300064
300102
  };
300065
300103
  taskStore.updateTaskState(task.id, 'completed', completedMsg);
300066
300104
  logger_1.logger.info(`[TaskTracking] Task ${task.id} completed`);
@@ -312972,17 +313010,28 @@ class SlackFrontend {
312972
313010
  const message = ev?.error?.message || 'Execution error';
312973
313011
  await this.maybePostError(ctx, 'Check failed', message, ev?.checkId).catch(() => { });
312974
313012
  }));
312975
- // On terminal state, replace 👀 with 👍 if we acked an inbound Slack message
313013
+ // On terminal state, replace 👀 with 👍 if we acked an inbound Slack message.
313014
+ // For error states, always post an error notice (bypass errorNotified flag)
313015
+ // so the user is never left without feedback when a run fails.
312976
313016
  this.subs.push(bus.on('StateTransition', async (env) => {
312977
313017
  const ev = (env && env.payload) || env;
312978
- if (ev && (ev.to === 'Completed' || ev.to === 'Error')) {
313018
+ if (ev && ev.to === 'Completed') {
313019
+ await this.finalizeReactions(ctx).catch(() => { });
313020
+ }
313021
+ else if (ev && ev.to === 'Error') {
313022
+ if (!this.errorNotified) {
313023
+ await this.maybePostError(ctx, 'Run failed', 'Workflow finished with errors').catch(() => { });
313024
+ }
312979
313025
  await this.finalizeReactions(ctx).catch(() => { });
312980
313026
  }
312981
313027
  }));
312982
313028
  this.subs.push(bus.on('Shutdown', async (env) => {
312983
313029
  const ev = (env && env.payload) || env;
312984
313030
  const message = ev?.error?.message || 'Fatal error';
312985
- await this.maybePostError(ctx, 'Run failed', message).catch(() => { });
313031
+ // Always post shutdown errors bypass errorNotified since a fatal
313032
+ // shutdown is critical and must reach the user even if a previous
313033
+ // (possibly unrelated) check already posted a non-fatal error.
313034
+ await this.forcePostError(ctx, 'Run failed', message).catch(() => { });
312986
313035
  }));
312987
313036
  // Add 👀 acknowledgement as soon as first check is scheduled for Slack-driven runs
312988
313037
  this.subs.push(bus.on('CheckScheduled', async () => {
@@ -313111,6 +313160,16 @@ class SlackFrontend {
313111
313160
  async maybePostError(ctx, title, message, checkId) {
313112
313161
  if (this.errorNotified)
313113
313162
  return;
313163
+ return this.postErrorToSlack(ctx, title, message, checkId);
313164
+ }
313165
+ /**
313166
+ * Post error to Slack regardless of errorNotified flag.
313167
+ * Used for fatal/shutdown errors that must always reach the user.
313168
+ */
313169
+ async forcePostError(ctx, title, message, checkId) {
313170
+ return this.postErrorToSlack(ctx, title, message, checkId);
313171
+ }
313172
+ async postErrorToSlack(ctx, title, message, checkId) {
313114
313173
  const slack = this.getSlack(ctx);
313115
313174
  if (!slack)
313116
313175
  return;
@@ -325541,46 +325600,51 @@ class AICheckProvider extends check_provider_interface_1.CheckProvider {
325541
325600
  // Check-level AI configuration (ai object)
325542
325601
  if (config.ai) {
325543
325602
  const aiAny = config.ai;
325603
+ // Helper to resolve Liquid templates in ai config values (e.g., "{{ inputs.max_iterations }}")
325604
+ const resolveLiquid = async (val) => {
325605
+ if (typeof val !== 'string' || !val.includes('{{'))
325606
+ return undefined;
325607
+ try {
325608
+ return (await this.liquidEngine.parseAndRender(val, {
325609
+ inputs: config.workflowInputs || {},
325610
+ env: process.env,
325611
+ })).trim();
325612
+ }
325613
+ catch {
325614
+ return undefined;
325615
+ }
325616
+ };
325617
+ // Helper to resolve a boolean that may be a Liquid template string
325618
+ const resolveBool = async (val) => {
325619
+ const resolved = (await resolveLiquid(val)) ?? val;
325620
+ if (typeof resolved === 'boolean')
325621
+ return resolved;
325622
+ if (typeof resolved === 'string')
325623
+ return resolved === 'true';
325624
+ return !!resolved;
325625
+ };
325544
325626
  const skipTransport = aiAny.skip_transport_context === true;
325545
325627
  // Only set properties that are actually defined to avoid overriding env vars
325546
325628
  if (aiAny.apiKey !== undefined) {
325547
325629
  aiConfig.apiKey = aiAny.apiKey;
325548
325630
  }
325549
325631
  if (aiAny.model !== undefined) {
325550
- let modelVal = String(aiAny.model);
325551
- if (modelVal.includes('{{')) {
325552
- try {
325553
- const rendered = await this.liquidEngine.parseAndRender(modelVal, {
325554
- inputs: config.workflowInputs || {},
325555
- env: process.env,
325556
- });
325557
- modelVal = rendered.trim();
325558
- }
325559
- catch { }
325560
- }
325632
+ const modelVal = (await resolveLiquid(aiAny.model)) ?? String(aiAny.model);
325561
325633
  if (modelVal) {
325562
325634
  aiConfig.model = modelVal;
325563
325635
  }
325564
325636
  }
325565
325637
  if (aiAny.timeout !== undefined) {
325566
- aiConfig.timeout = aiAny.timeout;
325638
+ const resolvedTimeout = (await resolveLiquid(aiAny.timeout)) ?? aiAny.timeout;
325639
+ aiConfig.timeout = Number(resolvedTimeout);
325567
325640
  }
325568
325641
  if (aiAny.max_iterations !== undefined || aiAny.maxIterations !== undefined) {
325569
325642
  const raw = aiAny.max_iterations ?? aiAny.maxIterations;
325570
- aiConfig.maxIterations = Number(raw);
325643
+ const resolved = (await resolveLiquid(raw)) ?? raw;
325644
+ aiConfig.maxIterations = Number(resolved);
325571
325645
  }
325572
325646
  if (aiAny.provider !== undefined) {
325573
- let providerVal = String(aiAny.provider);
325574
- if (providerVal.includes('{{')) {
325575
- try {
325576
- const rendered = await this.liquidEngine.parseAndRender(providerVal, {
325577
- inputs: config.workflowInputs || {},
325578
- env: process.env,
325579
- });
325580
- providerVal = rendered.trim();
325581
- }
325582
- catch { }
325583
- }
325647
+ const providerVal = (await resolveLiquid(aiAny.provider)) ?? String(aiAny.provider);
325584
325648
  if (providerVal) {
325585
325649
  aiConfig.provider = providerVal;
325586
325650
  }
@@ -325589,36 +325653,40 @@ class AICheckProvider extends check_provider_interface_1.CheckProvider {
325589
325653
  aiConfig.debug = aiAny.debug;
325590
325654
  }
325591
325655
  if (aiAny.enableDelegate !== undefined) {
325592
- aiConfig.enableDelegate = aiAny.enableDelegate;
325656
+ aiConfig.enableDelegate = await resolveBool(aiAny.enableDelegate);
325593
325657
  }
325594
325658
  if (aiAny.enableTasks !== undefined) {
325595
- aiConfig.enableTasks = aiAny.enableTasks;
325659
+ aiConfig.enableTasks = await resolveBool(aiAny.enableTasks);
325596
325660
  }
325597
325661
  if (aiAny.enableExecutePlan !== undefined) {
325598
- aiConfig.enableExecutePlan = aiAny.enableExecutePlan;
325662
+ aiConfig.enableExecutePlan = await resolveBool(aiAny.enableExecutePlan);
325599
325663
  }
325600
325664
  if (aiAny.allowEdit !== undefined) {
325601
- aiConfig.allowEdit = aiAny.allowEdit;
325665
+ aiConfig.allowEdit = await resolveBool(aiAny.allowEdit);
325602
325666
  }
325603
325667
  if (aiAny.allowedTools !== undefined) {
325604
325668
  aiConfig.allowedTools = aiAny.allowedTools;
325605
325669
  this.logDebug(`[AI Provider] Read allowedTools from YAML: ${JSON.stringify(aiAny.allowedTools)}`);
325606
325670
  }
325607
325671
  if (aiAny.disableTools !== undefined) {
325608
- aiConfig.disableTools = aiAny.disableTools;
325672
+ aiConfig.disableTools = await resolveBool(aiAny.disableTools);
325609
325673
  this.logDebug(`[AI Provider] Read disableTools from YAML: ${aiAny.disableTools}`);
325610
325674
  }
325611
325675
  if (aiAny.allowBash !== undefined) {
325612
- aiConfig.allowBash = aiAny.allowBash;
325676
+ aiConfig.allowBash = await resolveBool(aiAny.allowBash);
325613
325677
  }
325614
325678
  if (aiAny.bashConfig !== undefined) {
325615
325679
  aiConfig.bashConfig = aiAny.bashConfig;
325616
325680
  }
325617
325681
  if (aiAny.search_delegate_provider !== undefined) {
325618
- aiConfig.search_delegate_provider = aiAny.search_delegate_provider;
325682
+ aiConfig.search_delegate_provider =
325683
+ (await resolveLiquid(aiAny.search_delegate_provider)) ??
325684
+ aiAny.search_delegate_provider;
325619
325685
  }
325620
325686
  if (aiAny.search_delegate_model !== undefined) {
325621
- aiConfig.search_delegate_model = aiAny.search_delegate_model;
325687
+ aiConfig.search_delegate_model =
325688
+ (await resolveLiquid(aiAny.search_delegate_model)) ??
325689
+ aiAny.search_delegate_model;
325622
325690
  }
325623
325691
  if (aiAny.completion_prompt !== undefined) {
325624
325692
  aiConfig.completionPrompt = aiAny.completion_prompt;
@@ -325758,6 +325826,11 @@ class AICheckProvider extends check_provider_interface_1.CheckProvider {
325758
325826
  if (config.ai_max_iterations !== undefined && aiConfig.maxIterations === undefined) {
325759
325827
  aiConfig.maxIterations = config.ai_max_iterations;
325760
325828
  }
325829
+ // Default to 100 iterations if not configured (ProbeAgent's own default is 30)
325830
+ // Guard against NaN from template rendering (e.g., Number("{{ ... }}") = NaN)
325831
+ if (aiConfig.maxIterations === undefined || Number.isNaN(aiConfig.maxIterations)) {
325832
+ aiConfig.maxIterations = 100;
325833
+ }
325761
325834
  // Pass shared concurrency limiter for global AI call gating
325762
325835
  const sharedLimiter = sessionInfo?._parentContext?.sharedConcurrencyLimiter;
325763
325836
  if (sharedLimiter) {
@@ -372640,9 +372713,39 @@ class WorkspaceManager {
372640
372713
  const mainProjectName = sanitizePathComponent(configuredMainProjectName || this.extractProjectName(this.originalPath));
372641
372714
  this.usedNames.add(mainProjectName);
372642
372715
  // Create worktree for main project
372643
- const mainProjectPath = path.join(this.workspacePath, mainProjectName);
372716
+ let mainProjectPath = path.join(this.workspacePath, mainProjectName);
372644
372717
  // Check if original path is a git repository
372645
372718
  const isGitRepo = await this.isGitRepository(this.originalPath);
372719
+ // Prune stale worktree references (from previous runs that were cleaned up).
372720
+ // Without this, the worktree list grows unboundedly and can slow git operations.
372721
+ if (isGitRepo) {
372722
+ try {
372723
+ await command_executor_1.commandExecutor.execute(`git -C ${shellEscape(this.originalPath)} worktree prune`, {
372724
+ timeout: 15000,
372725
+ });
372726
+ }
372727
+ catch {
372728
+ // Best-effort — don't fail workspace init if prune fails
372729
+ }
372730
+ }
372731
+ // Detect if originalPath is a subdirectory of a git repo.
372732
+ // `git worktree add` always checks out the full repo, so if the user runs
372733
+ // visor from a subdirectory (e.g. /repo/subdir), the worktree will contain
372734
+ // the entire repo and we need to adjust mainProjectPath to point to the
372735
+ // corresponding subdirectory inside the worktree.
372736
+ let subdirOffset = '';
372737
+ if (isGitRepo) {
372738
+ const gitRootResult = await command_executor_1.commandExecutor.execute(`git -C ${shellEscape(this.originalPath)} rev-parse --show-toplevel`, { timeout: 5000 });
372739
+ if (gitRootResult.exitCode === 0) {
372740
+ const gitRoot = gitRootResult.stdout.trim();
372741
+ const normalizedOriginal = path.resolve(this.originalPath);
372742
+ const normalizedRoot = path.resolve(gitRoot);
372743
+ if (normalizedOriginal !== normalizedRoot) {
372744
+ subdirOffset = path.relative(normalizedRoot, normalizedOriginal);
372745
+ logger_1.logger.info(`[Workspace] Original path is a subdirectory of git repo: ${subdirOffset}`);
372746
+ }
372747
+ }
372748
+ }
372646
372749
  if (isGitRepo) {
372647
372750
  // Check if main project worktree already exists (reused workspace, e.g. Slack thread)
372648
372751
  const exists = await this.pathExists(mainProjectPath);
@@ -372680,6 +372783,23 @@ class WorkspaceManager {
372680
372783
  }
372681
372784
  }
372682
372785
  }
372786
+ // Remember the worktree root before any subdirectory adjustment.
372787
+ // Cleanup needs the actual worktree path (not the subdirectory inside it).
372788
+ const worktreeRootPath = mainProjectPath;
372789
+ // If the original path was a subdirectory, adjust mainProjectPath to
372790
+ // point to the corresponding subdirectory inside the worktree.
372791
+ // e.g. worktree at /tmp/ws/Oel contains full repo; if originalPath was
372792
+ // /repo/Oel, then mainProjectPath becomes /tmp/ws/Oel/Oel
372793
+ if (subdirOffset) {
372794
+ mainProjectPath = path.join(mainProjectPath, subdirOffset);
372795
+ logger_1.logger.info(`[Workspace] Adjusted main project path to subdirectory: ${mainProjectPath}`);
372796
+ // Ensure the subdirectory exists in the worktree
372797
+ const subdirExists = await this.pathExists(mainProjectPath);
372798
+ if (!subdirExists) {
372799
+ logger_1.logger.warn(`[Workspace] Subdirectory '${subdirOffset}' not found in worktree — falling back to worktree root`);
372800
+ mainProjectPath = path.join(this.workspacePath, mainProjectName);
372801
+ }
372802
+ }
372683
372803
  // Scan existing entries in the workspace directory to populate usedNames.
372684
372804
  // This handles reused workspaces (e.g. Slack threads) where a previous run
372685
372805
  // left symlinks on disk but the in-memory state was cleared by cleanup().
@@ -372702,6 +372822,7 @@ class WorkspaceManager {
372702
372822
  mainProjectPath,
372703
372823
  mainProjectName,
372704
372824
  originalPath: this.originalPath,
372825
+ worktreeRootPath,
372705
372826
  };
372706
372827
  this.initialized = true;
372707
372828
  logger_1.logger.info(`Workspace initialized: ${this.workspacePath}`);
@@ -372810,14 +372931,16 @@ class WorkspaceManager {
372810
372931
  ]);
372811
372932
  }
372812
372933
  try {
372813
- // Remove main project worktree if it exists
372934
+ // Remove main project worktree if it exists.
372935
+ // Use worktreeRootPath (the actual git worktree) rather than mainProjectPath
372936
+ // which may include a subdirectory offset (e.g. Oel/Oel instead of Oel).
372814
372937
  if (this.mainProjectInfo) {
372815
- const mainProjectPath = this.mainProjectInfo.mainProjectPath;
372938
+ const worktreePath = this.mainProjectInfo.worktreeRootPath || this.mainProjectInfo.mainProjectPath;
372816
372939
  // Check if path exists and if it's a worktree (not a symlink)
372817
372940
  try {
372818
- const stats = await fsp.lstat(mainProjectPath);
372941
+ const stats = await fsp.lstat(worktreePath);
372819
372942
  if (!stats.isSymbolicLink()) {
372820
- await this.removeMainProjectWorktree(mainProjectPath);
372943
+ await this.removeMainProjectWorktree(worktreePath);
372821
372944
  }
372822
372945
  }
372823
372946
  catch {
@@ -545893,9 +546016,13 @@ var init_ProbeAgent = __esm({
545893
546016
  }
545894
546017
  return await this.fallbackManager.executeWithFallback(
545895
546018
  async (provider, model, config2) => {
546019
+ let fallbackModel = provider(model);
546020
+ if (this.concurrencyLimiter) {
546021
+ fallbackModel = _ProbeAgent._wrapModelWithLimiter(fallbackModel, this.concurrencyLimiter, this.debug);
546022
+ }
545896
546023
  const fallbackOptions = {
545897
546024
  ...options,
545898
- model: provider(model),
546025
+ model: fallbackModel,
545899
546026
  abortSignal: controller.signal
545900
546027
  };
545901
546028
  if (config2.provider !== "google" && fallbackOptions.tools) {
@@ -545923,6 +546050,132 @@ var init_ProbeAgent = __esm({
545923
546050
  }
545924
546051
  );
545925
546052
  }
546053
+ /**
546054
+ * Wrap a LanguageModelV1 model so each doStream/doGenerate call acquires and
546055
+ * releases a concurrency limiter slot. This gates individual LLM API calls
546056
+ * (seconds each) instead of entire multi-step agent sessions (minutes).
546057
+ *
546058
+ * @param {Object} model - LanguageModelV1 model instance
546059
+ * @param {Object} limiter - Concurrency limiter with acquire/release/getStats
546060
+ * @param {boolean} debug - Enable debug logging
546061
+ * @returns {Object} Wrapped model with per-call concurrency gating
546062
+ * @private
546063
+ */
546064
+ static _wrapModelWithLimiter(model, limiter, debug) {
546065
+ return new Proxy(model, {
546066
+ get(target, prop) {
546067
+ if (prop === "doStream") {
546068
+ return async function(...args) {
546069
+ await limiter.acquire(null);
546070
+ if (debug) {
546071
+ const stats = limiter.getStats();
546072
+ console.log(`[DEBUG] Acquired AI slot for LLM call (${stats.globalActive}/${stats.maxConcurrent}, queue: ${stats.queueSize})`);
546073
+ }
546074
+ try {
546075
+ const result = await target.doStream(...args);
546076
+ const originalStream = result.stream;
546077
+ const originalReader = originalStream.getReader();
546078
+ let released = false;
546079
+ const releaseOnce = () => {
546080
+ if (released) return;
546081
+ released = true;
546082
+ limiter.release(null);
546083
+ };
546084
+ const wrappedStream = new ReadableStream({
546085
+ async pull(controller) {
546086
+ try {
546087
+ const { done, value: value2 } = await originalReader.read();
546088
+ if (done) {
546089
+ controller.close();
546090
+ releaseOnce();
546091
+ if (debug) {
546092
+ const stats = limiter.getStats();
546093
+ console.log(`[DEBUG] Released AI slot after LLM stream complete (${stats.globalActive}/${stats.maxConcurrent})`);
546094
+ }
546095
+ } else {
546096
+ controller.enqueue(value2);
546097
+ }
546098
+ } catch (err) {
546099
+ releaseOnce();
546100
+ if (debug) {
546101
+ console.log(`[DEBUG] Released AI slot on LLM stream error`);
546102
+ }
546103
+ controller.error(err);
546104
+ }
546105
+ },
546106
+ cancel() {
546107
+ releaseOnce();
546108
+ if (debug) {
546109
+ console.log(`[DEBUG] Released AI slot on LLM stream cancel`);
546110
+ }
546111
+ originalReader.cancel();
546112
+ }
546113
+ });
546114
+ return { ...result, stream: wrappedStream };
546115
+ } catch (err) {
546116
+ limiter.release(null);
546117
+ if (debug) {
546118
+ console.log(`[DEBUG] Released AI slot on doStream error`);
546119
+ }
546120
+ throw err;
546121
+ }
546122
+ };
546123
+ }
546124
+ if (prop === "doGenerate") {
546125
+ return async function(...args) {
546126
+ await limiter.acquire(null);
546127
+ if (debug) {
546128
+ const stats = limiter.getStats();
546129
+ console.log(`[DEBUG] Acquired AI slot for LLM generate (${stats.globalActive}/${stats.maxConcurrent})`);
546130
+ }
546131
+ try {
546132
+ const result = await target.doGenerate(...args);
546133
+ return result;
546134
+ } finally {
546135
+ limiter.release(null);
546136
+ if (debug) {
546137
+ const stats = limiter.getStats();
546138
+ console.log(`[DEBUG] Released AI slot after LLM generate (${stats.globalActive}/${stats.maxConcurrent})`);
546139
+ }
546140
+ }
546141
+ };
546142
+ }
546143
+ const value = target[prop];
546144
+ return typeof value === "function" ? value.bind(target) : value;
546145
+ }
546146
+ });
546147
+ }
546148
+ /**
546149
+ * Wrap an engine stream result so its textStream async generator acquires
546150
+ * and releases a concurrency limiter slot. Acquire happens when iteration
546151
+ * begins; release happens in finally (completion, error, or break).
546152
+ *
546153
+ * @param {Object} result - Engine result with { textStream, usage, ... }
546154
+ * @param {Object} limiter - Concurrency limiter with acquire/release/getStats
546155
+ * @param {boolean} debug - Enable debug logging
546156
+ * @returns {Object} Result with wrapped textStream
546157
+ * @private
546158
+ */
546159
+ static _wrapEngineStreamWithLimiter(result, limiter, debug) {
546160
+ const originalStream = result.textStream;
546161
+ async function* gatedStream() {
546162
+ await limiter.acquire(null);
546163
+ if (debug) {
546164
+ const stats = limiter.getStats();
546165
+ console.log(`[DEBUG] Acquired AI slot for engine stream (${stats.globalActive}/${stats.maxConcurrent}, queue: ${stats.queueSize})`);
546166
+ }
546167
+ try {
546168
+ yield* originalStream;
546169
+ } finally {
546170
+ limiter.release(null);
546171
+ if (debug) {
546172
+ const stats = limiter.getStats();
546173
+ console.log(`[DEBUG] Released AI slot after engine stream (${stats.globalActive}/${stats.maxConcurrent})`);
546174
+ }
546175
+ }
546176
+ }
546177
+ return { ...result, textStream: gatedStream() };
546178
+ }
545926
546179
  /**
545927
546180
  * Execute streamText with retry and fallback support
545928
546181
  * @param {Object} options - streamText options
@@ -545931,12 +546184,8 @@ var init_ProbeAgent = __esm({
545931
546184
  */
545932
546185
  async streamTextWithRetryAndFallback(options) {
545933
546186
  const limiter = this.concurrencyLimiter;
545934
- if (limiter) {
545935
- await limiter.acquire(null);
545936
- if (this.debug) {
545937
- const stats = limiter.getStats();
545938
- console.log(`[DEBUG] Acquired global AI concurrency slot (${stats.globalActive}/${stats.maxConcurrent}, queue: ${stats.queueSize})`);
545939
- }
546187
+ if (limiter && options.model) {
546188
+ options = { ...options, model: _ProbeAgent._wrapModelWithLimiter(options.model, limiter, this.debug) };
545940
546189
  }
545941
546190
  const controller = new AbortController();
545942
546191
  const timeoutState = { timeoutId: null };
@@ -545964,6 +546213,9 @@ var init_ProbeAgent = __esm({
545964
546213
  if (useClaudeCode || useCodex) {
545965
546214
  try {
545966
546215
  result = await this._tryEngineStreamPath(options, controller, timeoutState);
546216
+ if (result && limiter) {
546217
+ result = _ProbeAgent._wrapEngineStreamWithLimiter(result, limiter, this.debug);
546218
+ }
545967
546219
  } catch (error40) {
545968
546220
  if (this.debug) {
545969
546221
  const engineType = useClaudeCode ? "Claude Code" : "Codex";
@@ -545974,41 +546226,7 @@ var init_ProbeAgent = __esm({
545974
546226
  if (!result) {
545975
546227
  result = await this._executeWithVercelProvider(options, controller);
545976
546228
  }
545977
- if (limiter && result.textStream) {
545978
- const originalStream = result.textStream;
545979
- const debug = this.debug;
545980
- const wrappedStream = (async function* () {
545981
- try {
545982
- for await (const chunk of originalStream) {
545983
- yield chunk;
545984
- }
545985
- } finally {
545986
- limiter.release(null);
545987
- if (debug) {
545988
- const stats = limiter.getStats();
545989
- console.log(`[DEBUG] Released global AI concurrency slot (${stats.globalActive}/${stats.maxConcurrent}, queue: ${stats.queueSize})`);
545990
- }
545991
- }
545992
- })();
545993
- return new Proxy(result, {
545994
- get(target, prop) {
545995
- if (prop === "textStream") return wrappedStream;
545996
- const value = target[prop];
545997
- return typeof value === "function" ? value.bind(target) : value;
545998
- }
545999
- });
546000
- } else if (limiter) {
546001
- limiter.release(null);
546002
- }
546003
546229
  return result;
546004
- } catch (error40) {
546005
- if (limiter) {
546006
- limiter.release(null);
546007
- if (this.debug) {
546008
- console.log(`[DEBUG] Released global AI concurrency slot on error`);
546009
- }
546010
- }
546011
- throw error40;
546012
546230
  } finally {
546013
546231
  if (timeoutState.timeoutId) {
546014
546232
  clearTimeout(timeoutState.timeoutId);
@@ -609177,7 +609395,7 @@ module.exports = /*#__PURE__*/JSON.parse('["aaa","aarp","abb","abbott","abbvie",
609177
609395
  /***/ ((module) => {
609178
609396
 
609179
609397
  "use strict";
609180
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@probelabs/visor","version":"0.1.178","main":"dist/index.js","bin":{"visor":"./dist/index.js"},"exports":{".":{"require":"./dist/index.js","import":"./dist/index.js"},"./sdk":{"types":"./dist/sdk/sdk.d.ts","import":"./dist/sdk/sdk.mjs","require":"./dist/sdk/sdk.js"},"./cli":{"require":"./dist/index.js"}},"files":["dist/","defaults/","action.yml","README.md","LICENSE"],"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build:cli":"ncc build src/index.ts -o dist && cp -r defaults dist/ && cp -r output dist/ && cp -r docs dist/ && cp -r examples dist/ && cp -r src/debug-visualizer/ui dist/debug-visualizer/ && node scripts/inject-version.js && echo \'#!/usr/bin/env node\' | cat - dist/index.js > temp && mv temp dist/index.js && chmod +x dist/index.js","build:sdk":"tsup src/sdk.ts --dts --sourcemap --format esm,cjs --out-dir dist/sdk","build":"./scripts/build-oss.sh","build:ee":"npm run build:cli && npm run build:sdk","test":"jest && npm run test:yaml","test:unit":"jest","prepublishOnly":"npm run build","test:watch":"jest --watch","test:coverage":"jest --coverage","test:ee":"jest --testPathPatterns=\'tests/ee\' --testPathIgnorePatterns=\'/node_modules/\' --no-coverage","test:manual:bash":"RUN_MANUAL_TESTS=true jest tests/manual/bash-config-manual.test.ts","lint":"eslint src tests --ext .ts","lint:fix":"eslint src tests --ext .ts --fix","format":"prettier --write src tests","format:check":"prettier --check src tests","clean":"","clean:traces":"node scripts/clean-traces.js","prebuild":"npm run clean && node scripts/generate-config-schema.js","pretest":"npm run clean:traces && node scripts/generate-config-schema.js && npm run build:cli","pretest:unit":"npm run clean:traces && node scripts/generate-config-schema.js && npm run build:cli","test:with-build":"npm run build:cli && jest","test:yaml":"node dist/index.js test --progress compact","test:yaml:parallel":"node dist/index.js test --progress compact --max-parallel 4","prepare":"husky","pre-commit":"lint-staged","deploy:site":"cd site && npx wrangler pages deploy . --project-name=visor-site --commit-dirty=true","deploy:worker":"npx wrangler deploy","deploy":"npm run deploy:site && npm run deploy:worker","publish:ee":"./scripts/publish-ee.sh","release":"./scripts/release.sh","release:patch":"./scripts/release.sh patch","release:minor":"./scripts/release.sh minor","release:major":"./scripts/release.sh major","release:prerelease":"./scripts/release.sh prerelease","docs:validate":"node scripts/validate-readme-links.js","workshop:setup":"npm install -D reveal-md@6.1.2","workshop:serve":"cd workshop && reveal-md slides.md -w","workshop:export":"reveal-md workshop/slides.md --static workshop/build","workshop:pdf":"reveal-md workshop/slides.md --print workshop/Visor-Workshop.pdf --print-size letter","workshop:pdf:ci":"reveal-md workshop/slides.md --print workshop/Visor-Workshop.pdf --print-size letter --puppeteer-launch-args=\\"--no-sandbox --disable-dev-shm-usage\\"","workshop:pdf:a4":"reveal-md workshop/slides.md --print workshop/Visor-Workshop-A4.pdf --print-size A4","workshop:build":"npm run workshop:export && npm run workshop:pdf","simulate:issue":"TS_NODE_TRANSPILE_ONLY=1 ts-node scripts/simulate-gh-run.ts --event issues --action opened --debug","simulate:comment":"TS_NODE_TRANSPILE_ONLY=1 ts-node scripts/simulate-gh-run.ts --event issue_comment --action created --debug"},"keywords":["code-review","ai","github-action","cli","pr-review","visor"],"author":"Probe Labs","license":"MIT","description":"AI workflow engine for code review, assistants, and automation — orchestrate checks, MCP tools, and AI providers with YAML-driven pipelines","repository":{"type":"git","url":"git+https://github.com/probelabs/visor.git"},"bugs":{"url":"https://github.com/probelabs/visor/issues"},"homepage":"https://github.com/probelabs/visor#readme","dependencies":{"@actions/core":"^1.11.1","@apidevtools/swagger-parser":"^12.1.0","@grammyjs/runner":"^2.0.3","@modelcontextprotocol/sdk":"^1.25.3","@nyariv/sandboxjs":"github:probelabs/SandboxJS#23c4bb611f7d05f3cb8c523917b5f57103e48108","@octokit/action":"^8.0.2","@octokit/auth-app":"^8.1.0","@octokit/core":"^7.0.3","@octokit/rest":"^22.0.0","@opentelemetry/api":"^1.9.0","@opentelemetry/api-logs":"^0.203.0","@opentelemetry/core":"^1.30.1","@opentelemetry/exporter-logs-otlp-http":"^0.203.0","@opentelemetry/exporter-metrics-otlp-http":"^0.203.0","@opentelemetry/exporter-trace-otlp-grpc":"^0.203.0","@opentelemetry/exporter-trace-otlp-http":"^0.203.0","@opentelemetry/instrumentation":"^0.203.0","@opentelemetry/resources":"^1.30.1","@opentelemetry/sdk-logs":"^0.203.0","@opentelemetry/sdk-metrics":"^1.30.1","@opentelemetry/sdk-node":"^0.203.0","@opentelemetry/sdk-trace-base":"^1.30.1","@opentelemetry/semantic-conventions":"^1.30.1","@probelabs/probe":"^0.6.0-rc293","@types/commander":"^2.12.0","@types/uuid":"^10.0.0","acorn":"^8.16.0","acorn-walk":"^8.3.5","ajv":"^8.17.1","ajv-formats":"^3.0.1","better-sqlite3":"^11.0.0","blessed":"^0.1.81","botbuilder":"^4.23.3","botframework-connector":"^4.23.3","cli-table3":"^0.6.5","commander":"^14.0.0","deepmerge":"^4.3.1","dotenv":"^17.2.3","grammy":"^1.41.1","ignore":"^7.0.5","imapflow":"^1.2.12","js-yaml":"^4.1.0","jsonpath-plus":"^10.4.0","liquidjs":"^10.21.1","mailparser":"^3.9.3","minimatch":"^10.2.2","node-cron":"^3.0.3","nodemailer":"^8.0.1","open":"^9.1.0","resend":"^6.9.3","simple-git":"^3.28.0","uuid":"^11.1.0","ws":"^8.18.3"},"optionalDependencies":{"@anthropic/claude-code-sdk":"npm:null@*","@open-policy-agent/opa-wasm":"^1.10.0","knex":"^3.1.0","mysql2":"^3.11.0","pg":"^8.13.0","tedious":"^19.0.0"},"devDependencies":{"@eslint/js":"^9.34.0","@kie/act-js":"^2.6.2","@kie/mock-github":"^2.0.1","@swc/core":"^1.13.2","@swc/jest":"^0.2.37","@types/better-sqlite3":"^7.6.0","@types/blessed":"^0.1.27","@types/jest":"^30.0.0","@types/js-yaml":"^4.0.9","@types/mailparser":"^3.4.6","@types/node":"^24.3.0","@types/node-cron":"^3.0.11","@types/nodemailer":"^7.0.11","@types/ws":"^8.18.1","@typescript-eslint/eslint-plugin":"^8.42.0","@typescript-eslint/parser":"^8.42.0","@vercel/ncc":"^0.38.4","eslint":"^9.34.0","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4","husky":"^9.1.7","jest":"^30.1.3","lint-staged":"^16.1.6","prettier":"^3.6.2","reveal-md":"^6.1.2","ts-json-schema-generator":"^1.5.1","ts-node":"^10.9.2","tsup":"^8.5.0","typescript":"^5.9.2","wrangler":"^3.0.0"},"peerDependenciesMeta":{"@anthropic/claude-code-sdk":{"optional":true}},"directories":{"test":"tests"},"lint-staged":{"src/**/*.{ts,js}":["eslint --fix","prettier --write"],"tests/**/*.{ts,js}":["eslint --fix","prettier --write"],"*.{json,md,yml,yaml}":["prettier --write"]}}');
609398
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@probelabs/visor","version":"0.1.179","main":"dist/index.js","bin":{"visor":"./dist/index.js"},"exports":{".":{"require":"./dist/index.js","import":"./dist/index.js"},"./sdk":{"types":"./dist/sdk/sdk.d.ts","import":"./dist/sdk/sdk.mjs","require":"./dist/sdk/sdk.js"},"./cli":{"require":"./dist/index.js"}},"files":["dist/","defaults/","action.yml","README.md","LICENSE"],"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build:cli":"ncc build src/index.ts -o dist && cp -r defaults dist/ && cp -r output dist/ && cp -r docs dist/ && cp -r examples dist/ && cp -r src/debug-visualizer/ui dist/debug-visualizer/ && node scripts/inject-version.js && echo \'#!/usr/bin/env node\' | cat - dist/index.js > temp && mv temp dist/index.js && chmod +x dist/index.js","build:sdk":"tsup src/sdk.ts --dts --sourcemap --format esm,cjs --out-dir dist/sdk","build":"./scripts/build-oss.sh","build:ee":"npm run build:cli && npm run build:sdk","test":"jest && npm run test:yaml","test:unit":"jest","prepublishOnly":"npm run build","test:watch":"jest --watch","test:coverage":"jest --coverage","test:ee":"jest --testPathPatterns=\'tests/ee\' --testPathIgnorePatterns=\'/node_modules/\' --no-coverage","test:manual:bash":"RUN_MANUAL_TESTS=true jest tests/manual/bash-config-manual.test.ts","lint":"eslint src tests --ext .ts","lint:fix":"eslint src tests --ext .ts --fix","format":"prettier --write src tests","format:check":"prettier --check src tests","clean":"","clean:traces":"node scripts/clean-traces.js","prebuild":"npm run clean && node scripts/generate-config-schema.js","pretest":"npm run clean:traces && node scripts/generate-config-schema.js && npm run build:cli","pretest:unit":"npm run clean:traces && node scripts/generate-config-schema.js && npm run build:cli","test:with-build":"npm run build:cli && jest","test:yaml":"node dist/index.js test --progress compact","test:yaml:parallel":"node dist/index.js test --progress compact --max-parallel 4","prepare":"husky","pre-commit":"lint-staged","deploy:site":"cd site && npx wrangler pages deploy . --project-name=visor-site --commit-dirty=true","deploy:worker":"npx wrangler deploy","deploy":"npm run deploy:site && npm run deploy:worker","publish:ee":"./scripts/publish-ee.sh","release":"./scripts/release.sh","release:patch":"./scripts/release.sh patch","release:minor":"./scripts/release.sh minor","release:major":"./scripts/release.sh major","release:prerelease":"./scripts/release.sh prerelease","docs:validate":"node scripts/validate-readme-links.js","workshop:setup":"npm install -D reveal-md@6.1.2","workshop:serve":"cd workshop && reveal-md slides.md -w","workshop:export":"reveal-md workshop/slides.md --static workshop/build","workshop:pdf":"reveal-md workshop/slides.md --print workshop/Visor-Workshop.pdf --print-size letter","workshop:pdf:ci":"reveal-md workshop/slides.md --print workshop/Visor-Workshop.pdf --print-size letter --puppeteer-launch-args=\\"--no-sandbox --disable-dev-shm-usage\\"","workshop:pdf:a4":"reveal-md workshop/slides.md --print workshop/Visor-Workshop-A4.pdf --print-size A4","workshop:build":"npm run workshop:export && npm run workshop:pdf","simulate:issue":"TS_NODE_TRANSPILE_ONLY=1 ts-node scripts/simulate-gh-run.ts --event issues --action opened --debug","simulate:comment":"TS_NODE_TRANSPILE_ONLY=1 ts-node scripts/simulate-gh-run.ts --event issue_comment --action created --debug"},"keywords":["code-review","ai","github-action","cli","pr-review","visor"],"author":"Probe Labs","license":"MIT","description":"AI workflow engine for code review, assistants, and automation — orchestrate checks, MCP tools, and AI providers with YAML-driven pipelines","repository":{"type":"git","url":"git+https://github.com/probelabs/visor.git"},"bugs":{"url":"https://github.com/probelabs/visor/issues"},"homepage":"https://github.com/probelabs/visor#readme","dependencies":{"@actions/core":"^1.11.1","@apidevtools/swagger-parser":"^12.1.0","@grammyjs/runner":"^2.0.3","@modelcontextprotocol/sdk":"^1.25.3","@nyariv/sandboxjs":"github:probelabs/SandboxJS#23c4bb611f7d05f3cb8c523917b5f57103e48108","@octokit/action":"^8.0.2","@octokit/auth-app":"^8.1.0","@octokit/core":"^7.0.3","@octokit/rest":"^22.0.0","@opentelemetry/api":"^1.9.0","@opentelemetry/api-logs":"^0.203.0","@opentelemetry/core":"^1.30.1","@opentelemetry/exporter-logs-otlp-http":"^0.203.0","@opentelemetry/exporter-metrics-otlp-http":"^0.203.0","@opentelemetry/exporter-trace-otlp-grpc":"^0.203.0","@opentelemetry/exporter-trace-otlp-http":"^0.203.0","@opentelemetry/instrumentation":"^0.203.0","@opentelemetry/resources":"^1.30.1","@opentelemetry/sdk-logs":"^0.203.0","@opentelemetry/sdk-metrics":"^1.30.1","@opentelemetry/sdk-node":"^0.203.0","@opentelemetry/sdk-trace-base":"^1.30.1","@opentelemetry/semantic-conventions":"^1.30.1","@probelabs/probe":"^0.6.0-rc294","@types/commander":"^2.12.0","@types/uuid":"^10.0.0","acorn":"^8.16.0","acorn-walk":"^8.3.5","ajv":"^8.17.1","ajv-formats":"^3.0.1","better-sqlite3":"^11.0.0","blessed":"^0.1.81","botbuilder":"^4.23.3","botframework-connector":"^4.23.3","cli-table3":"^0.6.5","commander":"^14.0.0","deepmerge":"^4.3.1","dotenv":"^17.2.3","grammy":"^1.41.1","ignore":"^7.0.5","imapflow":"^1.2.12","js-yaml":"^4.1.0","jsonpath-plus":"^10.4.0","liquidjs":"^10.21.1","mailparser":"^3.9.3","minimatch":"^10.2.2","node-cron":"^3.0.3","nodemailer":"^8.0.1","open":"^9.1.0","resend":"^6.9.3","simple-git":"^3.28.0","uuid":"^11.1.0","ws":"^8.18.3"},"optionalDependencies":{"@anthropic/claude-code-sdk":"npm:null@*","@open-policy-agent/opa-wasm":"^1.10.0","knex":"^3.1.0","mysql2":"^3.11.0","pg":"^8.13.0","tedious":"^19.0.0"},"devDependencies":{"@eslint/js":"^9.34.0","@kie/act-js":"^2.6.2","@kie/mock-github":"^2.0.1","@swc/core":"^1.13.2","@swc/jest":"^0.2.37","@types/better-sqlite3":"^7.6.0","@types/blessed":"^0.1.27","@types/jest":"^30.0.0","@types/js-yaml":"^4.0.9","@types/mailparser":"^3.4.6","@types/node":"^24.3.0","@types/node-cron":"^3.0.11","@types/nodemailer":"^7.0.11","@types/ws":"^8.18.1","@typescript-eslint/eslint-plugin":"^8.42.0","@typescript-eslint/parser":"^8.42.0","@vercel/ncc":"^0.38.4","eslint":"^9.34.0","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4","husky":"^9.1.7","jest":"^30.1.3","lint-staged":"^16.1.6","prettier":"^3.6.2","reveal-md":"^6.1.2","ts-json-schema-generator":"^1.5.1","ts-node":"^10.9.2","tsup":"^8.5.0","typescript":"^5.9.2","wrangler":"^3.0.0"},"peerDependenciesMeta":{"@anthropic/claude-code-sdk":{"optional":true}},"directories":{"test":"tests"},"lint-staged":{"src/**/*.{ts,js}":["eslint --fix","prettier --write"],"tests/**/*.{ts,js}":["eslint --fix","prettier --write"],"*.{json,md,yml,yaml}":["prettier --write"]}}');
609181
609399
 
609182
609400
  /***/ })
609183
609401