@vm0/runner 3.5.0 → 3.6.0

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 (2) hide show
  1. package/index.js +146 -227
  2. package/package.json +1 -6
package/index.js CHANGED
@@ -857,53 +857,51 @@ function checkNetworkPrerequisites() {
857
857
  errors
858
858
  };
859
859
  }
860
- async function setupVMProxyRules(vmIp, proxyPort, runnerName) {
861
- const comment = `vm0:runner:${runnerName}`;
860
+ async function setupCIDRProxyRules(proxyPort) {
861
+ const comment = "vm0:cidr-proxy";
862
862
  console.log(
863
- `Setting up proxy rules for VM ${vmIp} -> localhost:${proxyPort} (comment: ${comment})`
863
+ `Setting up CIDR proxy rules for ${BRIDGE_CIDR} -> port ${proxyPort}`
864
864
  );
865
865
  try {
866
866
  await execCommand(
867
- `iptables -t nat -C PREROUTING -s ${vmIp} -p tcp --dport 80 -j REDIRECT --to-port ${proxyPort} -m comment --comment "${comment}"`
867
+ `iptables -t nat -C PREROUTING -s ${BRIDGE_CIDR} -p tcp --dport 80 -j REDIRECT --to-port ${proxyPort} -m comment --comment "${comment}"`
868
868
  );
869
- console.log(`Proxy rule for ${vmIp}:80 already exists`);
869
+ console.log("CIDR proxy rule for port 80 already exists");
870
870
  } catch {
871
871
  await execCommand(
872
- `iptables -t nat -A PREROUTING -s ${vmIp} -p tcp --dport 80 -j REDIRECT --to-port ${proxyPort} -m comment --comment "${comment}"`
872
+ `iptables -t nat -A PREROUTING -s ${BRIDGE_CIDR} -p tcp --dport 80 -j REDIRECT --to-port ${proxyPort} -m comment --comment "${comment}"`
873
873
  );
874
- console.log(`Proxy rule for ${vmIp}:80 added`);
874
+ console.log("CIDR proxy rule for port 80 added");
875
875
  }
876
876
  try {
877
877
  await execCommand(
878
- `iptables -t nat -C PREROUTING -s ${vmIp} -p tcp --dport 443 -j REDIRECT --to-port ${proxyPort} -m comment --comment "${comment}"`
878
+ `iptables -t nat -C PREROUTING -s ${BRIDGE_CIDR} -p tcp --dport 443 -j REDIRECT --to-port ${proxyPort} -m comment --comment "${comment}"`
879
879
  );
880
- console.log(`Proxy rule for ${vmIp}:443 already exists`);
880
+ console.log("CIDR proxy rule for port 443 already exists");
881
881
  } catch {
882
882
  await execCommand(
883
- `iptables -t nat -A PREROUTING -s ${vmIp} -p tcp --dport 443 -j REDIRECT --to-port ${proxyPort} -m comment --comment "${comment}"`
883
+ `iptables -t nat -A PREROUTING -s ${BRIDGE_CIDR} -p tcp --dport 443 -j REDIRECT --to-port ${proxyPort} -m comment --comment "${comment}"`
884
884
  );
885
- console.log(`Proxy rule for ${vmIp}:443 added`);
885
+ console.log("CIDR proxy rule for port 443 added");
886
886
  }
887
- console.log(`Proxy rules configured for VM ${vmIp}`);
888
887
  }
889
- async function removeVMProxyRules(vmIp, proxyPort, runnerName) {
890
- const comment = `vm0:runner:${runnerName}`;
891
- console.log(`Removing proxy rules for VM ${vmIp}...`);
888
+ async function cleanupCIDRProxyRules(proxyPort) {
889
+ const comment = "vm0:cidr-proxy";
890
+ console.log("Cleaning up CIDR proxy rules...");
892
891
  try {
893
892
  await execCommand(
894
- `iptables -t nat -D PREROUTING -s ${vmIp} -p tcp --dport 80 -j REDIRECT --to-port ${proxyPort} -m comment --comment "${comment}"`
893
+ `iptables -t nat -D PREROUTING -s ${BRIDGE_CIDR} -p tcp --dport 80 -j REDIRECT --to-port ${proxyPort} -m comment --comment "${comment}"`
895
894
  );
896
- console.log(`Proxy rule for ${vmIp}:80 removed`);
895
+ console.log("CIDR proxy rule for port 80 removed");
897
896
  } catch {
898
897
  }
899
898
  try {
900
899
  await execCommand(
901
- `iptables -t nat -D PREROUTING -s ${vmIp} -p tcp --dport 443 -j REDIRECT --to-port ${proxyPort} -m comment --comment "${comment}"`
900
+ `iptables -t nat -D PREROUTING -s ${BRIDGE_CIDR} -p tcp --dport 443 -j REDIRECT --to-port ${proxyPort} -m comment --comment "${comment}"`
902
901
  );
903
- console.log(`Proxy rule for ${vmIp}:443 removed`);
902
+ console.log("CIDR proxy rule for port 443 removed");
904
903
  } catch {
905
904
  }
906
- console.log(`Proxy rules cleanup complete for VM ${vmIp}`);
907
905
  }
908
906
  async function listTapDevices() {
909
907
  try {
@@ -8654,7 +8652,10 @@ def tls_clienthello(data: tls.ClientHelloData) -> None:
8654
8652
 
8655
8653
  vm_info = get_vm_info(client_ip)
8656
8654
  if not vm_info:
8657
- return # Not a registered VM, let it through
8655
+ # Not a registered VM - pass through without MITM interception
8656
+ # This is critical for CIDR-based rules where all VM traffic is redirected
8657
+ data.ignore_connection = True
8658
+ return
8658
8659
 
8659
8660
  # If MITM is enabled, let the normal flow handle it
8660
8661
  if vm_info.get("mitmEnabled", False):
@@ -9125,171 +9126,80 @@ function initProxyManager(config) {
9125
9126
  return globalProxyManager;
9126
9127
  }
9127
9128
 
9128
- // src/lib/metrics/provider.ts
9129
- import {
9130
- MeterProvider,
9131
- PeriodicExportingMetricReader
9132
- } from "@opentelemetry/sdk-metrics";
9133
- import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-proto";
9134
- import { Resource } from "@opentelemetry/resources";
9135
- import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
9136
- import { metrics } from "@opentelemetry/api";
9137
- var meterProvider = null;
9138
- var initialized = false;
9139
- var enabled = false;
9140
- var _runnerLabel = "";
9141
- function initMetrics(config) {
9142
- if (initialized) return;
9143
- initialized = true;
9144
- _runnerLabel = config.runnerLabel;
9145
- if (!config.axiomToken) {
9146
- console.log("[metrics] AXIOM_TOKEN not configured, metrics disabled");
9147
- return;
9148
- }
9149
- const env = config.environment ?? "dev";
9150
- const exporter = new OTLPMetricExporter({
9151
- url: "https://api.axiom.co/v1/metrics",
9152
- headers: {
9153
- Authorization: `Bearer ${config.axiomToken}`,
9154
- "X-Axiom-Dataset": `vm0-sandbox-op-log-${env}`
9155
- }
9156
- });
9157
- meterProvider = new MeterProvider({
9158
- resource: new Resource({
9159
- [ATTR_SERVICE_NAME]: config.serviceName,
9160
- "deployment.environment": env,
9161
- "runner.label": config.runnerLabel
9162
- }),
9163
- readers: [
9164
- new PeriodicExportingMetricReader({
9165
- exporter,
9166
- exportIntervalMillis: config.exportIntervalMs ?? 3e4
9167
- })
9168
- ]
9169
- });
9170
- metrics.setGlobalMeterProvider(meterProvider);
9171
- enabled = true;
9172
- console.log(
9173
- `[metrics] initialized for ${config.serviceName} (${env}), runner: ${config.runnerLabel}`
9174
- );
9175
- }
9176
- function isMetricsEnabled() {
9177
- return enabled;
9178
- }
9179
- function getRunnerLabel() {
9180
- return _runnerLabel;
9181
- }
9182
- function getMeter(name) {
9183
- return metrics.getMeter(name);
9129
+ // src/lib/metrics/instruments.ts
9130
+ var FLUSH_THRESHOLD_MS = 3e4;
9131
+ var sandboxContext = null;
9132
+ var pendingOps = [];
9133
+ var oldestPendingTime = null;
9134
+ function setSandboxContext(ctx) {
9135
+ sandboxContext = ctx;
9136
+ pendingOps = [];
9137
+ oldestPendingTime = null;
9184
9138
  }
9185
- async function flushMetrics() {
9186
- if (meterProvider) {
9187
- await meterProvider.forceFlush();
9139
+ async function clearSandboxContext() {
9140
+ const ctx = sandboxContext;
9141
+ const ops = pendingOps;
9142
+ sandboxContext = null;
9143
+ pendingOps = [];
9144
+ oldestPendingTime = null;
9145
+ if (ctx && ops.length > 0) {
9146
+ await flushOpsWithContext(ctx, ops);
9188
9147
  }
9189
9148
  }
9190
- async function shutdownMetrics() {
9191
- if (meterProvider) {
9192
- await meterProvider.shutdown();
9193
- }
9149
+ async function flushOps() {
9150
+ if (!sandboxContext || pendingOps.length === 0) return;
9151
+ const ctx = sandboxContext;
9152
+ const ops = pendingOps;
9153
+ pendingOps = [];
9154
+ oldestPendingTime = null;
9155
+ await flushOpsWithContext(ctx, ops);
9194
9156
  }
9195
-
9196
- // src/lib/metrics/instruments.ts
9197
- var runnerOperationTotal = null;
9198
- var runnerOperationErrorsTotal = null;
9199
- var runnerOperationDuration = null;
9200
- var sandboxOperationTotal = null;
9201
- var sandboxOperationErrorsTotal = null;
9202
- var sandboxOperationDuration = null;
9203
- function getRunnerInstruments() {
9204
- if (!runnerOperationTotal) {
9205
- const meter = getMeter("vm0-runner");
9206
- runnerOperationTotal = meter.createCounter("runner_operation_total", {
9207
- description: "Total number of runner operations"
9208
- });
9209
- runnerOperationErrorsTotal = meter.createCounter(
9210
- "runner_operation_errors_total",
9211
- {
9212
- description: "Total number of runner operation errors"
9213
- }
9214
- );
9215
- runnerOperationDuration = meter.createHistogram(
9216
- "runner_operation_duration_ms",
9217
- {
9218
- description: "Runner operation duration in milliseconds",
9219
- unit: "ms"
9220
- }
9221
- );
9222
- }
9223
- return {
9224
- runnerOperationTotal,
9225
- runnerOperationErrorsTotal,
9226
- runnerOperationDuration
9157
+ async function flushOpsWithContext(ctx, ops) {
9158
+ const { apiUrl, runId, sandboxToken } = ctx;
9159
+ const headers = {
9160
+ Authorization: `Bearer ${sandboxToken}`,
9161
+ "Content-Type": "application/json"
9227
9162
  };
9228
- }
9229
- function getSandboxInstruments() {
9230
- if (!sandboxOperationTotal) {
9231
- const meter = getMeter("vm0-runner");
9232
- sandboxOperationTotal = meter.createCounter("sandbox_operation_total", {
9233
- description: "Total number of sandbox operations"
9163
+ const bypassSecret = process.env.VERCEL_AUTOMATION_BYPASS_SECRET;
9164
+ if (bypassSecret) {
9165
+ headers["x-vercel-protection-bypass"] = bypassSecret;
9166
+ }
9167
+ try {
9168
+ const response = await fetch(`${apiUrl}/api/webhooks/agent/telemetry`, {
9169
+ method: "POST",
9170
+ headers,
9171
+ body: JSON.stringify({
9172
+ runId,
9173
+ sandboxOperations: ops
9174
+ })
9234
9175
  });
9235
- sandboxOperationErrorsTotal = meter.createCounter(
9236
- "sandbox_operation_errors_total",
9237
- {
9238
- description: "Total number of sandbox operation errors"
9239
- }
9240
- );
9241
- sandboxOperationDuration = meter.createHistogram(
9242
- "sandbox_operation_duration_ms",
9243
- {
9244
- description: "Sandbox operation duration in milliseconds",
9245
- unit: "ms"
9246
- }
9247
- );
9176
+ await response.text();
9177
+ if (!response.ok) {
9178
+ console.warn(
9179
+ `[metrics] Failed to flush operations: HTTP ${response.status}`
9180
+ );
9181
+ }
9182
+ } catch (err) {
9183
+ console.warn(`[metrics] Failed to flush operations: ${err}`);
9248
9184
  }
9249
- return {
9250
- sandboxOperationTotal,
9251
- sandboxOperationErrorsTotal,
9252
- sandboxOperationDuration
9253
- };
9254
9185
  }
9255
- function recordRunnerOperation(attrs) {
9256
- if (!isMetricsEnabled()) return;
9257
- const {
9258
- runnerOperationTotal: runnerOperationTotal2,
9259
- runnerOperationErrorsTotal: runnerOperationErrorsTotal2,
9260
- runnerOperationDuration: runnerOperationDuration2
9261
- } = getRunnerInstruments();
9262
- const labels = {
9263
- action_type: attrs.actionType,
9264
- runner_label: getRunnerLabel()
9265
- };
9266
- runnerOperationTotal2.add(1, labels);
9267
- if (!attrs.success) {
9268
- runnerOperationErrorsTotal2.add(1, labels);
9186
+ function recordOperation(attrs) {
9187
+ if (!sandboxContext) {
9188
+ return;
9269
9189
  }
9270
- runnerOperationDuration2.record(attrs.durationMs, {
9271
- ...labels,
9272
- success: String(attrs.success)
9273
- });
9274
- }
9275
- function recordSandboxOperation(attrs) {
9276
- if (!isMetricsEnabled()) return;
9277
- const {
9278
- sandboxOperationTotal: sandboxOperationTotal2,
9279
- sandboxOperationErrorsTotal: sandboxOperationErrorsTotal2,
9280
- sandboxOperationDuration: sandboxOperationDuration2
9281
- } = getSandboxInstruments();
9282
- const labels = {
9283
- sandbox_type: "runner",
9284
- action_type: attrs.actionType
9285
- };
9286
- sandboxOperationTotal2.add(1, labels);
9287
- if (!attrs.success) {
9288
- sandboxOperationErrorsTotal2.add(1, labels);
9190
+ const now = Date.now();
9191
+ if (oldestPendingTime && now - oldestPendingTime >= FLUSH_THRESHOLD_MS) {
9192
+ flushOps().catch(() => {
9193
+ });
9194
+ }
9195
+ if (oldestPendingTime === null) {
9196
+ oldestPendingTime = now;
9289
9197
  }
9290
- sandboxOperationDuration2.record(attrs.durationMs, {
9291
- ...labels,
9292
- success: String(attrs.success)
9198
+ pendingOps.push({
9199
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
9200
+ action_type: attrs.actionType,
9201
+ duration_ms: attrs.durationMs,
9202
+ success: attrs.success
9293
9203
  });
9294
9204
  }
9295
9205
 
@@ -9303,7 +9213,7 @@ async function withRunnerTiming(actionType, fn) {
9303
9213
  success = false;
9304
9214
  throw error;
9305
9215
  } finally {
9306
- recordRunnerOperation({
9216
+ recordOperation({
9307
9217
  actionType,
9308
9218
  durationMs: Date.now() - startTime,
9309
9219
  success
@@ -9319,7 +9229,7 @@ async function withSandboxTiming(actionType, fn) {
9319
9229
  success = false;
9320
9230
  throw error;
9321
9231
  } finally {
9322
- recordSandboxOperation({
9232
+ recordOperation({
9323
9233
  actionType,
9324
9234
  durationMs: Date.now() - startTime,
9325
9235
  success
@@ -9487,15 +9397,18 @@ async function installProxyCA(guest, caCertPath) {
9487
9397
  );
9488
9398
  }
9489
9399
  const caCert = fs8.readFileSync(caCertPath, "utf-8");
9400
+ const certWithNewline = caCert.endsWith("\n") ? caCert : caCert + "\n";
9490
9401
  console.log(
9491
- `[Executor] Installing proxy CA certificate (${caCert.length} bytes)`
9402
+ `[Executor] Installing proxy CA certificate (${certWithNewline.length} bytes)`
9492
9403
  );
9493
9404
  await guest.writeFileWithSudo(
9494
9405
  "/usr/local/share/ca-certificates/vm0-proxy-ca.crt",
9495
- caCert
9406
+ certWithNewline
9407
+ );
9408
+ await guest.execOrThrow(
9409
+ "cat /usr/local/share/ca-certificates/vm0-proxy-ca.crt | sudo tee -a /etc/ssl/certs/ca-certificates.crt > /dev/null"
9496
9410
  );
9497
- await guest.execOrThrow("sudo update-ca-certificates");
9498
- console.log(`[Executor] Proxy CA certificate installed successfully`);
9411
+ console.log("[Executor] Proxy CA certificate installed successfully");
9499
9412
  }
9500
9413
 
9501
9414
  // src/lib/executor.ts
@@ -9553,6 +9466,18 @@ async function reportPreflightFailure(apiUrl, runId, sandboxToken, error, bypass
9553
9466
  }
9554
9467
  }
9555
9468
  async function executeJob(context, config, options = {}) {
9469
+ setSandboxContext({
9470
+ apiUrl: config.server.url,
9471
+ runId: context.runId,
9472
+ sandboxToken: context.sandboxToken
9473
+ });
9474
+ if (context.apiStartTime) {
9475
+ recordOperation({
9476
+ actionType: "api_to_vm_start",
9477
+ durationMs: Date.now() - context.apiStartTime,
9478
+ success: true
9479
+ });
9480
+ }
9556
9481
  const vmId = getVmIdFromRunId(context.runId);
9557
9482
  let vm = null;
9558
9483
  let guestIp = null;
@@ -9594,19 +9519,25 @@ async function executeJob(context, config, options = {}) {
9594
9519
  log(
9595
9520
  `[Executor] Setting up network security for VM ${guestIp} (mitm=${mitmEnabled}, sealSecrets=${sealSecretsEnabled})`
9596
9521
  );
9597
- await setupVMProxyRules(guestIp, config.proxy.port, config.name);
9598
- getVMRegistry().register(guestIp, context.runId, context.sandboxToken, {
9599
- firewallRules: firewallConfig?.rules,
9600
- mitmEnabled,
9601
- sealSecretsEnabled
9602
- });
9603
- if (mitmEnabled) {
9604
- const caCertPath = path4.join(
9605
- config.proxy.ca_dir,
9606
- "mitmproxy-ca-cert.pem"
9522
+ await withSandboxTiming("network_setup", async () => {
9523
+ getVMRegistry().register(
9524
+ guestIp,
9525
+ context.runId,
9526
+ context.sandboxToken,
9527
+ {
9528
+ firewallRules: firewallConfig?.rules,
9529
+ mitmEnabled,
9530
+ sealSecretsEnabled
9531
+ }
9607
9532
  );
9608
- await installProxyCA(guest, caCertPath);
9609
- }
9533
+ if (mitmEnabled) {
9534
+ const caCertPath = path4.join(
9535
+ config.proxy.ca_dir,
9536
+ "mitmproxy-ca-cert.pem"
9537
+ );
9538
+ await installProxyCA(guest, caCertPath);
9539
+ }
9540
+ });
9610
9541
  }
9611
9542
  if (context.storageManifest) {
9612
9543
  await withSandboxTiming(
@@ -9634,12 +9565,15 @@ async function executeJob(context, config, options = {}) {
9634
9565
  if (!options.benchmarkMode) {
9635
9566
  log(`[Executor] Running preflight connectivity check...`);
9636
9567
  const bypassSecret = process.env.VERCEL_AUTOMATION_BYPASS_SECRET;
9637
- const preflight = await runPreflightCheck(
9638
- guest,
9639
- config.server.url,
9640
- context.runId,
9641
- context.sandboxToken,
9642
- bypassSecret
9568
+ const preflight = await withSandboxTiming(
9569
+ "preflight_check",
9570
+ () => runPreflightCheck(
9571
+ guest,
9572
+ config.server.url,
9573
+ context.runId,
9574
+ context.sandboxToken,
9575
+ bypassSecret
9576
+ )
9643
9577
  );
9644
9578
  if (!preflight.success) {
9645
9579
  log(`[Executor] Preflight check failed: ${preflight.error}`);
@@ -9711,7 +9645,7 @@ async function executeJob(context, config, options = {}) {
9711
9645
  );
9712
9646
  }
9713
9647
  const durationMs2 = Date.now() - startTime;
9714
- recordRunnerOperation({
9648
+ recordOperation({
9715
9649
  actionType: "agent_execute",
9716
9650
  durationMs: durationMs2,
9717
9651
  success: false
@@ -9727,7 +9661,7 @@ async function executeJob(context, config, options = {}) {
9727
9661
  const duration = Math.round(durationMs / 1e3);
9728
9662
  if (!completed) {
9729
9663
  log(`[Executor] Agent timed out after ${duration}s`);
9730
- recordRunnerOperation({
9664
+ recordOperation({
9731
9665
  actionType: "agent_execute",
9732
9666
  durationMs,
9733
9667
  success: false
@@ -9737,7 +9671,7 @@ async function executeJob(context, config, options = {}) {
9737
9671
  error: `Agent execution timed out after ${duration}s`
9738
9672
  };
9739
9673
  }
9740
- recordRunnerOperation({
9674
+ recordOperation({
9741
9675
  actionType: "agent_execute",
9742
9676
  durationMs,
9743
9677
  success: exitCode === 0
@@ -9765,13 +9699,6 @@ async function executeJob(context, config, options = {}) {
9765
9699
  } finally {
9766
9700
  if (context.experimentalFirewall?.enabled && guestIp) {
9767
9701
  log(`[Executor] Cleaning up network security for VM ${guestIp}`);
9768
- try {
9769
- await removeVMProxyRules(guestIp, config.proxy.port, config.name);
9770
- } catch (err) {
9771
- console.error(
9772
- `[Executor] Failed to remove VM proxy rules: ${err instanceof Error ? err.message : "Unknown error"}`
9773
- );
9774
- }
9775
9702
  getVMRegistry().unregister(guestIp);
9776
9703
  if (!options.benchmarkMode) {
9777
9704
  try {
@@ -9791,6 +9718,7 @@ async function executeJob(context, config, options = {}) {
9791
9718
  log(`[Executor] Cleaning up VM ${vmId}...`);
9792
9719
  await withSandboxTiming("cleanup", () => vm.kill());
9793
9720
  }
9721
+ await clearSandboxContext();
9794
9722
  }
9795
9723
  }
9796
9724
 
@@ -9826,18 +9754,6 @@ function createStatusUpdater(statusFilePath, state) {
9826
9754
  // src/lib/runner/setup.ts
9827
9755
  async function setupEnvironment(options) {
9828
9756
  const { config } = options;
9829
- const datasetSuffix = process.env.AXIOM_DATASET_SUFFIX;
9830
- if (!datasetSuffix) {
9831
- throw new Error(
9832
- "AXIOM_DATASET_SUFFIX is required. Set to 'dev' or 'prod'."
9833
- );
9834
- }
9835
- initMetrics({
9836
- serviceName: "vm0-runner",
9837
- runnerLabel: config.name,
9838
- axiomToken: process.env.AXIOM_TOKEN,
9839
- environment: datasetSuffix
9840
- });
9841
9757
  const networkCheck = checkNetworkPrerequisites();
9842
9758
  if (!networkCheck.ok) {
9843
9759
  console.error("Network prerequisites not met:");
@@ -9866,6 +9782,8 @@ async function setupEnvironment(options) {
9866
9782
  await proxyManager.start();
9867
9783
  proxyEnabled = true;
9868
9784
  console.log("Network proxy initialized successfully");
9785
+ console.log("Setting up CIDR proxy rules...");
9786
+ await setupCIDRProxyRules(config.proxy.port);
9869
9787
  } catch (err) {
9870
9788
  console.warn(
9871
9789
  `Network proxy not available: ${err instanceof Error ? err.message : "Unknown error"}`
@@ -9874,16 +9792,17 @@ async function setupEnvironment(options) {
9874
9792
  "Jobs with experimentalFirewall enabled will run without network interception"
9875
9793
  );
9876
9794
  }
9877
- return { proxyEnabled };
9795
+ return { proxyEnabled, proxyPort: config.proxy.port };
9878
9796
  }
9879
9797
  async function cleanupEnvironment(resources) {
9798
+ if (resources.proxyEnabled) {
9799
+ console.log("Cleaning up CIDR proxy rules...");
9800
+ await cleanupCIDRProxyRules(resources.proxyPort);
9801
+ }
9880
9802
  if (resources.proxyEnabled) {
9881
9803
  console.log("Stopping network proxy...");
9882
9804
  await getProxyManager().stop();
9883
9805
  }
9884
- console.log("Flushing metrics...");
9885
- await flushMetrics();
9886
- await shutdownMetrics();
9887
9806
  }
9888
9807
 
9889
9808
  // src/lib/runner/signals.ts
@@ -10720,7 +10639,7 @@ var benchmarkCommand = new Command4("benchmark").description(
10720
10639
  });
10721
10640
 
10722
10641
  // src/index.ts
10723
- var version = true ? "3.5.0" : "0.1.0";
10642
+ var version = true ? "3.6.0" : "0.1.0";
10724
10643
  program.name("vm0-runner").version(version).description("Self-hosted runner for VM0 agents");
10725
10644
  program.addCommand(startCommand);
10726
10645
  program.addCommand(doctorCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/runner",
3
- "version": "3.5.0",
3
+ "version": "3.6.0",
4
4
  "description": "Self-hosted runner for VM0 agents",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,11 +15,6 @@
15
15
  "."
16
16
  ],
17
17
  "dependencies": {
18
- "@opentelemetry/api": "^1.9.0",
19
- "@opentelemetry/exporter-metrics-otlp-proto": "^0.52.0",
20
- "@opentelemetry/resources": "^1.25.0",
21
- "@opentelemetry/sdk-metrics": "^1.25.0",
22
- "@opentelemetry/semantic-conventions": "^1.25.0",
23
18
  "ably": "^2.17.0",
24
19
  "commander": "^14.0.0",
25
20
  "yaml": "^2.3.4",