// src/concurrency.ts
var Mutex = class {
  locked = false;
  waiters = [];
  async acquire() {
    if (!this.locked) {
      this.locked = true;
      return () => this.release();
    }
    return new Promise((resolve) => {
      this.waiters.push(() => {
        resolve(() => this.release());
      });
    });
  }
  release() {
    const next = this.waiters.shift();
    if (next) {
      next();
    } else {
      this.locked = false;
    }
  }
  async runExclusive(fn) {
    const release = await this.acquire();
    try {
      return await fn();
    } finally {
      release();
    }
  }
  /** True iff someone holds the lock right now. Diagnostics only. */
  get isLocked() {
    return this.locked;
  }
  /** Pending waiter count. Diagnostics only. */
  get pending() {
    return this.waiters.length;
  }
};
async function mapConcurrent(items, concurrency, map) {
  if (!Number.isInteger(concurrency) || concurrency < 1) {
    throw new Error(`mapConcurrent: concurrency must be a positive integer, got ${concurrency}`);
  }
  if (items.length === 0) return [];
  const results = new Array(items.length);
  let nextIndex = 0;
  let stopped = false;
  let failed = false;
  let failure;
  const worker = async () => {
    while (!stopped) {
      const index = nextIndex;
      nextIndex += 1;
      if (index >= items.length) return;
      try {
        results[index] = await map(items[index], index);
      } catch (error) {
        stopped = true;
        if (!failed) {
          failed = true;
          failure = error;
        }
      }
    }
  };
  await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
  if (failed) throw failure;
  return results;
}

// src/run-score.ts
var DEFAULT_RUN_SCORE_WEIGHTS = {
  success: 4,
  goalProgress: 2,
  repoGroundedness: 1.5,
  driftPenalty: -1.5,
  toolUseQuality: 1,
  patchQuality: 1.25,
  testReality: 1.5,
  finalGate: 3,
  reviewerBlockers: -2,
  costUsd: -0.2,
  wallSeconds: -0.1
};
function aggregateRunScore(score, weights = {}) {
  const w = { ...DEFAULT_RUN_SCORE_WEIGHTS, ...weights };
  return w.success * clamp01(score.success) + w.goalProgress * clamp01(score.goalProgress) + w.repoGroundedness * clamp01(score.repoGroundedness) + w.driftPenalty * clamp01(score.driftPenalty) + w.toolUseQuality * clamp01(score.toolUseQuality) + w.patchQuality * clamp01(score.patchQuality) + w.testReality * clamp01(score.testReality) + w.finalGate * clamp01(score.finalGate) + w.reviewerBlockers * clamp01(score.reviewerBlockers) + w.costUsd * Math.max(0, finiteOrZero(score.costUsd)) + w.wallSeconds * Math.max(0, finiteOrZero(score.wallSeconds) / 60);
}
function clamp01(value) {
  if (!Number.isFinite(value)) return 0;
  return Math.max(0, Math.min(1, value));
}
function finiteOrZero(value) {
  return Number.isFinite(value) ? value : 0;
}

// src/abort-signal.ts
function combineAbortSignals(...signals) {
  const active = [
    ...new Set(signals.filter((signal) => signal !== void 0))
  ];
  if (active.length === 0) return void 0;
  if (active.length === 1) return active[0];
  return AbortSignal.any(active);
}

export {
  combineAbortSignals,
  Mutex,
  mapConcurrent,
  DEFAULT_RUN_SCORE_WEIGHTS,
  aggregateRunScore,
  clamp01
};
//# sourceMappingURL=chunk-WGXIEX7P.js.map