import { createRequire as __ac_createRequire } from "node:module";
const require = __ac_createRequire(import.meta.url);

// ../server/scripts/supervisor-entrypoint.ts
import { fileURLToPath } from "url";
import { existsSync as existsSync2 } from "node:fs";
import path3 from "node:path";

// ../server/src/server/pid-lock.ts
import { open, readFile, unlink, mkdir } from "node:fs/promises";
import { existsSync } from "node:fs";
import { join } from "node:path";
import { hostname } from "node:os";
var PidLockError = class extends Error {
  constructor(message, existingLock) {
    super(message);
    this.existingLock = existingLock;
    this.name = "PidLockError";
  }
};
function isPidRunning(pid) {
  try {
    process.kill(pid, 0);
    return true;
  } catch {
    return false;
  }
}
function getPidFilePath(appostleHome) {
  return join(appostleHome, "appostle.pid");
}
function resolveOwnerPid(ownerPid) {
  if (typeof ownerPid === "number" && Number.isInteger(ownerPid) && ownerPid > 0) {
    return ownerPid;
  }
  return process.pid;
}
async function acquirePidLock(appostleHome, listen, options) {
  const pidPath = getPidFilePath(appostleHome);
  if (!existsSync(appostleHome)) {
    await mkdir(appostleHome, { recursive: true });
  }
  let existingLock = null;
  try {
    const content = await readFile(pidPath, "utf-8");
    existingLock = JSON.parse(content);
  } catch {
  }
  const lockOwnerPid = resolveOwnerPid(options?.ownerPid);
  if (existingLock) {
    if (isPidRunning(existingLock.pid)) {
      if (existingLock.pid === lockOwnerPid) {
        return;
      }
      throw new PidLockError(
        `Another Appostle daemon is already running (PID ${existingLock.pid}, started ${existingLock.startedAt})`,
        existingLock
      );
    }
    await unlink(pidPath).catch(() => {
    });
  }
  const lockInfo = {
    pid: lockOwnerPid,
    startedAt: (/* @__PURE__ */ new Date()).toISOString(),
    hostname: hostname(),
    uid: process.getuid?.() ?? 0,
    listen,
    ...process.env.APPOSTLE_DESKTOP_MANAGED === "1" ? { desktopManaged: true } : {}
  };
  let fd;
  try {
    fd = await open(pidPath, "wx");
    await fd.write(JSON.stringify(lockInfo));
  } catch (err) {
    if (err.code === "EEXIST") {
      try {
        const content = await readFile(pidPath, "utf-8");
        const raceLock = JSON.parse(content);
        throw new PidLockError(
          `Another Appostle daemon is already running (PID ${raceLock.pid})`,
          raceLock
        );
      } catch (innerErr) {
        if (innerErr instanceof PidLockError) throw innerErr;
        throw new PidLockError("Failed to acquire PID lock due to race condition");
      }
    }
    throw err;
  } finally {
    await fd?.close();
  }
}
async function updatePidLock(appostleHome, patch, options) {
  const pidPath = getPidFilePath(appostleHome);
  const lockOwnerPid = resolveOwnerPid(options?.ownerPid);
  const content = await readFile(pidPath, "utf-8");
  const existingLock = JSON.parse(content);
  if (existingLock.pid !== lockOwnerPid) {
    throw new PidLockError(`Cannot update PID lock owned by PID ${existingLock.pid}`, existingLock);
  }
  const updatedLock = {
    ...existingLock,
    ...patch
  };
  const fd = await open(pidPath, "r+");
  try {
    await fd.truncate(0);
    await fd.writeFile(JSON.stringify(updatedLock));
  } finally {
    await fd.close();
  }
}
async function releasePidLock(appostleHome, options) {
  const pidPath = getPidFilePath(appostleHome);
  const lockOwnerPid = resolveOwnerPid(options?.ownerPid);
  try {
    const content = await readFile(pidPath, "utf-8");
    const lock = JSON.parse(content);
    if (lock.pid === lockOwnerPid) {
      await unlink(pidPath);
    }
  } catch {
  }
}

