@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/sdk/sdk.js CHANGED
@@ -646,7 +646,7 @@ var require_package = __commonJS({
646
646
  "package.json"(exports2, module2) {
647
647
  module2.exports = {
648
648
  name: "@probelabs/visor",
649
- version: "0.1.152",
649
+ version: "0.1.153",
650
650
  main: "dist/index.js",
651
651
  bin: {
652
652
  visor: "./dist/index.js"
@@ -864,11 +864,11 @@ function getTracer() {
864
864
  }
865
865
  async function withActiveSpan(name, attrs, fn) {
866
866
  const tracer = getTracer();
867
- return await new Promise((resolve14, reject) => {
867
+ return await new Promise((resolve15, reject) => {
868
868
  const callback = async (span) => {
869
869
  try {
870
870
  const res = await fn(span);
871
- resolve14(res);
871
+ resolve15(res);
872
872
  } catch (err) {
873
873
  try {
874
874
  if (err instanceof Error) span.recordException(err);
@@ -6039,7 +6039,7 @@ var init_check_runner = __esm({
6039
6039
  sandboxConfig.env_passthrough,
6040
6040
  workspaceDefaults?.env_passthrough
6041
6041
  );
6042
- const workdir = sandboxConfig.workdir || "/workspace";
6042
+ const workdir = sandboxConfig.workdir === "host" ? sandboxManager.getRepoPath() : sandboxConfig.workdir || "/workspace";
6043
6043
  let hostTracePath;
6044
6044
  if (!sandboxConfig.read_only) {
6045
6045
  const traceFileName = `.visor-trace-${(0, import_crypto.randomUUID)().slice(0, 8)}.ndjson`;
@@ -6972,7 +6972,7 @@ async function renderMermaidToPng(mermaidCode) {
6972
6972
  if (chromiumPath) {
6973
6973
  env.PUPPETEER_EXECUTABLE_PATH = chromiumPath;
6974
6974
  }
6975
- const result = await new Promise((resolve14) => {
6975
+ const result = await new Promise((resolve15) => {
6976
6976
  const proc = (0, import_child_process.spawn)(
6977
6977
  "npx",
6978
6978
  [
@@ -7002,13 +7002,13 @@ async function renderMermaidToPng(mermaidCode) {
7002
7002
  });
7003
7003
  proc.on("close", (code) => {
7004
7004
  if (code === 0) {
7005
- resolve14({ success: true });
7005
+ resolve15({ success: true });
7006
7006
  } else {
7007
- resolve14({ success: false, error: stderr || `Exit code ${code}` });
7007
+ resolve15({ success: false, error: stderr || `Exit code ${code}` });
7008
7008
  }
7009
7009
  });
7010
7010
  proc.on("error", (err) => {
7011
- resolve14({ success: false, error: err.message });
7011
+ resolve15({ success: false, error: err.message });
7012
7012
  });
7013
7013
  });
7014
7014
  if (!result.success) {
@@ -9236,7 +9236,7 @@ ${"=".repeat(60)}
9236
9236
  * Generate mock response for testing
9237
9237
  */
9238
9238
  async generateMockResponse(_prompt, _checkName, _schema) {
9239
- await new Promise((resolve14) => setTimeout(resolve14, 500));
9239
+ await new Promise((resolve15) => setTimeout(resolve15, 500));
9240
9240
  const name = (_checkName || "").toLowerCase();
9241
9241
  if (name.includes("extract-facts")) {
9242
9242
  const arr = Array.from({ length: 6 }, (_, i) => ({
@@ -9597,7 +9597,7 @@ var init_command_executor = __esm({
9597
9597
  * Execute command with stdin input
9598
9598
  */
9599
9599
  executeWithStdin(command, options) {
9600
- return new Promise((resolve14, reject) => {
9600
+ return new Promise((resolve15, reject) => {
9601
9601
  const childProcess = (0, import_child_process2.exec)(
9602
9602
  command,
9603
9603
  {
@@ -9609,7 +9609,7 @@ var init_command_executor = __esm({
9609
9609
  if (error && error.killed && (error.code === "ETIMEDOUT" || error.signal === "SIGTERM")) {
9610
9610
  reject(new Error(`Command timed out after ${options.timeout || 3e4}ms`));
9611
9611
  } else {
9612
- resolve14({
9612
+ resolve15({
9613
9613
  stdout: stdout || "",
9614
9614
  stderr: stderr || "",
9615
9615
  exitCode: error ? error.code || 1 : 0
@@ -11514,7 +11514,10 @@ function projectWorkflowToGraph(workflow, workflowInputs, _parentCheckId) {
11514
11514
  group_by: "check",
11515
11515
  collapse: false
11516
11516
  }
11517
- }
11517
+ },
11518
+ ...workflow.sandboxes && { sandboxes: workflow.sandboxes },
11519
+ ...workflow.sandbox && { sandbox: workflow.sandbox },
11520
+ ...workflow.sandbox_defaults && { sandbox_defaults: workflow.sandbox_defaults }
11518
11521
  };
11519
11522
  if (logger.isDebugEnabled?.()) {
11520
11523
  logger.debug(
@@ -13163,7 +13166,7 @@ var init_config_schema = __esm({
13163
13166
  description: "Arguments/inputs for the workflow"
13164
13167
  },
13165
13168
  overrides: {
13166
- $ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255%3E%3E",
13169
+ $ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13519-28113-src_types_config.ts-0-55265%3E%3E",
13167
13170
  description: "Override specific step configurations in the workflow"
13168
13171
  },
13169
13172
  output_mapping: {
@@ -13179,7 +13182,7 @@ var init_config_schema = __esm({
13179
13182
  description: "Config file path - alternative to workflow ID (loads a Visor config file as workflow)"
13180
13183
  },
13181
13184
  workflow_overrides: {
13182
- $ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255%3E%3E",
13185
+ $ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13519-28113-src_types_config.ts-0-55265%3E%3E",
13183
13186
  description: "Alias for overrides - workflow step overrides (backward compatibility)"
13184
13187
  },
13185
13188
  ref: {
@@ -13600,11 +13603,11 @@ var init_config_schema = __esm({
13600
13603
  },
13601
13604
  description: "Array of blocked command patterns (e.g., ['rm -rf', 'sudo'])"
13602
13605
  },
13603
- noDefaultAllow: {
13606
+ disableDefaultAllow: {
13604
13607
  type: "boolean",
13605
13608
  description: "Disable default safe command list (use with caution)"
13606
13609
  },
13607
- noDefaultDeny: {
13610
+ disableDefaultDeny: {
13608
13611
  type: "boolean",
13609
13612
  description: "Disable default dangerous command blocklist (use with extreme caution)"
13610
13613
  },
@@ -13868,7 +13871,7 @@ var init_config_schema = __esm({
13868
13871
  description: "Custom output name (defaults to workflow name)"
13869
13872
  },
13870
13873
  overrides: {
13871
- $ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255%3E%3E",
13874
+ $ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13519-28113-src_types_config.ts-0-55265%3E%3E",
13872
13875
  description: "Step overrides"
13873
13876
  },
13874
13877
  output_mapping: {
@@ -13883,13 +13886,13 @@ var init_config_schema = __esm({
13883
13886
  "^x-": {}
13884
13887
  }
13885
13888
  },
13886
- "Record<string,Partial<interface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255>>": {
13889
+ "Record<string,Partial<interface-src_types_config.ts-13519-28113-src_types_config.ts-0-55265>>": {
13887
13890
  type: "object",
13888
13891
  additionalProperties: {
13889
- $ref: "#/definitions/Partial%3Cinterface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255%3E"
13892
+ $ref: "#/definitions/Partial%3Cinterface-src_types_config.ts-13519-28113-src_types_config.ts-0-55265%3E"
13890
13893
  }
13891
13894
  },
13892
- "Partial<interface-src_types_config.ts-13509-28103-src_types_config.ts-0-55255>": {
13895
+ "Partial<interface-src_types_config.ts-13519-28113-src_types_config.ts-0-55265>": {
13893
13896
  type: "object",
13894
13897
  additionalProperties: false
13895
13898
  },
@@ -14595,6 +14598,13 @@ var init_config_schema = __esm({
14595
14598
  cache: {
14596
14599
  $ref: "#/definitions/SandboxCacheConfig",
14597
14600
  description: "Cache volume configuration"
14601
+ },
14602
+ bind_paths: {
14603
+ type: "array",
14604
+ items: {
14605
+ $ref: "#/definitions/SandboxBindPath"
14606
+ },
14607
+ description: "Additional host paths to bind-mount into the sandbox"
14598
14608
  }
14599
14609
  },
14600
14610
  additionalProperties: false,
@@ -14655,6 +14665,29 @@ var init_config_schema = __esm({
14655
14665
  "^x-": {}
14656
14666
  }
14657
14667
  },
14668
+ SandboxBindPath: {
14669
+ type: "object",
14670
+ properties: {
14671
+ host: {
14672
+ type: "string",
14673
+ description: "Host path (supports ~ prefix for home directory)"
14674
+ },
14675
+ container: {
14676
+ type: "string",
14677
+ description: "Container path (defaults to resolved host path)"
14678
+ },
14679
+ read_only: {
14680
+ type: "boolean",
14681
+ description: "Mount as read-only (default: true)"
14682
+ }
14683
+ },
14684
+ required: ["host"],
14685
+ additionalProperties: false,
14686
+ description: "Additional host path to bind-mount into the sandbox",
14687
+ patternProperties: {
14688
+ "^x-": {}
14689
+ }
14690
+ },
14658
14691
  SandboxDefaults: {
14659
14692
  type: "object",
14660
14693
  properties: {
@@ -16028,7 +16061,6 @@ ${errors}`);
16028
16061
  ["compose", config.compose],
16029
16062
  ["service", config.service],
16030
16063
  ["cache", config.cache],
16031
- ["visor_path", config.visor_path],
16032
16064
  ["resources", config.resources]
16033
16065
  ];
16034
16066
  for (const [field, value] of dockerOnlyFields) {
@@ -16074,20 +16106,6 @@ ${errors}`);
16074
16106
  message: `Compose file path '${config.compose}' in sandbox '${name}' must not contain '..' path traversal`
16075
16107
  });
16076
16108
  }
16077
- if (config.visor_path) {
16078
- if (!config.visor_path.startsWith("/")) {
16079
- errors.push({
16080
- field: `sandboxes.${name}.visor_path`,
16081
- message: `visor_path '${config.visor_path}' in sandbox '${name}' must be an absolute path (start with /)`
16082
- });
16083
- }
16084
- if (/\.\./.test(config.visor_path)) {
16085
- errors.push({
16086
- field: `sandboxes.${name}.visor_path`,
16087
- message: `visor_path '${config.visor_path}' in sandbox '${name}' must not contain '..' path traversal`
16088
- });
16089
- }
16090
- }
16091
16109
  if (config.cache?.paths) {
16092
16110
  for (const p of config.cache.paths) {
16093
16111
  if (!p.startsWith("/")) {
@@ -16116,11 +16134,25 @@ ${errors}`);
16116
16134
  }
16117
16135
  }
16118
16136
  }
16119
- if (config.workdir) {
16137
+ if (config.visor_path) {
16138
+ if (!config.visor_path.startsWith("/")) {
16139
+ errors.push({
16140
+ field: `sandboxes.${name}.visor_path`,
16141
+ message: `visor_path '${config.visor_path}' in sandbox '${name}' must be an absolute path (start with /)`
16142
+ });
16143
+ }
16144
+ if (/\.\./.test(config.visor_path)) {
16145
+ errors.push({
16146
+ field: `sandboxes.${name}.visor_path`,
16147
+ message: `visor_path '${config.visor_path}' in sandbox '${name}' must not contain '..' path traversal`
16148
+ });
16149
+ }
16150
+ }
16151
+ if (config.workdir && config.workdir !== "host") {
16120
16152
  if (!config.workdir.startsWith("/")) {
16121
16153
  errors.push({
16122
16154
  field: `sandboxes.${name}.workdir`,
16123
- message: `Workdir '${config.workdir}' in sandbox '${name}' must be an absolute path (start with /)`
16155
+ message: `Workdir '${config.workdir}' in sandbox '${name}' must be an absolute path (start with /) or the literal "host"`
16124
16156
  });
16125
16157
  }
16126
16158
  if (/\.\./.test(config.workdir)) {
@@ -16130,6 +16162,37 @@ ${errors}`);
16130
16162
  });
16131
16163
  }
16132
16164
  }
16165
+ if (config.bind_paths) {
16166
+ for (let i = 0; i < config.bind_paths.length; i++) {
16167
+ const bp = config.bind_paths[i];
16168
+ if (!bp.host) {
16169
+ errors.push({
16170
+ field: `sandboxes.${name}.bind_paths[${i}].host`,
16171
+ message: `bind_paths[${i}] in sandbox '${name}' is missing required 'host' field`
16172
+ });
16173
+ }
16174
+ if (bp.host && /\.\./.test(bp.host)) {
16175
+ errors.push({
16176
+ field: `sandboxes.${name}.bind_paths[${i}].host`,
16177
+ message: `bind_paths[${i}].host '${bp.host}' in sandbox '${name}' must not contain '..' path traversal`
16178
+ });
16179
+ }
16180
+ if (bp.container) {
16181
+ if (!bp.container.startsWith("/")) {
16182
+ errors.push({
16183
+ field: `sandboxes.${name}.bind_paths[${i}].container`,
16184
+ message: `bind_paths[${i}].container '${bp.container}' in sandbox '${name}' must be an absolute path (start with /)`
16185
+ });
16186
+ }
16187
+ if (/\.\./.test(bp.container)) {
16188
+ errors.push({
16189
+ field: `sandboxes.${name}.bind_paths[${i}].container`,
16190
+ message: `bind_paths[${i}].container '${bp.container}' in sandbox '${name}' must not contain '..' path traversal`
16191
+ });
16192
+ }
16193
+ }
16194
+ }
16195
+ }
16133
16196
  }
16134
16197
  /**
16135
16198
  * Validate individual check configuration
@@ -20236,11 +20299,11 @@ async function handleCreateTrigger(args, context2, store) {
20236
20299
  error: `Available workflows: ${context2.availableWorkflows.slice(0, 5).join(", ")}${context2.availableWorkflows.length > 5 ? "..." : ""}`
20237
20300
  };
20238
20301
  }
20239
- if ((!args.trigger_channels || args.trigger_channels.length === 0) && (!args.trigger_contains || args.trigger_contains.length === 0) && !args.trigger_match) {
20302
+ if ((!args.trigger_channels || args.trigger_channels.length === 0) && (!args.trigger_from || args.trigger_from.length === 0) && (!args.trigger_contains || args.trigger_contains.length === 0) && !args.trigger_match) {
20240
20303
  return {
20241
20304
  success: false,
20242
20305
  message: "Missing trigger filters",
20243
- error: "Please specify at least one filter: trigger_channels, trigger_contains, or trigger_match."
20306
+ error: "Please specify at least one filter: trigger_channels, trigger_from, trigger_contains, or trigger_match."
20244
20307
  };
20245
20308
  }
20246
20309
  const permissionCheck = checkSchedulePermissions(context2, args.workflow);
@@ -20258,6 +20321,7 @@ async function handleCreateTrigger(args, context2, store) {
20258
20321
  creatorName: context2.userName,
20259
20322
  description: args.trigger_description,
20260
20323
  channels: args.trigger_channels,
20324
+ fromUsers: args.trigger_from,
20261
20325
  fromBots: args.trigger_from_bots ?? false,
20262
20326
  contains: args.trigger_contains,
20263
20327
  matchPattern: args.trigger_match,
@@ -20276,7 +20340,8 @@ async function handleCreateTrigger(args, context2, store) {
20276
20340
 
20277
20341
  **Workflow**: ${trigger.workflow}
20278
20342
  **Channels**: ${trigger.channels?.join(", ") || "all"}
20279
- ${trigger.contains?.length ? `**Contains**: ${trigger.contains.join(", ")}
20343
+ ${trigger.fromUsers?.length ? `**From users**: ${trigger.fromUsers.join(", ")}
20344
+ ` : ""}${trigger.contains?.length ? `**Contains**: ${trigger.contains.join(", ")}
20280
20345
  ` : ""}${trigger.matchPattern ? `**Pattern**: /${trigger.matchPattern}/
20281
20346
  ` : ""}${trigger.description ? `**Description**: ${trigger.description}
20282
20347
  ` : ""}
@@ -20402,7 +20467,7 @@ Slack messages in specific channels. Use the create_trigger, list_triggers, dele
20402
20467
  actions for this. Message triggers fire workflows based on message content, channel, sender, and thread scope.
20403
20468
 
20404
20469
  TRIGGER ACTIONS:
20405
- - create_trigger: Create a new message trigger (requires workflow + at least one filter)
20470
+ - 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.
20406
20471
  - list_triggers: Show user's message triggers
20407
20472
  - delete_trigger: Remove a trigger by ID
20408
20473
  - update_trigger: Enable/disable a trigger by ID
@@ -20499,6 +20564,9 @@ User: "cancel schedule abc123"
20499
20564
  User: "watch #cicd for messages containing 'failed' and run %handle-cicd"
20500
20565
  \u2192 { "action": "create_trigger", "trigger_channels": ["C0CICD"], "trigger_contains": ["failed"], "workflow": "handle-cicd" }
20501
20566
 
20567
+ User: "trigger on each of my messages in this channel and run %auto-reply" (user ID is U3P2L4XNE)
20568
+ \u2192 { "action": "create_trigger", "trigger_channels": ["C09V810NY6R"], "trigger_from": ["U3P2L4XNE"], "workflow": "auto-reply" }
20569
+
20502
20570
  User: "list my message triggers"
20503
20571
  \u2192 { "action": "list_triggers" }
20504
20572
 
@@ -20580,6 +20648,11 @@ User: "disable trigger abc123"
20580
20648
  items: { type: "string" },
20581
20649
  description: 'For create_trigger: Slack channel IDs to monitor (e.g., ["C0CICD"]). Supports wildcard suffix (e.g., "CENG*").'
20582
20650
  },
20651
+ trigger_from: {
20652
+ type: "array",
20653
+ items: { type: "string" },
20654
+ 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.'
20655
+ },
20583
20656
  trigger_from_bots: {
20584
20657
  type: "boolean",
20585
20658
  description: "For create_trigger: allow bot messages to trigger (default: false)"
@@ -20938,7 +21011,7 @@ var init_mcp_custom_sse_server = __esm({
20938
21011
  * Returns the actual bound port number
20939
21012
  */
20940
21013
  async start() {
20941
- return new Promise((resolve14, reject) => {
21014
+ return new Promise((resolve15, reject) => {
20942
21015
  try {
20943
21016
  this.server = import_http.default.createServer((req, res) => {
20944
21017
  this.handleRequest(req, res).catch((error) => {
@@ -20972,7 +21045,7 @@ var init_mcp_custom_sse_server = __esm({
20972
21045
  );
20973
21046
  }
20974
21047
  this.startKeepalive();
20975
- resolve14(this.port);
21048
+ resolve15(this.port);
20976
21049
  });
20977
21050
  } catch (error) {
20978
21051
  reject(error);
@@ -21035,7 +21108,7 @@ var init_mcp_custom_sse_server = __esm({
21035
21108
  logger.debug(
21036
21109
  `[CustomToolsSSEServer:${this.sessionId}] Grace period before stop: ${waitMs}ms (activeToolCalls=${this.activeToolCalls})`
21037
21110
  );
21038
- await new Promise((resolve14) => setTimeout(resolve14, waitMs));
21111
+ await new Promise((resolve15) => setTimeout(resolve15, waitMs));
21039
21112
  }
21040
21113
  }
21041
21114
  if (this.activeToolCalls > 0) {
@@ -21044,7 +21117,7 @@ var init_mcp_custom_sse_server = __esm({
21044
21117
  `[CustomToolsSSEServer:${this.sessionId}] Waiting for ${this.activeToolCalls} active tool call(s) before stop`
21045
21118
  );
21046
21119
  while (this.activeToolCalls > 0 && Date.now() - startedAt < effectiveDrainTimeoutMs) {
21047
- await new Promise((resolve14) => setTimeout(resolve14, 250));
21120
+ await new Promise((resolve15) => setTimeout(resolve15, 250));
21048
21121
  }
21049
21122
  if (this.activeToolCalls > 0) {
21050
21123
  logger.warn(
@@ -21069,21 +21142,21 @@ var init_mcp_custom_sse_server = __esm({
21069
21142
  }
21070
21143
  this.connections.clear();
21071
21144
  if (this.server) {
21072
- await new Promise((resolve14, reject) => {
21145
+ await new Promise((resolve15, reject) => {
21073
21146
  const timeout = setTimeout(() => {
21074
21147
  if (this.debug) {
21075
21148
  logger.debug(
21076
21149
  `[CustomToolsSSEServer:${this.sessionId}] Force closing server after timeout`
21077
21150
  );
21078
21151
  }
21079
- this.server?.close(() => resolve14());
21152
+ this.server?.close(() => resolve15());
21080
21153
  }, 5e3);
21081
21154
  this.server.close((error) => {
21082
21155
  clearTimeout(timeout);
21083
21156
  if (error) {
21084
21157
  reject(error);
21085
21158
  } else {
21086
- resolve14();
21159
+ resolve15();
21087
21160
  }
21088
21161
  });
21089
21162
  });
@@ -21509,7 +21582,7 @@ var init_mcp_custom_sse_server = __esm({
21509
21582
  logger.warn(
21510
21583
  `[CustomToolsSSEServer:${this.sessionId}] Tool ${toolName} failed (attempt ${attempt + 1}/${retryCount + 1}): ${errorMsg}. Retrying in ${delay}ms`
21511
21584
  );
21512
- await new Promise((resolve14) => setTimeout(resolve14, delay));
21585
+ await new Promise((resolve15) => setTimeout(resolve15, delay));
21513
21586
  attempt++;
21514
21587
  }
21515
21588
  }
@@ -30779,8 +30852,8 @@ var require_util2 = __commonJS({
30779
30852
  function createDeferredPromise() {
30780
30853
  let res;
30781
30854
  let rej;
30782
- const promise = new Promise((resolve14, reject) => {
30783
- res = resolve14;
30855
+ const promise = new Promise((resolve15, reject) => {
30856
+ res = resolve15;
30784
30857
  rej = reject;
30785
30858
  });
30786
30859
  return { promise, resolve: res, reject: rej };
@@ -32285,8 +32358,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r
32285
32358
  });
32286
32359
  }
32287
32360
  });
32288
- const busboyResolve = new Promise((resolve14, reject) => {
32289
- busboy.on("finish", resolve14);
32361
+ const busboyResolve = new Promise((resolve15, reject) => {
32362
+ busboy.on("finish", resolve15);
32290
32363
  busboy.on("error", (err) => reject(new TypeError(err)));
32291
32364
  });
32292
32365
  if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk);
@@ -32820,9 +32893,9 @@ var require_dispatcher_base = __commonJS({
32820
32893
  }
32821
32894
  close(callback) {
32822
32895
  if (callback === void 0) {
32823
- return new Promise((resolve14, reject) => {
32896
+ return new Promise((resolve15, reject) => {
32824
32897
  this.close((err, data) => {
32825
- return err ? reject(err) : resolve14(data);
32898
+ return err ? reject(err) : resolve15(data);
32826
32899
  });
32827
32900
  });
32828
32901
  }
@@ -32860,12 +32933,12 @@ var require_dispatcher_base = __commonJS({
32860
32933
  err = null;
32861
32934
  }
32862
32935
  if (callback === void 0) {
32863
- return new Promise((resolve14, reject) => {
32936
+ return new Promise((resolve15, reject) => {
32864
32937
  this.destroy(err, (err2, data) => {
32865
32938
  return err2 ? (
32866
32939
  /* istanbul ignore next: should never error */
32867
32940
  reject(err2)
32868
- ) : resolve14(data);
32941
+ ) : resolve15(data);
32869
32942
  });
32870
32943
  });
32871
32944
  }
@@ -33927,16 +34000,16 @@ var require_client = __commonJS({
33927
34000
  return this[kNeedDrain] < 2;
33928
34001
  }
33929
34002
  async [kClose]() {
33930
- return new Promise((resolve14) => {
34003
+ return new Promise((resolve15) => {
33931
34004
  if (!this[kSize]) {
33932
- resolve14(null);
34005
+ resolve15(null);
33933
34006
  } else {
33934
- this[kClosedResolve] = resolve14;
34007
+ this[kClosedResolve] = resolve15;
33935
34008
  }
33936
34009
  });
33937
34010
  }
33938
34011
  async [kDestroy](err) {
33939
- return new Promise((resolve14) => {
34012
+ return new Promise((resolve15) => {
33940
34013
  const requests = this[kQueue].splice(this[kPendingIdx]);
33941
34014
  for (let i = 0; i < requests.length; i++) {
33942
34015
  const request = requests[i];
@@ -33947,7 +34020,7 @@ var require_client = __commonJS({
33947
34020
  this[kClosedResolve]();
33948
34021
  this[kClosedResolve] = null;
33949
34022
  }
33950
- resolve14();
34023
+ resolve15();
33951
34024
  };
33952
34025
  if (this[kHTTP2Session] != null) {
33953
34026
  util.destroy(this[kHTTP2Session], err);
@@ -34527,7 +34600,7 @@ var require_client = __commonJS({
34527
34600
  });
34528
34601
  }
34529
34602
  try {
34530
- const socket = await new Promise((resolve14, reject) => {
34603
+ const socket = await new Promise((resolve15, reject) => {
34531
34604
  client[kConnector]({
34532
34605
  host,
34533
34606
  hostname,
@@ -34539,7 +34612,7 @@ var require_client = __commonJS({
34539
34612
  if (err) {
34540
34613
  reject(err);
34541
34614
  } else {
34542
- resolve14(socket2);
34615
+ resolve15(socket2);
34543
34616
  }
34544
34617
  });
34545
34618
  });
@@ -35163,12 +35236,12 @@ upgrade: ${upgrade}\r
35163
35236
  cb();
35164
35237
  }
35165
35238
  }
35166
- const waitForDrain = () => new Promise((resolve14, reject) => {
35239
+ const waitForDrain = () => new Promise((resolve15, reject) => {
35167
35240
  assert(callback === null);
35168
35241
  if (socket[kError]) {
35169
35242
  reject(socket[kError]);
35170
35243
  } else {
35171
- callback = resolve14;
35244
+ callback = resolve15;
35172
35245
  }
35173
35246
  });
35174
35247
  if (client[kHTTPConnVersion] === "h2") {
@@ -35514,8 +35587,8 @@ var require_pool_base = __commonJS({
35514
35587
  if (this[kQueue].isEmpty()) {
35515
35588
  return Promise.all(this[kClients].map((c) => c.close()));
35516
35589
  } else {
35517
- return new Promise((resolve14) => {
35518
- this[kClosedResolve] = resolve14;
35590
+ return new Promise((resolve15) => {
35591
+ this[kClosedResolve] = resolve15;
35519
35592
  });
35520
35593
  }
35521
35594
  }
@@ -36093,7 +36166,7 @@ var require_readable = __commonJS({
36093
36166
  if (this.closed) {
36094
36167
  return Promise.resolve(null);
36095
36168
  }
36096
- return new Promise((resolve14, reject) => {
36169
+ return new Promise((resolve15, reject) => {
36097
36170
  const signalListenerCleanup = signal ? util.addAbortListener(signal, () => {
36098
36171
  this.destroy();
36099
36172
  }) : noop;
@@ -36102,7 +36175,7 @@ var require_readable = __commonJS({
36102
36175
  if (signal && signal.aborted) {
36103
36176
  reject(signal.reason || Object.assign(new Error("The operation was aborted"), { name: "AbortError" }));
36104
36177
  } else {
36105
- resolve14(null);
36178
+ resolve15(null);
36106
36179
  }
36107
36180
  }).on("error", noop).on("data", function(chunk) {
36108
36181
  limit -= chunk.length;
@@ -36124,11 +36197,11 @@ var require_readable = __commonJS({
36124
36197
  throw new TypeError("unusable");
36125
36198
  }
36126
36199
  assert(!stream[kConsume]);
36127
- return new Promise((resolve14, reject) => {
36200
+ return new Promise((resolve15, reject) => {
36128
36201
  stream[kConsume] = {
36129
36202
  type,
36130
36203
  stream,
36131
- resolve: resolve14,
36204
+ resolve: resolve15,
36132
36205
  reject,
36133
36206
  length: 0,
36134
36207
  body: []
@@ -36163,12 +36236,12 @@ var require_readable = __commonJS({
36163
36236
  }
36164
36237
  }
36165
36238
  function consumeEnd(consume2) {
36166
- const { type, body, resolve: resolve14, stream, length } = consume2;
36239
+ const { type, body, resolve: resolve15, stream, length } = consume2;
36167
36240
  try {
36168
36241
  if (type === "text") {
36169
- resolve14(toUSVString(Buffer.concat(body)));
36242
+ resolve15(toUSVString(Buffer.concat(body)));
36170
36243
  } else if (type === "json") {
36171
- resolve14(JSON.parse(Buffer.concat(body)));
36244
+ resolve15(JSON.parse(Buffer.concat(body)));
36172
36245
  } else if (type === "arrayBuffer") {
36173
36246
  const dst = new Uint8Array(length);
36174
36247
  let pos = 0;
@@ -36176,12 +36249,12 @@ var require_readable = __commonJS({
36176
36249
  dst.set(buf, pos);
36177
36250
  pos += buf.byteLength;
36178
36251
  }
36179
- resolve14(dst.buffer);
36252
+ resolve15(dst.buffer);
36180
36253
  } else if (type === "blob") {
36181
36254
  if (!Blob2) {
36182
36255
  Blob2 = require("buffer").Blob;
36183
36256
  }
36184
- resolve14(new Blob2(body, { type: stream[kContentType] }));
36257
+ resolve15(new Blob2(body, { type: stream[kContentType] }));
36185
36258
  }
36186
36259
  consumeFinish(consume2);
36187
36260
  } catch (err) {
@@ -36438,9 +36511,9 @@ var require_api_request = __commonJS({
36438
36511
  };
36439
36512
  function request(opts, callback) {
36440
36513
  if (callback === void 0) {
36441
- return new Promise((resolve14, reject) => {
36514
+ return new Promise((resolve15, reject) => {
36442
36515
  request.call(this, opts, (err, data) => {
36443
- return err ? reject(err) : resolve14(data);
36516
+ return err ? reject(err) : resolve15(data);
36444
36517
  });
36445
36518
  });
36446
36519
  }
@@ -36613,9 +36686,9 @@ var require_api_stream = __commonJS({
36613
36686
  };
36614
36687
  function stream(opts, factory, callback) {
36615
36688
  if (callback === void 0) {
36616
- return new Promise((resolve14, reject) => {
36689
+ return new Promise((resolve15, reject) => {
36617
36690
  stream.call(this, opts, factory, (err, data) => {
36618
- return err ? reject(err) : resolve14(data);
36691
+ return err ? reject(err) : resolve15(data);
36619
36692
  });
36620
36693
  });
36621
36694
  }
@@ -36896,9 +36969,9 @@ var require_api_upgrade = __commonJS({
36896
36969
  };
36897
36970
  function upgrade(opts, callback) {
36898
36971
  if (callback === void 0) {
36899
- return new Promise((resolve14, reject) => {
36972
+ return new Promise((resolve15, reject) => {
36900
36973
  upgrade.call(this, opts, (err, data) => {
36901
- return err ? reject(err) : resolve14(data);
36974
+ return err ? reject(err) : resolve15(data);
36902
36975
  });
36903
36976
  });
36904
36977
  }
@@ -36987,9 +37060,9 @@ var require_api_connect = __commonJS({
36987
37060
  };
36988
37061
  function connect(opts, callback) {
36989
37062
  if (callback === void 0) {
36990
- return new Promise((resolve14, reject) => {
37063
+ return new Promise((resolve15, reject) => {
36991
37064
  connect.call(this, opts, (err, data) => {
36992
- return err ? reject(err) : resolve14(data);
37065
+ return err ? reject(err) : resolve15(data);
36993
37066
  });
36994
37067
  });
36995
37068
  }
@@ -40612,7 +40685,7 @@ var require_fetch = __commonJS({
40612
40685
  async function dispatch({ body }) {
40613
40686
  const url = requestCurrentURL(request);
40614
40687
  const agent = fetchParams.controller.dispatcher;
40615
- return new Promise((resolve14, reject) => agent.dispatch(
40688
+ return new Promise((resolve15, reject) => agent.dispatch(
40616
40689
  {
40617
40690
  path: url.pathname + url.search,
40618
40691
  origin: url.origin,
@@ -40688,7 +40761,7 @@ var require_fetch = __commonJS({
40688
40761
  }
40689
40762
  }
40690
40763
  }
40691
- resolve14({
40764
+ resolve15({
40692
40765
  status,
40693
40766
  statusText,
40694
40767
  headersList: headers[kHeadersList],
@@ -40731,7 +40804,7 @@ var require_fetch = __commonJS({
40731
40804
  const val = headersList[n + 1].toString("latin1");
40732
40805
  headers[kHeadersList].append(key, val);
40733
40806
  }
40734
- resolve14({
40807
+ resolve15({
40735
40808
  status,
40736
40809
  statusText: STATUS_CODES[status],
40737
40810
  headersList: headers[kHeadersList],
@@ -44526,7 +44599,7 @@ var init_mcp_check_provider = __esm({
44526
44599
  logger.warn(
44527
44600
  `MCP ${transportName} failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${delay}ms: ${error instanceof Error ? error.message : String(error)}`
44528
44601
  );
44529
- await new Promise((resolve14) => setTimeout(resolve14, delay));
44602
+ await new Promise((resolve15) => setTimeout(resolve15, delay));
44530
44603
  attempt += 1;
44531
44604
  } finally {
44532
44605
  try {
@@ -44808,7 +44881,7 @@ async function acquirePromptLock() {
44808
44881
  activePrompt = true;
44809
44882
  return;
44810
44883
  }
44811
- await new Promise((resolve14) => waiters.push(resolve14));
44884
+ await new Promise((resolve15) => waiters.push(resolve15));
44812
44885
  activePrompt = true;
44813
44886
  }
44814
44887
  function releasePromptLock() {
@@ -44818,7 +44891,7 @@ function releasePromptLock() {
44818
44891
  }
44819
44892
  async function interactivePrompt(options) {
44820
44893
  await acquirePromptLock();
44821
- return new Promise((resolve14, reject) => {
44894
+ return new Promise((resolve15, reject) => {
44822
44895
  const dbg = process.env.VISOR_DEBUG === "true";
44823
44896
  try {
44824
44897
  if (dbg) {
@@ -44905,12 +44978,12 @@ async function interactivePrompt(options) {
44905
44978
  };
44906
44979
  const finish = (value) => {
44907
44980
  cleanup();
44908
- resolve14(value);
44981
+ resolve15(value);
44909
44982
  };
44910
44983
  if (options.timeout && options.timeout > 0) {
44911
44984
  timeoutId = setTimeout(() => {
44912
44985
  cleanup();
44913
- if (defaultValue !== void 0) return resolve14(defaultValue);
44986
+ if (defaultValue !== void 0) return resolve15(defaultValue);
44914
44987
  return reject(new Error("Input timeout"));
44915
44988
  }, options.timeout);
44916
44989
  }
@@ -45042,7 +45115,7 @@ async function interactivePrompt(options) {
45042
45115
  });
45043
45116
  }
45044
45117
  async function simplePrompt(prompt) {
45045
- return new Promise((resolve14) => {
45118
+ return new Promise((resolve15) => {
45046
45119
  const rl = readline.createInterface({
45047
45120
  input: process.stdin,
45048
45121
  output: process.stdout
@@ -45058,7 +45131,7 @@ async function simplePrompt(prompt) {
45058
45131
  rl.question(`${prompt}
45059
45132
  > `, (answer) => {
45060
45133
  rl.close();
45061
- resolve14(answer.trim());
45134
+ resolve15(answer.trim());
45062
45135
  });
45063
45136
  });
45064
45137
  }
@@ -45226,7 +45299,7 @@ function isStdinAvailable() {
45226
45299
  return !process.stdin.isTTY;
45227
45300
  }
45228
45301
  async function readStdin(timeout, maxSize = 1024 * 1024) {
45229
- return new Promise((resolve14, reject) => {
45302
+ return new Promise((resolve15, reject) => {
45230
45303
  let data = "";
45231
45304
  let timeoutId;
45232
45305
  if (timeout) {
@@ -45253,7 +45326,7 @@ async function readStdin(timeout, maxSize = 1024 * 1024) {
45253
45326
  };
45254
45327
  const onEnd = () => {
45255
45328
  cleanup();
45256
- resolve14(data.trim());
45329
+ resolve15(data.trim());
45257
45330
  };
45258
45331
  const onError = (err) => {
45259
45332
  cleanup();
@@ -52534,7 +52607,7 @@ var init_docker_image_sandbox = __esm({
52534
52607
  */
52535
52608
  async start() {
52536
52609
  const image = await this.buildImageIfNeeded();
52537
- const workdir = this.config.workdir || "/workspace";
52610
+ const workdir = this.config.workdir === "host" ? this.repoPath : this.config.workdir || "/workspace";
52538
52611
  const visorPath = this.config.visor_path || "/opt/visor";
52539
52612
  const readOnlySuffix = this.config.read_only ? ":ro" : "";
52540
52613
  const args = [
@@ -52562,6 +52635,14 @@ var init_docker_image_sandbox = __esm({
52562
52635
  for (const mount of this.cacheVolumeMounts) {
52563
52636
  args.push("-v", mount);
52564
52637
  }
52638
+ if (this.config.bind_paths) {
52639
+ for (const bp of this.config.bind_paths) {
52640
+ const hostPath = bp.host.startsWith("~") ? (0, import_path9.resolve)((process.env.HOME || "/root") + bp.host.slice(1)) : (0, import_path9.resolve)(bp.host);
52641
+ const containerPath = bp.container || hostPath;
52642
+ const readOnly = bp.read_only !== false;
52643
+ args.push("-v", `${hostPath}:${containerPath}${readOnly ? ":ro" : ""}`);
52644
+ }
52645
+ }
52565
52646
  args.push(image, "sleep", "infinity");
52566
52647
  logger.info(`Starting sandbox container '${this.containerName}'`);
52567
52648
  const { stdout } = await execFileAsync(args[0], args.slice(1), {
@@ -53014,7 +53095,7 @@ var init_bubblewrap_sandbox = __esm({
53014
53095
  * Build the bwrap command-line arguments.
53015
53096
  */
53016
53097
  buildArgs(options) {
53017
- const workdir = this.config.workdir || "/workspace";
53098
+ const workdir = this.config.workdir === "host" ? this.repoPath : this.config.workdir || "/workspace";
53018
53099
  const args = [];
53019
53100
  args.push("--ro-bind", "/usr", "/usr");
53020
53101
  args.push("--ro-bind", "/bin", "/bin");
@@ -53041,6 +53122,14 @@ var init_bubblewrap_sandbox = __esm({
53041
53122
  }
53042
53123
  const visorPath = this.config.visor_path || "/opt/visor";
53043
53124
  args.push("--ro-bind", this.visorDistPath, visorPath);
53125
+ if (this.config.bind_paths) {
53126
+ for (const bp of this.config.bind_paths) {
53127
+ const hostPath = bp.host.startsWith("~") ? (0, import_path10.resolve)((process.env.HOME || "/root") + bp.host.slice(1)) : (0, import_path10.resolve)(bp.host);
53128
+ const containerPath = bp.container || hostPath;
53129
+ const readOnly = bp.read_only !== false;
53130
+ args.push(readOnly ? "--ro-bind" : "--bind", hostPath, containerPath);
53131
+ }
53132
+ }
53044
53133
  args.push("--chdir", workdir);
53045
53134
  args.push("--unshare-pid");
53046
53135
  args.push("--new-session");
@@ -53190,6 +53279,16 @@ var init_seatbelt_sandbox = __esm({
53190
53279
  }
53191
53280
  const visorDistPath = this.escapePath(this.visorDistPath);
53192
53281
  lines.push(`(allow file-read* (subpath "${visorDistPath}"))`);
53282
+ if (this.config.bind_paths) {
53283
+ for (const bp of this.config.bind_paths) {
53284
+ const hostPath = bp.host.startsWith("~") ? (0, import_path11.resolve)((process.env.HOME || "/root") + bp.host.slice(1)) : (0, import_path11.resolve)(bp.host);
53285
+ const escapedPath = this.escapePath(hostPath);
53286
+ lines.push(`(allow file-read* (subpath "${escapedPath}"))`);
53287
+ if (bp.read_only === false) {
53288
+ lines.push(`(allow file-write* (subpath "${escapedPath}"))`);
53289
+ }
53290
+ }
53291
+ }
53193
53292
  if (this.config.network !== false) {
53194
53293
  lines.push("(allow network*)");
53195
53294
  }
@@ -53950,8 +54049,8 @@ var init_workspace_manager = __esm({
53950
54049
  );
53951
54050
  if (this.cleanupRequested && this.activeOperations === 0) {
53952
54051
  logger.debug(`[Workspace] All references released, proceeding with deferred cleanup`);
53953
- for (const resolve14 of this.cleanupResolvers) {
53954
- resolve14();
54052
+ for (const resolve15 of this.cleanupResolvers) {
54053
+ resolve15();
53955
54054
  }
53956
54055
  this.cleanupResolvers = [];
53957
54056
  }
@@ -54108,19 +54207,19 @@ var init_workspace_manager = __esm({
54108
54207
  );
54109
54208
  this.cleanupRequested = true;
54110
54209
  await Promise.race([
54111
- new Promise((resolve14) => {
54210
+ new Promise((resolve15) => {
54112
54211
  if (this.activeOperations === 0) {
54113
- resolve14();
54212
+ resolve15();
54114
54213
  } else {
54115
- this.cleanupResolvers.push(resolve14);
54214
+ this.cleanupResolvers.push(resolve15);
54116
54215
  }
54117
54216
  }),
54118
- new Promise((resolve14) => {
54217
+ new Promise((resolve15) => {
54119
54218
  setTimeout(() => {
54120
54219
  logger.warn(
54121
54220
  `[Workspace] Cleanup timeout after ${timeout}ms, proceeding anyway (${this.activeOperations} operations still active)`
54122
54221
  );
54123
- resolve14();
54222
+ resolve15();
54124
54223
  }, timeout);
54125
54224
  })
54126
54225
  ]);
@@ -55504,8 +55603,8 @@ ${content}
55504
55603
  * Sleep utility
55505
55604
  */
55506
55605
  sleep(ms) {
55507
- return new Promise((resolve14) => {
55508
- const t = setTimeout(resolve14, ms);
55606
+ return new Promise((resolve15) => {
55607
+ const t = setTimeout(resolve15, ms);
55509
55608
  if (typeof t.unref === "function") {
55510
55609
  try {
55511
55610
  t.unref();
@@ -55790,8 +55889,8 @@ ${end}`);
55790
55889
  async updateGroupedComment(ctx, comments, group, changedIds) {
55791
55890
  const existingLock = this.updateLocks.get(group);
55792
55891
  let resolveLock;
55793
- const ourLock = new Promise((resolve14) => {
55794
- resolveLock = resolve14;
55892
+ const ourLock = new Promise((resolve15) => {
55893
+ resolveLock = resolve15;
55795
55894
  });
55796
55895
  this.updateLocks.set(group, ourLock);
55797
55896
  try {
@@ -56104,7 +56203,7 @@ ${blocks}
56104
56203
  * Sleep utility for enforcing delays
56105
56204
  */
56106
56205
  sleep(ms) {
56107
- return new Promise((resolve14) => setTimeout(resolve14, ms));
56206
+ return new Promise((resolve15) => setTimeout(resolve15, ms));
56108
56207
  }
56109
56208
  };
56110
56209
  }