// 重构前 index.ts 只读参考：commit 6a04144d3f5103014f75b637d7e6bc2f45bf007f，blob 56e590c1a6b5ca7ad128bf2c992f60e46c355a58；可用 `git show 6a04144d3f5103014f75b637d7e6bc2f45bf007f:src/components/microservices/code-queue/src/index.ts` 查看。

import { spawn } from "node:child_process";
import { existsSync, readFileSync } from "node:fs";
import { resolve } from "node:path";
import { codeAgentGitConfigEntries, codeExecutionModeInfo, opencodeNpmPackage } from "./code-agent/common";
import type { DevContainerCommandLog, DevContainerPlan, JsonValue, QueueTask, RuntimeConfig } from "./types";

export interface ProviderRuntimeContext {
  config: Pick<RuntimeConfig,
    "codexHome" | "defaultWorkdir" | "devContainerDefaultProviderId" | "devContainerImage" | "devContainerMasterHost" | "devContainerWorkdir" | "executionProviderIds" | "mainProviderId" | "remoteCodexEnvKeys" | "remoteDefaultWorkdir" | "runnerSkillsSourcePath" | "skillsPath" | "sourceCodexConfig" | "windowsNativeCodexBridgeDir" | "windowsNativeCodexCommand" | "windowsNativeCodexConnectHost" | "windowsNativeCodexDefaultWorkdir" | "windowsNativeCodexIdleTimeoutMs"
  >;
  safePreview: (value: string, max?: number) => string;
}

let context: ProviderRuntimeContext | null = null;

export function configureProviderRuntime(runtimeContext: ProviderRuntimeContext): void {
  context = runtimeContext;
}

function ctx(): ProviderRuntimeContext {
  if (context === null) throw new Error("provider-runtime module is not configured");
  return context;
}

function shellQuote(value: string): string {
  return `'${value.replace(/'/gu, "'\\''")}'`;
}

function safeDockerName(value: string): string {
  return value.replace(/[^a-zA-Z0-9_.-]/gu, "-").replace(/^-+/u, "").slice(0, 80) || "node";
}

function normalizeProviderId(value: unknown): string | null {
  if (typeof value !== "string") return null;
  const trimmed = value.trim();
  return /^[A-Za-z0-9_.-]{1,64}$/u.test(trimmed) ? trimmed : null;
}

function normalizeTaskProviderId(value: unknown): string {
  return normalizeProviderId(value) ?? ctx().config.mainProviderId;
}

function providerIsMain(providerId: string): boolean {
  return normalizeTaskProviderId(providerId) === ctx().config.mainProviderId;
}

function defaultWorkdirForProvider(providerId: string): string {
  return providerIsMain(providerId) ? ctx().config.defaultWorkdir : ctx().config.remoteDefaultWorkdir;
}

function resolveTaskCwd(providerId: string, value: unknown): string {
  const raw = typeof value === "string" ? value.trim() : "";
  const base = defaultWorkdirForProvider(providerId);
  if (raw.length === 0) return base;
  return raw.startsWith("/") ? raw : resolve(base, raw);
}

function remoteHostWorkdirForTask(task: QueueTask): string {
  const base = defaultWorkdirForProvider(task.providerId);
  return task.cwd === base || task.cwd.startsWith(`${base}/`) ? base : task.cwd;
}

function executionProviderOptions(): JsonValue[] {
  const ids = Array.from(new Set([
    ctx().config.mainProviderId,
    ...ctx().config.executionProviderIds,
    ctx().config.devContainerDefaultProviderId,
  ].map(normalizeProviderId).filter((value): value is string => value !== null)));
  return ids.map((providerId) => ({
    id: providerId,
    label: providerIsMain(providerId) ? `${providerId} (local)` : providerId,
    kind: providerIsMain(providerId) ? "local" : "remote-dev-container",
    defaultWorkdir: defaultWorkdirForProvider(providerId),
    supportsWindowsNativeCodex: !providerIsMain(providerId),
    windowsNativeDefaultWorkdir: providerIsMain(providerId) ? null : ctx().config.windowsNativeCodexDefaultWorkdir,
    containerName: providerIsMain(providerId) ? null : buildDevContainerPlan(providerId, {}).containerName,
  }));
}

function executionModeOptions(): JsonValue[] {
  return [
    {
      ...codeExecutionModeInfo("default"),
      id: "default",
      defaultWorkdir: null,
    },
    {
      ...codeExecutionModeInfo("windows-native"),
      id: "windows-native",
      defaultWorkdir: ctx().config.windowsNativeCodexDefaultWorkdir,
      bridgeDir: ctx().config.windowsNativeCodexBridgeDir,
      connectHost: ctx().config.windowsNativeCodexConnectHost,
    },
  ];
}

function numericIdFromProvider(providerId: string): number {
  const digits = providerId.match(/\d+/u)?.[0] ?? "";
  if (digits.length > 0) {
    const parsed = Number(digits);
    if (Number.isInteger(parsed) && parsed >= 0 && parsed <= 4095) return parsed;
  }
  let hash = 0;
  for (const char of providerId) hash = (Math.imul(hash, 31) + char.charCodeAt(0)) >>> 0;
  return 100 + (hash % 3900);
}

function buildDevContainerPlan(providerId: string, body: Record<string, unknown>): DevContainerPlan {
  const safeProvider = safeDockerName(providerId);
  const tunId = numericIdFromProvider(providerId);
  const imageFromBody = typeof body.image === "string" && body.image.trim().length > 0 ? body.image.trim() : "";
  const workdirFromBody = typeof body.workdir === "string" && body.workdir.trim().length > 0 ? body.workdir.trim() : "";
  const masterFromBody = typeof body.masterHost === "string" && body.masterHost.trim().length > 0 ? body.masterHost.trim() : "";
  const containerFromBody = typeof body.containerName === "string" && body.containerName.trim().length > 0 ? body.containerName.trim() : "";
  const image = imageFromBody.length > 0
    ? imageFromBody
    : ctx().config.devContainerImage.length > 0
      ? ctx().config.devContainerImage
      : `unidesk-code-queue:${safeProvider.toLowerCase()}`;
  const workdir = workdirFromBody.length > 0 ? workdirFromBody : ctx().config.devContainerWorkdir;
  const thirdOctet = providerId === "D601" ? 6 : Math.max(1, Math.min(250, Math.floor(tunId / 64)));
  const baseOctet = providerId === "D601" ? 0 : (tunId % 64) * 4;
  const serverLastOctet = providerId === "D601" ? 1 : baseOctet + 1;
  const clientLastOctet = providerId === "D601" ? 2 : baseOctet + 2;
  return {
    providerId,
    containerName: safeDockerName(containerFromBody.length > 0 ? containerFromBody : `unidesk-codex-dev-${safeProvider}`),
    image,
    workdir,
    containerWorkdir: workdir,
    remoteCodexHome: "/var/lib/unidesk/code-queue/codex-home",
    remoteOpencodeXdgDir: "/var/lib/unidesk/code-queue/opencode-xdg",
    masterHost: masterFromBody.length > 0 ? masterFromBody : ctx().config.devContainerMasterHost,
    tunId,
    tunName: `tun${tunId}`,
    serverIp: `10.214.${thirdOctet}.${serverLastOctet}`,
    clientIp: `10.214.${thirdOctet}.${clientLastOctet}`,
    natChain: safeDockerName(`UNIDESK-CODEX-DEV-${safeProvider}`).toUpperCase().slice(0, 28),
    egressFirewallChain: safeDockerName(`UD-CQ-EGRESS-${safeProvider}`).toUpperCase().slice(0, 28),
    keyDir: `/home/ubuntu/.unidesk/codex-dev-proxy/${safeProvider}`,
    masterKeyPath: resolve(ctx().config.defaultWorkdir, ".state/code-queue/dev-proxy", safeProvider, "id_ed25519"),
  };
}

