import { GitClient } from "./git-client.ts"; /** 单条历史主题的最大保留 Unicode 字符数。 */ const MAX_SUBJECT_CHARS = 200; /* oxlint-disable no-control-regex -- 该正则用于清除控制字符、行分隔符与双向文本控制符 */ const UNSAFE_SUBJECT_CHARACTERS = /[\u0000-\u001F\u007F-\u009F\u2028\u2029\u202A-\u202E\u2066-\u2069]/gu; /* oxlint-enable no-control-regex */ /** 清理并按 Unicode 字符截断一条提交主题。 */ function sanitizeSubject(subject: string): string { const cleaned = subject.replace(UNSAFE_SUBJECT_CHARACTERS, " ").trim(); const characters = Array.from(cleaned); if (characters.length <= MAX_SUBJECT_CHARS) { return cleaned; } return `${characters.slice(0, MAX_SUBJECT_CHARS - 1).join("")}…`; } /** * 单次读取最近提交主题;历史不可用时静默降级,明确的外部取消仍向上传播。 */ export async function collectRecentCommitSubjects( git: GitClient, cwd: string, count: number, signal?: AbortSignal, ): Promise { if (count <= 0) { return []; } try { const result = await git.run( ["log", "--no-show-signature", "--format=%s", "-n", String(count)], { cwd, signal, acceptedExitCodes: [0, 128], }, ); if (result.code !== 0) { return []; } return result.stdout .split("\n") .map(sanitizeSubject) .filter((subject) => subject.length > 0) .slice(0, count); } catch (error) { if (signal?.aborted) { throw error; } return []; } }