"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/pr-comment.ts
var pr_comment_exports = {};
__export(pr_comment_exports, {
  RIDDLE_PROOF_PR_COMMENT_MARKER: () => RIDDLE_PROOF_PR_COMMENT_MARKER,
  buildRiddleProofPrCommentMarkdown: () => buildRiddleProofPrCommentMarkdown,
  summarizeRiddleProofPrComment: () => summarizeRiddleProofPrComment
});
module.exports = __toCommonJS(pr_comment_exports);

// src/public-state.ts
function asRecord(value) {
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
}
function stringValue(value) {
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
}
function booleanValue(value) {
  return typeof value === "boolean" ? value : void 0;
}
function numberValue(value) {
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
}
function firstStringValue(...values) {
  for (const value of values) {
    const text = stringValue(value);
    if (text) return text;
  }
  return void 0;
}
function firstBooleanValue(...values) {
  for (const value of values) {
    const bool = booleanValue(value);
    if (typeof bool === "boolean") return bool;
  }
  return void 0;
}
function firstRecordValue(...values) {
  for (const value of values) {
    const record = asRecord(value);
    if (Object.keys(record).length) return record;
  }
  return void 0;
}
function countValue(value) {
  const number = numberValue(value);
  return typeof number === "number" && number > 0 ? Math.trunc(number) : 0;
}
function checkpointSummaryFrom(...values) {
  const record = firstRecordValue(...values);
  if (!record) return void 0;
  const accepted = countValue(record.response_count);
  const rejected = countValue(record.rejected_response_count);
  const ignored = countValue(record.ignored_response_count);
  const duplicate = countValue(record.duplicate_response_count);
  const summary = {
    pending: booleanValue(record.pending),
    accepted_response_count: accepted,
    rejected_response_count: rejected,
    ignored_response_count: ignored,
    duplicate_response_count: duplicate,
    latest_decision: stringValue(record.latest_decision),
    audit_disclosure_required: rejected > 0 || ignored > 0 || duplicate > 0
  };
  return Object.values(summary).some((value) => typeof value !== "undefined") ? summary : void 0;
}
function uniqueStrings(values) {
  return [...new Set(values.filter(Boolean))];
}
function summarizeRiddleProofPublicState(input) {
  const record = asRecord(input);
  const runCard = asRecord(record.run_card);
  const stopCondition = asRecord(runCard.stop_condition);
  const raw = asRecord(record.raw);
  const request = asRecord(record.request);
  const requestMetadata = asRecord(record.request_metadata);
  const prState = asRecord(record.pr_state);
  const handoff = asRecord(record.pr_handoff_policy);
  const handoffState = stringValue(handoff.state);
  const status = firstStringValue(record.status, stopCondition.status);
  const ok = booleanValue(record.ok) ?? null;
  const shipMode = firstStringValue(request.ship_mode, requestMetadata.ship_mode, record.ship_mode, handoff.ship_mode);
  const explicitShippingDisabled = firstBooleanValue(
    record.shipping_disabled,
    stopCondition.shipping_disabled,
    raw.shipping_disabled,
    handoff.shipping_disabled
  );
  const shippingDisabled = explicitShippingDisabled === true || shipMode === "none" || handoffState === "proof_complete_ship_disabled";
  const explicitShipAuthorized = firstBooleanValue(
    record.ship_authorized,
    stopCondition.ship_authorized,
    raw.ship_authorized
  );
  const authorizationEvidence = Boolean(
    status === "shipped" || record.marked_ready === true || stringValue(prState.status) === "merged" || record.merge_commit || record.merged_at
  );
  const shipAuthorizedBeforeHold = explicitShipAuthorized ?? authorizationEvidence;
  const explicitShipHeld = firstBooleanValue(record.ship_held, stopCondition.ship_held, raw.ship_held);
  const inferredHeld = status === "ready_to_ship" && shippingDisabled && !shipAuthorizedBeforeHold;
  const shipHeld = explicitShipHeld === true || inferredHeld;
  const shipAuthorized = shipHeld ? false : shipAuthorizedBeforeHold === true;
  const proofComplete = Boolean(
    status === "ready_to_ship" || status === "shipped" || status === "completed" || status === "passed" || ok === true || handoff.proof_complete === true
  );
  const checkpointSummary = checkpointSummaryFrom(
    record.checkpoint_summary,
    stopCondition.checkpoint_summary,
    asRecord(record.details).checkpoint_summary,
    asRecord(raw.details).checkpoint_summary
  );
  const blockedOrWaiting = status === "blocked" || status === "failed" || status === "awaiting_checkpoint" || handoffState === "proof_blocked" || handoffState === "proof_review_required" || handoffState === "proof_failed" || handoffState === "proof_checkpoint_required";
  const proofPassed = Boolean(proofComplete && !blockedOrWaiting);
  const explicitMergeReady = firstBooleanValue(record.merge_ready, stopCondition.merge_ready, raw.merge_ready, handoff.merge_ready);
  const normalPrAllowed = firstBooleanValue(record.normal_pr_allowed, raw.normal_pr_allowed, handoff.normal_pr_allowed);
  const baseHandoffAllowed = !blockedOrWaiting && !shipHeld && !shippingDisabled;
  const mergeReady = baseHandoffAllowed && normalPrAllowed !== false && (explicitMergeReady ?? shipAuthorized);
  const syncAllowed = mergeReady;
  let policyState = "unknown";
  if (status === "awaiting_checkpoint" || handoffState === "proof_checkpoint_required") policyState = "awaiting_checkpoint";
  else if (status === "failed" || handoffState === "proof_failed") policyState = "proof_failed";
  else if (status === "blocked" || handoffState === "proof_blocked" || handoffState === "proof_review_required") policyState = "proof_blocked";
  else if (handoffState === "proof_complete_ship_disabled") policyState = "proof_complete_ship_disabled";
  else if (proofComplete && shipHeld && !shipAuthorized) policyState = "proof_passed_ship_held";
  else if (proofComplete && shippingDisabled && !shipAuthorized) policyState = "proof_complete_ship_disabled";
  else if (shipAuthorized) policyState = "ship_authorized";
  else if (proofPassed) policyState = "proof_passed";
  else if (status === "running") policyState = "proof_in_progress";
  const requiredDisclosures = [];
  if (shipHeld) requiredDisclosures.push("ship_held");
  if (shippingDisabled) requiredDisclosures.push("shipping_disabled");
  if (checkpointSummary?.audit_disclosure_required) requiredDisclosures.push("checkpoint_audit_counters");
  if (status === "awaiting_checkpoint" || handoffState === "proof_checkpoint_required") requiredDisclosures.push("checkpoint_required");
  const prohibitedClaims = [];
  if (!shipAuthorized || shipHeld || shippingDisabled) prohibitedClaims.push("ship_authorized", "shipped");
  if (!mergeReady) prohibitedClaims.push("merge_ready");
  if (!syncAllowed) prohibitedClaims.push("sync_allowed");
  if (blockedOrWaiting) {
    prohibitedClaims.push("proof_passed", "ready_to_ship");
  }
  if (checkpointSummary?.audit_disclosure_required) {
    prohibitedClaims.push("all_checkpoint_responses_accepted");
  }
  const resultLabel2 = policyState === "awaiting_checkpoint" ? "checkpoint required" : policyState === "proof_blocked" ? "blocked" : policyState === "proof_failed" ? "failed" : policyState === "proof_complete_ship_disabled" ? "proof complete; shipping disabled" : policyState === "proof_passed_ship_held" ? "proof passed; ship held" : policyState === "ship_authorized" ? status === "shipped" ? "shipped" : "ship authorized" : policyState === "proof_passed" ? "passed" : policyState === "proof_in_progress" ? "running" : status || "recorded";
  return {
    status,
    ok,
    policy_state: policyState,
    result_label: resultLabel2,
    proof_complete: proofComplete,
    proof_passed: proofPassed,
    ship_held: shipHeld,
    shipping_disabled: shippingDisabled,
    ship_authorized: shipAuthorized,
    merge_ready: mergeReady,
    sync_allowed: syncAllowed,
    checkpoint_summary: checkpointSummary,
    required_disclosures: uniqueStrings(requiredDisclosures),
    prohibited_claims: uniqueStrings(prohibitedClaims)
  };
}

