import type { ChatMessage } from "../mergefix/plan";
import type { CommitSummary, DiffResult } from "~/lib/types";
export const MAX_COMMITS = 30;
export const MAX_DIFF_CHARS = 12_000;
const MAX_COMMIT_BODY_CHARS = 600;
const MAX_FILES = 200;
const MAX_TITLE_CHARS = 100;
const MAX_BODY_CHARS = 6000;
const LOCKFILE =
/(^|\/)(bun\.lockb?|package-lock\.json|yarn\.lock|pnpm-lock\.yaml|Cargo\.lock|go\.sum|poetry\.lock|Pipfile\.lock|Gemfile\.lock|composer\.lock|flake\.lock|[^/]+\.lock)$/;
export type DescribeInput = {
base: string;
head: string;
commits: Pick<CommitSummary, "subject" | "message">[];
diff: Pick<DiffResult, "patch" | "files">;
};
export type PullSuggestion = { title: string; body: string };
export function isLockfile(path: string): boolean {
return LOCKFILE.test(path);
}
function commitLines(commits: DescribeInput["commits"]): string {
const shown = commits.slice(0, MAX_COMMITS).map((commit) => {
const body = commit.message.slice(commit.subject.length).trim().slice(0, MAX_COMMIT_BODY_CHARS);
return body ? `- ${commit.subject}\n ${body.replace(/\n/g, "\n ")}` : `- ${commit.subject}`;
});
const omitted = commits.length - shown.length;
if (omitted > 0) shown.push(`- (${omitted} more commits omitted)`);
return shown.join("\n");
}
function fileLines(files: DescribeInput["diff"]["files"]): string {
const shown = files.slice(0, MAX_FILES).map((file) => {
const name = file.oldPath && file.oldPath !== file.path ? `${file.oldPath} -> ${file.path}` : file.path;
const stats = file.binary ? "binary" : `+${file.additions} -${file.deletions}`;