Files
pikasTech-unidesk/scripts/src/gh/board-audit.ts
T
2026-06-26 00:16:53 +08:00

103 lines
3.9 KiB
TypeScript

// SPEC: PJ2026-010606 GitHub入口 draft-2026-06-25-gh-split
// Moved mechanically from scripts/src/gh.ts:6666-6756.
import { bodySha } from "./auth-and-safety";
import { mergedKnownMetaIssues, parseBoardTables } from "./board-parser";
import { normalizeNewlines } from "./body-profiles";
import { commandError, isGitHubError } from "./client";
import { getIssue } from "./issue-read";
import { CODE_QUEUE_BOARD_TARGET_ISSUE } from "./types";
import type { GitHubCommandResult, GitHubOptions } from "./types";
export async function issueBoardAudit(repo: string, token: string, options: GitHubOptions): Promise<GitHubCommandResult> {
const commandName = "issue board-audit";
const boardIssue = await getIssue(token, repo, options.boardIssue);
if (isGitHubError(boardIssue)) return commandError(commandName, repo, boardIssue, { boardIssue: options.boardIssue });
const parsed = parseBoardTables(boardIssue.body ?? "");
const openRows = parsed.sections.filter((section) => section.kind === "open").flatMap((section) => section.rows);
const closedRows = parsed.sections.filter((section) => section.kind === "closed").flatMap((section) => section.rows);
const body = boardIssue.body ?? "";
return {
ok: true,
command: commandName,
repo,
dryRun: true,
planned: true,
readOnly: true,
boardIssue: {
number: boardIssue.number,
title: boardIssue.title,
state: boardIssue.state,
url: boardIssue.html_url,
bodyChars: body.length,
bodyLines: body.length === 0 ? 0 : normalizeNewlines(body).split("\n").length,
bodySha: bodySha(body),
updatedAt: boardIssue.updated_at ?? null,
},
config: {
limit: options.limit,
knownMetaIssues: mergedKnownMetaIssues(options),
ignoredIssues: options.ignoredIssues,
briefIndexManagedIssuePattern: options.boardIssue === CODE_QUEUE_BOARD_TARGET_ISSUE ? "YYYY-MM-DD 指挥简报(北京时间)" : null,
openClosedCoverageValidation: false,
requiredColumns: [],
},
summary: {
openIssues: null,
closedIssues: null,
openRows: openRows.length,
closedRows: closedRows.length,
parsedSections: parsed.sections.length,
parsedRows: parsed.sections.reduce((sum, section) => sum + section.rows.length, 0),
parserWarnings: parsed.warnings.length,
missingOpenIssues: 0,
closedInOpenRows: 0,
missingClosedRows: 0,
openInClosedRows: 0,
rowValidationWarnings: 0,
ignoredIssues: 0,
boardOnlyRows: 0,
staleOpenRows: 0,
recommendedActions: 0,
},
validation: {
openClosedCoverage: {
enabled: false,
reason: "OPEN/CLOSED table coverage validation has been disabled; this command no longer compares GitHub issue state against board rows.",
},
rowRequiredColumns: {
enabled: false,
reason: "board-audit no longer reports missing required row columns; use board-row commands when intentionally maintaining a legacy OPEN/CLOSED table.",
},
},
sections: parsed.sections.map((section) => ({
kind: section.kind,
heading: section.heading,
headingLine: section.headingLine,
headerLine: section.headerLine,
headers: section.headers,
rows: section.rows.length,
issueNumbers: section.rows.flatMap((row) => row.issueNumbers),
})),
parserWarnings: parsed.warnings,
missingOpenIssues: [],
closedInOpenRows: [],
missingClosedRows: [],
openInClosedRows: [],
staleOpenRows: [],
boardOnlyRows: [],
rowValidationWarnings: [],
ignoredIssues: [],
recommendedActions: [],
request: {
method: "GET",
paths: [
`/repos/{owner}/{repo}/issues/${options.boardIssue}`,
],
query: {},
},
note: "Read-only board structure audit; OPEN/CLOSED coverage validation is disabled, no issue body was edited, no issue was closed, and no comments were written.",
};
}