// src/pr-comment.ts
var RIDDLE_PROOF_PR_COMMENT_MARKER = "<!-- riddle-proof:pr-comment:v1 -->";
function asRecord2(value) {
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
}
function asArray(value) {
  return Array.isArray(value) ? value : [];
}
function stringValue2(value) {
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
}
function numberValue2(value) {
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
}
function booleanValue2(value) {
  return typeof value === "boolean" ? value : void 0;
}
function firstStringValue2(...values) {
  for (const value of values) {
    const text = stringValue2(value);
    if (text) return text;
  }
  return void 0;
}
function artifactKind(name, url) {
  const target = `${name} ${url}`.toLowerCase();
  if (/\.(png|jpe?g|gif|webp|avif|svg)(\?|#|$)/.test(target)) return "image";
  if (/\.(json|har|txt|md|html|log)(\?|#|$)/.test(target)) return "data";
  return "artifact";
}
function artifactDisplayName(value, fallback) {
  const raw = stringValue2(value);
  if (raw) return raw;
  return fallback;
}
function collectArtifacts(runResponse) {
  const proofResult = asRecord2(runResponse.proofResult);
  const outputs = asArray(proofResult.outputs);
  const artifacts = [];
  const seen = /* @__PURE__ */ new Set();
  for (const [index, item] of outputs.entries()) {
    const artifact = asRecord2(item);
    const url = stringValue2(artifact.url);
    if (!url || seen.has(url)) continue;
    seen.add(url);
    const name = artifactDisplayName(artifact.name, `artifact-${index + 1}`);
    artifacts.push({
      name,
      url,
      kind: artifactKind(name, url),
      size_bytes: numberValue2(artifact.size)
    });
  }
  return artifacts;
}
function pageSummaries(result) {
  const pages = [];
  for (const page of asArray(result.pages)) {
    const record = asRecord2(page);
    const route = stringValue2(record.route) || stringValue2(record.url) || "page";
    const checks = asRecord2(record.checks);
    let passed = 0;
    let failed = 0;
    for (const value of Object.values(checks)) {
      if (value === true) passed += 1;
      if (value === false) failed += 1;
    }
    pages.push({ route, passed, failed });
  }
  return pages;
}
function summarizeExplicitChecks(value) {
  let passed = 0;
  let failed = 0;
  const visit = (current, inChecks = false) => {
    if (current === true && inChecks) {
      passed += 1;
      return;
    }
    if (current === false && inChecks) {
      failed += 1;
      return;
    }
    if (Array.isArray(current)) {
      for (const item of current) visit(item, inChecks);
      return;
    }
    if (current && typeof current === "object") {
      for (const [key, item] of Object.entries(current)) {
        visit(item, inChecks || key === "checks");
      }
    }
  };
  visit(value);
  return { passed, failed };
}
function selectPrimaryImage(artifacts) {
  const images = artifacts.filter((artifact) => artifact.kind === "image");
  return images.find((artifact) => /after|proof|screenshot/i.test(artifact.name)) || images[0];
}
function firstRecordValue2(...values) {
  for (const value of values) {
    const record = asRecord2(value);
    if (Object.keys(record).length) return record;
  }
  return void 0;
}
function checkpointSummaryFrom2(...values) {
  const record = firstRecordValue2(...values);
  if (!record) return void 0;
  const summary = {
    pending: booleanValue2(record.pending),
    response_count: numberValue2(record.response_count),
    rejected_response_count: numberValue2(record.rejected_response_count),
    ignored_response_count: numberValue2(record.ignored_response_count),
    duplicate_response_count: numberValue2(record.duplicate_response_count),
    latest_decision: stringValue2(record.latest_decision),
    latest_packet_id: stringValue2(record.latest_packet_id),
    latest_resume_token: stringValue2(record.latest_resume_token)
  };
  return Object.values(summary).some((value) => typeof value !== "undefined") ? summary : void 0;
}
function summarizeRiddleProofPrComment(input) {
  const runResponse = asRecord2(input.runResponse);
  const result = asRecord2(input.result);
  const proofResult = asRecord2(runResponse.proofResult);
  const preview = asRecord2(runResponse.preview);
  const resultRunCard = asRecord2(result.run_card);
  const stopCondition = asRecord2(resultRunCard.stop_condition);
  const resultDetails = asRecord2(result.details);
  const resultRaw = asRecord2(result.raw);
  const rawDetails = asRecord2(resultRaw.details);
  const artifacts = collectArtifacts(runResponse);
  const pages = pageSummaries(result);
  const checkSource = { ...result };
  delete checkSource.ok;
  const nestedChecks = summarizeExplicitChecks(checkSource);
  const ok = booleanValue2(result.ok) ?? booleanValue2(runResponse.ok) ?? null;
  const checkpointSummary = checkpointSummaryFrom2(
    result.checkpoint_summary,
    stopCondition.checkpoint_summary,
    resultDetails.checkpoint_summary,
    rawDetails.checkpoint_summary,
    proofResult.checkpoint_summary
  );
  const publicState = summarizeRiddleProofPublicState({
    ...result,
    status: firstStringValue2(result.status, stopCondition.status),
    checkpoint_summary: checkpointSummary || result.checkpoint_summary
  });
  return {
    ok,
    status: stringValue2(proofResult.status),
    result_status: publicState.status,
    job_id: stringValue2(proofResult.job_id),
    duration_ms: numberValue2(proofResult.duration_ms),
    proof_url: stringValue2(runResponse.proofUrl),
    preview_id: stringValue2(preview.id),
    preview_url: stringValue2(preview.preview_url) || stringValue2(preview.url),
    preview_publish_recovered: booleanValue2(preview.publish_recovered),
    preview_publish_error: stringValue2(preview.publish_error),
    ship_held: publicState.ship_held,
    shipping_disabled: publicState.shipping_disabled,
    ship_authorized: publicState.ship_authorized,
    proof_decision: firstStringValue2(result.proof_decision, stopCondition.proof_decision, resultRaw.proof_decision),
    merge_recommendation: firstStringValue2(result.merge_recommendation, stopCondition.merge_recommendation, resultRaw.merge_recommendation),
    checkpoint_summary: checkpointSummary,
    public_state: publicState,
    passed_checks: nestedChecks.passed,
    failed_checks: nestedChecks.failed,
    pages,
    artifacts,
    primary_image: selectPrimaryImage(artifacts)
  };
}
function formatDuration(ms) {
  if (typeof ms !== "number" || !Number.isFinite(ms)) return "";
  const seconds = Math.max(0, Math.round(ms / 1e3));
  const minutes = Math.floor(seconds / 60);
  const remainder = seconds % 60;
  return minutes > 0 ? `${minutes}m${String(remainder).padStart(2, "0")}s` : `${seconds}s`;
}
function markdownLink(label, url) {
  return `[${label.replace(/\]/g, "\\]")}](${url})`;
}
function resultLabel(summary) {
  if (summary.public_state?.result_label) return summary.public_state.result_label;
  if (summary.ok === true) {
    if (summary.result_status === "shipped") return "shipped";
    if (summary.result_status === "completed") return "completed";
    if (summary.ship_held === true) return "proof passed; ship held";
    if (summary.ship_authorized === true) return "passed; ship authorized";
    return "passed";
  }
  if (summary.ok === false) return "failed";
  return summary.result_status || summary.status || "recorded";
}
function artifactRank(artifact) {
  const name = artifact.name.toLowerCase();
  if (name === "proof.json") return 0;
  if (name === "result.json") return 1;
  if (name.includes("proof") && name.endsWith(".json") && !name.includes("layout")) return 2;
  if (name === "console.json") return 3;
  if (artifact.kind === "data") return 10;
  if (artifact.kind === "image") return 20;
  return 30;
}
function formatBool(value) {
  return typeof value === "boolean" ? String(value) : "unknown";
}
function hasShipControl(summary) {
  return typeof summary.ship_held === "boolean" || typeof summary.shipping_disabled === "boolean" || typeof summary.ship_authorized === "boolean";
}
function checkpointSummaryLine(summary) {
  const accepted = summary.response_count ?? 0;
  const rejected = summary.rejected_response_count ?? 0;
  const ignored = summary.ignored_response_count ?? 0;
  const parts = [`${accepted} accepted`, `${rejected} rejected`, `${ignored} ignored`];
  if ((summary.duplicate_response_count ?? 0) > 0) parts.push(`${summary.duplicate_response_count} duplicate`);
  const state = summary.pending === true ? "pending" : summary.pending === false ? "complete" : "";
  return [
    parts.join(" / "),
    state,
    summary.latest_decision ? `latest decision \`${summary.latest_decision}\`` : ""
  ].filter(Boolean).join("; ");
}
function buildRiddleProofPrCommentMarkdown(input) {
  const summary = summarizeRiddleProofPrComment(input);
  const title = input.title?.trim() || "Riddle Proof Evidence";
  const lines = [
    RIDDLE_PROOF_PR_COMMENT_MARKER,
    `## ${title}`,
    "",
    `**Result:** ${resultLabel(summary)}`
  ];
  if (input.goal?.trim()) lines.push(`**Goal:** ${input.goal.trim()}`);
  if (input.successCriteria?.trim()) lines.push(`**Success criteria:** ${input.successCriteria.trim()}`);
  if (summary.result_status) lines.push(`**Evidence status:** ${summary.result_status}`);
  if (summary.status) lines.push(`**Riddle job status:** ${summary.status}`);
  if (summary.job_id) lines.push(`**Riddle job:** \`${summary.job_id}\``);
  if (summary.duration_ms) lines.push(`**Duration:** ${formatDuration(summary.duration_ms)}`);
  if (hasShipControl(summary)) {
    lines.push(`**Ship control:** held=${formatBool(summary.ship_held)}, shipping_disabled=${formatBool(summary.shipping_disabled)}, authorized=${formatBool(summary.ship_authorized)}`);
  }
  if (summary.proof_decision) lines.push(`**Proof decision:** \`${summary.proof_decision}\``);
  if (summary.merge_recommendation) lines.push(`**Merge recommendation:** ${summary.merge_recommendation}`);
  if (summary.checkpoint_summary) lines.push(`**Checkpoints:** ${checkpointSummaryLine(summary.checkpoint_summary)}`);
  if (summary.proof_url) lines.push(`**Proof URL:** ${markdownLink(summary.proof_url, summary.proof_url)}`);
  if (summary.preview_id || summary.preview_url) {
    const previewLabel = summary.preview_id ? `\`${summary.preview_id}\`` : "preview";
    lines.push(`**Preview:** ${summary.preview_url ? markdownLink(previewLabel, summary.preview_url) : previewLabel}`);
  }
  if (summary.preview_publish_recovered) {
    const detail = summary.preview_publish_error ? `: ${summary.preview_publish_error}` : "";
    lines.push(`**Preview publish recovery:** recovered after publish error${detail}`);
  }
  lines.push(`**Checks:** ${summary.passed_checks} passed / ${summary.failed_checks} failed`);
  lines.push("");
  if (summary.primary_image) {
    lines.push("### Screenshot");
    lines.push(`![${summary.primary_image.name}](${summary.primary_image.url})`);
    lines.push("");
  }
  if (summary.pages.length) {
    lines.push("### Page Checks");
    for (const page of summary.pages.slice(0, 12)) {
      lines.push(`- \`${page.route}\`: ${page.passed} passed / ${page.failed} failed`);
    }
    if (summary.pages.length > 12) lines.push(`- ${summary.pages.length - 12} more page(s) omitted`);
    lines.push("");
  }
  const linkedArtifacts = summary.artifacts.filter((artifact) => artifact.url !== summary.primary_image?.url).sort((left, right) => artifactRank(left) - artifactRank(right) || left.name.localeCompare(right.name)).slice(0, 20);
  if (linkedArtifacts.length) {
    lines.push("### Artifacts");
    for (const artifact of linkedArtifacts) {
      lines.push(`- ${markdownLink(artifact.name, artifact.url)}`);
    }
    if (summary.artifacts.length - (summary.primary_image ? 1 : 0) > linkedArtifacts.length) {
      lines.push(`- ${summary.artifacts.length - (summary.primary_image ? 1 : 0) - linkedArtifacts.length} more artifact(s) omitted`);
    }
    lines.push("");
  }
  if (input.source?.trim()) {
    lines.push(`_Source: ${input.source.trim()}_`);
  } else {
    lines.push("_Updated by `riddle-proof-loop pr-comment`._");
  }
  return `${lines.join("\n").trim()}
`;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  RIDDLE_PROOF_PR_COMMENT_MARKER,
  buildRiddleProofPrCommentMarkdown,
  summarizeRiddleProofPrComment
});
