@probelabs/visor 0.1.144-ee → 0.1.145-ee

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 (68) hide show
  1. package/dist/config.d.ts.map +1 -1
  2. package/dist/docs/architecture.md +28 -0
  3. package/dist/docs/configuration.md +2 -0
  4. package/dist/docs/sandbox-engines.md +357 -0
  5. package/dist/docs/security.md +40 -0
  6. package/dist/generated/config-schema.d.ts +5 -0
  7. package/dist/generated/config-schema.d.ts.map +1 -1
  8. package/dist/generated/config-schema.json +9 -0
  9. package/dist/index.js +670 -162
  10. package/dist/providers/mcp-check-provider.d.ts.map +1 -1
  11. package/dist/sandbox/bubblewrap-sandbox.d.ts +30 -0
  12. package/dist/sandbox/bubblewrap-sandbox.d.ts.map +1 -0
  13. package/dist/sandbox/index.d.ts +3 -1
  14. package/dist/sandbox/index.d.ts.map +1 -1
  15. package/dist/sandbox/sandbox-manager.d.ts +3 -2
  16. package/dist/sandbox/sandbox-manager.d.ts.map +1 -1
  17. package/dist/sandbox/seatbelt-sandbox.d.ts +36 -0
  18. package/dist/sandbox/seatbelt-sandbox.d.ts.map +1 -0
  19. package/dist/sandbox/types.d.ts +3 -1
  20. package/dist/sandbox/types.d.ts.map +1 -1
  21. package/dist/sdk/{check-provider-registry-Q7D5SQAV.mjs → check-provider-registry-HFPKHYTG.mjs} +4 -4
  22. package/dist/sdk/{check-provider-registry-VTNNTMWC.mjs → check-provider-registry-TH25S2OB.mjs} +7 -7
  23. package/dist/sdk/{chunk-AUHRKE6Z.mjs → chunk-3BOOHJI5.mjs} +467 -100
  24. package/dist/sdk/chunk-3BOOHJI5.mjs.map +1 -0
  25. package/dist/sdk/{chunk-PXWWPPNF.mjs → chunk-GZMQPC6D.mjs} +459 -92
  26. package/dist/sdk/chunk-GZMQPC6D.mjs.map +1 -0
  27. package/dist/sdk/chunk-I42ZCVA5.mjs +1502 -0
  28. package/dist/sdk/chunk-I42ZCVA5.mjs.map +1 -0
  29. package/dist/sdk/chunk-L3XPYQ6I.mjs +739 -0
  30. package/dist/sdk/chunk-L3XPYQ6I.mjs.map +1 -0
  31. package/dist/sdk/chunk-OM3WYVFI.mjs +443 -0
  32. package/dist/sdk/chunk-OM3WYVFI.mjs.map +1 -0
  33. package/dist/sdk/{chunk-AKCHIYWU.mjs → chunk-YOKAA4IU.mjs} +96 -63
  34. package/dist/sdk/chunk-YOKAA4IU.mjs.map +1 -0
  35. package/dist/sdk/{config-KOKJ3PYE.mjs → config-AAB2FL22.mjs} +2 -2
  36. package/dist/sdk/failure-condition-evaluator-O464EJMD.mjs +17 -0
  37. package/dist/sdk/github-frontend-MSX6Q2WL.mjs +1356 -0
  38. package/dist/sdk/github-frontend-MSX6Q2WL.mjs.map +1 -0
  39. package/dist/sdk/{host-WGFJVD4L.mjs → host-GA76UESS.mjs} +2 -2
  40. package/dist/sdk/routing-RIHVCEIU.mjs +25 -0
  41. package/dist/sdk/{schedule-tool-handler-FBXABUWX.mjs → schedule-tool-handler-BTLEDYAI.mjs} +4 -4
  42. package/dist/sdk/{schedule-tool-handler-7RGTKO24.mjs → schedule-tool-handler-NYL2ONJB.mjs} +7 -7
  43. package/dist/sdk/sdk.d.mts +3 -1
  44. package/dist/sdk/sdk.d.ts +3 -1
  45. package/dist/sdk/sdk.js +578 -178
  46. package/dist/sdk/sdk.js.map +1 -1
  47. package/dist/sdk/sdk.mjs +5 -5
  48. package/dist/sdk/trace-helpers-QQSTZGDT.mjs +25 -0
  49. package/dist/sdk/trace-helpers-QQSTZGDT.mjs.map +1 -0
  50. package/dist/sdk/{workflow-check-provider-62MO2NB6.mjs → workflow-check-provider-3IIKJFM4.mjs} +4 -4
  51. package/dist/sdk/workflow-check-provider-3IIKJFM4.mjs.map +1 -0
  52. package/dist/sdk/{workflow-check-provider-FLBIJQ4Z.mjs → workflow-check-provider-LVUUL2PZ.mjs} +7 -7
  53. package/dist/sdk/workflow-check-provider-LVUUL2PZ.mjs.map +1 -0
  54. package/dist/slack/socket-runner.d.ts.map +1 -1
  55. package/dist/utils/workspace-manager.d.ts +9 -0
  56. package/dist/utils/workspace-manager.d.ts.map +1 -1
  57. package/package.json +2 -2
  58. package/dist/sdk/chunk-AKCHIYWU.mjs.map +0 -1
  59. package/dist/sdk/chunk-AUHRKE6Z.mjs.map +0 -1
  60. package/dist/sdk/chunk-PXWWPPNF.mjs.map +0 -1
  61. /package/dist/sdk/{check-provider-registry-Q7D5SQAV.mjs.map → check-provider-registry-HFPKHYTG.mjs.map} +0 -0
  62. /package/dist/sdk/{check-provider-registry-VTNNTMWC.mjs.map → check-provider-registry-TH25S2OB.mjs.map} +0 -0
  63. /package/dist/sdk/{config-KOKJ3PYE.mjs.map → config-AAB2FL22.mjs.map} +0 -0
  64. /package/dist/sdk/{schedule-tool-handler-7RGTKO24.mjs.map → failure-condition-evaluator-O464EJMD.mjs.map} +0 -0
  65. /package/dist/sdk/{host-WGFJVD4L.mjs.map → host-GA76UESS.mjs.map} +0 -0
  66. /package/dist/sdk/{schedule-tool-handler-FBXABUWX.mjs.map → routing-RIHVCEIU.mjs.map} +0 -0
  67. /package/dist/sdk/{workflow-check-provider-62MO2NB6.mjs.map → schedule-tool-handler-BTLEDYAI.mjs.map} +0 -0
  68. /package/dist/sdk/{workflow-check-provider-FLBIJQ4Z.mjs.map → schedule-tool-handler-NYL2ONJB.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.144';
3
- process.env.PROBE_VERSION = '0.6.0-rc259';
4
- process.env.VISOR_COMMIT_SHA = '0f8df6f53e18e9ad94507e1761debabaf533c0df';
5
- process.env.VISOR_COMMIT_SHORT = '0f8df6f';
2
+ process.env.VISOR_VERSION = '0.1.145';
3
+ process.env.PROBE_VERSION = '0.6.0-rc260';
4
+ process.env.VISOR_COMMIT_SHA = '7f399fc32c663ce91b7adbb19c6f29bcd7f41931';
5
+ process.env.VISOR_COMMIT_SHORT = '7f399fc';
6
6
  /******/ (() => { // webpackBootstrap
7
7
  /******/ var __webpack_modules__ = ({
8
8
 
@@ -164445,99 +164445,131 @@ class ConfigManager {
164445
164445
  message: `Sandbox name '${name}' contains invalid characters. Only letters, numbers, dots, hyphens, underscores allowed.`,
164446
164446
  });
164447
164447
  }
164448
- // Must have exactly one mode
164449
- const modes = [
164450
- config.image ? 'image' : null,
164451
- config.dockerfile || config.dockerfile_inline ? 'dockerfile' : null,
164452
- config.compose ? 'compose' : null,
164453
- ].filter(Boolean);
164454
- if (modes.length === 0) {
164448
+ // Validate engine field if present
164449
+ if (config.engine && !['docker', 'bubblewrap', 'seatbelt'].includes(config.engine)) {
164455
164450
  errors.push({
164456
- field: `sandboxes.${name}`,
164457
- message: `Sandbox '${name}' must specify one of: image, dockerfile, dockerfile_inline, or compose`,
164458
- });
164459
- }
164460
- else if (modes.length > 1) {
164461
- errors.push({
164462
- field: `sandboxes.${name}`,
164463
- message: `Sandbox '${name}' has multiple modes (${modes.join(', ')}). Specify exactly one.`,
164451
+ field: `sandboxes.${name}.engine`,
164452
+ message: `Sandbox '${name}' has invalid engine '${config.engine}'. Must be 'docker', 'bubblewrap', or 'seatbelt'.`,
164464
164453
  });
164465
164454
  }
164466
- // Compose mode requires service
164467
- if (config.compose && !config.service) {
164468
- errors.push({
164469
- field: `sandboxes.${name}.service`,
164470
- message: `Sandbox '${name}' uses compose mode but is missing required 'service' field`,
164471
- });
164472
- }
164473
- // Validate file paths don't contain traversal
164474
- if (config.dockerfile && /\.\./.test(config.dockerfile)) {
164475
- errors.push({
164476
- field: `sandboxes.${name}.dockerfile`,
164477
- message: `Dockerfile path '${config.dockerfile}' in sandbox '${name}' must not contain '..' path traversal`,
164478
- });
164479
- }
164480
- if (config.compose && /\.\./.test(config.compose)) {
164481
- errors.push({
164482
- field: `sandboxes.${name}.compose`,
164483
- message: `Compose file path '${config.compose}' in sandbox '${name}' must not contain '..' path traversal`,
164484
- });
164455
+ const isNativeEngine = config.engine === 'bubblewrap' || config.engine === 'seatbelt';
164456
+ if (isNativeEngine) {
164457
+ // Native engine (bubblewrap/seatbelt): reject Docker-only fields
164458
+ const dockerOnlyFields = [
164459
+ ['image', config.image],
164460
+ ['dockerfile', config.dockerfile],
164461
+ ['dockerfile_inline', config.dockerfile_inline],
164462
+ ['compose', config.compose],
164463
+ ['service', config.service],
164464
+ ['cache', config.cache],
164465
+ ['visor_path', config.visor_path],
164466
+ ['resources', config.resources],
164467
+ ];
164468
+ for (const [field, value] of dockerOnlyFields) {
164469
+ if (value !== undefined) {
164470
+ errors.push({
164471
+ field: `sandboxes.${name}.${field}`,
164472
+ message: `Sandbox '${name}' uses ${config.engine} engine but has Docker-only field '${field}'. Remove it or switch to engine: docker.`,
164473
+ });
164474
+ }
164475
+ }
164485
164476
  }
164486
- // Validate container paths are absolute and safe
164487
- if (config.workdir) {
164488
- if (!config.workdir.startsWith('/')) {
164477
+ else {
164478
+ // Docker engine (default): must have exactly one mode
164479
+ const modes = [
164480
+ config.image ? 'image' : null,
164481
+ config.dockerfile || config.dockerfile_inline ? 'dockerfile' : null,
164482
+ config.compose ? 'compose' : null,
164483
+ ].filter(Boolean);
164484
+ if (modes.length === 0) {
164489
164485
  errors.push({
164490
- field: `sandboxes.${name}.workdir`,
164491
- message: `Workdir '${config.workdir}' in sandbox '${name}' must be an absolute path (start with /)`,
164486
+ field: `sandboxes.${name}`,
164487
+ message: `Sandbox '${name}' must specify one of: image, dockerfile, dockerfile_inline, or compose`,
164492
164488
  });
164493
164489
  }
164494
- if (/\.\./.test(config.workdir)) {
164490
+ else if (modes.length > 1) {
164495
164491
  errors.push({
164496
- field: `sandboxes.${name}.workdir`,
164497
- message: `Workdir '${config.workdir}' in sandbox '${name}' must not contain '..' path traversal`,
164492
+ field: `sandboxes.${name}`,
164493
+ message: `Sandbox '${name}' has multiple modes (${modes.join(', ')}). Specify exactly one.`,
164498
164494
  });
164499
164495
  }
164500
- }
164501
- if (config.visor_path) {
164502
- if (!config.visor_path.startsWith('/')) {
164496
+ // Compose mode requires service
164497
+ if (config.compose && !config.service) {
164503
164498
  errors.push({
164504
- field: `sandboxes.${name}.visor_path`,
164505
- message: `visor_path '${config.visor_path}' in sandbox '${name}' must be an absolute path (start with /)`,
164499
+ field: `sandboxes.${name}.service`,
164500
+ message: `Sandbox '${name}' uses compose mode but is missing required 'service' field`,
164506
164501
  });
164507
164502
  }
164508
- if (/\.\./.test(config.visor_path)) {
164503
+ // Validate file paths don't contain traversal
164504
+ if (config.dockerfile && /\.\./.test(config.dockerfile)) {
164509
164505
  errors.push({
164510
- field: `sandboxes.${name}.visor_path`,
164511
- message: `visor_path '${config.visor_path}' in sandbox '${name}' must not contain '..' path traversal`,
164506
+ field: `sandboxes.${name}.dockerfile`,
164507
+ message: `Dockerfile path '${config.dockerfile}' in sandbox '${name}' must not contain '..' path traversal`,
164512
164508
  });
164513
164509
  }
164514
- }
164515
- // Validate cache paths are absolute and safe
164516
- if (config.cache?.paths) {
164517
- for (const p of config.cache.paths) {
164518
- if (!p.startsWith('/')) {
164510
+ if (config.compose && /\.\./.test(config.compose)) {
164511
+ errors.push({
164512
+ field: `sandboxes.${name}.compose`,
164513
+ message: `Compose file path '${config.compose}' in sandbox '${name}' must not contain '..' path traversal`,
164514
+ });
164515
+ }
164516
+ // Validate visor_path
164517
+ if (config.visor_path) {
164518
+ if (!config.visor_path.startsWith('/')) {
164519
164519
  errors.push({
164520
- field: `sandboxes.${name}.cache.paths`,
164521
- message: `Cache path '${p}' in sandbox '${name}' must be absolute (start with /)`,
164522
- value: p,
164520
+ field: `sandboxes.${name}.visor_path`,
164521
+ message: `visor_path '${config.visor_path}' in sandbox '${name}' must be an absolute path (start with /)`,
164523
164522
  });
164524
164523
  }
164525
- if (/\.\./.test(p)) {
164524
+ if (/\.\./.test(config.visor_path)) {
164525
+ errors.push({
164526
+ field: `sandboxes.${name}.visor_path`,
164527
+ message: `visor_path '${config.visor_path}' in sandbox '${name}' must not contain '..' path traversal`,
164528
+ });
164529
+ }
164530
+ }
164531
+ // Validate cache paths are absolute and safe
164532
+ if (config.cache?.paths) {
164533
+ for (const p of config.cache.paths) {
164534
+ if (!p.startsWith('/')) {
164535
+ errors.push({
164536
+ field: `sandboxes.${name}.cache.paths`,
164537
+ message: `Cache path '${p}' in sandbox '${name}' must be absolute (start with /)`,
164538
+ value: p,
164539
+ });
164540
+ }
164541
+ if (/\.\./.test(p)) {
164542
+ errors.push({
164543
+ field: `sandboxes.${name}.cache.paths`,
164544
+ message: `Cache path '${p}' in sandbox '${name}' must not contain '..' path traversal`,
164545
+ value: p,
164546
+ });
164547
+ }
164548
+ }
164549
+ }
164550
+ // Validate resource limits
164551
+ if (config.resources?.cpu !== undefined) {
164552
+ if (typeof config.resources.cpu !== 'number' || config.resources.cpu <= 0) {
164526
164553
  errors.push({
164527
- field: `sandboxes.${name}.cache.paths`,
164528
- message: `Cache path '${p}' in sandbox '${name}' must not contain '..' path traversal`,
164529
- value: p,
164554
+ field: `sandboxes.${name}.resources.cpu`,
164555
+ message: `CPU limit in sandbox '${name}' must be a positive number`,
164556
+ value: config.resources.cpu,
164530
164557
  });
164531
164558
  }
164532
164559
  }
164533
164560
  }
164534
- // Validate resource limits
164535
- if (config.resources?.cpu !== undefined) {
164536
- if (typeof config.resources.cpu !== 'number' || config.resources.cpu <= 0) {
164561
+ // Common validations for all engines
164562
+ if (config.workdir) {
164563
+ if (!config.workdir.startsWith('/')) {
164537
164564
  errors.push({
164538
- field: `sandboxes.${name}.resources.cpu`,
164539
- message: `CPU limit in sandbox '${name}' must be a positive number`,
164540
- value: config.resources.cpu,
164565
+ field: `sandboxes.${name}.workdir`,
164566
+ message: `Workdir '${config.workdir}' in sandbox '${name}' must be an absolute path (start with /)`,
164567
+ });
164568
+ }
164569
+ if (/\.\./.test(config.workdir)) {
164570
+ errors.push({
164571
+ field: `sandboxes.${name}.workdir`,
164572
+ message: `Workdir '${config.workdir}' in sandbox '${name}' must not contain '..' path traversal`,
164541
164573
  });
164542
164574
  }
164543
164575
  }
@@ -173132,6 +173164,11 @@ exports.configSchema = {
173132
173164
  SandboxConfig: {
173133
173165
  type: 'object',
173134
173166
  properties: {
173167
+ engine: {
173168
+ type: 'string',
173169
+ enum: ['docker', 'bubblewrap', 'seatbelt'],
173170
+ description: "Sandbox engine type: 'docker' (default), 'bubblewrap' (Linux namespaces), or 'seatbelt' (macOS sandbox-exec)",
173171
+ },
173135
173172
  image: {
173136
173173
  type: 'string',
173137
173174
  description: 'Docker image to use (e.g., "node:20-alpine")',
@@ -188304,6 +188341,7 @@ class McpCheckProvider extends check_provider_interface_1.CheckProvider {
188304
188341
  outputs: this.buildOutputContext(dependencyResults),
188305
188342
  args: sessionInfo?.args || {},
188306
188343
  env: this.getSafeEnvironmentVariables(),
188344
+ inputs: config.workflowInputs || sessionInfo?.workflowInputs || {},
188307
188345
  };
188308
188346
  // Render method arguments if needed
188309
188347
  let methodArgs = cfg.methodArgs || {};
@@ -191865,6 +191903,150 @@ class PRReviewer {
191865
191903
  exports.PRReviewer = PRReviewer;
191866
191904
 
191867
191905
 
191906
+ /***/ }),
191907
+
191908
+ /***/ 11207:
191909
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
191910
+
191911
+ "use strict";
191912
+
191913
+ /**
191914
+ * Bubblewrap-based sandbox implementation.
191915
+ * Uses Linux kernel namespaces for lightweight process isolation (~5-50ms overhead).
191916
+ * Requires the `bwrap` binary to be installed on the host.
191917
+ */
191918
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
191919
+ exports.BubblewrapSandbox = void 0;
191920
+ const util_1 = __nccwpck_require__(39023);
191921
+ const child_process_1 = __nccwpck_require__(35317);
191922
+ const fs_1 = __nccwpck_require__(79896);
191923
+ const path_1 = __nccwpck_require__(16928);
191924
+ const logger_1 = __nccwpck_require__(86999);
191925
+ const sandbox_telemetry_1 = __nccwpck_require__(34826);
191926
+ const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
191927
+ const EXEC_MAX_BUFFER = 50 * 1024 * 1024; // 50MB
191928
+ class BubblewrapSandbox {
191929
+ name;
191930
+ config;
191931
+ repoPath;
191932
+ constructor(name, config, repoPath) {
191933
+ this.name = name;
191934
+ this.config = config;
191935
+ this.repoPath = (0, path_1.resolve)(repoPath);
191936
+ }
191937
+ /**
191938
+ * Check if bwrap binary is available on the system.
191939
+ */
191940
+ static async isAvailable() {
191941
+ try {
191942
+ await execFileAsync('which', ['bwrap'], { timeout: 5000 });
191943
+ return true;
191944
+ }
191945
+ catch {
191946
+ return false;
191947
+ }
191948
+ }
191949
+ /**
191950
+ * Execute a command inside a bubblewrap sandbox.
191951
+ * Each exec creates a fresh namespace — no persistent container.
191952
+ */
191953
+ async exec(options) {
191954
+ const args = this.buildArgs(options);
191955
+ args.push('--', '/bin/sh', '-c', options.command);
191956
+ logger_1.logger.debug(`[BubblewrapSandbox] Executing in sandbox '${this.name}': ${options.command.slice(0, 100)}`);
191957
+ try {
191958
+ const { stdout, stderr } = await execFileAsync('bwrap', args, {
191959
+ maxBuffer: options.maxBuffer || EXEC_MAX_BUFFER,
191960
+ timeout: options.timeoutMs || 600000,
191961
+ });
191962
+ (0, sandbox_telemetry_1.addEvent)('visor.sandbox.bwrap.exec', {
191963
+ 'visor.sandbox.name': this.name,
191964
+ 'visor.sandbox.exit_code': 0,
191965
+ });
191966
+ return { stdout, stderr, exitCode: 0 };
191967
+ }
191968
+ catch (err) {
191969
+ const execErr = err;
191970
+ const exitCode = typeof execErr.code === 'number' ? execErr.code : 1;
191971
+ (0, sandbox_telemetry_1.addEvent)('visor.sandbox.bwrap.exec', {
191972
+ 'visor.sandbox.name': this.name,
191973
+ 'visor.sandbox.exit_code': exitCode,
191974
+ });
191975
+ return {
191976
+ stdout: execErr.stdout || '',
191977
+ stderr: execErr.stderr || '',
191978
+ exitCode,
191979
+ };
191980
+ }
191981
+ }
191982
+ /**
191983
+ * No-op: bubblewrap processes are ephemeral (no persistent container to stop).
191984
+ */
191985
+ async stop() {
191986
+ // Nothing to clean up — bwrap processes exit when the command finishes,
191987
+ // and --die-with-parent ensures cleanup if the parent dies.
191988
+ }
191989
+ /**
191990
+ * Build the bwrap command-line arguments.
191991
+ */
191992
+ buildArgs(options) {
191993
+ const workdir = this.config.workdir || '/workspace';
191994
+ const args = [];
191995
+ // Read-only system directories
191996
+ args.push('--ro-bind', '/usr', '/usr');
191997
+ args.push('--ro-bind', '/bin', '/bin');
191998
+ // /lib and /lib64 may not exist on all distros (e.g., Alpine uses /usr/lib)
191999
+ if ((0, fs_1.existsSync)('/lib')) {
192000
+ args.push('--ro-bind', '/lib', '/lib');
192001
+ }
192002
+ if ((0, fs_1.existsSync)('/lib64')) {
192003
+ args.push('--ro-bind', '/lib64', '/lib64');
192004
+ }
192005
+ // DNS resolution and TLS certificates
192006
+ if ((0, fs_1.existsSync)('/etc/resolv.conf')) {
192007
+ args.push('--ro-bind', '/etc/resolv.conf', '/etc/resolv.conf');
192008
+ }
192009
+ if ((0, fs_1.existsSync)('/etc/ssl')) {
192010
+ args.push('--ro-bind', '/etc/ssl', '/etc/ssl');
192011
+ }
192012
+ // Virtual filesystems
192013
+ args.push('--dev', '/dev');
192014
+ args.push('--proc', '/proc');
192015
+ args.push('--tmpfs', '/tmp');
192016
+ args.push('--tmpfs', '/root');
192017
+ // Workspace mount — the only writable directory (unless read_only)
192018
+ if (this.config.read_only) {
192019
+ args.push('--ro-bind', this.repoPath, workdir);
192020
+ }
192021
+ else {
192022
+ args.push('--bind', this.repoPath, workdir);
192023
+ }
192024
+ // Working directory inside sandbox
192025
+ args.push('--chdir', workdir);
192026
+ // Namespace isolation
192027
+ args.push('--unshare-pid');
192028
+ args.push('--new-session');
192029
+ args.push('--die-with-parent');
192030
+ // Network isolation
192031
+ if (this.config.network === false) {
192032
+ args.push('--unshare-net');
192033
+ }
192034
+ // Clean environment — only explicitly passed vars are visible
192035
+ args.push('--clearenv');
192036
+ // Pass filtered environment variables.
192037
+ // Safe: execFile passes each arg as a separate argv entry — no shell interpretation.
192038
+ for (const [key, value] of Object.entries(options.env)) {
192039
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
192040
+ throw new Error(`Invalid environment variable name: '${key}'`);
192041
+ }
192042
+ args.push('--setenv', key, value);
192043
+ }
192044
+ return args;
192045
+ }
192046
+ }
192047
+ exports.BubblewrapSandbox = BubblewrapSandbox;
192048
+
192049
+
191868
192050
  /***/ }),
191869
192051
 
191870
192052
  /***/ 10878:
@@ -192691,8 +192873,9 @@ function filterEnvForSandbox(checkEnv, hostEnv, passthroughPatterns, defaultPatt
192691
192873
  "use strict";
192692
192874
 
192693
192875
  /**
192694
- * SandboxManager — lifecycle management for Docker sandbox environments.
192695
- * Handles lazy container startup, reuse, exec routing, and cleanup.
192876
+ * SandboxManager — lifecycle management for sandbox environments.
192877
+ * Handles lazy container/process startup, reuse, exec routing, and cleanup.
192878
+ * Supports Docker (image, compose), Bubblewrap (Linux namespaces), and Seatbelt (macOS sandbox-exec) engines.
192696
192879
  */
192697
192880
  Object.defineProperty(exports, "__esModule", ({ value: true }));
192698
192881
  exports.SandboxManager = void 0;
@@ -192756,6 +192939,20 @@ class SandboxManager {
192756
192939
  throw new Error(`Sandbox '${name}' is not defined`);
192757
192940
  }
192758
192941
  const mode = config.compose ? 'compose' : 'image';
192942
+ // Bubblewrap engine: ephemeral per-exec, no persistent container
192943
+ if (config.engine === 'bubblewrap') {
192944
+ const { BubblewrapSandbox } = __nccwpck_require__(11207);
192945
+ const instance = new BubblewrapSandbox(name, config, this.repoPath);
192946
+ this.instances.set(name, instance);
192947
+ return instance;
192948
+ }
192949
+ // Seatbelt engine: macOS sandbox-exec, ephemeral per-exec
192950
+ if (config.engine === 'seatbelt') {
192951
+ const { SeatbeltSandbox } = __nccwpck_require__(46429);
192952
+ const instance = new SeatbeltSandbox(name, config, this.repoPath);
192953
+ this.instances.set(name, instance);
192954
+ return instance;
192955
+ }
192759
192956
  return (0, sandbox_telemetry_1.withActiveSpan)('visor.sandbox.start', {
192760
192957
  'visor.sandbox.name': name,
192761
192958
  'visor.sandbox.mode': mode,
@@ -192884,6 +193081,165 @@ function setSpanError(err) {
192884
193081
  }
192885
193082
 
192886
193083
 
193084
+ /***/ }),
193085
+
193086
+ /***/ 46429:
193087
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
193088
+
193089
+ "use strict";
193090
+
193091
+ /**
193092
+ * macOS Seatbelt sandbox implementation.
193093
+ * Uses Apple's sandbox-exec with dynamically-generated SBPL profiles
193094
+ * for lightweight process isolation on macOS.
193095
+ * Requires the `sandbox-exec` binary (ships with macOS).
193096
+ */
193097
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
193098
+ exports.SeatbeltSandbox = void 0;
193099
+ const util_1 = __nccwpck_require__(39023);
193100
+ const child_process_1 = __nccwpck_require__(35317);
193101
+ const path_1 = __nccwpck_require__(16928);
193102
+ const fs_1 = __nccwpck_require__(79896);
193103
+ const logger_1 = __nccwpck_require__(86999);
193104
+ const sandbox_telemetry_1 = __nccwpck_require__(34826);
193105
+ const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
193106
+ const EXEC_MAX_BUFFER = 50 * 1024 * 1024; // 50MB
193107
+ class SeatbeltSandbox {
193108
+ name;
193109
+ config;
193110
+ repoPath;
193111
+ constructor(name, config, repoPath) {
193112
+ this.name = name;
193113
+ this.config = config;
193114
+ // Resolve symlinks — macOS has /var → /private/var, /tmp → /private/tmp etc.
193115
+ // sandbox-exec operates on real paths, so we must resolve before building profiles.
193116
+ this.repoPath = (0, fs_1.realpathSync)((0, path_1.resolve)(repoPath));
193117
+ }
193118
+ /**
193119
+ * Check if sandbox-exec binary is available on the system.
193120
+ */
193121
+ static async isAvailable() {
193122
+ try {
193123
+ await execFileAsync('which', ['sandbox-exec'], { timeout: 5000 });
193124
+ return true;
193125
+ }
193126
+ catch {
193127
+ return false;
193128
+ }
193129
+ }
193130
+ /**
193131
+ * Execute a command inside a macOS seatbelt sandbox.
193132
+ * Each exec creates a fresh sandbox process — no persistent container.
193133
+ */
193134
+ async exec(options) {
193135
+ const profile = this.buildProfile();
193136
+ // Validate env var names
193137
+ for (const key of Object.keys(options.env)) {
193138
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
193139
+ throw new Error(`Invalid environment variable name: '${key}'`);
193140
+ }
193141
+ }
193142
+ // Build args: sandbox-exec -p '<profile>' /usr/bin/env -i KEY=VAL ... /bin/sh -c '<command>'
193143
+ const args = ['-p', profile];
193144
+ // Use env -i to clear inherited environment, then set explicit vars
193145
+ args.push('/usr/bin/env', '-i');
193146
+ for (const [key, value] of Object.entries(options.env)) {
193147
+ args.push(`${key}=${value}`);
193148
+ }
193149
+ args.push('/bin/sh', '-c', options.command);
193150
+ logger_1.logger.debug(`[SeatbeltSandbox] Executing in sandbox '${this.name}': ${options.command.slice(0, 100)}`);
193151
+ try {
193152
+ const { stdout, stderr } = await execFileAsync('sandbox-exec', args, {
193153
+ maxBuffer: options.maxBuffer || EXEC_MAX_BUFFER,
193154
+ timeout: options.timeoutMs || 600000,
193155
+ cwd: this.repoPath,
193156
+ });
193157
+ (0, sandbox_telemetry_1.addEvent)('visor.sandbox.seatbelt.exec', {
193158
+ 'visor.sandbox.name': this.name,
193159
+ 'visor.sandbox.exit_code': 0,
193160
+ });
193161
+ return { stdout, stderr, exitCode: 0 };
193162
+ }
193163
+ catch (err) {
193164
+ const execErr = err;
193165
+ const exitCode = typeof execErr.code === 'number' ? execErr.code : 1;
193166
+ (0, sandbox_telemetry_1.addEvent)('visor.sandbox.seatbelt.exec', {
193167
+ 'visor.sandbox.name': this.name,
193168
+ 'visor.sandbox.exit_code': exitCode,
193169
+ });
193170
+ return {
193171
+ stdout: execErr.stdout || '',
193172
+ stderr: execErr.stderr || '',
193173
+ exitCode,
193174
+ };
193175
+ }
193176
+ }
193177
+ /**
193178
+ * No-op: sandbox-exec processes are ephemeral (no persistent container to stop).
193179
+ */
193180
+ async stop() {
193181
+ // Nothing to clean up — sandbox-exec processes exit when the command finishes.
193182
+ }
193183
+ /**
193184
+ * Escape a path for use inside an SBPL profile string.
193185
+ * Escapes backslashes and double quotes.
193186
+ */
193187
+ escapePath(p) {
193188
+ return p.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
193189
+ }
193190
+ /**
193191
+ * Build the SBPL (Seatbelt Profile Language) profile string.
193192
+ */
193193
+ buildProfile() {
193194
+ const repoPath = this.escapePath(this.repoPath);
193195
+ const lines = [];
193196
+ lines.push('(version 1)');
193197
+ lines.push('(deny default)');
193198
+ // Allow basic process execution
193199
+ lines.push('(allow process-exec)');
193200
+ lines.push('(allow process-fork)');
193201
+ // Allow read access to system paths.
193202
+ // macOS uses symlinks: /var → /private/var, /tmp → /private/tmp, /etc → /private/etc.
193203
+ // We include both the symlink paths and /private to cover resolution.
193204
+ lines.push('(allow file-read*');
193205
+ lines.push(' (literal "/")');
193206
+ lines.push(' (subpath "/usr")');
193207
+ lines.push(' (subpath "/bin")');
193208
+ lines.push(' (subpath "/sbin")');
193209
+ lines.push(' (subpath "/Library")');
193210
+ lines.push(' (subpath "/System")');
193211
+ lines.push(' (subpath "/private")');
193212
+ lines.push(' (subpath "/var")');
193213
+ lines.push(' (subpath "/etc")');
193214
+ lines.push(' (subpath "/dev")');
193215
+ lines.push(' (subpath "/tmp"))');
193216
+ // Allow write to /tmp and /dev
193217
+ lines.push('(allow file-write*');
193218
+ lines.push(' (subpath "/tmp")');
193219
+ lines.push(' (subpath "/private/tmp")');
193220
+ lines.push(' (subpath "/dev"))');
193221
+ // Allow xcrun cache writes (macOS git/Xcode tools write to /var/folders/.../T/xcrun_db-*)
193222
+ lines.push('(allow file-write* (regex #"/private/var/folders/.*/T/xcrun_db"))');
193223
+ // Workspace read access
193224
+ lines.push(`(allow file-read* (subpath "${repoPath}"))`);
193225
+ // Workspace write access (unless read_only)
193226
+ if (!this.config.read_only) {
193227
+ lines.push(`(allow file-write* (subpath "${repoPath}"))`);
193228
+ }
193229
+ // Network access (unless explicitly disabled)
193230
+ if (this.config.network !== false) {
193231
+ lines.push('(allow network*)');
193232
+ }
193233
+ // Allow sysctl, mach lookups, signal for basic process operation
193234
+ lines.push('(allow sysctl-read)');
193235
+ lines.push('(allow mach-lookup)');
193236
+ lines.push('(allow signal)');
193237
+ return lines.join('\n');
193238
+ }
193239
+ }
193240
+ exports.SeatbeltSandbox = SeatbeltSandbox;
193241
+
193242
+
192887
193243
  /***/ }),
192888
193244
 
192889
193245
  /***/ 50504:
@@ -198456,7 +198812,9 @@ const cache_prewarmer_1 = __nccwpck_require__(50200);
198456
198812
  const rate_limiter_1 = __nccwpck_require__(53065);
198457
198813
  const trace_helpers_1 = __nccwpck_require__(75338);
198458
198814
  const scheduler_1 = __nccwpck_require__(28404);
198815
+ const crypto_1 = __nccwpck_require__(76982);
198459
198816
  const slack_output_adapter_1 = __nccwpck_require__(45330);
198817
+ const workspace_manager_1 = __nccwpck_require__(6134);
198460
198818
  class SlackSocketRunner {
198461
198819
  appToken;
198462
198820
  endpoint;
@@ -198587,6 +198945,8 @@ class SlackSocketRunner {
198587
198945
  }
198588
198946
  const url = await this.openConnection();
198589
198947
  await this.connect(url);
198948
+ // Clean up stale workspace directories from previous runs
198949
+ workspace_manager_1.WorkspaceManager.cleanupStale().catch(() => { });
198590
198950
  }
198591
198951
  async openConnection() {
198592
198952
  const resp = await fetch('https://slack.com/api/apps.connections.open', {
@@ -198882,6 +199242,22 @@ class SlackSocketRunner {
198882
199242
  return this.cfg;
198883
199243
  }
198884
199244
  })();
199245
+ // Derive stable workspace name from Slack thread identity so all messages
199246
+ // in the same thread share the same workspace directory (git checkouts persist).
199247
+ const wsChannel = String(ev.channel || '');
199248
+ const wsThreadTs = String(ev.thread_ts || ev.ts || ev.event_ts || '');
199249
+ if (wsChannel && wsThreadTs) {
199250
+ const hash = (0, crypto_1.createHash)('sha256')
199251
+ .update(`${wsChannel}:${wsThreadTs}`)
199252
+ .digest('hex')
199253
+ .slice(0, 8);
199254
+ const workspaceName = `slack-${hash}`;
199255
+ if (!cfgForRun.workspace) {
199256
+ cfgForRun.workspace = {};
199257
+ }
199258
+ cfgForRun.workspace.name = workspaceName;
199259
+ cfgForRun.workspace.cleanup_on_exit = false;
199260
+ }
198885
199261
  // Seed first message for this thread to allow initial human-input to consume it exactly once
198886
199262
  try {
198887
199263
  const { getPromptStateManager } = await Promise.resolve().then(() => __importStar(__nccwpck_require__(27716)));
@@ -222022,17 +222398,36 @@ class WorkspaceManager {
222022
222398
  // Check if original path is a git repository
222023
222399
  const isGitRepo = await this.isGitRepository(this.originalPath);
222024
222400
  if (isGitRepo) {
222025
- // Create worktree for main project
222026
- await this.createMainProjectWorktree(mainProjectPath);
222401
+ // Check if main project worktree already exists (reused workspace, e.g. Slack thread)
222402
+ const exists = await this.pathExists(mainProjectPath);
222403
+ if (exists) {
222404
+ logger_1.logger.info(`[Workspace] Reusing existing main project worktree: ${mainProjectPath}`);
222405
+ const isValid = await this.isGitRepository(mainProjectPath);
222406
+ if (!isValid) {
222407
+ logger_1.logger.warn(`[Workspace] Existing path is not a valid git dir, recreating`);
222408
+ await fsp.rm(mainProjectPath, { recursive: true, force: true });
222409
+ try {
222410
+ await command_executor_1.commandExecutor.execute(`git -C ${shellEscape(this.originalPath)} worktree prune`, { timeout: 10000 });
222411
+ }
222412
+ catch { }
222413
+ await this.createMainProjectWorktree(mainProjectPath);
222414
+ }
222415
+ }
222416
+ else {
222417
+ await this.createMainProjectWorktree(mainProjectPath);
222418
+ }
222027
222419
  }
222028
222420
  else {
222029
222421
  // If not a git repo, create a symlink instead
222030
222422
  logger_1.logger.debug(`Original path is not a git repo, creating symlink`);
222031
- try {
222032
- await fsp.symlink(this.originalPath, mainProjectPath);
222033
- }
222034
- catch (error) {
222035
- throw new Error(`Failed to create symlink for main project: ${error}`);
222423
+ const exists = await this.pathExists(mainProjectPath);
222424
+ if (!exists) {
222425
+ try {
222426
+ await fsp.symlink(this.originalPath, mainProjectPath);
222427
+ }
222428
+ catch (error) {
222429
+ throw new Error(`Failed to create symlink for main project: ${error}`);
222430
+ }
222036
222431
  }
222037
222432
  }
222038
222433
  // Register cleanup handlers
@@ -222102,6 +222497,16 @@ class WorkspaceManager {
222102
222497
  * @param timeout Maximum time to wait for active operations (default: 60s)
222103
222498
  */
222104
222499
  async cleanup(timeout = 60000) {
222500
+ // Respect cleanupOnExit flag — persisted workspaces (e.g. Slack threads) should not be cleaned up
222501
+ if (!this.config.cleanupOnExit) {
222502
+ logger_1.logger.debug(`[Workspace] Skipping cleanup (cleanupOnExit=false): ${this.workspacePath}`);
222503
+ WorkspaceManager.instances.delete(this.sessionId);
222504
+ this.initialized = false;
222505
+ this.mainProjectInfo = null;
222506
+ this.projects.clear();
222507
+ this.usedNames.clear();
222508
+ return;
222509
+ }
222105
222510
  logger_1.logger.info(`Cleaning up workspace: ${this.workspacePath} (active operations: ${this.activeOperations})`);
222106
222511
  // If there are active operations, wait for them to complete
222107
222512
  if (this.activeOperations > 0) {
@@ -222157,6 +222562,70 @@ class WorkspaceManager {
222157
222562
  logger_1.logger.warn(`Failed to cleanup workspace: ${error}`);
222158
222563
  }
222159
222564
  }
222565
+ /**
222566
+ * Check if a path exists (file or directory).
222567
+ */
222568
+ async pathExists(p) {
222569
+ try {
222570
+ await fsp.access(p);
222571
+ return true;
222572
+ }
222573
+ catch {
222574
+ return false;
222575
+ }
222576
+ }
222577
+ /**
222578
+ * Clean up stale workspace directories older than maxAge.
222579
+ * Call periodically (e.g. at socket-runner startup) to prevent disk bloat.
222580
+ */
222581
+ static async cleanupStale(basePath = process.env.VISOR_WORKSPACE_PATH || '/tmp/visor-workspaces', maxAgeMs = 24 * 60 * 60 * 1000) {
222582
+ let cleaned = 0;
222583
+ try {
222584
+ const entries = await fsp.readdir(basePath, { withFileTypes: true });
222585
+ const now = Date.now();
222586
+ for (const entry of entries) {
222587
+ if (!entry.isDirectory())
222588
+ continue;
222589
+ const dirPath = path.join(basePath, entry.name);
222590
+ try {
222591
+ const stat = await fsp.stat(dirPath);
222592
+ if (now - stat.mtimeMs > maxAgeMs) {
222593
+ // Prune any git worktrees before removing the directory
222594
+ try {
222595
+ const subdirs = await fsp.readdir(dirPath, { withFileTypes: true });
222596
+ for (const sub of subdirs) {
222597
+ if (!sub.isDirectory())
222598
+ continue;
222599
+ const subPath = path.join(dirPath, sub.name);
222600
+ const gitFilePath = path.join(subPath, '.git');
222601
+ try {
222602
+ const gitContent = await fsp.readFile(gitFilePath, 'utf-8');
222603
+ const match = gitContent.match(/gitdir:\s*(.+)/);
222604
+ if (match) {
222605
+ const worktreeGitDir = match[1].trim();
222606
+ const repoGitDir = worktreeGitDir.replace(/\/\.git\/worktrees\/.*$/, '');
222607
+ await command_executor_1.commandExecutor.execute(`git -C ${shellEscape(repoGitDir)} worktree remove ${shellEscape(subPath)} --force`, { timeout: 10000 });
222608
+ }
222609
+ }
222610
+ catch { }
222611
+ }
222612
+ }
222613
+ catch { }
222614
+ await fsp.rm(dirPath, { recursive: true, force: true });
222615
+ cleaned++;
222616
+ }
222617
+ }
222618
+ catch { }
222619
+ }
222620
+ if (cleaned > 0) {
222621
+ logger_1.logger.info(`[Workspace] Cleaned up ${cleaned} stale workspace(s) from ${basePath}`);
222622
+ }
222623
+ }
222624
+ catch (error) {
222625
+ logger_1.logger.debug(`[Workspace] Stale cleanup error: ${error}`);
222626
+ }
222627
+ return cleaned;
222628
+ }
222160
222629
  /**
222161
222630
  * Create worktree for the main project
222162
222631
  *
@@ -265589,7 +266058,7 @@ var require_package2 = __commonJS({
265589
266058
  module2.exports = {
265590
266059
  name: "@aws-sdk/client-bedrock-runtime",
265591
266060
  description: "AWS SDK for JavaScript Bedrock Runtime Client for Node.js, Browser and React Native",
265592
- version: "3.997.0",
266061
+ version: "3.998.0",
265593
266062
  scripts: {
265594
266063
  build: "concurrently 'yarn:build:types' 'yarn:build:es' && yarn build:cjs",
265595
266064
  "build:cjs": "node ../../scripts/compilation/inline client-bedrock-runtime",
@@ -265609,49 +266078,49 @@ var require_package2 = __commonJS({
265609
266078
  dependencies: {
265610
266079
  "@aws-crypto/sha256-browser": "5.2.0",
265611
266080
  "@aws-crypto/sha256-js": "5.2.0",
265612
- "@aws-sdk/core": "^3.973.13",
265613
- "@aws-sdk/credential-provider-node": "^3.972.12",
265614
- "@aws-sdk/eventstream-handler-node": "^3.972.7",
265615
- "@aws-sdk/middleware-eventstream": "^3.972.4",
265616
- "@aws-sdk/middleware-host-header": "^3.972.4",
265617
- "@aws-sdk/middleware-logger": "^3.972.4",
265618
- "@aws-sdk/middleware-recursion-detection": "^3.972.4",
265619
- "@aws-sdk/middleware-user-agent": "^3.972.13",
265620
- "@aws-sdk/middleware-websocket": "^3.972.8",
265621
- "@aws-sdk/region-config-resolver": "^3.972.4",
265622
- "@aws-sdk/token-providers": "3.997.0",
265623
- "@aws-sdk/types": "^3.973.2",
265624
- "@aws-sdk/util-endpoints": "^3.996.1",
265625
- "@aws-sdk/util-user-agent-browser": "^3.972.4",
265626
- "@aws-sdk/util-user-agent-node": "^3.972.12",
265627
- "@smithy/config-resolver": "^4.4.7",
265628
- "@smithy/core": "^3.23.4",
265629
- "@smithy/eventstream-serde-browser": "^4.2.9",
265630
- "@smithy/eventstream-serde-config-resolver": "^4.3.9",
265631
- "@smithy/eventstream-serde-node": "^4.2.9",
265632
- "@smithy/fetch-http-handler": "^5.3.10",
265633
- "@smithy/hash-node": "^4.2.9",
265634
- "@smithy/invalid-dependency": "^4.2.9",
265635
- "@smithy/middleware-content-length": "^4.2.9",
265636
- "@smithy/middleware-endpoint": "^4.4.18",
265637
- "@smithy/middleware-retry": "^4.4.35",
265638
- "@smithy/middleware-serde": "^4.2.10",
265639
- "@smithy/middleware-stack": "^4.2.9",
265640
- "@smithy/node-config-provider": "^4.3.9",
265641
- "@smithy/node-http-handler": "^4.4.11",
265642
- "@smithy/protocol-http": "^5.3.9",
265643
- "@smithy/smithy-client": "^4.11.7",
265644
- "@smithy/types": "^4.12.1",
265645
- "@smithy/url-parser": "^4.2.9",
266081
+ "@aws-sdk/core": "^3.973.14",
266082
+ "@aws-sdk/credential-provider-node": "^3.972.13",
266083
+ "@aws-sdk/eventstream-handler-node": "^3.972.8",
266084
+ "@aws-sdk/middleware-eventstream": "^3.972.5",
266085
+ "@aws-sdk/middleware-host-header": "^3.972.5",
266086
+ "@aws-sdk/middleware-logger": "^3.972.5",
266087
+ "@aws-sdk/middleware-recursion-detection": "^3.972.5",
266088
+ "@aws-sdk/middleware-user-agent": "^3.972.14",
266089
+ "@aws-sdk/middleware-websocket": "^3.972.9",
266090
+ "@aws-sdk/region-config-resolver": "^3.972.5",
266091
+ "@aws-sdk/token-providers": "3.998.0",
266092
+ "@aws-sdk/types": "^3.973.3",
266093
+ "@aws-sdk/util-endpoints": "^3.996.2",
266094
+ "@aws-sdk/util-user-agent-browser": "^3.972.5",
266095
+ "@aws-sdk/util-user-agent-node": "^3.972.13",
266096
+ "@smithy/config-resolver": "^4.4.9",
266097
+ "@smithy/core": "^3.23.6",
266098
+ "@smithy/eventstream-serde-browser": "^4.2.10",
266099
+ "@smithy/eventstream-serde-config-resolver": "^4.3.10",
266100
+ "@smithy/eventstream-serde-node": "^4.2.10",
266101
+ "@smithy/fetch-http-handler": "^5.3.11",
266102
+ "@smithy/hash-node": "^4.2.10",
266103
+ "@smithy/invalid-dependency": "^4.2.10",
266104
+ "@smithy/middleware-content-length": "^4.2.10",
266105
+ "@smithy/middleware-endpoint": "^4.4.20",
266106
+ "@smithy/middleware-retry": "^4.4.37",
266107
+ "@smithy/middleware-serde": "^4.2.11",
266108
+ "@smithy/middleware-stack": "^4.2.10",
266109
+ "@smithy/node-config-provider": "^4.3.10",
266110
+ "@smithy/node-http-handler": "^4.4.12",
266111
+ "@smithy/protocol-http": "^5.3.10",
266112
+ "@smithy/smithy-client": "^4.12.0",
266113
+ "@smithy/types": "^4.13.0",
266114
+ "@smithy/url-parser": "^4.2.10",
265646
266115
  "@smithy/util-base64": "^4.3.1",
265647
266116
  "@smithy/util-body-length-browser": "^4.2.1",
265648
266117
  "@smithy/util-body-length-node": "^4.2.2",
265649
- "@smithy/util-defaults-mode-browser": "^4.3.34",
265650
- "@smithy/util-defaults-mode-node": "^4.2.37",
265651
- "@smithy/util-endpoints": "^3.2.9",
265652
- "@smithy/util-middleware": "^4.2.9",
265653
- "@smithy/util-retry": "^4.2.9",
265654
- "@smithy/util-stream": "^4.5.14",
266118
+ "@smithy/util-defaults-mode-browser": "^4.3.36",
266119
+ "@smithy/util-defaults-mode-node": "^4.2.39",
266120
+ "@smithy/util-endpoints": "^3.3.1",
266121
+ "@smithy/util-middleware": "^4.2.10",
266122
+ "@smithy/util-retry": "^4.2.10",
266123
+ "@smithy/util-stream": "^4.5.15",
265655
266124
  "@smithy/util-utf8": "^4.2.1",
265656
266125
  tslib: "^2.6.2"
265657
266126
  },
@@ -266370,7 +266839,7 @@ var init_package = __esm({
266370
266839
  "node_modules/@aws-sdk/nested-clients/package.json"() {
266371
266840
  package_default = {
266372
266841
  name: "@aws-sdk/nested-clients",
266373
- version: "3.996.1",
266842
+ version: "3.996.2",
266374
266843
  description: "Nested clients for AWS SDK packages.",
266375
266844
  main: "./dist-cjs/index.js",
266376
266845
  module: "./dist-es/index.js",
@@ -266399,40 +266868,40 @@ var init_package = __esm({
266399
266868
  dependencies: {
266400
266869
  "@aws-crypto/sha256-browser": "5.2.0",
266401
266870
  "@aws-crypto/sha256-js": "5.2.0",
266402
- "@aws-sdk/core": "^3.973.13",
266403
- "@aws-sdk/middleware-host-header": "^3.972.4",
266404
- "@aws-sdk/middleware-logger": "^3.972.4",
266405
- "@aws-sdk/middleware-recursion-detection": "^3.972.4",
266406
- "@aws-sdk/middleware-user-agent": "^3.972.13",
266407
- "@aws-sdk/region-config-resolver": "^3.972.4",
266408
- "@aws-sdk/types": "^3.973.2",
266409
- "@aws-sdk/util-endpoints": "^3.996.1",
266410
- "@aws-sdk/util-user-agent-browser": "^3.972.4",
266411
- "@aws-sdk/util-user-agent-node": "^3.972.12",
266412
- "@smithy/config-resolver": "^4.4.7",
266413
- "@smithy/core": "^3.23.4",
266414
- "@smithy/fetch-http-handler": "^5.3.10",
266415
- "@smithy/hash-node": "^4.2.9",
266416
- "@smithy/invalid-dependency": "^4.2.9",
266417
- "@smithy/middleware-content-length": "^4.2.9",
266418
- "@smithy/middleware-endpoint": "^4.4.18",
266419
- "@smithy/middleware-retry": "^4.4.35",
266420
- "@smithy/middleware-serde": "^4.2.10",
266421
- "@smithy/middleware-stack": "^4.2.9",
266422
- "@smithy/node-config-provider": "^4.3.9",
266423
- "@smithy/node-http-handler": "^4.4.11",
266424
- "@smithy/protocol-http": "^5.3.9",
266425
- "@smithy/smithy-client": "^4.11.7",
266426
- "@smithy/types": "^4.12.1",
266427
- "@smithy/url-parser": "^4.2.9",
266871
+ "@aws-sdk/core": "^3.973.14",
266872
+ "@aws-sdk/middleware-host-header": "^3.972.5",
266873
+ "@aws-sdk/middleware-logger": "^3.972.5",
266874
+ "@aws-sdk/middleware-recursion-detection": "^3.972.5",
266875
+ "@aws-sdk/middleware-user-agent": "^3.972.14",
266876
+ "@aws-sdk/region-config-resolver": "^3.972.5",
266877
+ "@aws-sdk/types": "^3.973.3",
266878
+ "@aws-sdk/util-endpoints": "^3.996.2",
266879
+ "@aws-sdk/util-user-agent-browser": "^3.972.5",
266880
+ "@aws-sdk/util-user-agent-node": "^3.972.13",
266881
+ "@smithy/config-resolver": "^4.4.9",
266882
+ "@smithy/core": "^3.23.6",
266883
+ "@smithy/fetch-http-handler": "^5.3.11",
266884
+ "@smithy/hash-node": "^4.2.10",
266885
+ "@smithy/invalid-dependency": "^4.2.10",
266886
+ "@smithy/middleware-content-length": "^4.2.10",
266887
+ "@smithy/middleware-endpoint": "^4.4.20",
266888
+ "@smithy/middleware-retry": "^4.4.37",
266889
+ "@smithy/middleware-serde": "^4.2.11",
266890
+ "@smithy/middleware-stack": "^4.2.10",
266891
+ "@smithy/node-config-provider": "^4.3.10",
266892
+ "@smithy/node-http-handler": "^4.4.12",
266893
+ "@smithy/protocol-http": "^5.3.10",
266894
+ "@smithy/smithy-client": "^4.12.0",
266895
+ "@smithy/types": "^4.13.0",
266896
+ "@smithy/url-parser": "^4.2.10",
266428
266897
  "@smithy/util-base64": "^4.3.1",
266429
266898
  "@smithy/util-body-length-browser": "^4.2.1",
266430
266899
  "@smithy/util-body-length-node": "^4.2.2",
266431
- "@smithy/util-defaults-mode-browser": "^4.3.34",
266432
- "@smithy/util-defaults-mode-node": "^4.2.37",
266433
- "@smithy/util-endpoints": "^3.2.9",
266434
- "@smithy/util-middleware": "^4.2.9",
266435
- "@smithy/util-retry": "^4.2.9",
266900
+ "@smithy/util-defaults-mode-browser": "^4.3.36",
266901
+ "@smithy/util-defaults-mode-node": "^4.2.39",
266902
+ "@smithy/util-endpoints": "^3.3.1",
266903
+ "@smithy/util-middleware": "^4.2.10",
266904
+ "@smithy/util-retry": "^4.2.10",
266436
266905
  "@smithy/util-utf8": "^4.2.1",
266437
266906
  tslib: "^2.6.2"
266438
266907
  },
@@ -286423,7 +286892,11 @@ var init_esm3 = __esm({
286423
286892
  #matchGlobstar(file, pattern, partial, fileIndex, patternIndex) {
286424
286893
  const firstgs = pattern.indexOf(GLOBSTAR, patternIndex);
286425
286894
  const lastgs = pattern.lastIndexOf(GLOBSTAR);
286426
- const [head2, body, tail] = [
286895
+ const [head2, body, tail] = partial ? [
286896
+ pattern.slice(patternIndex, firstgs),
286897
+ pattern.slice(firstgs + 1),
286898
+ []
286899
+ ] : [
286427
286900
  pattern.slice(patternIndex, firstgs),
286428
286901
  pattern.slice(firstgs + 1, lastgs),
286429
286902
  pattern.slice(lastgs + 1)
@@ -286460,7 +286933,7 @@ var init_esm3 = __esm({
286460
286933
  return false;
286461
286934
  }
286462
286935
  }
286463
- return sawSome;
286936
+ return partial || sawSome;
286464
286937
  }
286465
286938
  const bodySegments = [[[], 0]];
286466
286939
  let currentBody = bodySegments[0];
@@ -286509,7 +286982,7 @@ var init_esm3 = __esm({
286509
286982
  }
286510
286983
  fileIndex++;
286511
286984
  }
286512
- return null;
286985
+ return partial || null;
286513
286986
  }
286514
286987
  #matchOne(file, pattern, partial, fileIndex, patternIndex) {
286515
286988
  let fi;
@@ -328993,6 +329466,15 @@ function normalizeJsonQuotes(str) {
328993
329466
  }
328994
329467
  return result;
328995
329468
  }
329469
+ function isCodeBlockEmbeddedInDocument(text, match2) {
329470
+ const beforeBlock = text.substring(0, match2.index).trim();
329471
+ const afterBlock = text.substring(match2.index + match2[0].length).trim();
329472
+ const hasMarkdownHeadings = /^#{1,6}\s/m.test(beforeBlock) || /^#{1,6}\s/m.test(afterBlock);
329473
+ if (hasMarkdownHeadings) {
329474
+ return true;
329475
+ }
329476
+ return false;
329477
+ }
328996
329478
  function cleanSchemaResponse(response) {
328997
329479
  if (!response || typeof response !== "string") {
328998
329480
  return response;
@@ -329012,11 +329494,11 @@ function cleanSchemaResponse(response) {
329012
329494
  return cleanSchemaResponse(innerContent);
329013
329495
  }
329014
329496
  const jsonBlockMatch = trimmed.match(/```json\s*\n([\s\S]*?)\n```/);
329015
- if (jsonBlockMatch) {
329497
+ if (jsonBlockMatch && !isCodeBlockEmbeddedInDocument(trimmed, jsonBlockMatch)) {
329016
329498
  return normalizeJsonQuotes(jsonBlockMatch[1].trim());
329017
329499
  }
329018
329500
  const anyBlockMatch = trimmed.match(/```\s*\n([{\[][\s\S]*?[}\]])\s*```/);
329019
- if (anyBlockMatch) {
329501
+ if (anyBlockMatch && !isCodeBlockEmbeddedInDocument(trimmed, anyBlockMatch)) {
329020
329502
  return normalizeJsonQuotes(anyBlockMatch[1].trim());
329021
329503
  }
329022
329504
  const codeBlockPatterns = [
@@ -329025,7 +329507,7 @@ function cleanSchemaResponse(response) {
329025
329507
  ];
329026
329508
  for (const pattern of codeBlockPatterns) {
329027
329509
  const match2 = trimmed.match(pattern);
329028
- if (match2) {
329510
+ if (match2 && !isCodeBlockEmbeddedInDocument(trimmed, match2)) {
329029
329511
  return normalizeJsonQuotes(match2[1].trim());
329030
329512
  }
329031
329513
  }
@@ -329036,7 +329518,7 @@ function cleanSchemaResponse(response) {
329036
329518
  }
329037
329519
  const codeBlockStartPattern = /```(?:json)?\s*\n?\s*([{\[])/;
329038
329520
  const codeBlockMatch = trimmed.match(codeBlockStartPattern);
329039
- if (codeBlockMatch) {
329521
+ if (codeBlockMatch && !isCodeBlockEmbeddedInDocument(trimmed, codeBlockMatch)) {
329040
329522
  const startIndex = codeBlockMatch.index + codeBlockMatch[0].length - 1;
329041
329523
  const openChar = codeBlockMatch[1];
329042
329524
  const closeChar = openChar === "{" ? "}" : "]";
@@ -350734,6 +351216,10 @@ function parseSimpleCommand(command) {
350734
351216
  // Logical OR
350735
351217
  /(?<!\\);/,
350736
351218
  // Command separator (but not escaped \;)
351219
+ /\n/,
351220
+ // Newline command separator (multi-line commands)
351221
+ /\r/,
351222
+ // Carriage return (CRLF line endings)
350737
351223
  /&$/,
350738
351224
  // Background execution
350739
351225
  /\$\(/,
@@ -350840,6 +351326,8 @@ function isComplexPattern(pattern) {
350840
351326
  // Logical OR
350841
351327
  /;/,
350842
351328
  // Command separator
351329
+ /\n/,
351330
+ // Newline command separator
350843
351331
  /&$/,
350844
351332
  // Background execution
350845
351333
  /\$\(/,
@@ -351212,6 +351700,26 @@ var init_bashPermissions = __esm({
351212
351700
  i5++;
351213
351701
  continue;
351214
351702
  }
351703
+ if (char === "\n" || char === "\r" && nextChar === "\n") {
351704
+ if (current2.trim()) {
351705
+ components.push(current2.trim());
351706
+ }
351707
+ current2 = "";
351708
+ if (char === "\r") {
351709
+ i5 += 2;
351710
+ } else {
351711
+ i5++;
351712
+ }
351713
+ continue;
351714
+ }
351715
+ if (char === "\r") {
351716
+ if (current2.trim()) {
351717
+ components.push(current2.trim());
351718
+ }
351719
+ current2 = "";
351720
+ i5++;
351721
+ continue;
351722
+ }
351215
351723
  }
351216
351724
  current2 += char;
351217
351725
  i5++;
@@ -396052,7 +396560,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"100":"Continue","101":"Switching Pro
396052
396560
  /***/ ((module) => {
396053
396561
 
396054
396562
  "use strict";
396055
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@probelabs/visor","version":"0.1.42","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-rc259","@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"]}}');
396563
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@probelabs/visor","version":"0.1.42","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-rc260","@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"]}}');
396056
396564
 
396057
396565
  /***/ })
396058
396566