@probelabs/visor 0.1.152 → 0.1.153

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 (88) hide show
  1. package/dist/config.d.ts.map +1 -1
  2. package/dist/docs/ai-configuration.md +4 -4
  3. package/dist/docs/sandbox-engines.md +53 -5
  4. package/dist/examples/ai-with-bash.yaml +2 -2
  5. package/dist/examples/sandbox-bind-paths.yaml +31 -0
  6. package/dist/examples/sandbox-host-workdir.yaml +27 -0
  7. package/dist/examples/workflow-sandbox.yaml +43 -0
  8. package/dist/generated/config-schema.d.ts +38 -8
  9. package/dist/generated/config-schema.d.ts.map +1 -1
  10. package/dist/generated/config-schema.json +40 -8
  11. package/dist/index.js +149 -37
  12. package/dist/output/traces/{run-2026-03-04T06-46-24-105Z.ndjson → run-2026-03-04T13-24-27-240Z.ndjson} +84 -84
  13. package/dist/{traces/run-2026-03-04T06-47-08-884Z.ndjson → output/traces/run-2026-03-04T13-25-12-321Z.ndjson} +1802 -1802
  14. package/dist/sandbox/bubblewrap-sandbox.d.ts.map +1 -1
  15. package/dist/sandbox/check-runner.d.ts.map +1 -1
  16. package/dist/sandbox/docker-image-sandbox.d.ts.map +1 -1
  17. package/dist/sandbox/seatbelt-sandbox.d.ts.map +1 -1
  18. package/dist/sandbox/types.d.ts +13 -0
  19. package/dist/sandbox/types.d.ts.map +1 -1
  20. package/dist/scheduler/schedule-tool.d.ts +2 -0
  21. package/dist/scheduler/schedule-tool.d.ts.map +1 -1
  22. package/dist/sdk/{check-provider-registry-QBURXJ6B.mjs → check-provider-registry-CSIZGIKC.mjs} +3 -3
  23. package/dist/sdk/{check-provider-registry-VY5ZZAEU.mjs → check-provider-registry-OEPUY5P6.mjs} +6 -6
  24. package/dist/sdk/{check-provider-registry-DCZR46KQ.mjs → check-provider-registry-ZOGNKTC3.mjs} +3 -3
  25. package/dist/sdk/{chunk-FYK2DJK6.mjs → chunk-CPYQDJ27.mjs} +86 -26
  26. package/dist/sdk/chunk-CPYQDJ27.mjs.map +1 -0
  27. package/dist/sdk/{chunk-QRR6OJQN.mjs → chunk-EYQWEVZF.mjs} +130 -91
  28. package/dist/sdk/chunk-EYQWEVZF.mjs.map +1 -0
  29. package/dist/sdk/{chunk-FP3RZSLW.mjs → chunk-KBX4OIXL.mjs} +2 -2
  30. package/dist/sdk/{chunk-XJZKNTKZ.mjs → chunk-NYK7WDGH.mjs} +130 -91
  31. package/dist/sdk/chunk-NYK7WDGH.mjs.map +1 -0
  32. package/dist/sdk/{chunk-6VQ73GYD.mjs → chunk-SMR5N5MG.mjs} +2 -2
  33. package/dist/sdk/{chunk-6VQ73GYD.mjs.map → chunk-SMR5N5MG.mjs.map} +1 -1
  34. package/dist/sdk/{chunk-PCI4FXAO.mjs → chunk-U7KB66AN.mjs} +138 -99
  35. package/dist/sdk/chunk-U7KB66AN.mjs.map +1 -0
  36. package/dist/sdk/{chunk-LLVVHYIP.mjs → chunk-VBN45DBR.mjs} +3 -3
  37. package/dist/sdk/{config-MTEIGCOQ.mjs → config-SW3VO4DQ.mjs} +2 -2
  38. package/dist/sdk/{failure-condition-evaluator-TV227HAG.mjs → failure-condition-evaluator-Y32S6DB2.mjs} +3 -3
  39. package/dist/sdk/{github-frontend-YLSS5NQ7.mjs → github-frontend-6SIR7QWX.mjs} +3 -3
  40. package/dist/sdk/{host-WNCX3MPT.mjs → host-YBJOWFT4.mjs} +2 -2
  41. package/dist/sdk/{routing-FKWK5BHS.mjs → routing-U63OJMZQ.mjs} +4 -4
  42. package/dist/sdk/{schedule-tool-IJC2TSKU.mjs → schedule-tool-74VMD77T.mjs} +3 -3
  43. package/dist/sdk/{schedule-tool-62XTFB6K.mjs → schedule-tool-NMCFABHK.mjs} +3 -3
  44. package/dist/sdk/{schedule-tool-VOZ536P4.mjs → schedule-tool-NYRLSV4F.mjs} +6 -6
  45. package/dist/sdk/{schedule-tool-handler-WBIZSBGJ.mjs → schedule-tool-handler-2TFSBZ2O.mjs} +6 -6
  46. package/dist/sdk/{schedule-tool-handler-5K275UT6.mjs → schedule-tool-handler-DRVRLVGD.mjs} +3 -3
  47. package/dist/sdk/{schedule-tool-handler-T4L2ECBA.mjs → schedule-tool-handler-EOQBRZSD.mjs} +3 -3
  48. package/dist/sdk/sdk.d.mts +15 -2
  49. package/dist/sdk/sdk.d.ts +15 -2
  50. package/dist/sdk/sdk.js +210 -111
  51. package/dist/sdk/sdk.js.map +1 -1
  52. package/dist/sdk/sdk.mjs +5 -5
  53. package/dist/sdk/{trace-helpers-W33WMBL7.mjs → trace-helpers-2BIVADUK.mjs} +2 -2
  54. package/dist/sdk/{workflow-check-provider-6TEZHBZJ.mjs → workflow-check-provider-4NHVFLMQ.mjs} +3 -3
  55. package/dist/sdk/{workflow-check-provider-FONJYRMR.mjs → workflow-check-provider-GIW4WECT.mjs} +3 -3
  56. package/dist/sdk/{workflow-check-provider-LREOGGTH.mjs → workflow-check-provider-UQMMFLSK.mjs} +6 -6
  57. package/dist/state-machine/workflow-projection.d.ts.map +1 -1
  58. package/dist/traces/{run-2026-03-04T06-46-24-105Z.ndjson → run-2026-03-04T13-24-27-240Z.ndjson} +84 -84
  59. package/dist/{output/traces/run-2026-03-04T06-47-08-884Z.ndjson → traces/run-2026-03-04T13-25-12-321Z.ndjson} +1802 -1802
  60. package/dist/types/config.d.ts +2 -2
  61. package/dist/types/config.d.ts.map +1 -1
  62. package/dist/types/workflow.d.ts +8 -0
  63. package/dist/types/workflow.d.ts.map +1 -1
  64. package/package.json +1 -1
  65. package/dist/sdk/chunk-FYK2DJK6.mjs.map +0 -1
  66. package/dist/sdk/chunk-PCI4FXAO.mjs.map +0 -1
  67. package/dist/sdk/chunk-QRR6OJQN.mjs.map +0 -1
  68. package/dist/sdk/chunk-XJZKNTKZ.mjs.map +0 -1
  69. /package/dist/sdk/{check-provider-registry-DCZR46KQ.mjs.map → check-provider-registry-CSIZGIKC.mjs.map} +0 -0
  70. /package/dist/sdk/{check-provider-registry-QBURXJ6B.mjs.map → check-provider-registry-OEPUY5P6.mjs.map} +0 -0
  71. /package/dist/sdk/{check-provider-registry-VY5ZZAEU.mjs.map → check-provider-registry-ZOGNKTC3.mjs.map} +0 -0
  72. /package/dist/sdk/{chunk-FP3RZSLW.mjs.map → chunk-KBX4OIXL.mjs.map} +0 -0
  73. /package/dist/sdk/{chunk-LLVVHYIP.mjs.map → chunk-VBN45DBR.mjs.map} +0 -0
  74. /package/dist/sdk/{config-MTEIGCOQ.mjs.map → config-SW3VO4DQ.mjs.map} +0 -0
  75. /package/dist/sdk/{failure-condition-evaluator-TV227HAG.mjs.map → failure-condition-evaluator-Y32S6DB2.mjs.map} +0 -0
  76. /package/dist/sdk/{github-frontend-YLSS5NQ7.mjs.map → github-frontend-6SIR7QWX.mjs.map} +0 -0
  77. /package/dist/sdk/{host-WNCX3MPT.mjs.map → host-YBJOWFT4.mjs.map} +0 -0
  78. /package/dist/sdk/{routing-FKWK5BHS.mjs.map → routing-U63OJMZQ.mjs.map} +0 -0
  79. /package/dist/sdk/{schedule-tool-62XTFB6K.mjs.map → schedule-tool-74VMD77T.mjs.map} +0 -0
  80. /package/dist/sdk/{schedule-tool-IJC2TSKU.mjs.map → schedule-tool-NMCFABHK.mjs.map} +0 -0
  81. /package/dist/sdk/{schedule-tool-VOZ536P4.mjs.map → schedule-tool-NYRLSV4F.mjs.map} +0 -0
  82. /package/dist/sdk/{schedule-tool-handler-5K275UT6.mjs.map → schedule-tool-handler-2TFSBZ2O.mjs.map} +0 -0
  83. /package/dist/sdk/{schedule-tool-handler-T4L2ECBA.mjs.map → schedule-tool-handler-DRVRLVGD.mjs.map} +0 -0
  84. /package/dist/sdk/{schedule-tool-handler-WBIZSBGJ.mjs.map → schedule-tool-handler-EOQBRZSD.mjs.map} +0 -0
  85. /package/dist/sdk/{trace-helpers-W33WMBL7.mjs.map → trace-helpers-2BIVADUK.mjs.map} +0 -0
  86. /package/dist/sdk/{workflow-check-provider-6TEZHBZJ.mjs.map → workflow-check-provider-4NHVFLMQ.mjs.map} +0 -0
  87. /package/dist/sdk/{workflow-check-provider-FONJYRMR.mjs.map → workflow-check-provider-GIW4WECT.mjs.map} +0 -0
  88. /package/dist/sdk/{workflow-check-provider-LREOGGTH.mjs.map → workflow-check-provider-UQMMFLSK.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.152';
2
+ process.env.VISOR_VERSION = '0.1.153';
3
3
  process.env.PROBE_VERSION = '0.6.0-rc269';
4
- process.env.VISOR_COMMIT_SHA = 'fa1265c0b241f426e6fe44449a8c2f0a0aea1ba7';
5
- process.env.VISOR_COMMIT_SHORT = 'fa1265c0';
4
+ process.env.VISOR_COMMIT_SHA = '812209528637eae4c9bc2358354377275099850f';
5
+ process.env.VISOR_COMMIT_SHORT = '81220952';
6
6
  /******/ (() => { // webpackBootstrap
7
7
  /******/ var __webpack_modules__ = ({
8
8
 
@@ -164503,7 +164503,6 @@ class ConfigManager {
164503
164503
  ['compose', config.compose],
164504
164504
  ['service', config.service],
164505
164505
  ['cache', config.cache],
164506
- ['visor_path', config.visor_path],
164507
164506
  ['resources', config.resources],
164508
164507
  ];
164509
164508
  for (const [field, value] of dockerOnlyFields) {
@@ -164554,21 +164553,6 @@ class ConfigManager {
164554
164553
  message: `Compose file path '${config.compose}' in sandbox '${name}' must not contain '..' path traversal`,
164555
164554
  });
164556
164555
  }
164557
- // Validate visor_path
164558
- if (config.visor_path) {
164559
- if (!config.visor_path.startsWith('/')) {
164560
- errors.push({
164561
- field: `sandboxes.${name}.visor_path`,
164562
- message: `visor_path '${config.visor_path}' in sandbox '${name}' must be an absolute path (start with /)`,
164563
- });
164564
- }
164565
- if (/\.\./.test(config.visor_path)) {
164566
- errors.push({
164567
- field: `sandboxes.${name}.visor_path`,
164568
- message: `visor_path '${config.visor_path}' in sandbox '${name}' must not contain '..' path traversal`,
164569
- });
164570
- }
164571
- }
164572
164556
  // Validate cache paths are absolute and safe
164573
164557
  if (config.cache?.paths) {
164574
164558
  for (const p of config.cache.paths) {
@@ -164600,11 +164584,26 @@ class ConfigManager {
164600
164584
  }
164601
164585
  }
164602
164586
  // Common validations for all engines
164603
- if (config.workdir) {
164587
+ // Validate visor_path
164588
+ if (config.visor_path) {
164589
+ if (!config.visor_path.startsWith('/')) {
164590
+ errors.push({
164591
+ field: `sandboxes.${name}.visor_path`,
164592
+ message: `visor_path '${config.visor_path}' in sandbox '${name}' must be an absolute path (start with /)`,
164593
+ });
164594
+ }
164595
+ if (/\.\./.test(config.visor_path)) {
164596
+ errors.push({
164597
+ field: `sandboxes.${name}.visor_path`,
164598
+ message: `visor_path '${config.visor_path}' in sandbox '${name}' must not contain '..' path traversal`,
164599
+ });
164600
+ }
164601
+ }
164602
+ if (config.workdir && config.workdir !== 'host') {
164604
164603
  if (!config.workdir.startsWith('/')) {
164605
164604
  errors.push({
164606
164605
  field: `sandboxes.${name}.workdir`,
164607
- message: `Workdir '${config.workdir}' in sandbox '${name}' must be an absolute path (start with /)`,
164606
+ message: `Workdir '${config.workdir}' in sandbox '${name}' must be an absolute path (start with /) or the literal "host"`,
164608
164607
  });
164609
164608
  }
164610
164609
  if (/\.\./.test(config.workdir)) {
@@ -164614,6 +164613,38 @@ class ConfigManager {
164614
164613
  });
164615
164614
  }
164616
164615
  }
164616
+ // Validate bind_paths
164617
+ if (config.bind_paths) {
164618
+ for (let i = 0; i < config.bind_paths.length; i++) {
164619
+ const bp = config.bind_paths[i];
164620
+ if (!bp.host) {
164621
+ errors.push({
164622
+ field: `sandboxes.${name}.bind_paths[${i}].host`,
164623
+ message: `bind_paths[${i}] in sandbox '${name}' is missing required 'host' field`,
164624
+ });
164625
+ }
164626
+ if (bp.host && /\.\./.test(bp.host)) {
164627
+ errors.push({
164628
+ field: `sandboxes.${name}.bind_paths[${i}].host`,
164629
+ message: `bind_paths[${i}].host '${bp.host}' in sandbox '${name}' must not contain '..' path traversal`,
164630
+ });
164631
+ }
164632
+ if (bp.container) {
164633
+ if (!bp.container.startsWith('/')) {
164634
+ errors.push({
164635
+ field: `sandboxes.${name}.bind_paths[${i}].container`,
164636
+ message: `bind_paths[${i}].container '${bp.container}' in sandbox '${name}' must be an absolute path (start with /)`,
164637
+ });
164638
+ }
164639
+ if (/\.\./.test(bp.container)) {
164640
+ errors.push({
164641
+ field: `sandboxes.${name}.bind_paths[${i}].container`,
164642
+ message: `bind_paths[${i}].container '${bp.container}' in sandbox '${name}' must not contain '..' path traversal`,
164643
+ });
164644
+ }
164645
+ }
164646
+ }
164647
+ }
164617
164648
  }
164618
164649
  /**
164619
164650
  * Validate individual check configuration
@@ -170161,7 +170192,7 @@ exports.configSchema = {
170161
170192
  description: 'Arguments/inputs for the workflow',
170162
170193
  },
170163
170194
  overrides: {
170164
- $ref: '#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255%3E%3E',
170195
+ $ref: '#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13519-28113-src_types_config.ts-0-55265%3E%3E',
170165
170196
  description: 'Override specific step configurations in the workflow',
170166
170197
  },
170167
170198
  output_mapping: {
@@ -170177,7 +170208,7 @@ exports.configSchema = {
170177
170208
  description: 'Config file path - alternative to workflow ID (loads a Visor config file as workflow)',
170178
170209
  },
170179
170210
  workflow_overrides: {
170180
- $ref: '#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255%3E%3E',
170211
+ $ref: '#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13519-28113-src_types_config.ts-0-55265%3E%3E',
170181
170212
  description: 'Alias for overrides - workflow step overrides (backward compatibility)',
170182
170213
  },
170183
170214
  ref: {
@@ -170598,11 +170629,11 @@ exports.configSchema = {
170598
170629
  },
170599
170630
  description: "Array of blocked command patterns (e.g., ['rm -rf', 'sudo'])",
170600
170631
  },
170601
- noDefaultAllow: {
170632
+ disableDefaultAllow: {
170602
170633
  type: 'boolean',
170603
170634
  description: 'Disable default safe command list (use with caution)',
170604
170635
  },
170605
- noDefaultDeny: {
170636
+ disableDefaultDeny: {
170606
170637
  type: 'boolean',
170607
170638
  description: 'Disable default dangerous command blocklist (use with extreme caution)',
170608
170639
  },
@@ -170866,7 +170897,7 @@ exports.configSchema = {
170866
170897
  description: 'Custom output name (defaults to workflow name)',
170867
170898
  },
170868
170899
  overrides: {
170869
- $ref: '#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255%3E%3E',
170900
+ $ref: '#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13519-28113-src_types_config.ts-0-55265%3E%3E',
170870
170901
  description: 'Step overrides',
170871
170902
  },
170872
170903
  output_mapping: {
@@ -170881,13 +170912,13 @@ exports.configSchema = {
170881
170912
  '^x-': {},
170882
170913
  },
170883
170914
  },
170884
- 'Record<string,Partial<interface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255>>': {
170915
+ 'Record<string,Partial<interface-src_types_config.ts-13519-28113-src_types_config.ts-0-55265>>': {
170885
170916
  type: 'object',
170886
170917
  additionalProperties: {
170887
- $ref: '#/definitions/Partial%3Cinterface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255%3E',
170918
+ $ref: '#/definitions/Partial%3Cinterface-src_types_config.ts-13519-28113-src_types_config.ts-0-55265%3E',
170888
170919
  },
170889
170920
  },
170890
- 'Partial<interface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255>': {
170921
+ 'Partial<interface-src_types_config.ts-13519-28113-src_types_config.ts-0-55265>': {
170891
170922
  type: 'object',
170892
170923
  additionalProperties: false,
170893
170924
  },
@@ -171594,6 +171625,13 @@ exports.configSchema = {
171594
171625
  $ref: '#/definitions/SandboxCacheConfig',
171595
171626
  description: 'Cache volume configuration',
171596
171627
  },
171628
+ bind_paths: {
171629
+ type: 'array',
171630
+ items: {
171631
+ $ref: '#/definitions/SandboxBindPath',
171632
+ },
171633
+ description: 'Additional host paths to bind-mount into the sandbox',
171634
+ },
171597
171635
  },
171598
171636
  additionalProperties: false,
171599
171637
  description: 'Configuration for a single sandbox environment',
@@ -171653,6 +171691,29 @@ exports.configSchema = {
171653
171691
  '^x-': {},
171654
171692
  },
171655
171693
  },
171694
+ SandboxBindPath: {
171695
+ type: 'object',
171696
+ properties: {
171697
+ host: {
171698
+ type: 'string',
171699
+ description: 'Host path (supports ~ prefix for home directory)',
171700
+ },
171701
+ container: {
171702
+ type: 'string',
171703
+ description: 'Container path (defaults to resolved host path)',
171704
+ },
171705
+ read_only: {
171706
+ type: 'boolean',
171707
+ description: 'Mount as read-only (default: true)',
171708
+ },
171709
+ },
171710
+ required: ['host'],
171711
+ additionalProperties: false,
171712
+ description: 'Additional host path to bind-mount into the sandbox',
171713
+ patternProperties: {
171714
+ '^x-': {},
171715
+ },
171716
+ },
171656
171717
  SandboxDefaults: {
171657
171718
  type: 'object',
171658
171719
  properties: {
@@ -190701,7 +190762,7 @@ class BubblewrapSandbox {
190701
190762
  * Build the bwrap command-line arguments.
190702
190763
  */
190703
190764
  buildArgs(options) {
190704
- const workdir = this.config.workdir || '/workspace';
190765
+ const workdir = this.config.workdir === 'host' ? this.repoPath : this.config.workdir || '/workspace';
190705
190766
  const args = [];
190706
190767
  // Read-only system directories
190707
190768
  args.push('--ro-bind', '/usr', '/usr');
@@ -190735,6 +190796,17 @@ class BubblewrapSandbox {
190735
190796
  // Visor dist mount (read-only) — required for child visor process
190736
190797
  const visorPath = this.config.visor_path || '/opt/visor';
190737
190798
  args.push('--ro-bind', this.visorDistPath, visorPath);
190799
+ // Additional bind mounts
190800
+ if (this.config.bind_paths) {
190801
+ for (const bp of this.config.bind_paths) {
190802
+ const hostPath = bp.host.startsWith('~')
190803
+ ? (0, path_1.resolve)((process.env.HOME || '/root') + bp.host.slice(1))
190804
+ : (0, path_1.resolve)(bp.host);
190805
+ const containerPath = bp.container || hostPath;
190806
+ const readOnly = bp.read_only !== false; // default true
190807
+ args.push(readOnly ? '--ro-bind' : '--bind', hostPath, containerPath);
190808
+ }
190809
+ }
190738
190810
  // Working directory inside sandbox
190739
190811
  args.push('--chdir', workdir);
190740
190812
  // Namespace isolation
@@ -191069,7 +191141,9 @@ class CheckRunner {
191069
191141
  // Filter environment variables
191070
191142
  const env = (0, env_filter_1.filterEnvForSandbox)(checkConfig.env, process.env, sandboxConfig.env_passthrough, workspaceDefaults?.env_passthrough);
191071
191143
  // Set up child trace file relay (skip for read-only sandboxes)
191072
- const workdir = sandboxConfig.workdir || '/workspace';
191144
+ const workdir = sandboxConfig.workdir === 'host'
191145
+ ? sandboxManager.getRepoPath()
191146
+ : sandboxConfig.workdir || '/workspace';
191073
191147
  let hostTracePath;
191074
191148
  if (!sandboxConfig.read_only) {
191075
191149
  const traceFileName = `.visor-trace-${(0, crypto_1.randomUUID)().slice(0, 8)}.ndjson`;
@@ -191414,7 +191488,7 @@ class DockerImageSandbox {
191414
191488
  */
191415
191489
  async start() {
191416
191490
  const image = await this.buildImageIfNeeded();
191417
- const workdir = this.config.workdir || '/workspace';
191491
+ const workdir = this.config.workdir === 'host' ? this.repoPath : this.config.workdir || '/workspace';
191418
191492
  const visorPath = this.config.visor_path || '/opt/visor';
191419
191493
  const readOnlySuffix = this.config.read_only ? ':ro' : '';
191420
191494
  const args = [
@@ -191445,6 +191519,17 @@ class DockerImageSandbox {
191445
191519
  for (const mount of this.cacheVolumeMounts) {
191446
191520
  args.push('-v', mount);
191447
191521
  }
191522
+ // Additional bind mounts
191523
+ if (this.config.bind_paths) {
191524
+ for (const bp of this.config.bind_paths) {
191525
+ const hostPath = bp.host.startsWith('~')
191526
+ ? (0, path_1.resolve)((process.env.HOME || '/root') + bp.host.slice(1))
191527
+ : (0, path_1.resolve)(bp.host);
191528
+ const containerPath = bp.container || hostPath;
191529
+ const readOnly = bp.read_only !== false; // default true
191530
+ args.push('-v', `${hostPath}:${containerPath}${readOnly ? ':ro' : ''}`);
191531
+ }
191532
+ }
191448
191533
  // Image and keep-alive command
191449
191534
  args.push(image, 'sleep', 'infinity');
191450
191535
  logger_1.logger.info(`Starting sandbox container '${this.containerName}'`);
@@ -191945,6 +192030,20 @@ class SeatbeltSandbox {
191945
192030
  // Visor dist read access — required for child visor process
191946
192031
  const visorDistPath = this.escapePath(this.visorDistPath);
191947
192032
  lines.push(`(allow file-read* (subpath "${visorDistPath}"))`);
192033
+ // Additional bind paths
192034
+ if (this.config.bind_paths) {
192035
+ for (const bp of this.config.bind_paths) {
192036
+ const hostPath = bp.host.startsWith('~')
192037
+ ? (0, path_1.resolve)((process.env.HOME || '/root') + bp.host.slice(1))
192038
+ : (0, path_1.resolve)(bp.host);
192039
+ // Seatbelt operates on real host paths — container field is ignored
192040
+ const escapedPath = this.escapePath(hostPath);
192041
+ lines.push(`(allow file-read* (subpath "${escapedPath}"))`);
192042
+ if (bp.read_only === false) {
192043
+ lines.push(`(allow file-write* (subpath "${escapedPath}"))`);
192044
+ }
192045
+ }
192046
+ }
191948
192047
  // Network access (unless explicitly disabled)
191949
192048
  if (this.config.network !== false) {
191950
192049
  lines.push('(allow network*)');
@@ -194077,14 +194176,15 @@ async function handleCreateTrigger(args, context, store) {
194077
194176
  error: `Available workflows: ${context.availableWorkflows.slice(0, 5).join(', ')}${context.availableWorkflows.length > 5 ? '...' : ''}`,
194078
194177
  };
194079
194178
  }
194080
- // Need at least one filter (channels, contains, or match)
194179
+ // Need at least one filter (channels, from, contains, or match)
194081
194180
  if ((!args.trigger_channels || args.trigger_channels.length === 0) &&
194181
+ (!args.trigger_from || args.trigger_from.length === 0) &&
194082
194182
  (!args.trigger_contains || args.trigger_contains.length === 0) &&
194083
194183
  !args.trigger_match) {
194084
194184
  return {
194085
194185
  success: false,
194086
194186
  message: 'Missing trigger filters',
194087
- error: 'Please specify at least one filter: trigger_channels, trigger_contains, or trigger_match.',
194187
+ error: 'Please specify at least one filter: trigger_channels, trigger_from, trigger_contains, or trigger_match.',
194088
194188
  };
194089
194189
  }
194090
194190
  // Check permissions for the workflow
@@ -194103,6 +194203,7 @@ async function handleCreateTrigger(args, context, store) {
194103
194203
  creatorName: context.userName,
194104
194204
  description: args.trigger_description,
194105
194205
  channels: args.trigger_channels,
194206
+ fromUsers: args.trigger_from,
194106
194207
  fromBots: args.trigger_from_bots ?? false,
194107
194208
  contains: args.trigger_contains,
194108
194209
  matchPattern: args.trigger_match,
@@ -194119,7 +194220,7 @@ async function handleCreateTrigger(args, context, store) {
194119
194220
 
194120
194221
  **Workflow**: ${trigger.workflow}
194121
194222
  **Channels**: ${trigger.channels?.join(', ') || 'all'}
194122
- ${trigger.contains?.length ? `**Contains**: ${trigger.contains.join(', ')}\n` : ''}${trigger.matchPattern ? `**Pattern**: /${trigger.matchPattern}/\n` : ''}${trigger.description ? `**Description**: ${trigger.description}\n` : ''}
194223
+ ${trigger.fromUsers?.length ? `**From users**: ${trigger.fromUsers.join(', ')}\n` : ''}${trigger.contains?.length ? `**Contains**: ${trigger.contains.join(', ')}\n` : ''}${trigger.matchPattern ? `**Pattern**: /${trigger.matchPattern}/\n` : ''}${trigger.description ? `**Description**: ${trigger.description}\n` : ''}
194123
194224
  ID: \`${trigger.id.substring(0, 8)}\``,
194124
194225
  };
194125
194226
  }
@@ -194263,7 +194364,7 @@ Slack messages in specific channels. Use the create_trigger, list_triggers, dele
194263
194364
  actions for this. Message triggers fire workflows based on message content, channel, sender, and thread scope.
194264
194365
 
194265
194366
  TRIGGER ACTIONS:
194266
- - create_trigger: Create a new message trigger (requires workflow + at least one filter)
194367
+ - create_trigger: Create a new message trigger (requires workflow + at least one filter). Supports filtering by user IDs (trigger_from), channels, keywords, regex, and thread scope.
194267
194368
  - list_triggers: Show user's message triggers
194268
194369
  - delete_trigger: Remove a trigger by ID
194269
194370
  - update_trigger: Enable/disable a trigger by ID
@@ -194360,6 +194461,9 @@ User: "cancel schedule abc123"
194360
194461
  User: "watch #cicd for messages containing 'failed' and run %handle-cicd"
194361
194462
  → { "action": "create_trigger", "trigger_channels": ["C0CICD"], "trigger_contains": ["failed"], "workflow": "handle-cicd" }
194362
194463
 
194464
+ User: "trigger on each of my messages in this channel and run %auto-reply" (user ID is U3P2L4XNE)
194465
+ → { "action": "create_trigger", "trigger_channels": ["C09V810NY6R"], "trigger_from": ["U3P2L4XNE"], "workflow": "auto-reply" }
194466
+
194363
194467
  User: "list my message triggers"
194364
194468
  → { "action": "list_triggers" }
194365
194469
 
@@ -194441,6 +194545,11 @@ User: "disable trigger abc123"
194441
194545
  items: { type: 'string' },
194442
194546
  description: 'For create_trigger: Slack channel IDs to monitor (e.g., ["C0CICD"]). Supports wildcard suffix (e.g., "CENG*").',
194443
194547
  },
194548
+ trigger_from: {
194549
+ type: 'array',
194550
+ items: { type: 'string' },
194551
+ description: 'For create_trigger: Slack user IDs to filter by. Only messages from these users will trigger the workflow. E.g., ["U3P2L4XNE"]. If omitted, messages from any user will trigger.',
194552
+ },
194444
194553
  trigger_from_bots: {
194445
194554
  type: 'boolean',
194446
194555
  description: 'For create_trigger: allow bot messages to trigger (default: false)',
@@ -209173,6 +209282,9 @@ function projectWorkflowToGraph(workflow, workflowInputs, _parentCheckId) {
209173
209282
  collapse: false,
209174
209283
  },
209175
209284
  },
209285
+ ...(workflow.sandboxes && { sandboxes: workflow.sandboxes }),
209286
+ ...(workflow.sandbox && { sandbox: workflow.sandbox }),
209287
+ ...(workflow.sandbox_defaults && { sandbox_defaults: workflow.sandbox_defaults }),
209176
209288
  };
209177
209289
  if (logger_1.logger.isDebugEnabled?.()) {
209178
209290
  logger_1.logger.debug(`[WorkflowProjection] Projected workflow '${workflow.id}' with ${Object.keys(checks).length} steps`);
@@ -395123,7 +395235,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"100":"Continue","101":"Switching Pro
395123
395235
  /***/ ((module) => {
395124
395236
 
395125
395237
  "use strict";
395126
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@probelabs/visor","version":"0.1.152","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","@modelcontextprotocol/sdk":"^1.25.3","@nyariv/sandboxjs":"github:probelabs/SandboxJS#f1c13b8eee98734a8ea024061eada4aa9a9ff2e9","@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/core":"^1.30.1","@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-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-rc269","@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","cli-table3":"^0.6.5","commander":"^14.0.0","deepmerge":"^4.3.1","dotenv":"^17.2.3","ignore":"^7.0.5","js-yaml":"^4.1.0","jsonpath-plus":"^10.4.0","liquidjs":"^10.21.1","minimatch":"^10.2.2","node-cron":"^3.0.3","open":"^9.1.0","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/node":"^24.3.0","@types/node-cron":"^3.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"]}}');
395238
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@probelabs/visor","version":"0.1.153","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","@modelcontextprotocol/sdk":"^1.25.3","@nyariv/sandboxjs":"github:probelabs/SandboxJS#f1c13b8eee98734a8ea024061eada4aa9a9ff2e9","@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/core":"^1.30.1","@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-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-rc269","@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","cli-table3":"^0.6.5","commander":"^14.0.0","deepmerge":"^4.3.1","dotenv":"^17.2.3","ignore":"^7.0.5","js-yaml":"^4.1.0","jsonpath-plus":"^10.4.0","liquidjs":"^10.21.1","minimatch":"^10.2.2","node-cron":"^3.0.3","open":"^9.1.0","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/node":"^24.3.0","@types/node-cron":"^3.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"]}}');
395127
395239
 
395128
395240
  /***/ })
395129
395241