function appendLimited(buffer: string, chunk: Buffer | string, maxBytes: number): { value: string; truncated: boolean } {
  const text = typeof chunk === "string" ? chunk : chunk.toString("utf8");
  if (buffer.length >= maxBytes) return { value: buffer, truncated: true };
  const remaining = maxBytes - buffer.length;
  if (text.length <= remaining) return { value: buffer + text, truncated: false };
  return { value: buffer + text.slice(0, remaining), truncated: true };
}

interface CliRunResult {
  code: number | null;
  signal: NodeJS.Signals | null;
  stdout: string;
  stderr: string;
  timedOut: boolean;
  truncated: boolean;
  spawnError: Error | null;
}

function runCliCommand(args: string[], timeoutMs: number): Promise<CliRunResult> {
  const maxBuffer = 8 * 1024 * 1024;
  return new Promise((resolveRun) => {
    let stdout = "";
    let stderr = "";
    let truncated = false;
    let timedOut = false;
    let spawnError: Error | null = null;
    const child = spawn("bun", args, {
      cwd: ctx().config.defaultWorkdir,
      stdio: ["ignore", "pipe", "pipe"],
    });
    const timer = setTimeout(() => {
      timedOut = true;
      child.kill("SIGTERM");
      setTimeout(() => child.kill("SIGKILL"), 2_000).unref?.();
    }, timeoutMs);
    timer.unref?.();
    child.stdout.on("data", (chunk: Buffer) => {
      const next = appendLimited(stdout, chunk, maxBuffer);
      stdout = next.value;
      truncated ||= next.truncated;
    });
    child.stderr.on("data", (chunk: Buffer) => {
      const next = appendLimited(stderr, chunk, maxBuffer);
      stderr = next.value;
      truncated ||= next.truncated;
    });
    child.on("error", (error) => {
      spawnError = error;
    });
    child.on("close", (code, signal) => {
      clearTimeout(timer);
      resolveRun({
        code: timedOut && code === 0 ? null : code,
        signal: signal as NodeJS.Signals | null,
        stdout,
        stderr,
        timedOut,
        truncated,
        spawnError,
      });
    });
  });
}

function buildFrontendHostSshArgs(providerId: string, command: string, timeoutMs: number): string[] {
  const waitMs = Math.max(timeoutMs + 5_000, 20_000);
  return [
    "scripts/cli.ts",
    "--main-server-ip",
    ctx().config.devContainerMasterHost,
    "debug",
    "dispatch",
    providerId,
    "host.ssh",
    "--wait-ms",
    String(waitMs),
    "--payload-json",
    JSON.stringify({ source: "code-queue", mode: "exec", command, timeoutMs }),
  ];
}

function parseFrontendHostSshResult(run: CliRunResult): { stdout: string; stderr: string; exitCode: number | null } {
  let stdout = run.stdout;
  let stderr = run.stderr;
  let exitCode = run.code;
  try {
    const parsed = JSON.parse(run.stdout) as {
      ok?: boolean;
      error?: unknown;
      data?: {
        dispatch?: unknown;
        wait?: {
          task?: {
            status?: string;
            result?: {
              stdout?: string;
              stderr?: string;
              exitCode?: number;
            };
          };
        };
      };
    };
    const task = parsed.data?.wait?.task;
    const result = task?.result;
    if (result !== undefined) {
      stdout = typeof result.stdout === "string" ? result.stdout : "";
      stderr = [typeof result.stderr === "string" ? result.stderr : "", run.stderr].filter((part) => part.length > 0).join("\n");
      exitCode = typeof result.exitCode === "number" ? result.exitCode : task?.status === "succeeded" ? 0 : 1;
    } else if (parsed.ok === false || task?.status === "failed") {
      stdout = "";
      stderr = [JSON.stringify(parsed.error ?? task ?? parsed.data?.dispatch ?? parsed), run.stderr].filter((part) => part.length > 0).join("\n");
      exitCode = 1;
    }
  } catch {
    // Keep raw stdout/stderr when the CLI itself failed before returning dispatch JSON.
  }
  return { stdout, stderr, exitCode };
}

async function runFrontendHostSsh(providerId: string, command: string, timeoutMs: number): Promise<CliRunResult & { parsedStdout: string; parsedStderr: string; parsedExitCode: number | null }> {
  const run = await runCliCommand(buildFrontendHostSshArgs(providerId, command, timeoutMs), Math.max(timeoutMs + 15_000, 30_000));
  const parsed = parseFrontendHostSshResult(run);
  return { ...run, parsedStdout: parsed.stdout, parsedStderr: parsed.stderr, parsedExitCode: parsed.exitCode };
}

function encodedScriptCommand(encodedScript: string): string {
  return [
    "set -euo pipefail",
    "tmp=$(mktemp /tmp/unidesk-code-queue-ssh.XXXXXX)",
    "cleanup(){ rm -f \"$tmp\"; }",
    "trap cleanup EXIT",
    "base64 -d > \"$tmp\" <<'UNIDESK_CODE_QUEUE_SCRIPT'",
    encodedScript,
    "UNIDESK_CODE_QUEUE_SCRIPT",
    "bash \"$tmp\"",
  ].join("\n");
}

function commandLogFromRun(name: string, providerId: string, started: number, run: CliRunResult & { parsedStdout: string; parsedStderr: string; parsedExitCode: number | null }): DevContainerCommandLog {
  const errorParts: string[] = [];
  if (run.parsedStderr.length > 0) errorParts.push(run.parsedStderr);
  if (run.timedOut) errorParts.push(`Error: command timed out after ${Date.now() - started}ms`);
  if (run.spawnError !== null) errorParts.push(`${run.spawnError.name}: ${run.spawnError.message}`);
  if (run.truncated) errorParts.push("output truncated at 8388608 bytes");
  return {
    name,
    providerId,
    exitCode: run.parsedExitCode,
    signal: run.signal,
    durationMs: Date.now() - started,
    stdout: run.parsedStdout,
    stderr: errorParts.join("\n").trim(),
  };
}

async function uploadAndRunLargeScript(providerId: string, encodedScript: string, timeoutMs: number, name: string, started: number): Promise<DevContainerCommandLog> {
  const token = `${Date.now()}-${Math.random().toString(16).slice(2)}`.replace(/[^A-Za-z0-9.-]/gu, "-");
  const b64Path = `/tmp/unidesk-code-queue-${token}.b64`;
  const scriptPath = `/tmp/unidesk-code-queue-${token}.sh`;
  const init = await runFrontendHostSsh(providerId, `set -euo pipefail\numask 077\n: > ${shellQuote(b64Path)}`, 15_000);
  if (init.parsedExitCode !== 0) return commandLogFromRun(name, providerId, started, init);
  const chunkSize = 1800;
  for (let offset = 0; offset < encodedScript.length; offset += chunkSize) {
    const chunk = encodedScript.slice(offset, offset + chunkSize);
    const appendCommand = [
      "set -euo pipefail",
      `cat >> ${shellQuote(b64Path)} <<'UNIDESK_CODE_QUEUE_CHUNK'`,
      chunk,
      "UNIDESK_CODE_QUEUE_CHUNK",
    ].join("\n");
    const append = await runFrontendHostSsh(providerId, appendCommand, 15_000);
    if (append.parsedExitCode !== 0) return commandLogFromRun(name, providerId, started, append);
  }
  const runCommand = [
    "set -uo pipefail",
    `base64 -d ${shellQuote(b64Path)} > ${shellQuote(scriptPath)}`,
    `rm -f ${shellQuote(b64Path)}`,
    `bash ${shellQuote(scriptPath)}`,
    "code=$?",
    `rm -f ${shellQuote(scriptPath)}`,
    "exit \"$code\"",
  ].join("\n");
  const run = await runFrontendHostSsh(providerId, runCommand, timeoutMs);
  return commandLogFromRun(name, providerId, started, run);
}