// ../server/src/server/appostle-home.ts
import os from "node:os";
import path from "node:path";
import { mkdirSync } from "node:fs";
function expandHomeDir(input) {
  if (input.startsWith("~/")) {
    return path.join(os.homedir(), input.slice(2));
  }
  if (input === "~") {
    return os.homedir();
  }
  return input;
}
function resolveAppostleHome(env = process.env) {
  const raw = env.APPOSTLE_HOME ?? "~/.appostle";
  const resolved = path.resolve(expandHomeDir(raw));
  mkdirSync(resolved, { recursive: true });
  return resolved;
}

// ../server/scripts/supervisor.ts
import { fork, spawn } from "child_process";
function describeExit(code, signal) {
  return signal ?? (typeof code === "number" ? `code ${code}` : "unknown");
}
function parseLifecycleMessage(msg) {
  if (typeof msg !== "object" || msg === null || !("type" in msg)) {
    return null;
  }
  const type = msg.type;
  if (type === "appostle:shutdown") {
    return { type: "appostle:shutdown" };
  }
  if (type === "appostle:ready") {
    const listen = msg.listen;
    if (typeof listen !== "string" || listen.trim().length === 0) {
      return null;
    }
    return { type: "appostle:ready", listen };
  }
  if (type === "appostle:restart") {
    const reason = msg.reason;
    return {
      type: "appostle:restart",
      ...typeof reason === "string" && reason.trim().length > 0 ? { reason } : {}
    };
  }
  return null;
}
function runSupervisor(options) {
  const restartOnCrash = options.restartOnCrash ?? false;
  const workerArgs = options.workerArgs ?? process.argv.slice(2);
  const workerEnv = options.workerEnv ?? process.env;
  const workerExecArgv = options.workerExecArgv ?? ["--import", "tsx"];
  const resolveWorkerSpawnSpec = options.resolveWorkerSpawnSpec;
  let child = null;
  let restarting = false;
  let shuttingDown = false;
  let exiting = false;
  const log = (message) => {
    process.stderr.write(`[${options.name}] ${message}
`);
  };
  const exitSupervisor = (code) => {
    if (exiting) {
      return;
    }
    exiting = true;
    Promise.resolve(options.onSupervisorExit?.()).catch((error) => {
      const message = error instanceof Error ? error.message : String(error);
      log(`Supervisor exit cleanup failed: ${message}`);
    }).finally(() => {
      process.exit(code);
    });
  };
  const spawnWorker = () => {
    let workerEntry;
    try {
      workerEntry = options.resolveWorkerEntry();
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error);
      log(`Failed to resolve worker entry: ${message}`);
      exitSupervisor(1);
      return;
    }
    const spawnSpec = resolveWorkerSpawnSpec?.(workerEntry) ?? null;
    if (spawnSpec) {
      child = spawn(spawnSpec.command, spawnSpec.args, {
        stdio: ["inherit", "inherit", "inherit", "ipc"],
        env: spawnSpec.env ?? workerEnv
      });
    } else {
      child = fork(workerEntry, workerArgs, {
        stdio: "inherit",
        env: workerEnv,
        execArgv: workerExecArgv
      });
    }
    child.on("message", (msg) => {
      const lifecycleMessage = parseLifecycleMessage(msg);
      if (!lifecycleMessage) {
        return;
      }
      if (lifecycleMessage.type === "appostle:ready") {
        Promise.resolve(options.onWorkerReady?.({ listen: lifecycleMessage.listen })).catch(
          (error) => {
            const message = error instanceof Error ? error.message : String(error);
            log(`Worker ready callback failed: ${message}`);
          }
        );
        return;
      }
      if (lifecycleMessage.type === "appostle:shutdown") {
        requestShutdown("Shutdown requested by worker");
        return;
      }
      requestRestart("Restart requested by worker");
    });
    child.on("exit", (code, signal) => {
      const exitDescriptor = describeExit(code, signal);
      if (shuttingDown) {
        log(`Worker exited (${exitDescriptor}). Supervisor shutting down.`);
        exitSupervisor(0);
        return;
      }
      const crashed = restartOnCrash && (code !== 0 && code !== null || signal !== null && signal === "SIGKILL");
      if (restarting || crashed) {
        restarting = false;
        log(`Worker exited (${exitDescriptor}). Restarting worker...`);
        spawnWorker();
        return;
      }
      log(`Worker exited (${exitDescriptor}). Supervisor exiting.`);
      exitSupervisor(typeof code === "number" ? code : 0);
    });
  };
  const requestRestart = (reason) => {
    if (!child || restarting || shuttingDown) {
      return;
    }
    restarting = true;
    log(`${reason}. Stopping worker for restart...`);
    child.kill("SIGTERM");
  };
  const requestShutdown = (reason) => {
    if (shuttingDown) {
      return;
    }
    shuttingDown = true;
    restarting = false;
    log(`${reason}. Stopping worker...`);
    if (!child) {
      exitSupervisor(0);
      return;
    }
    child.kill("SIGTERM");
  };
  const forwardSignal = (signal) => {
    requestShutdown(`Received ${signal}`);
  };
  process.on("SIGINT", () => forwardSignal("SIGINT"));
  process.on("SIGTERM", () => forwardSignal("SIGTERM"));
  process.stdout.write(`[${options.name}] ${options.startupMessage}
`);
  spawnWorker();
}

