import { splitLines } from "../git/merge3";
import { hunkQuestionId } from "./decide";
import type { ClefRequest, ClefResponse } from "./decide";
import type { MergeFixProvider } from "./plan";
const SECURITY_HINT = /password|secret|token|auth|crypto|permission/i;
/** Union of both sides' lines, keeping head order first: a plausible deterministic "AI" resolution. */
function unionLines(ours: string, theirs: string): string {
const lines = splitLines(ours);
const seen = new Set(lines);
for (const line of splitLines(theirs)) if (!seen.has(line)) lines.push(line);
return lines.join("");
}
function spread(ids: string[], pick: string, top: number): Record<string, number> {
const rest = ids.length > 1 ? (1 - top) / (ids.length - 1) : 0;
return Object.fromEntries(ids.map((id) => [id, id === pick ? top : rest]));
}
/**
* Deterministic stand-in for the generative model and Clef, selected with MERGEFIX_PROVIDER=mock. It picks
* the first AI candidate with high confidence and flags anything that mentions credentials as security-sensitive.
*/
export function mockProvider(): MergeFixProvider {
return {
async generate({ hunk }) {
return {
text: `\`\`\`merge\n${unionLines(hunk.ours, hunk.theirs)}\`\`\``,
usage: { inputTokens: 100, outputTokens: 20 },
};
},
async decide(request: ClefRequest): Promise<ClefResponse> {
const answers: ClefResponse["answers"] = {};
for (const [id, question] of Object.entries(request.questions)) {
if (question.type !== "choice") continue;
const ids = Object.keys(question.criteria);
const pick =
ids.find((option) => option.startsWith("ai_")) ??
ids.find((option) => option === "ours_then_theirs") ??