import {
  launchProcessSync
} from "./chunk-OR64ZGRZ.js";
import {
  expandTildePath
} from "./chunk-IXEJRKCZ.js";

// src/coding/git-context.ts
import path from "path";
var DEFAULT_GIT_TIMEOUT_MS = 2e3;
function defaultGitInvoker() {
  return (cwd, args) => {
    const result = launchProcessSync("git", args, {
      cwd,
      encoding: "utf-8",
      timeout: DEFAULT_GIT_TIMEOUT_MS,
      shell: false
    });
    if (result.error) {
      return { stdout: "", exitCode: 127 };
    }
    return {
      stdout: typeof result.stdout === "string" ? result.stdout : "",
      exitCode: typeof result.status === "number" ? result.status : 1
    };
  };
}
function stableHash(input) {
  let hash = 2166136261;
  for (let i = 0; i < input.length; i++) {
    hash ^= input.charCodeAt(i);
    hash = Math.imul(hash, 16777619) >>> 0;
  }
  return hash.toString(16).padStart(8, "0");
}
function normalizeOriginUrl(rawUrl) {
  let url = rawUrl.trim();
  if (!url) return "";
  if (/\.git$/i.test(url)) url = url.slice(0, -4);
  if (/^[A-Za-z]:[\\/]/.test(url)) {
    return url.toLowerCase();
  }
  const protoMatch = /^[a-z][a-z0-9+.-]*:\/\/(?:[^@/]+@)?(\[[^\]]+\]|[^/:]*)(?::(\d+))?(\/.*)?$/i.exec(url);
  if (protoMatch) {
    let host = protoMatch[1] ?? "";
    const wasBracketed = host.startsWith("[") && host.endsWith("]");
    if (wasBracketed) host = host.slice(1, -1);
    const port = protoMatch[2];
    const repoPath = (protoMatch[3] ?? "").replace(/^\/+/, "");
    const hostPort = port ? wasBracketed ? `[${host}]:${port}` : `${host}:${port}` : host;
    const prefix = hostPort.length > 0 ? hostPort : "localhost";
    return `${prefix}/${repoPath}`.toLowerCase();
  }
  const scpMatch = /^(?:([^@\s/]+)@)?(\[[^\]]+\]|[^:@\s/]+):(.+)$/.exec(url);
  if (scpMatch) {
    let host = scpMatch[2] ?? "";
    if (host.startsWith("[") && host.endsWith("]")) host = host.slice(1, -1);
    const repoPath = scpMatch[3] ?? "";
    if (repoPath.startsWith("//")) {
      return url.toLowerCase();
    }
    return `${host}/${repoPath.replace(/^\/+/, "")}`.toLowerCase();
  }
  return url.toLowerCase();
}
async function resolveGitContext(cwd, options = {}) {
  try {
    if (typeof cwd !== "string" || cwd.length === 0) return null;
    const expanded = expandTildePath(cwd);
    if (!path.isAbsolute(expanded)) return null;
    const invoker = options.invoker ?? defaultGitInvoker();
    const topLevel = invoker(expanded, ["rev-parse", "--show-toplevel"]);
    if (topLevel.exitCode !== 0) return null;
    const rootPath = topLevel.stdout.trim();
    if (!rootPath) return null;
    const branchResult = invoker(rootPath, ["rev-parse", "--abbrev-ref", "HEAD"]);
    let branch = null;
    if (branchResult.exitCode === 0) {
      const raw = branchResult.stdout.trim();
      branch = raw && raw !== "HEAD" ? raw : null;
    } else {
      const unbornRef = invoker(rootPath, ["symbolic-ref", "--quiet", "HEAD"]);
      if (unbornRef.exitCode === 0) {
        const raw = unbornRef.stdout.trim();
        const prefix = "refs/heads/";
        if (raw.startsWith(prefix)) {
          const candidate = raw.slice(prefix.length);
          if (candidate) branch = candidate;
        }
      }
    }
    const originResult = invoker(rootPath, ["remote", "get-url", "origin"]);
    let projectId;
    if (originResult.exitCode === 0) {
      const normalized = normalizeOriginUrl(originResult.stdout);
      projectId = normalized ? `origin:${stableHash(normalized)}` : `root:${stableHash(rootPath)}`;
    } else {
      projectId = `root:${stableHash(rootPath)}`;
    }
    const headRef = invoker(rootPath, ["symbolic-ref", "--quiet", "refs/remotes/origin/HEAD"]);
    let defaultBranch = null;
    if (headRef.exitCode === 0) {
      const raw = headRef.stdout.trim();
      const prefix = "refs/remotes/origin/";
      if (raw.startsWith(prefix)) {
        const candidate = raw.slice(prefix.length);
        if (candidate) defaultBranch = candidate;
      }
    }
    return {
      projectId,
      branch,
      rootPath,
      defaultBranch
    };
  } catch {
    return null;
  }
}

// src/procedural/reinforcement-core.ts
function clusterByKey(items, keyFn) {
  const clusters = /* @__PURE__ */ new Map();
  for (const item of items) {
    const key = keyFn(item);
    if (typeof key !== "string") {
      throw new TypeError(
        `clusterByKey: keyFn must return a string, got ${key === null ? "null" : typeof key}`
      );
    }
    const existing = clusters.get(key);
    if (existing) {
      existing.push(item);
    } else {
      clusters.set(key, [item]);
    }
  }
  return clusters;
}

export {
  clusterByKey,
  stableHash,
  normalizeOriginUrl,
  resolveGitContext
};
//# sourceMappingURL=chunk-D54LZC5L.js.map