function runCodeQueueSsh(providerId: string, script: string, timeoutMs: number, name: string): Promise<DevContainerCommandLog> {
  const started = Date.now();
  const encodedScript = Buffer.from(script, "utf8").toString("base64");
  const inlineCommand = encodedScriptCommand(encodedScript);
  if (inlineCommand.length > 3_400) return uploadAndRunLargeScript(providerId, encodedScript, timeoutMs, name, started);
  return runFrontendHostSsh(providerId, inlineCommand, timeoutMs).then((run) => commandLogFromRun(name, providerId, started, run));
}

function throwIfCommandFailed(command: DevContainerCommandLog): void {
  if (command.exitCode === 0) return;
  throw new Error(`${command.name} failed on ${command.providerId ?? "local"} exit=${command.exitCode} stderr=${ctx().safePreview(command.stderr, 1000)}`);
}

function masterKeySetupScript(plan: DevContainerPlan): string {
  const marker = `unidesk-codex-dev-proxy-${plan.providerId}`;
  return `set -euo pipefail
PROVIDER_ID=${shellQuote(plan.providerId)}
TUN_ID=${shellQuote(String(plan.tunId))}
KEY=${shellQuote(plan.masterKeyPath)}
BASE=$(dirname "$KEY")
MARK=${shellQuote(marker)}
mkdir -p "$BASE" /root/.ssh /etc/ssh/sshd_config.d
chmod 700 /root/.ssh
if [ ! -s "$KEY" ]; then
  ssh-keygen -t ed25519 -N '' -C "$MARK" -f "$KEY" >/dev/null
fi
chmod 600 "$KEY"
printf 'PermitTunnel yes\\n' > /etc/ssh/sshd_config.d/90-unidesk-codex-dev-tunnel.conf
sshd -t
if command -v systemctl >/dev/null 2>&1; then systemctl reload ssh || systemctl reload sshd || true; fi
if command -v service >/dev/null 2>&1; then service ssh reload || service sshd reload || true; fi
touch /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
tmp=$(mktemp)
grep -v "$MARK" /root/.ssh/authorized_keys > "$tmp" || true
cat "$tmp" > /root/.ssh/authorized_keys
rm -f "$tmp"
PUB=$(cat "$KEY.pub")
printf 'tunnel="%s",no-agent-forwarding,no-X11-forwarding,no-pty %s\\n' "$TUN_ID" "$PUB" >> /root/.ssh/authorized_keys
echo "master_key_ready provider=$PROVIDER_ID key=$KEY permitTunnel=$(sshd -T | awk '$1==\"permittunnel\"{print $2; exit}')"`;
}

function masterKeyReadScript(plan: DevContainerPlan): string {
  return `set -euo pipefail
base64 -w0 ${shellQuote(plan.masterKeyPath)}`;
}

function remoteKeyInstallScript(plan: DevContainerPlan, privateKeyBase64: string): string {
  return `set -euo pipefail
KEY_DIR=${shellQuote(plan.keyDir)}
MASTER=${shellQuote(plan.masterHost)}
umask 077
mkdir -p "$KEY_DIR"
printf %s ${shellQuote(privateKeyBase64)} | base64 -d > "$KEY_DIR/id_ed25519"
chmod 600 "$KEY_DIR/id_ed25519"
ssh-keyscan -H "$MASTER" > "$KEY_DIR/known_hosts" 2>/dev/null
chmod 600 "$KEY_DIR/known_hosts"
echo "remote_key_ready keyDir=$KEY_DIR master=$MASTER"`;
}

function base64Text(value: string): string {
  return Buffer.from(value, "utf8").toString("base64");
}

function remoteCodexEnvFile(): string {
  return ctx().config.remoteCodexEnvKeys
    .map((key) => key.trim())
    .filter((key) => /^[A-Za-z_][A-Za-z0-9_]*$/u.test(key) && process.env[key] !== undefined)
    .map((key) => `${key}=${String(process.env[key] ?? "").replace(/\r?\n/gu, "")}`)
    .join("\n");
}

function remoteCodexConfigText(): string {
  const homeConfig = resolve(ctx().config.codexHome, "config.toml");
  const path = existsSync(homeConfig) ? homeConfig : ctx().config.sourceCodexConfig;
  if (!existsSync(path)) return "";
  return readFileSync(path, "utf8");
}

function remoteCodexConfigInstallScript(plan: DevContainerPlan): string {
  const configBase64 = base64Text(remoteCodexConfigText());
  const envBase64 = base64Text(remoteCodexEnvFile());
  return `set -euo pipefail
KEY_DIR=${shellQuote(plan.keyDir)}
CODEX_HOME_DIR="$KEY_DIR/codex-home"
OPENCODE_XDG_DIR="$KEY_DIR/opencode-xdg"
mkdir -p "$CODEX_HOME_DIR" "$OPENCODE_XDG_DIR"
chmod 700 "$KEY_DIR" "$CODEX_HOME_DIR" "$OPENCODE_XDG_DIR"
printf %s ${shellQuote(configBase64)} | base64 -d > "$CODEX_HOME_DIR/config.toml"
printf %s ${shellQuote(envBase64)} | base64 -d > "$KEY_DIR/codex-env"
chmod 600 "$CODEX_HOME_DIR/config.toml" "$KEY_DIR/codex-env"
echo "remote_codex_config_ready keyDir=$KEY_DIR codexHome=$CODEX_HOME_DIR opencodeXdg=$OPENCODE_XDG_DIR envKeys=${ctx().config.remoteCodexEnvKeys.filter((key) => process.env[key] !== undefined).length}"`;
}