// ../server/src/server/speech/providers/local/sherpa/sherpa-runtime-env.ts
import { createRequire } from "node:module";
import path2 from "node:path";
function sherpaPlatformArch(platform = process.platform, arch = process.arch) {
  const normalizedPlatform = platform === "win32" ? "win" : platform;
  return `${normalizedPlatform}-${arch}`;
}
function sherpaPlatformPackageName(platform = process.platform, arch = process.arch) {
  return `sherpa-onnx-${sherpaPlatformArch(platform, arch)}`;
}
function sherpaLoaderEnvKey(platform = process.platform) {
  if (platform === "linux") {
    return "LD_LIBRARY_PATH";
  }
  if (platform === "darwin") {
    return "DYLD_LIBRARY_PATH";
  }
  if (platform === "win32") {
    return "PATH";
  }
  return null;
}
function prependEnvPath(existing, value) {
  const parts = (existing ?? "").split(path2.delimiter).filter(Boolean);
  if (parts.includes(value)) {
    return parts.join(path2.delimiter);
  }
  return [value, ...parts].join(path2.delimiter);
}
function resolveSherpaLoaderEnv(platform = process.platform, arch = process.arch) {
  const key = sherpaLoaderEnvKey(platform);
  if (!key) {
    return null;
  }
  const packageName = sherpaPlatformPackageName(platform, arch);
  const require2 = createRequire(import.meta.url);
  try {
    const pkgJson = require2.resolve(`${packageName}/package.json`);
    return {
      key,
      libDir: path2.dirname(pkgJson),
      packageName
    };
  } catch {
    return null;
  }
}
function findEnvKey(env, key) {
  const lower = key.toLowerCase();
  for (const k of Object.keys(env)) {
    if (k.toLowerCase() === lower) return k;
  }
  return key;
}
function applySherpaLoaderEnv(env, platform = process.platform, arch = process.arch) {
  const resolved = resolveSherpaLoaderEnv(platform, arch);
  if (!resolved) {
    return {
      changed: false,
      key: null,
      libDir: null,
      packageName: null
    };
  }
  const actualKey = findEnvKey(env, resolved.key);
  const next = prependEnvPath(env[actualKey], resolved.libDir);
  const changed = next !== (env[actualKey] ?? "");
  env[actualKey] = next;
  return {
    changed,
    key: resolved.key,
    libDir: resolved.libDir,
    packageName: resolved.packageName
  };
}

