#!/usr/bin/env node
import {
  DEFAULT_BOX_IMAGE_REF,
  daytonaBackend,
  ensureDaytonaCredentials,
  ensureDaytonaEnvLoaded,
  getClient,
  resolveDaytonaCustomClaudeMd,
  resolveDockerfileContext
} from "./chunk-ZGVMN54V.js";
import {
  createCloudProvider
} from "./chunk-MXXXKJYS.js";
import {
  stageClaudeStaticForUpload,
  stageCodexStaticForUpload,
  stageOpencodeStaticForUpload
} from "./chunk-ZJXTIH6C.js";
import {
  DOCKER_CONTEXT_FILE_MAP,
  computeContextSha256,
  readCliStamp,
  readPreparedStateRaw,
  resolveContextFilesFrom,
  writePreparedStateRaw
} from "./chunk-SNTHHWKY.js";
import "./chunk-G3H2L3O2.js";

// ../../packages/sandbox-daytona/dist/index.js
import { Image } from "@daytonaio/sdk";
import { existsSync } from "fs";
import { dirname, resolve } from "path";
import { fileURLToPath } from "url";
var SCHEMA = 1;
function resolveDaytonaContextFiles() {
  const ctx = resolveDockerfileContext();
  if (!ctx) return null;
  const here = dirname(fileURLToPath(import.meta.url));
  const packageRoot = resolve(here, "..");
  const monorepoRoot = resolve(here, "..", "..", "..");
  const dockerPackageRoot = resolve(monorepoRoot, "packages", "sandbox-docker");
  const docker = resolveContextFilesFrom(DOCKER_CONTEXT_FILE_MAP, {
    contextDir: ctx.context,
    devRoot: existsSync(dockerPackageRoot) ? dockerPackageRoot : packageRoot
  });
  if (!docker) return null;
  const overlay = resolveDaytonaCustomClaudeMd();
  if (!overlay) return null;
  return [
    ...docker,
    // Daytona-specific overlay: separate logical name so a docker/daytona
    // CLAUDE.md drift produces different fingerprints (the daytona snapshot
    // contains both files in distinct locations).
    { rel: "daytona/custom-system-CLAUDE.md", abs: overlay }
  ];
}
async function computeDaytonaContextFingerprint() {
  const files = resolveDaytonaContextFiles();
  if (!files) return null;
  return { contextSha256: await computeContextSha256(files), files };
}
function readPreparedDaytonaState() {
  const raw = readPreparedStateRaw("daytona");
  if (raw === null || typeof raw !== "object") return null;
  const parsed = raw;
  if (parsed.schema !== SCHEMA) return null;
  return { schema: SCHEMA, base: parsed.base };
}
function writePreparedDaytonaState(opts) {
  const stamp = readCliStamp();
  const state = {
    schema: SCHEMA,
    base: {
      imageRef: opts.snapshotName,
      contextSha256: opts.contextSha256,
      cliVersion: stamp.cliVersion,
      cliCommit: stamp.cliCommit,
      createdAt: (/* @__PURE__ */ new Date()).toISOString()
    }
  };
  writePreparedStateRaw("daytona", state);
}
function preparedMatches(state, current) {
  return state?.base?.contextSha256 === current;
}
function defaultSnapshotName(fingerprint) {
  if (fingerprint) return `agentbox-base-${fingerprint.slice(0, 12)}`;
  return `agentbox-base-${Math.floor(Date.now() / 1e3).toString()}`;
}
async function stageAllAgentStatic(opts) {
  const [claudeStaged, codexStaged, opencodeStaged] = await Promise.all([
    stageClaudeStaticForUpload({ hostWorkspace: opts.hostWorkspace }),
    stageCodexStaticForUpload(),
    stageOpencodeStaticForUpload()
  ]);
  return [
    {
      kind: "claude",
      remoteTar: "/tmp/agentbox-seed-claude.tar.gz",
      extractDir: "/home/vscode/.claude",
      staged: claudeStaged
    },
    {
      kind: "codex",
      remoteTar: "/tmp/agentbox-seed-codex.tar.gz",
      extractDir: "/home/vscode/.codex",
      staged: codexStaged
    },
    {
      kind: "opencode",
      remoteTar: "/tmp/agentbox-seed-opencode.tar.gz",
      extractDir: "/home/vscode/.local/share/opencode",
      staged: opencodeStaged
    }
  ];
}
async function prepareDaytona(opts) {
  ensureDaytonaEnvLoaded();
  const log = opts.onLog ?? (() => {
  });
  const fingerprint = await computeDaytonaContextFingerprint();
  const snapshotName = opts.name ?? defaultSnapshotName(fingerprint?.contextSha256 ?? null);
  const prepared = readPreparedDaytonaState();
  if (!opts.force && fingerprint && preparedMatches(prepared, fingerprint.contextSha256)) {
    try {
      const existing = await getClient().snapshot.get(
        prepared?.base?.imageRef ?? snapshotName
      );
      if (existing?.name) {
        log(
          `daytona snapshot '${existing.name}' up to date (fingerprint ${fingerprint.contextSha256.slice(0, 12)}) \u2014 skipping rebuild (pass --force to override)`
        );
        return { snapshotName: existing.name };
      }
      log(
        `recorded snapshot '${prepared?.base?.imageRef ?? snapshotName}' not found on Daytona; rebuilding`
      );
    } catch {
      log(
        `recorded snapshot lookup failed; rebuilding (pass --force to silence)`
      );
    }
  } else if (!opts.force && fingerprint && prepared?.base?.contextSha256) {
    log(
      `daytona build context changed (was ${prepared.base.contextSha256.slice(0, 12)}, now ${fingerprint.contextSha256.slice(0, 12)}); rebuilding snapshot`
    );
  }
  const ctx = resolveDockerfileContext();
  if (!ctx) {
    throw new Error(
      "could not locate AgentBox Dockerfile.box build context for the Daytona snapshot. Set AGENTBOX_DOCKER_CONTEXT to the directory containing Dockerfile.box."
    );
  }
  const daytonaClaudeMd = resolveDaytonaCustomClaudeMd();
  if (!daytonaClaudeMd) {
    throw new Error(
      "could not locate packages/sandbox-daytona/scripts/custom-system-CLAUDE.md (or its staged runtime/daytona/ copy). Ensure `pnpm -w build` ran so the CLI staging populated runtime/daytona/."
    );
  }
  const stages = await stageAllAgentStatic({ hostWorkspace: opts.hostWorkspace });
  for (const s of stages) {
    for (const w of s.staged.warnings) log(w);
  }
  try {
    let image = Image.fromDockerfile(ctx.dockerfile);
    image = image.addLocalFile(daytonaClaudeMd, "/tmp/agentbox-custom-CLAUDE.md");
    const extractCmds = [
      "install -m 0644 /tmp/agentbox-custom-CLAUDE.md /etc/claude-code/CLAUDE.md",
      "rm -f /tmp/agentbox-custom-CLAUDE.md"
    ];
    const usable = stages.filter((s) => s.staged.tarballPath !== null);
    for (const s of usable) {
      image = image.addLocalFile(s.staged.tarballPath, s.remoteTar);
      extractCmds.push(`mkdir -p ${s.extractDir}`);
      extractCmds.push(`tar -xzf ${s.remoteTar} -C ${s.extractDir}`);
    }
    if (usable.length > 0) {
      extractCmds.push(
        "chown -R vscode:vscode /home/vscode/.claude /home/vscode/.codex /home/vscode/.local"
      );
      extractCmds.push("rm -f /tmp/agentbox-seed-*.tar.gz");
    }
    image = image.dockerfileCommands(["USER root"]).runCommands(...extractCmds).dockerfileCommands(["USER vscode"]);
    const client = getClient();
    log(`creating Daytona snapshot '${snapshotName}'\u2026`);
    const snapshot = await client.snapshot.create(
      { name: snapshotName, image },
      {
        onLogs: (chunk) => log(String(chunk).split("\n").filter(Boolean).join(" "))
      }
    );
    log(`snapshot '${snapshot.name}' is ${snapshot.state ?? "created"}`);
    if (fingerprint) {
      writePreparedDaytonaState({
        snapshotName: snapshot.name ?? snapshotName,
        contextSha256: fingerprint.contextSha256
      });
      log(
        `recorded daytona-prepared.json (fingerprint ${fingerprint.contextSha256.slice(0, 12)})`
      );
    }
    return { snapshotName: snapshot.name ?? snapshotName };
  } finally {
    await Promise.all(stages.map((s) => s.staged.cleanup()));
  }
}
function isAgentboxName(name) {
  return typeof name === "string" && name.toLowerCase().startsWith("agentbox");
}
async function getDaytonaStatus() {
  try {
    ensureDaytonaEnvLoaded();
  } catch (err) {
    return {
      configured: false,
      snapshots: [],
      volumes: [],
      reason: err instanceof Error ? err.message : String(err)
    };
  }
  let client;
  try {
    client = getClient();
  } catch (err) {
    return {
      configured: false,
      snapshots: [],
      volumes: [],
      reason: err instanceof Error ? err.message.split("\n")[0] : String(err)
    };
  }
  const snapshots = [];
  const volumes = [];
  let reason;
  try {
    const list = await client.snapshot.list();
    const items = list.items ?? (Array.isArray(list) ? list : []);
    for (const s of items) {
      const dto = s;
      if (!isAgentboxName(dto.name)) continue;
      snapshots.push({
        name: dto.name,
        state: typeof dto.state === "string" ? dto.state : void 0,
        sizeGb: typeof dto.size === "number" ? dto.size : void 0,
        createdAt: typeof dto.createdAt === "string" ? dto.createdAt : void 0,
        errorReason: typeof dto.errorReason === "string" ? dto.errorReason : void 0
      });
    }
  } catch (err) {
    reason = `snapshot list failed: ${err instanceof Error ? err.message.split("\n")[0] : String(err)}`;
  }
  try {
    const list = await client.volume.list();
    const items = Array.isArray(list) ? list : list.items ?? [];
    for (const v of items) {
      const dto = v;
      if (!isAgentboxName(dto.name)) continue;
      volumes.push({
        name: dto.name,
        id: typeof dto.id === "string" ? dto.id : "",
        state: typeof dto.state === "string" ? dto.state : void 0,
        createdAt: typeof dto.createdAt === "string" ? dto.createdAt : void 0,
        lastUsedAt: typeof dto.lastUsedAt === "string" ? dto.lastUsedAt : void 0
      });
    }
  } catch (err) {
    const msg = `volume list failed: ${err instanceof Error ? err.message.split("\n")[0] : String(err)}`;
    reason = reason ? `${reason}; ${msg}` : msg;
  }
  return {
    configured: true,
    snapshots: snapshots.sort((a, b) => (b.createdAt ?? "").localeCompare(a.createdAt ?? "")),
    volumes: volumes.sort((a, b) => a.name.localeCompare(b.name)),
    reason
  };
}
var cloudProvider = createCloudProvider(daytonaBackend, {
  defaultResources: { cpu: 2, memory: 4, disk: 8 }
});
var daytonaProvider = {
  ...cloudProvider,
  prepare: prepareDaytona
};
export {
  DEFAULT_BOX_IMAGE_REF,
  daytonaBackend,
  daytonaProvider,
  ensureDaytonaCredentials,
  ensureDaytonaEnvLoaded,
  getDaytonaStatus,
  resolveDockerfileContext
};
//# sourceMappingURL=dist-PTJ6CEQY.js.map