function remoteContainerStartScript(plan: DevContainerPlan, forceRecreate: boolean): string {
  return `set -euo pipefail
CONTAINER=${shellQuote(plan.containerName)}
REQUESTED_IMAGE=${shellQuote(plan.image)}
KEY_DIR=${shellQuote(plan.keyDir)}
WORKDIR=${shellQuote(plan.workdir)}
CONTAINER_WORKDIR=${shellQuote(plan.containerWorkdir)}
SKILLS_SOURCE=${shellQuote(ctx().config.runnerSkillsSourcePath)}
SKILLS_TARGET=${shellQuote(ctx().config.skillsPath)}
IMAGE="$REQUESTED_IMAGE"
SSH_DIR="\${UNIDESK_HOST_ROOT_SSH_DIR:-$HOME/.ssh}"
SSH_MOUNT_ARGS=()
if [ -d "$SSH_DIR" ]; then SSH_MOUNT_ARGS=(-v "$SSH_DIR":/root/.ssh:ro); fi
HOST_PATH_MOUNT_ARGS=()
if [ -d /mnt ]; then HOST_PATH_MOUNT_ARGS+=(-v /mnt:/mnt); fi
SKILLS_MOUNT_ARGS=()
if [ ! -d "$SKILLS_SOURCE" ]; then
  echo "missing runner skills source $SKILLS_SOURCE; expected read-only projection to $SKILLS_TARGET" >&2
  exit 1
fi
SKILLS_MOUNT_ARGS=(-v "$SKILLS_SOURCE":"$SKILLS_TARGET":ro)
if ! docker image inspect "$IMAGE" >/dev/null 2>&1; then
  echo "missing dev container image $REQUESTED_IMAGE" >&2
  exit 1
fi
test -r "$KEY_DIR/id_ed25519"
test -r "$KEY_DIR/known_hosts"
test -r "$KEY_DIR/codex-env"
test -r /usr/bin/busybox
mkdir -p "$WORKDIR" "$KEY_DIR/opencode-xdg"
if [ ${forceRecreate ? "1" : "0"} -eq 0 ] && docker inspect "$CONTAINER" >/dev/null 2>&1; then
  STATE=$(docker inspect "$CONTAINER" --format '{{.State.Status}}' 2>/dev/null || true)
  LABEL_WORKDIR=$(docker inspect "$CONTAINER" --format '{{ index .Config.Labels "unidesk.workdir" }}' 2>/dev/null || true)
  if [ "$STATE" = "running" ] && [ "$LABEL_WORKDIR" = "$WORKDIR" ]; then
    docker exec "$CONTAINER" bash -lc 'echo reuse_ready; command -v bash; test "$UNIDESK_SKILLS_PATH" = "/root/.agents/skills"; test -r "$UNIDESK_SKILLS_PATH/docs-spec/SKILL.md"; test -r "$UNIDESK_SKILLS_PATH/cli-spec/SKILL.md"; test -r "$UNIDESK_SKILLS_PATH/frontend-design/SKILL.md"; if [ -r "$UNIDESK_SKILLS_PATH/playwright-cli/SKILL.md" ]; then :; else test -r "$UNIDESK_SKILLS_PATH/playwright/SKILL.md"; fi; test -d /run/unidesk-dev-proxy; test -d /var/lib/unidesk/code-queue/codex-home; test -d /var/lib/unidesk/code-queue/opencode-xdg' >/dev/null
    echo "remote_container_reused container=$CONTAINER image=$(docker inspect "$CONTAINER" --format '{{.Config.Image}}') workdir=$WORKDIR"
    exit 0
  fi
fi
docker rm -f "$CONTAINER" >/dev/null 2>&1 || true
cid=$(docker run -d \\
  --name "$CONTAINER" \\
  --hostname ${shellQuote(`codex-dev-${plan.providerId}`)} \\
  --user root \\
  --no-healthcheck \\
  --cap-add NET_ADMIN \\
  --device /dev/net/tun \\
  --add-host host.docker.internal:host-gateway \\
  --label unidesk.role=codex-dev \\
  --label unidesk.provider=${shellQuote(plan.providerId)} \\
  --label "unidesk.workdir=$WORKDIR" \\
  --label com.docker.compose.project=unidesk-code-queue-dev \\
  --label com.docker.compose.service=codex-dev \\
  --env-file "$KEY_DIR/codex-env" \\
  -e CODEX_HOME=${shellQuote(plan.remoteCodexHome)} \\
  -e CODEX_INTERNAL_ORIGINATOR_OVERRIDE=unidesk_code_queue \\
  -e UNIDESK_SKILLS_PATH="$SKILLS_TARGET" \\
  -e XDG_DATA_HOME=${shellQuote(resolve(plan.remoteOpencodeXdgDir, "data"))} \\
  -e XDG_CONFIG_HOME=${shellQuote(resolve(plan.remoteOpencodeXdgDir, "config"))} \\
  -e XDG_CACHE_HOME=${shellQuote(resolve(plan.remoteOpencodeXdgDir, "cache"))} \\
  -e XDG_STATE_HOME=${shellQuote(resolve(plan.remoteOpencodeXdgDir, "state"))} \\
  -v /var/run/docker.sock:/var/run/docker.sock \\
  -v /usr/bin/busybox:/usr/local/bin/busybox:ro \\
  -v "$KEY_DIR":/run/unidesk-dev-proxy:ro \\
  -v "$KEY_DIR/codex-home":${shellQuote(plan.remoteCodexHome)} \\
  -v "$KEY_DIR/opencode-xdg":${shellQuote(plan.remoteOpencodeXdgDir)} \\
  "\${SSH_MOUNT_ARGS[@]}" \\
  "\${HOST_PATH_MOUNT_ARGS[@]}" \\
  "\${SKILLS_MOUNT_ARGS[@]}" \\
  -v "$WORKDIR":"$CONTAINER_WORKDIR" \\
  -v "$WORKDIR":/root/unidesk \\
  -w "$CONTAINER_WORKDIR" \\
  "$IMAGE" \\
  bash -lc 'mkdir -p /tmp/unidesk-tools; ln -sf /usr/local/bin/busybox /tmp/unidesk-tools/ip; ln -sf /usr/local/bin/busybox /tmp/unidesk-tools/ping; export PATH=/tmp/unidesk-tools:$PATH; echo ready; sleep infinity')
docker exec "$CONTAINER" bash -lc 'mkdir -p /tmp/unidesk-tools; ln -sf /usr/local/bin/busybox /tmp/unidesk-tools/ip; ln -sf /usr/local/bin/busybox /tmp/unidesk-tools/ping; export PATH=/tmp/unidesk-tools:$PATH; echo container=$(hostname); pwd; ip route show default; test "$UNIDESK_SKILLS_PATH" = "/root/.agents/skills"; test -d "$UNIDESK_SKILLS_PATH"; test -r "$UNIDESK_SKILLS_PATH/docs-spec/SKILL.md"; test -r "$UNIDESK_SKILLS_PATH/cli-spec/SKILL.md"; test -r "$UNIDESK_SKILLS_PATH/frontend-design/SKILL.md"; if [ -r "$UNIDESK_SKILLS_PATH/playwright-cli/SKILL.md" ]; then :; else test -r "$UNIDESK_SKILLS_PATH/playwright/SKILL.md"; fi; ls -ld /dev/net/tun /run/unidesk-dev-proxy/id_ed25519 /var/lib/unidesk/code-queue/codex-home /var/lib/unidesk/code-queue/opencode-xdg "$UNIDESK_SKILLS_PATH"; command -v ssh; command -v ip; command -v ping'
docker exec "$CONTAINER" bash -lc 'command -v iptables; iptables --version'
echo "remote_container_ready container=$CONTAINER cid=$cid image=$IMAGE workdir=$WORKDIR skillsTarget=$SKILLS_TARGET"`;
}

function masterProxyPrepareScript(plan: DevContainerPlan): string {
  return `set -euo pipefail
TUN=${shellQuote(plan.tunName)}
CLIENT_IP=${shellQuote(plan.clientIp)}
CHAIN=${shellQuote(plan.natChain)}
EGRESS=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++){if($i=="dev"){print $(i+1); exit}}}')
if [ -z "$EGRESS" ]; then echo "cannot detect master egress interface" >&2; exit 1; fi
ip link show "$TUN" >/dev/null 2>&1 && ip link delete "$TUN" || true
sysctl -w net.ipv4.ip_forward=1 >/dev/null
iptables -t nat -N "$CHAIN" 2>/dev/null || true
iptables -t nat -F "$CHAIN"
iptables -t nat -A "$CHAIN" -s "$CLIENT_IP/32" -o "$EGRESS" -j MASQUERADE
iptables -t nat -C POSTROUTING -j "$CHAIN" 2>/dev/null || iptables -t nat -A POSTROUTING -j "$CHAIN"
iptables -C FORWARD -i "$TUN" -o "$EGRESS" -j ACCEPT 2>/dev/null || iptables -I FORWARD 1 -i "$TUN" -o "$EGRESS" -j ACCEPT
iptables -C FORWARD -i "$EGRESS" -o "$TUN" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || iptables -I FORWARD 1 -i "$EGRESS" -o "$TUN" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
echo "master_proxy_prepared tun=$TUN egress=$EGRESS client=$CLIENT_IP chain=$CHAIN"
iptables -t nat -L "$CHAIN" -v -n -x`;
}

