// src/console/state.ts
import { promises as fs, createReadStream } from "fs";
import { createInterface } from "readline";
import path from "path";
var MAX_LEDGER_TAIL = 50;
var MAX_VERDICT_TAIL = 25;
var MAX_DEDUP_TAIL = 10;
async function gatherConsoleState(orchestrator) {
  const errors = [];
  const capturedAt = (/* @__PURE__ */ new Date()).toISOString();
  const bufferState = readBufferState(orchestrator, errors);
  const extractionQueue = readExtractionQueue(orchestrator, errors);
  const dedupRecent = readDedupRecent(orchestrator, errors);
  const maintenanceLedgerTail = await readMaintenanceLedgerTail(
    orchestrator,
    errors
  );
  const qmdProbe = readQmdProbe(orchestrator, errors);
  const daemon = readDaemonInfo(orchestrator, errors);
  return {
    capturedAt,
    bufferState,
    extractionQueue,
    dedupRecent,
    maintenanceLedgerTail,
    qmdProbe,
    daemon,
    errors
  };
}
function readBufferState(orchestrator, errors) {
  try {
    const getTurns = orchestrator.buffer?.getTurns;
    if (typeof getTurns !== "function") {
      return { turnsCount: 0, byteCount: 0 };
    }
    const turns = getTurns.call(orchestrator.buffer) ?? [];
    let byteCount = 0;
    for (const turn of turns) {
      const content = typeof turn?.content === "string" ? turn.content : "";
      byteCount += Buffer.byteLength(content, "utf8");
    }
    return { turnsCount: turns.length, byteCount };
  } catch (err) {
    errors.push(`bufferState: ${describeError(err)}`);
    return { turnsCount: 0, byteCount: 0 };
  }
}
function readExtractionQueue(orchestrator, errors) {
  try {
    const depth = typeof orchestrator.getConsoleExtractionQueueDepth === "function" ? orchestrator.getConsoleExtractionQueueDepth() : 0;
    const verdicts = typeof orchestrator.getConsoleExtractionRecentVerdicts === "function" ? orchestrator.getConsoleExtractionRecentVerdicts() : [];
    const recentVerdicts = (verdicts ?? []).slice(-MAX_VERDICT_TAIL).map((v) => ({
      ts: typeof v?.ts === "string" ? v.ts : "",
      kind: typeof v?.kind === "string" ? v.kind : "unknown",
      ...typeof v?.reason === "string" ? { reason: v.reason } : {}
    }));
    return { depth: Number.isFinite(depth) ? depth : 0, recentVerdicts };
  } catch (err) {
    errors.push(`extractionQueue: ${describeError(err)}`);
    return { depth: 0, recentVerdicts: [] };
  }
}
function readDedupRecent(orchestrator, errors) {
  try {
    if (typeof orchestrator.getConsoleDedupRecentDecisions !== "function") return [];
    const raw = orchestrator.getConsoleDedupRecentDecisions() ?? [];
    return raw.slice(-MAX_DEDUP_TAIL).map((d) => ({
      ts: typeof d?.ts === "string" ? d.ts : "",
      decision: typeof d?.decision === "string" ? d.decision : "unknown",
      ...typeof d?.fingerprint === "string" ? { fingerprint: d.fingerprint } : {},
      ...typeof d?.similarity === "number" && Number.isFinite(d.similarity) ? { similarity: d.similarity } : {}
    }));
  } catch (err) {
    errors.push(`dedupRecent: ${describeError(err)}`);
    return [];
  }
}
async function streamLedgerTopN(ledgerPath, topN, project) {
  let stream;
  try {
    await fs.stat(ledgerPath);
  } catch (err) {
    const code = err.code;
    if (code === "ENOENT") return [];
    throw err;
  }
  try {
    stream = createReadStream(ledgerPath, { encoding: "utf-8" });
  } catch (err) {
    const code = err.code;
    if (code === "ENOENT") return [];
    throw err;
  }
  const rl = createInterface({ input: stream, crlfDelay: Infinity });
  const cap = Math.max(1, topN) * 2;
  const buf = [];
  const truncate = () => {
    buf.sort((a, b) => {
      const aMs = Date.parse(a.ts);
      const bMs = Date.parse(b.ts);
      if (Number.isFinite(aMs) && Number.isFinite(bMs)) return bMs - aMs;
      if (Number.isFinite(aMs)) return -1;
      if (Number.isFinite(bMs)) return 1;
      return 0;
    });
    if (buf.length > topN) buf.length = topN;
  };
  try {
    for await (const line of rl) {
      const trimmed = line.trim();
      if (!trimmed) continue;
      let parsed;
      try {
        parsed = JSON.parse(trimmed);
      } catch {
        continue;
      }
      if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
        continue;
      }
      const event = project(parsed);
      if (event === null) continue;
      if (!event.ts || !Number.isFinite(Date.parse(event.ts))) continue;
      buf.push(event);
      if (buf.length >= cap) truncate();
    }
  } finally {
    rl.close();
    stream.close();
  }
  truncate();
  return buf.reverse();
}
function projectLedgerRow(p) {
  const ts = typeof p.ts === "string" && p.ts.length > 0 ? p.ts : typeof p.hour === "string" && p.hour.length > 0 ? p.hour : typeof p.rebuiltAt === "string" && p.rebuiltAt.length > 0 ? p.rebuiltAt : "";
  const category = typeof p.category === "string" && p.category.length > 0 ? p.category : typeof p.verdictKind === "string" ? "judge-verdict" : typeof p.turnCount === "number" ? "observation" : "unknown";
  const summary = summarizeLedgerEvent(p);
  return { ts, category, summary };
}
async function readMaintenanceLedgerTail(orchestrator, errors) {
  try {
    const memoryDir = orchestrator.config?.memoryDir;
    if (!memoryDir || typeof memoryDir !== "string") return [];
    const ledgerDir = path.join(memoryDir, "state", "observation-ledger");
    const verdictsTopN = await streamLedgerTopN(
      path.join(ledgerDir, "extraction-judge-verdicts.jsonl"),
      MAX_LEDGER_TAIL,
      projectLedgerRow
    );
    const rebuiltTopN = await streamLedgerTopN(
      path.join(ledgerDir, "rebuilt-observations.jsonl"),
      MAX_LEDGER_TAIL,
      projectLedgerRow
    );
    const events = [...verdictsTopN, ...rebuiltTopN];
    if (events.length === 0) return [];
    events.sort((a, b) => {
      const aMs = Date.parse(a.ts);
      const bMs = Date.parse(b.ts);
      if (Number.isFinite(aMs) && Number.isFinite(bMs)) return bMs - aMs;
      if (Number.isFinite(aMs)) return -1;
      if (Number.isFinite(bMs)) return 1;
      return 0;
    });
    const tail = events.slice(0, MAX_LEDGER_TAIL);
    return tail.reverse();
  } catch (err) {
    errors.push(`maintenanceLedgerTail: ${describeError(err)}`);
    return [];
  }
}
function summarizeLedgerEvent(p) {
  const parts = [];
  if (typeof p.verdictKind === "string") parts.push(`verdict=${p.verdictKind}`);
  if (typeof p.reason === "string" && p.reason.length > 0) {
    const trimmed = p.reason.length > 80 ? `${p.reason.slice(0, 80)}\u2026` : p.reason;
    parts.push(`reason=${trimmed}`);
  }
  if (typeof p.candidateCategory === "string") {
    parts.push(`cat=${p.candidateCategory}`);
  }
  if (typeof p.sessionKey === "string" && p.sessionKey.length > 0) {
    parts.push(`session=${p.sessionKey}`);
  }
  if (typeof p.turnCount === "number" && Number.isFinite(p.turnCount)) {
    parts.push(`turns=${p.turnCount}`);
  }
  if (typeof p.userTurns === "number" && Number.isFinite(p.userTurns)) {
    parts.push(`u=${p.userTurns}`);
  }
  if (typeof p.assistantTurns === "number" && Number.isFinite(p.assistantTurns)) {
    parts.push(`a=${p.assistantTurns}`);
  }
  if (parts.length === 0) {
    return typeof p.category === "string" ? p.category : "event";
  }
  return parts.join(" ");
}
function readQmdProbe(orchestrator, errors) {
  try {
    const qmd = orchestrator.qmd;
    if (!qmd) {
      return { available: false, daemonMode: false, debug: "qmd unavailable" };
    }
    const available = typeof qmd.isAvailable === "function" ? qmd.isAvailable() : false;
    const daemonMode = typeof qmd.isDaemonMode === "function" ? qmd.isDaemonMode() : false;
    const debug = typeof qmd.debugStatus === "function" ? qmd.debugStatus() : "";
    return { available, daemonMode, debug };
  } catch (err) {
    errors.push(`qmdProbe: ${describeError(err)}`);
    return { available: false, daemonMode: false, debug: "" };
  }
}
function readDaemonInfo(orchestrator, errors) {
  try {
    if (typeof orchestrator.getConsoleDaemonInfo === "function") {
      const info = orchestrator.getConsoleDaemonInfo();
      return {
        uptimeMs: Number.isFinite(info?.uptimeMs) ? info.uptimeMs : 0,
        version: typeof info?.version === "string" ? info.version : "unknown"
      };
    }
    const uptimeMs = Math.round((process.uptime?.() ?? 0) * 1e3);
    return { uptimeMs, version: resolvePackageVersion() };
  } catch (err) {
    errors.push(`daemon: ${describeError(err)}`);
    return { uptimeMs: 0, version: "unknown" };
  }
}
function resolvePackageVersion() {
  try {
    const env = process.env?.REMNIC_VERSION;
    if (typeof env === "string" && env.length > 0) return env;
  } catch {
  }
  return "unknown";
}
function describeError(err) {
  if (err instanceof Error) return err.message;
  try {
    return String(err);
  } catch {
    return "unknown error";
  }
}

export {
  gatherConsoleState
};
//# sourceMappingURL=chunk-TYEOAFH3.js.map