// 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 { 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.", }; }