function containerTunnelStartScript(plan: DevContainerPlan): string {
  return `set -euo pipefail
CONTAINER=${shellQuote(plan.containerName)}
docker exec -i "$CONTAINER" bash -s <<'INNER'
set -euo pipefail
mkdir -p /tmp/unidesk-tools
ln -sf /usr/local/bin/busybox /tmp/unidesk-tools/ip
ln -sf /usr/local/bin/busybox /tmp/unidesk-tools/ping
export PATH=/tmp/unidesk-tools:$PATH
MASTER=${shellQuote(plan.masterHost)}
TUN_ID=${shellQuote(String(plan.tunId))}
TUN=${shellQuote(plan.tunName)}
CLIENT_IP=${shellQuote(plan.clientIp)}
SERVER_IP=${shellQuote(plan.serverIp)}
EGRESS_CHAIN=${shellQuote(plan.egressFirewallChain)}
KNOWN_HOSTS=/tmp/unidesk-dev-proxy-known_hosts
cp /run/unidesk-dev-proxy/known_hosts "$KNOWN_HOSTS"
chmod 600 "$KNOWN_HOSTS"
MASTER_IP=$(getent ahostsv4 "$MASTER" 2>/dev/null | awk '{print $1; exit}' || true)
if [ -z "$MASTER_IP" ]; then MASTER_IP="$MASTER"; fi
case "$MASTER_IP" in
  *.*.*.*) ;;
  *) echo "cannot resolve IPv4 master host: $MASTER" >&2; exit 1 ;;
esac
DEFAULT_LINE=$(ip route show default | head -1)
DEFAULT_GW=$(printf '%s\\n' "$DEFAULT_LINE" | sed -n 's/^default via \\([^ ]*\\) dev \\([^ ]*\\).*/\\1/p')
DEFAULT_DEV=$(printf '%s\\n' "$DEFAULT_LINE" | sed -n 's/^default via \\([^ ]*\\) dev \\([^ ]*\\).*/\\2/p')
LINK_ROUTE=$(ip route show | awk '$2=="dev" && $3 !~ /^tun/ { print; exit }')
ORIG_DEV=$(printf '%s\\n' "$LINK_ROUTE" | awk '{print $3}')
if [ -n "$DEFAULT_GW" ] && [ -n "$DEFAULT_DEV" ] && [ "$DEFAULT_DEV" != "$TUN" ]; then
  ORIG_GW="$DEFAULT_GW"
  ORIG_DEV="$DEFAULT_DEV"
else
  ORIG_IP=$(ip addr show "$ORIG_DEV" | sed -n 's/.*inet \\([0-9.]*\\)\\/.*/\\1/p' | head -1)
  ORIG_GW=$(printf '%s\\n' "$ORIG_IP" | awk -F. 'NF==4 { printf "%s.%s.%s.1", $1, $2, $3 }')
fi
if [ -z "$ORIG_GW" ] || [ -z "$ORIG_DEV" ]; then echo "cannot detect docker bridge route: default=$DEFAULT_LINE link=$LINK_ROUTE" >&2; exit 1; fi
( ping -c 1 -W 3 google.com >/tmp/direct-ping.log 2>&1 && echo direct_ping=unexpected_ok ) || echo direct_ping=failed_expected
if ! command -v iptables >/dev/null 2>&1; then
  echo "iptables is required for sealed dev-container egress" >&2
  exit 1
fi
if command -v pkill >/dev/null 2>&1; then
  pkill -f "ssh .* -w $TUN_ID:$TUN_ID .*$MASTER" >/dev/null 2>&1 || true
elif command -v busybox >/dev/null 2>&1; then
  busybox ps | while read -r pid user command args; do
    case "$command $args" in
      *"ssh -f -N -w $TUN_ID:$TUN_ID"*|*"ssh -N -w $TUN_ID:$TUN_ID"*) kill "$pid" >/dev/null 2>&1 || true ;;
    esac
  done
fi
ip link delete "$TUN" >/dev/null 2>&1 || true
while iptables -w -D OUTPUT -j "$EGRESS_CHAIN" >/dev/null 2>&1; do :; done
if command -v ip6tables >/dev/null 2>&1; then
  while ip6tables -w -D OUTPUT -j "\${EGRESS_CHAIN}6" >/dev/null 2>&1; do :; done
fi
ip route replace "$MASTER_IP/32" via "$ORIG_GW" dev "$ORIG_DEV"
ip route replace default via "$ORIG_GW" dev "$ORIG_DEV"
SSH_LOG=/tmp/unidesk-dev-proxy-ssh.log
rm -f "$SSH_LOG"
if ! ssh -f -N -w $TUN_ID:$TUN_ID -o Tunnel=point-to-point -o ExitOnForwardFailure=yes -o ServerAliveInterval=15 -o ServerAliveCountMax=2 -o StrictHostKeyChecking=yes -o UserKnownHostsFile="$KNOWN_HOSTS" -i /run/unidesk-dev-proxy/id_ed25519 root@$MASTER 2>"$SSH_LOG"; then
  cat "$SSH_LOG" >&2 2>/dev/null || true
  exit 1
fi
for i in 1 2 3 4 5 6 7 8 9 10; do ip link show "$TUN" >/dev/null 2>&1 && break; sleep 1; done
if ! ip link show "$TUN" >/dev/null 2>&1; then
  echo "ssh tunnel did not create $TUN via $ORIG_GW/$ORIG_DEV" >&2
  cat "$SSH_LOG" >&2 2>/dev/null || true
  if command -v busybox >/dev/null 2>&1; then busybox ps >&2 || true; fi
  ip route show >&2 || true
  exit 1
fi
ip addr replace $CLIENT_IP peer $SERVER_IP dev "$TUN"
ip link set "$TUN" up
ip route replace default via $SERVER_IP dev "$TUN"
printf 'nameserver 8.8.8.8\\nnameserver 1.1.1.1\\noptions timeout:2 attempts:2\\n' > /etc/resolv.conf
iptables -w -N "$EGRESS_CHAIN" 2>/dev/null || true
iptables -w -F "$EGRESS_CHAIN"
iptables -w -A "$EGRESS_CHAIN" -o lo -j RETURN
iptables -w -A "$EGRESS_CHAIN" -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN
iptables -w -A "$EGRESS_CHAIN" -o "$TUN" -j RETURN
iptables -w -A "$EGRESS_CHAIN" -d "$MASTER_IP/32" -o "$ORIG_DEV" -p tcp --dport 22 -j RETURN
iptables -w -A "$EGRESS_CHAIN" -j REJECT --reject-with icmp-port-unreachable
iptables -w -I OUTPUT 1 -j "$EGRESS_CHAIN"
if command -v ip6tables >/dev/null 2>&1; then
  CHAIN6="\${EGRESS_CHAIN}6"
  ip6tables -w -N "$CHAIN6" 2>/dev/null || true
  ip6tables -w -F "$CHAIN6"
  ip6tables -w -A "$CHAIN6" -o lo -j RETURN
  ip6tables -w -A "$CHAIN6" -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN
  ip6tables -w -A "$CHAIN6" -d ::1/128 -j RETURN
  ip6tables -w -A "$CHAIN6" -d fc00::/7 -j RETURN
  ip6tables -w -A "$CHAIN6" -d fe80::/10 -j RETURN
  ip6tables -w -A "$CHAIN6" -j REJECT
  ip6tables -w -I OUTPUT 1 -j "$CHAIN6"
fi
cat > /tmp/unidesk-dev-egress.env <<EOF
EGRESS_CHAIN=$EGRESS_CHAIN
ORIG_DEV=$ORIG_DEV
TUN=$TUN
MASTER=$MASTER
MASTER_IP=$MASTER_IP
SERVER_IP=$SERVER_IP
EOF
echo "container_tunnel_ready orig=$ORIG_GW/$ORIG_DEV route_to_master=$(ip route get $MASTER_IP | head -1) default=$(ip route show default | head -1) dns=$(tr '\\n' ' ' </etc/resolv.conf)"
echo "sealed_egress_ready chain=$EGRESS_CHAIN allowed=tun:$TUN,master:$MASTER_IP:22/$ORIG_DEV"
iptables -S "$EGRESS_CHAIN"
INNER`;
}

