// src/identity-continuity.ts
function parseFrontmatterValue(raw) {
  try {
    return JSON.parse(raw);
  } catch {
    return raw;
  }
}
function parseFrontmatter(raw) {
  const parsed = {};
  for (const line of raw.split("\n")) {
    const idx = line.indexOf(":");
    if (idx <= 0) continue;
    const key = line.slice(0, idx).trim();
    const value = line.slice(idx + 1).trim();
    parsed[key] = parseFrontmatterValue(value);
  }
  return parsed;
}
function emitSection(lines, title, value) {
  if (!value || value.trim().length === 0) return;
  lines.push(`## ${title}`, "", value.trim(), "");
}
function parseSection(body, title) {
  const escaped = title.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
  const re = new RegExp(`## ${escaped}\\n\\n([\\s\\S]*?)(?=\\n## |$)`);
  const match = body.match(re);
  if (!match) return void 0;
  const value = match[1].trim();
  return value.length > 0 ? value : void 0;
}
function serializeContinuityIncident(incident) {
  const lines = [
    "---",
    `id: ${JSON.stringify(incident.id)}`,
    `state: ${JSON.stringify(incident.state)}`,
    `openedAt: ${JSON.stringify(incident.openedAt)}`,
    `updatedAt: ${JSON.stringify(incident.updatedAt)}`
  ];
  if (incident.closedAt) lines.push(`closedAt: ${JSON.stringify(incident.closedAt)}`);
  if (incident.triggerWindow) lines.push(`triggerWindow: ${JSON.stringify(incident.triggerWindow)}`);
  lines.push("---", "");
  emitSection(lines, "Symptom", incident.symptom);
  emitSection(lines, "Suspected Cause", incident.suspectedCause);
  emitSection(lines, "Fix Applied", incident.fixApplied);
  emitSection(lines, "Verification Result", incident.verificationResult);
  emitSection(lines, "Preventive Rule", incident.preventiveRule);
  return lines.join("\n").trimEnd() + "\n";
}
function parseContinuityIncident(raw) {
  const match = raw.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
  if (!match) return null;
  const frontmatter = parseFrontmatter(match[1]);
  const body = match[2] ?? "";
  const id = typeof frontmatter.id === "string" ? frontmatter.id : "";
  const stateRaw = frontmatter.state;
  const state = stateRaw === "closed" ? "closed" : "open";
  const openedAt = typeof frontmatter.openedAt === "string" ? frontmatter.openedAt : "";
  const updatedAt = typeof frontmatter.updatedAt === "string" ? frontmatter.updatedAt : openedAt;
  const symptom = parseSection(body, "Symptom");
  if (!id || !openedAt || !updatedAt || !symptom) return null;
  return {
    id,
    state,
    openedAt,
    updatedAt,
    triggerWindow: typeof frontmatter.triggerWindow === "string" ? frontmatter.triggerWindow : void 0,
    symptom,
    suspectedCause: parseSection(body, "Suspected Cause"),
    fixApplied: parseSection(body, "Fix Applied"),
    verificationResult: parseSection(body, "Verification Result"),
    preventiveRule: parseSection(body, "Preventive Rule"),
    closedAt: typeof frontmatter.closedAt === "string" ? frontmatter.closedAt : void 0
  };
}
function createContinuityIncidentRecord(id, input, nowIso) {
  return {
    id,
    state: "open",
    openedAt: nowIso,
    updatedAt: nowIso,
    triggerWindow: input.triggerWindow?.trim() || void 0,
    symptom: input.symptom.trim(),
    suspectedCause: input.suspectedCause?.trim() || void 0
  };
}
function closeContinuityIncidentRecord(incident, closure, nowIso) {
  return {
    ...incident,
    state: "closed",
    updatedAt: nowIso,
    closedAt: nowIso,
    fixApplied: closure.fixApplied.trim(),
    verificationResult: closure.verificationResult.trim(),
    preventiveRule: closure.preventiveRule?.trim() || incident.preventiveRule
  };
}
var LOOP_HEADER = "# Continuity Improvement Loops";
var LOOP_CADENCES = /* @__PURE__ */ new Set(["daily", "weekly", "monthly", "quarterly"]);
var LOOP_STATUSES = /* @__PURE__ */ new Set(["active", "paused", "retired"]);
var STALE_LAST_REVIEWED_FALLBACK = "1970-01-01T00:00:00.000Z";
function normalizeLoopField(value) {
  if (typeof value !== "string") return void 0;
  const trimmed = value.trim();
  if (trimmed.length === 0) return void 0;
  return trimmed.replace(/\s+/g, " ");
}
function isValidIso(value) {
  const ts = Date.parse(value);
  return Number.isFinite(ts);
}
function normalizeContinuityLoop(input, nowIso) {
  const id = normalizeLoopField(input.id);
  const cadence = normalizeLoopField(input.cadence);
  const status = normalizeLoopField(input.status);
  const purpose = normalizeLoopField(input.purpose);
  const killCondition = normalizeLoopField(input.killCondition);
  const notes = normalizeLoopField(input.notes);
  const lastReviewedRaw = "lastReviewed" in input && typeof input.lastReviewed === "string" ? input.lastReviewed : void 0;
  const lastReviewed = normalizeLoopField(lastReviewedRaw) ?? nowIso;
  if (!id || !cadence || !status || !purpose || !killCondition) return null;
  if (!LOOP_CADENCES.has(cadence)) return null;
  if (!LOOP_STATUSES.has(status)) return null;
  if (!isValidIso(lastReviewed)) return null;
  return {
    id,
    cadence,
    purpose,
    status,
    killCondition,
    lastReviewed,
    notes
  };
}
function serializeContinuityLoopSection(loop) {
  const lines = [
    `## ${loop.id}`,
    `cadence: ${loop.cadence}`,
    `purpose: ${loop.purpose}`,
    `status: ${loop.status}`,
    `killCondition: ${loop.killCondition}`,
    `lastReviewed: ${loop.lastReviewed}`
  ];
  if (loop.notes) lines.push(`notes: ${loop.notes}`);
  return lines.join("\n");
}
function splitLoopMarkdown(raw) {
  const text = (raw ?? "").replace(/\r/g, "");
  const lines = text.split("\n");
  const headerLines = [];
  const sections = [];
  let current = null;
  for (const line of lines) {
    const sectionMatch = line.match(/^##\s+(.+?)\s*$/);
    if (sectionMatch) {
      if (current) sections.push({ title: current.title, body: current.body.trimEnd() });
      current = { title: sectionMatch[1].trim(), body: "" };
      continue;
    }
    if (!current) {
      headerLines.push(line);
      continue;
    }
    current.body += current.body.length > 0 ? `
${line}` : line;
  }
  if (current) sections.push({ title: current.title, body: current.body.trimEnd() });
  const headerRaw = headerLines.join("\n").trim();
  const header = headerRaw.length > 0 ? headerRaw : LOOP_HEADER;
  return { header, sections };
}
function parseLoopFromSection(section, nowIso) {
  const fields = {};
  for (const line of section.body.split("\n")) {
    const kv = line.match(/^([A-Za-z][A-Za-z0-9_]*):\s*(.+?)\s*$/);
    if (!kv) continue;
    fields[kv[1]] = kv[2];
  }
  const parsedLastReviewed = normalizeLoopField(fields.lastReviewed);
  const safeLastReviewed = parsedLastReviewed && isValidIso(parsedLastReviewed) ? parsedLastReviewed : STALE_LAST_REVIEWED_FALLBACK;
  return normalizeContinuityLoop(
    {
      id: section.title,
      cadence: fields.cadence ?? "",
      purpose: fields.purpose ?? "",
      status: fields.status ?? "",
      killCondition: fields.killCondition ?? "",
      lastReviewed: safeLastReviewed,
      notes: fields.notes
    },
    nowIso
  );
}
function joinLoopMarkdown(header, sections) {
  const lines = [header.trim(), ""];
  for (const section of sections) {
    lines.push(`## ${section.title}`);
    if (section.body.trim().length > 0) {
      lines.push(section.body.trimEnd());
    }
    lines.push("");
  }
  return lines.join("\n").replace(/\n{3,}/g, "\n\n").trimEnd() + "\n";
}
function parseContinuityImprovementLoops(raw) {
  const parsed = splitLoopMarkdown(raw);
  const nowIso = (/* @__PURE__ */ new Date()).toISOString();
  return parsed.sections.map((section) => parseLoopFromSection(section, nowIso)).filter((loop) => loop !== null);
}
function upsertContinuityLoopInMarkdown(raw, input, nowIso) {
  const normalized = normalizeContinuityLoop(input, nowIso);
  if (!normalized) {
    throw new Error("Invalid continuity loop input");
  }
  const parsed = splitLoopMarkdown(raw);
  let replaced = false;
  const nextSections = parsed.sections.map((section) => {
    if (normalizeLoopField(section.title) !== normalized.id) return section;
    replaced = true;
    return { title: normalized.id, body: serializeContinuityLoopSection(normalized).split("\n").slice(1).join("\n") };
  });
  if (!replaced) {
    nextSections.push({
      title: normalized.id,
      body: serializeContinuityLoopSection(normalized).split("\n").slice(1).join("\n")
    });
  }
  return { markdown: joinLoopMarkdown(parsed.header, nextSections), loop: normalized };
}
function reviewContinuityLoopInMarkdown(raw, id, input, nowIso) {
  const parsed = splitLoopMarkdown(raw);
  const normalizedId = normalizeLoopField(id);
  if (!normalizedId) {
    return { markdown: joinLoopMarkdown(parsed.header, parsed.sections), loop: null };
  }
  let updatedLoop = null;
  const nextSections = parsed.sections.map((section) => {
    if (normalizeLoopField(section.title) !== normalizedId) return section;
    const existing = parseLoopFromSection(section, nowIso);
    if (!existing) return section;
    const reviewed = applyContinuityLoopReview(existing, input, nowIso);
    updatedLoop = reviewed;
    return { title: reviewed.id, body: serializeContinuityLoopSection(reviewed).split("\n").slice(1).join("\n") };
  });
  return { markdown: joinLoopMarkdown(parsed.header, nextSections), loop: updatedLoop };
}
function applyContinuityLoopReview(existing, input, nowIso) {
  const nextStatus = normalizeLoopField(input.status);
  const nextNotes = normalizeLoopField(input.notes);
  const reviewedAt = normalizeLoopField(input.reviewedAt) ?? nowIso;
  return {
    ...existing,
    status: nextStatus && LOOP_STATUSES.has(nextStatus) ? nextStatus : existing.status,
    notes: nextNotes ?? existing.notes,
    lastReviewed: isValidIso(reviewedAt) ? reviewedAt : nowIso
  };
}

export {
  serializeContinuityIncident,
  parseContinuityIncident,
  createContinuityIncidentRecord,
  closeContinuityIncidentRecord,
  parseContinuityImprovementLoops,
  upsertContinuityLoopInMarkdown,
  reviewContinuityLoopInMarkdown
};
//# sourceMappingURL=chunk-QSVPYQPG.js.map