// ../server/scripts/supervisor-entrypoint.ts
function parseConfig(argv) {
  let devMode = false;
  const workerArgs = [];
  for (const arg of argv) {
    if (arg === "--dev") {
      devMode = true;
      continue;
    }
    workerArgs.push(arg);
  }
  return { devMode, workerArgs };
}
function resolveWorkerEntry() {
  const candidates = [
    // Single-package bundle (appostle-installer): worker ships next to this
    // supervisor-entrypoint as `worker.js`.
    fileURLToPath(new URL("./worker.js", import.meta.url)),
    // Legacy @appostle/server layouts (dev / older multi-package install).
    fileURLToPath(new URL("../server/server/index.js", import.meta.url)),
    fileURLToPath(new URL("../dist/server/server/index.js", import.meta.url)),
    fileURLToPath(new URL("../src/server/index.ts", import.meta.url)),
    fileURLToPath(new URL("../../src/server/index.ts", import.meta.url))
  ];
  for (const candidate of candidates) {
    if (existsSync2(candidate)) {
      return candidate;
    }
  }
  return candidates[0];
}
function resolveDevWorkerEntry() {
  const candidate = fileURLToPath(new URL("../src/server/index.ts", import.meta.url));
  if (!existsSync2(candidate)) {
    throw new Error(`Dev worker entry not found: ${candidate}`);
  }
  return candidate;
}
function resolveWorkerExecArgv(workerEntry) {
  return workerEntry.endsWith(".ts") ? ["--import", "tsx"] : [];
}
function resolvePackagedNodeEntrypointRunnerPath(currentScriptPath) {
  const packageMarker = `${path3.sep}node_modules${path3.sep}@appostle${path3.sep}server${path3.sep}`;
  const markerIndex = currentScriptPath.lastIndexOf(packageMarker);
  if (markerIndex === -1) {
    return null;
  }
  const appRoot = currentScriptPath.slice(0, markerIndex);
  const runnerPath = path3.join(appRoot, "dist", "daemon", "node-entrypoint-runner.js");
  return existsSync2(runnerPath) ? runnerPath : null;
}
async function main() {
  const config = parseConfig(process.argv.slice(2));
  const workerEntry = config.devMode ? resolveDevWorkerEntry() : resolveWorkerEntry();
  const workerExecArgv = resolveWorkerExecArgv(workerEntry);
  const workerEnv = { ...process.env, APPOSTLE_SUPERVISED: "1" };
  const packagedNodeEntrypointRunner = process.env.ELECTRON_RUN_AS_NODE === "1" ? resolvePackagedNodeEntrypointRunnerPath(fileURLToPath(import.meta.url)) : null;
  applySherpaLoaderEnv(workerEnv);
  const appostleHome = resolveAppostleHome(workerEnv);
  try {
    await acquirePidLock(appostleHome, null, {
      ownerPid: process.pid
    });
  } catch (error) {
    if (error instanceof PidLockError) {
      process.stderr.write(`${error.message}
`);
      process.exit(1);
      return;
    }
    throw error;
  }
  let lockReleased = false;
  const releaseLock = async () => {
    if (lockReleased) {
      return;
    }
    lockReleased = true;
    await releasePidLock(appostleHome, {
      ownerPid: process.pid
    });
  };
  runSupervisor({
    name: "DaemonRunner",
    startupMessage: config.devMode ? "Starting daemon worker (dev mode, crash restarts enabled)" : "Starting daemon worker (IPC restart enabled)",
    resolveWorkerEntry: () => workerEntry,
    workerArgs: config.workerArgs,
    workerEnv,
    workerExecArgv,
    resolveWorkerSpawnSpec: packagedNodeEntrypointRunner ? (resolvedWorkerEntry) => ({
      command: process.execPath,
      args: [
        packagedNodeEntrypointRunner,
        "node-script",
        resolvedWorkerEntry,
        ...config.workerArgs
      ],
      env: {
        ...workerEnv,
        ELECTRON_RUN_AS_NODE: "1"
      }
    }) : void 0,
    restartOnCrash: config.devMode,
    onWorkerReady: async ({ listen }) => {
      await updatePidLock(appostleHome, { listen }, { ownerPid: process.pid });
    },
    onSupervisorExit: releaseLock
  });
}
void main().catch((error) => {
  const message = error instanceof Error ? error.stack ?? error.message : String(error);
  process.stderr.write(`${message}
`);
  process.exit(1);
});
//# sourceMappingURL=supervisor-entrypoint.js.map