function masterProxyFinishScript(plan: DevContainerPlan): string {
  return `set -euo pipefail
TUN=${shellQuote(plan.tunName)}
SERVER_IP=${shellQuote(plan.serverIp)}
CLIENT_IP=${shellQuote(plan.clientIp)}
CHAIN=${shellQuote(plan.natChain)}
for i in 1 2 3 4 5; do ip link show "$TUN" >/dev/null 2>&1 && break; sleep 1; done
ip addr replace $SERVER_IP peer $CLIENT_IP dev "$TUN"
ip link set "$TUN" up
echo "master_tunnel_ready $(ip addr show "$TUN" | tr '\\n' ' ')"
iptables -t nat -L "$CHAIN" -v -n -x`;
}

function masterProxyEvidenceScript(plan: DevContainerPlan): string {
  return `set -euo pipefail
CHAIN=${shellQuote(plan.natChain)}
TUN=${shellQuote(plan.tunName)}
iptables -t nat -L "$CHAIN" -v -n -x
ip -s link show "$TUN"`;
}

function devContainerPingScript(plan: DevContainerPlan): string {
  return `set -euo pipefail
CONTAINER=${shellQuote(plan.containerName)}
docker exec "$CONTAINER" bash -lc 'export PATH=/tmp/unidesk-tools:$PATH; source /tmp/unidesk-dev-egress.env 2>/dev/null || true; echo route=$(ip route show default | head -1); echo route_8_8_8_8=$(ip route get 8.8.8.8 | head -1); echo resolv=$(tr "\\n" " " </etc/resolv.conf); if [ -n "\${EGRESS_CHAIN:-}" ]; then iptables -S "$EGRESS_CHAIN"; fi; if [ -n "\${ORIG_DEV:-}" ]; then ( ping -I "$ORIG_DEV" -c 1 -W 3 8.8.8.8 >/tmp/sealed-direct-ping.log 2>&1 && echo sealed_direct_ping=unexpected_ok ) || echo sealed_direct_ping=blocked_expected; fi; ping -c 1 -W 5 google.com'`;
}

function windowsNativeBridgeServerSource(): string {
  return String.raw`#!/usr/bin/env python3
import argparse
import os
import socket
import subprocess
import sys
import threading
import time


def write_text(path, text):
    tmp = path + ".tmp"
    with open(tmp, "w", encoding="utf-8") as handle:
        handle.write(text)
    os.replace(tmp, path)


def main():
    parser = argparse.ArgumentParser(description="UniDesk Windows native Codex stdio bridge")
    parser.add_argument("--session", required=True)
    parser.add_argument("--cwd", required=True)
    parser.add_argument("--codex-command", required=True)
    parser.add_argument("--bind-host", default="0.0.0.0")
    parser.add_argument("--port", type=int, default=0)
    parser.add_argument("--port-file", required=True)
    parser.add_argument("--pid-file", required=True)
    parser.add_argument("--idle-timeout", type=float, default=600)
    parser.add_argument("--initial-connect-timeout", type=float, default=90)
    parser.add_argument("--stdout-log", required=True)
    parser.add_argument("--stderr-log", required=True)
    args = parser.parse_args()

    if not args.cwd.startswith("/mnt/"):
        raise SystemExit("windows-native Codex cwd must be under /mnt/<drive>")
    if not os.path.isdir(args.cwd):
        raise SystemExit("windows-native Codex cwd does not exist: " + args.cwd)

    env = os.environ.copy()
    home = os.path.expanduser("~")
    env["PATH"] = os.path.join(home, ".local", "bin") + os.pathsep + env.get("PATH", "")
    env["CODEX_INTERNAL_ORIGINATOR_OVERRIDE"] = "unidesk_code_queue_windows_native"
    bridge_env_keys = [
        "OPENAI_API_KEY",
        "CRS_OAI_KEY",
        "OPENAI_BASE_URL",
        "OPENAI_API_BASE",
        "MINIMAX_API_KEY",
        "MINIMAX_API_BASE",
        "MINIMAX_MODEL",
        "CODEX_INTERNAL_ORIGINATOR_OVERRIDE",
    ]
    existing_wsl_env = [item for item in env.get("WSLENV", "").split(":") if item]
    existing_wsl_names = {item.split("/", 1)[0] for item in existing_wsl_env}
    for key in bridge_env_keys:
        if key in env and key not in existing_wsl_names:
            existing_wsl_env.append(key)
    env["WSLENV"] = ":".join(existing_wsl_env)

    child = subprocess.Popen(
        ["win-cmd", args.codex_command],
        cwd=args.cwd,
        env=env,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        bufsize=0,
    )

    clients = set()
    lock = threading.Lock()
    last_empty_at = time.time()
    ever_connected = False
    stop_event = threading.Event()

    def log(message):
        print(message, file=sys.stderr, flush=True)

    def close_client(conn):
        try:
            conn.close()
        except OSError:
            pass
        with lock:
            clients.discard(conn)

    def broadcast(data):
        dead = []
        with lock:
            snapshot = list(clients)
        for conn in snapshot:
            try:
                conn.sendall(data)
            except OSError:
                dead.append(conn)
        for conn in dead:
            close_client(conn)

    def pump_stdout():
        with open(args.stdout_log, "ab", buffering=0) as log_file:
            while True:
                data = child.stdout.readline() if child.stdout is not None else b""
                if not data:
                    break
                log_file.write(data)
                broadcast(data)
        stop_event.set()
        with lock:
            snapshot = list(clients)
        for conn in snapshot:
            close_client(conn)

    def pump_stderr():
        with open(args.stderr_log, "ab", buffering=0) as log_file:
            while True:
                data = child.stderr.readline() if child.stderr is not None else b""
                if not data:
                    break
                log_file.write(data)

    threading.Thread(target=pump_stdout, daemon=True).start()
    threading.Thread(target=pump_stderr, daemon=True).start()

    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind((args.bind_host, args.port))
    server.listen(8)
    server.settimeout(1)
    port = server.getsockname()[1]
    os.makedirs(os.path.dirname(args.port_file), exist_ok=True)
    write_text(args.port_file, str(port))
    write_text(args.pid_file, str(os.getpid()))
    log("windows_native_codex_bridge_ready session=%s pid=%s port=%s child=%s cwd=%s" % (args.session, os.getpid(), port, child.pid, args.cwd))

    def handle_client(conn):
        nonlocal last_empty_at
        try:
            while True:
                data = conn.recv(65536)
                if not data:
                    break
                if child.stdin is not None:
                    child.stdin.write(data)
                    child.stdin.flush()
        except (BrokenPipeError, OSError):
            pass
        finally:
            close_client(conn)
            with lock:
                if len(clients) == 0:
                    last_empty_at = time.time()

    try:
        while not stop_event.is_set():
            if child.poll() is not None:
                break
            with lock:
                empty_for = time.time() - last_empty_at if len(clients) == 0 else 0
                no_client_yet = not ever_connected and len(clients) == 0
            if no_client_yet and empty_for >= args.initial_connect_timeout:
                log("windows_native_codex_bridge_initial_connect_timeout session=%s seconds=%.1f" % (args.session, empty_for))
                break
            if not no_client_yet and empty_for >= args.idle_timeout:
                log("windows_native_codex_bridge_idle_timeout session=%s seconds=%.1f" % (args.session, empty_for))
                break
            try:
                conn, _addr = server.accept()
            except socket.timeout:
                continue
            with lock:
                clients.add(conn)
                ever_connected = True
            threading.Thread(target=handle_client, args=(conn,), daemon=True).start()
    finally:
        try:
            server.close()
        except OSError:
            pass
        if child.poll() is None:
            child.terminate()
            try:
                child.wait(timeout=5)
            except subprocess.TimeoutExpired:
                child.kill()
        try:
            os.remove(args.port_file)
        except OSError:
            pass
        log("windows_native_codex_bridge_exit session=%s childExit=%s" % (args.session, child.poll()))


if __name__ == "__main__":
    main()
`;
}

function windowsNativeContainerClientSource(): string {
  return String.raw`const fs = require("node:fs");
const dns = require("node:dns");
const net = require("node:net");
const { spawnSync } = require("node:child_process");

const host = process.env.UNIDESK_WINDOWS_NATIVE_CODEX_HOST || "host.docker.internal";
const port = Number(process.env.UNIDESK_WINDOWS_NATIVE_CODEX_PORT);
const extraHosts = String(process.env.UNIDESK_WINDOWS_NATIVE_CODEX_EXTRA_HOSTS || "").split(/[,\s]+/u).filter(Boolean);
const connectDeadlineMs = Math.max(5000, Number(process.env.UNIDESK_WINDOWS_NATIVE_CODEX_CONNECT_TIMEOUT_MS || 60000));
if (!Number.isInteger(port) || port <= 0) throw new Error("UNIDESK_WINDOWS_NATIVE_CODEX_PORT is invalid");

function gatewayFromHex(value) {
  const bytes = value.match(/../g);
  return bytes ? bytes.reverse().map((item) => Number.parseInt(item, 16)).join(".") : "";
}

function routeGateways() {
  try {
    return fs.readFileSync("/proc/net/route", "utf8").trim().split(/\n/u).slice(1).flatMap((line) => {
      const parts = line.trim().split(/\s+/u);
      if (parts.length < 3 || parts[0].startsWith("tun") || parts[2] === "00000000") return [];
      const gateway = gatewayFromHex(parts[2]);
      return gateway.length > 0 ? [{ iface: parts[0], gateway }] : [];
    });
  } catch {
    return [];
  }
}

function lookup4(name) {
  return new Promise((resolve) => {
    dns.lookup(name, { family: 4, all: true }, (error, addresses) => {
      resolve(error ? [] : [...new Set(addresses.map((item) => item.address))]);
    });
  });
}

function ensureHostRoutes(ips) {
  const ipBin = fs.existsSync("/tmp/unidesk-tools/ip") ? "/tmp/unidesk-tools/ip" : "ip";
  for (const { iface, gateway } of routeGateways()) {
    for (const ip of ips) {
      spawnSync(ipBin, ["route", "replace", ip + "/32", "via", gateway, "dev", iface], { stdio: "ignore" });
    }
  }
}

function connectOnce(candidate) {
  return new Promise((resolve, reject) => {
    const socket = net.createConnection({ host: candidate, port });
    const timer = setTimeout(() => socket.destroy(new Error("connect timeout")), 2500);
    socket.once("connect", () => {
      clearTimeout(timer);
      resolve(socket);
    });
    socket.once("error", (error) => {
      clearTimeout(timer);
      reject(error);
    });
  });
}

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function connect() {
  const hostIps = await lookup4(host);
  ensureHostRoutes(hostIps);
  const candidates = [...new Set([...hostIps, host, ...extraHosts, ...routeGateways().map((item) => item.gateway), "172.17.0.1"].filter(Boolean))];
  const errors = [];
  const deadline = Date.now() + connectDeadlineMs;
  let attempt = 0;
  while (Date.now() < deadline) {
    attempt += 1;
    for (const candidate of candidates) {
      try {
        return await connectOnce(candidate);
      } catch (error) {
        errors.push(candidate + "=" + (error && error.message ? error.message : String(error)));
        while (errors.length > 24) errors.shift();
      }
    }
    await sleep(500);
  }
  throw new Error("could not connect to Windows native Codex bridge after " + attempt + " attempts in " + connectDeadlineMs + "ms: " + errors.join("; "));
}

(async () => {
  const socket = await connect();
  socket.setNoDelay(true);
  socket.on("data", (chunk) => {
    if (!process.stdout.write(chunk)) socket.pause();
  });
  process.stdout.on("drain", () => socket.resume());
  socket.on("end", () => process.exit(0));
  socket.on("close", () => process.exit(0));
  socket.on("error", (error) => {
    console.error(error && error.stack ? error.stack : String(error));
    process.exit(1);
  });
  process.stdin.on("data", (chunk) => {
    if (!socket.write(chunk)) process.stdin.pause();
  });
  socket.on("drain", () => process.stdin.resume());
  process.stdin.on("end", () => socket.end());
})().catch((error) => {
  console.error(error && error.stack ? error.stack : String(error));
  process.exit(1);
});`;
}

function windowsNativeBridgeInstallScript(): string {
  const bridgeBase64 = base64Text(windowsNativeBridgeServerSource());
  return `mkdir -p ${shellQuote(ctx().config.windowsNativeCodexBridgeDir)}
printf %s ${shellQuote(bridgeBase64)} | base64 -d > ${shellQuote(resolve(ctx().config.windowsNativeCodexBridgeDir, "bridge.py"))}
chmod 700 ${shellQuote(resolve(ctx().config.windowsNativeCodexBridgeDir, "bridge.py"))}`;
}

function hwpodWrapperSource(): string {
  const candidates = [
    "/usr/local/bin/hwpod",
    resolve(ctx().config.defaultWorkdir, "scripts/hwpod"),
    "/app/scripts/hwpod",
    "/root/unidesk/scripts/hwpod",
    resolve(process.cwd(), "scripts/hwpod"),
  ];
  const path = candidates.find((candidate) => existsSync(candidate));
  if (path === undefined) throw new Error(`hwpod wrapper source not found in ${candidates.join(", ")}`);
  return readFileSync(path, "utf8");
}

function remoteCodexRuntimePrepareScript(plan: DevContainerPlan): string {
  const hwpodWrapper = base64Text(hwpodWrapperSource());
  return `set -euo pipefail
CONTAINER=${shellQuote(plan.containerName)}
docker exec -i "$CONTAINER" bash -s <<'INNER'
set -euo pipefail
WORKDIR=${shellQuote(plan.containerWorkdir)}
CODEX_HOME_DIR=${shellQuote(plan.remoteCodexHome)}
OPENCODE_XDG_DIR=${shellQuote(plan.remoteOpencodeXdgDir)}
export PATH=/tmp/unidesk-tools:$PATH
if command -v apt-get >/dev/null 2>&1; then
  missing=""
  for c in git gh rg curl python3 pip3 jq rsync patch make gcc g++ tar gzip unzip; do command -v "$c" >/dev/null 2>&1 || missing="$missing $c"; done
  if [ -n "$missing" ]; then
    export DEBIAN_FRONTEND=noninteractive
    apt-get update
    packages="git ripgrep curl python3 python3-pip jq rsync patch make gcc g++ tar gzip unzip ca-certificates"
    if echo "$missing" | grep -qw gh; then
      if apt-cache show gh >/dev/null 2>&1; then
        packages="$packages gh"
      else
        echo "warning: apt package gh is unavailable in this container base image" >&2
      fi
    fi
    apt-get install -y --no-install-recommends $packages
    rm -rf /var/lib/apt/lists/*
  fi
fi
if ! command -v codex >/dev/null 2>&1; then
  npm install -g --no-audit --no-fund --prefer-offline @openai/codex@0.128.0
fi
if ! command -v opencode >/dev/null 2>&1; then
  npm install -g --no-audit --no-fund --prefer-offline ${opencodeNpmPackage}
fi
printf %s ${shellQuote(hwpodWrapper)} | base64 -d > /usr/local/bin/hwpod
chmod 755 /usr/local/bin/hwpod
mkdir -p "$WORKDIR" "$CODEX_HOME_DIR" "$OPENCODE_XDG_DIR/data" "$OPENCODE_XDG_DIR/config" "$OPENCODE_XDG_DIR/cache" "$OPENCODE_XDG_DIR/state"
echo "code_agent_runtime_ready codex=$(command -v codex) opencode=$(command -v opencode) hwpod=$(command -v hwpod) cwd=$WORKDIR home=$CODEX_HOME_DIR opencodeXdg=$OPENCODE_XDG_DIR"
INNER`;
}

function remoteAppServerCommand(task: QueueTask): string {
  const plan = buildDevContainerPlan(task.providerId, { workdir: remoteHostWorkdirForTask(task) });
  const gitConfigEntries = codeAgentGitConfigEntries("");
  const gitConfigExports = [
    ...gitConfigEntries.map(([key, value], index) => `export GIT_CONFIG_KEY_$((\${GIT_CONFIG_COUNT:-0}+${index}))=${shellQuote(key)} GIT_CONFIG_VALUE_$((\${GIT_CONFIG_COUNT:-0}+${index}))=${shellQuote(value)}`),
    `export GIT_CONFIG_COUNT=$((\${GIT_CONFIG_COUNT:-0}+${gitConfigEntries.length}))`,
  ].join("; ");
  const inner = [
    "set -euo pipefail",
    `mkdir -p ${shellQuote(task.cwd)}`,
    `cd ${shellQuote(task.cwd)}`,
    `export CODEX_HOME=${shellQuote(plan.remoteCodexHome)}`,
    "export CODEX_INTERNAL_ORIGINATOR_OVERRIDE=unidesk_code_queue",
    `export UNIDESK_SKILLS_PATH=${shellQuote(ctx().config.skillsPath)}`,
    gitConfigExports,
    "exec codex app-server --listen stdio://",
  ].join("; ");
  return `docker exec -i ${shellQuote(plan.containerName)} bash -lc ${shellQuote(inner)}`;
}

function windowsNativeSessionName(task: QueueTask): string {
  return safeDockerName(`${task.id}-attempt-${task.currentAttempt || 0}`).slice(0, 120);
}

function windowsNativeAppServerCommand(task: QueueTask): string {
  const plan = buildDevContainerPlan(task.providerId, { workdir: remoteHostWorkdirForTask(task) });
  const session = windowsNativeSessionName(task);
  const sessionDir = resolve(ctx().config.windowsNativeCodexBridgeDir, "sessions", session);
  const portFile = resolve(sessionDir, "port");
  const pidFile = resolve(sessionDir, "pid");
  const stdoutLog = resolve(sessionDir, "codex.stdout.jsonl");
  const stderrLog = resolve(sessionDir, "codex.stderr.log");
  const serverLog = resolve(sessionDir, "bridge.log");
  const bridgePy = resolve(ctx().config.windowsNativeCodexBridgeDir, "bridge.py");
  const clientSource = windowsNativeContainerClientSource();
  const install = windowsNativeBridgeInstallScript();
  const idleSeconds = Math.max(30, Math.floor(ctx().config.windowsNativeCodexIdleTimeoutMs / 1000));
  const initialConnectSeconds = Math.max(45, Math.min(120, idleSeconds));
  return [
    "set -euo pipefail",
    `export PATH="$HOME/.local/bin:$PATH"`,
    `CWD=${shellQuote(task.cwd)}`,
    `case "$CWD" in /mnt/*) ;; *) echo "windows-native executionMode requires cwd under /mnt/<drive>, got $CWD" >&2; exit 64 ;; esac`,
    `test -d "$CWD" || { echo "windows-native cwd does not exist: $CWD" >&2; exit 64; }`,
    install,
    `SESSION_DIR=${shellQuote(sessionDir)}`,
    `PORT_FILE=${shellQuote(portFile)}`,
    `PID_FILE=${shellQuote(pidFile)}`,
    `KEY_DIR=${shellQuote(plan.keyDir)}`,
    `[ ! -r "$KEY_DIR/codex-env" ] || { set -a; . "$KEY_DIR/codex-env"; set +a; }`,
    `mkdir -p "$SESSION_DIR"`,
    `if [ -s "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" >/dev/null 2>&1 && [ -s "$PORT_FILE" ]; then :; else rm -f "$PORT_FILE" "$PID_FILE"; nohup python3 ${shellQuote(bridgePy)} --session ${shellQuote(session)} --cwd "$CWD" --codex-command ${shellQuote(ctx().config.windowsNativeCodexCommand)} --bind-host 0.0.0.0 --port 0 --port-file "$PORT_FILE" --pid-file "$PID_FILE" --idle-timeout ${shellQuote(String(idleSeconds))} --initial-connect-timeout ${shellQuote(String(initialConnectSeconds))} --stdout-log ${shellQuote(stdoutLog)} --stderr-log ${shellQuote(stderrLog)} > ${shellQuote(serverLog)} 2>&1 & fi`,
    `for i in $(seq 1 120); do [ -s "$PORT_FILE" ] && break; sleep 0.25; done`,
    `if [ ! -s "$PORT_FILE" ]; then echo "windows-native Codex bridge did not become ready; log follows:" >&2; tail -80 ${shellQuote(serverLog)} >&2 2>/dev/null || true; exit 65; fi`,
    `PORT=$(cat "$PORT_FILE")`,
    `WSL_HOSTS=$(hostname -I 2>/dev/null | tr ' ' ',' | sed 's/,,*/,/g; s/^,//; s/,$//')`,
    `echo "windows_native_codex_stdio provider=${task.providerId} session=${session} container=${plan.containerName} port=$PORT cwd=$CWD" >&2`,
    `CLIENT_SOURCE=${shellQuote(clientSource)}`,
    `CLIENT_CMD='if command -v node >/dev/null 2>&1; then exec node -e "$UNIDESK_WINDOWS_NATIVE_CODEX_CLIENT_SOURCE"; fi; if command -v bun >/dev/null 2>&1; then exec bun -e "$UNIDESK_WINDOWS_NATIVE_CODEX_CLIENT_SOURCE"; fi; echo "windows-native relay container requires node or bun" >&2; exit 127'`,
    `docker exec -i -e UNIDESK_WINDOWS_NATIVE_CODEX_HOST=${shellQuote(ctx().config.windowsNativeCodexConnectHost)} -e UNIDESK_WINDOWS_NATIVE_CODEX_PORT="$PORT" -e UNIDESK_WINDOWS_NATIVE_CODEX_EXTRA_HOSTS="$WSL_HOSTS" -e UNIDESK_WINDOWS_NATIVE_CODEX_CONNECT_TIMEOUT_MS=60000 -e UNIDESK_WINDOWS_NATIVE_CODEX_CLIENT_SOURCE="$CLIENT_SOURCE" ${shellQuote(plan.containerName)} bash -lc "$CLIENT_CMD"`,
  ].join("; ");
}


export {
  buildDevContainerPlan,
  containerTunnelStartScript,
  defaultWorkdirForProvider,
  devContainerPingScript,
  executionModeOptions,
  executionProviderOptions,
  masterKeyReadScript,
  masterKeySetupScript,
  masterProxyEvidenceScript,
  masterProxyFinishScript,
  masterProxyPrepareScript,
  normalizeProviderId,
  normalizeTaskProviderId,
  providerIsMain,
  remoteAppServerCommand,
  remoteCodexConfigInstallScript,
  remoteCodexRuntimePrepareScript,
  remoteContainerStartScript,
  remoteHostWorkdirForTask,
  remoteKeyInstallScript,
  resolveTaskCwd,
  runCodeQueueSsh,
  shellQuote,
  throwIfCommandFailed,
  windowsNativeAppServerCommand,
};

export const providerRuntimeForTest = {
  remoteContainerStartScript,
  remoteAppServerCommand,
};
