fix: add gh issue comments command

This commit is contained in:
Codex
2026-07-04 12:10:30 +00:00
parent 79aeca5b3b
commit 1ed621a067
9 changed files with 152 additions and 14 deletions
+76 -2
View File
@@ -10,9 +10,13 @@ import { commentSummary, compactCommentSummary, compactIssueViewCommentSummary }
import { GITHUB_REST_PAGE_SIZE } from "./types";
import type { GitHubCommandResult, GitHubComment, GitHubErrorPayload, GitHubIssue, GitHubIssueListPage, GitHubIssueListResult, GitHubIssueSearchResponse, IssueListState, IssueViewJsonField } from "./types";
export async function listIssueComments(token: string, repo: string, issueNumber: number): Promise<GitHubComment[] | GitHubErrorPayload> {
export async function listIssueComments(token: string, repo: string, issueNumber: number, options: { page?: number; perPage?: number } = {}): Promise<GitHubComment[] | GitHubErrorPayload> {
const { owner, name } = repoParts(repo);
return githubRequest<GitHubComment[]>(token, "GET", `/repos/${owner}/${name}/issues/${issueNumber}/comments?per_page=100`);
const params = new URLSearchParams({
per_page: String(options.perPage ?? GITHUB_REST_PAGE_SIZE),
page: String(options.page ?? 1),
});
return githubRequest<GitHubComment[]>(token, "GET", `/repos/${owner}/${name}/issues/${issueNumber}/comments?${params.toString()}`);
}
export function githubSearchLabelQualifier(label: string): string {
@@ -99,6 +103,22 @@ export async function getIssueComment(token: string, repo: string, commentId: nu
return githubRequest<GitHubComment>(token, "GET", `/repos/${owner}/${name}/issues/comments/${commentId}`);
}
async function listRecentIssueComments(token: string, repo: string, issueNumber: number, totalComments: number, limit: number): Promise<GitHubComment[] | GitHubErrorPayload> {
if (totalComments <= 0 || limit <= 0) return [];
const boundedLimit = Math.min(limit, GITHUB_REST_PAGE_SIZE);
const pages: GitHubComment[][] = [];
let collected = 0;
let page = Math.max(1, Math.ceil(totalComments / GITHUB_REST_PAGE_SIZE));
while (page >= 1 && collected < boundedLimit) {
const pageComments = await listIssueComments(token, repo, issueNumber, { page, perPage: GITHUB_REST_PAGE_SIZE });
if (isGitHubError(pageComments)) return pageComments;
pages.unshift(pageComments);
collected += pageComments.length;
page -= 1;
}
return pages.flat().slice(-boundedLimit);
}
export function selectedIssueJson(issue: GitHubIssue, comments: GitHubComment[] | null, fields: IssueViewJsonField[] | undefined, options: { includeFullCommentBodies?: boolean } = {}): Record<string, unknown> | null {
if (fields === undefined) return null;
const summary = issueSummary(issue);
@@ -151,3 +171,57 @@ export async function issueRead(repo: string, token: string, issueNumber: number
export async function issueView(repo: string, token: string, issueNumber: number, jsonFields: IssueViewJsonField[] | undefined, disclosure: Record<string, unknown> | null = null, options: { includeFullCommentBodies?: boolean } = {}): Promise<GitHubCommandResult> {
return issueRead(repo, token, issueNumber, jsonFields, "issue view", disclosure, options);
}
export async function issueComments(repo: string, token: string, issueNumber: number, limit: number, options: { includeFullCommentBodies?: boolean } = {}): Promise<GitHubCommandResult> {
const issue = await getIssue(token, repo, issueNumber);
if (isGitHubError(issue)) return commandError("issue comments", repo, issue, { issueNumber });
const totalComments = Math.max(0, issue.comments ?? 0);
const boundedLimit = Math.min(limit, GITHUB_REST_PAGE_SIZE);
const includeFullCommentBodies = options.includeFullCommentBodies === true;
const comments = await listRecentIssueComments(token, repo, issueNumber, totalComments, boundedLimit);
if (isGitHubError(comments)) return commandError("issue comments", repo, comments, {
issueNumber,
issue: issueSummary(issue, { includeBody: false, includePreview: false }),
});
const shownFrom = comments.length === 0 ? 0 : Math.max(1, totalComments - comments.length + 1);
return {
ok: true,
command: "issue comments",
repo,
issue: issueSummary(issue, { includeBody: false, includePreview: false }),
issueNumber,
limit: boundedLimit,
totalComments,
returned: comments.length,
omitted: Math.max(0, totalComments - comments.length),
commentRange: {
from: shownFrom,
to: comments.length === 0 ? 0 : shownFrom + comments.length - 1,
total: totalComments,
},
comments: comments.map(includeFullCommentBodies ? commentSummary : compactCommentSummary),
disclosure: {
boundedRecentComments: true,
fullCommentBodiesIncluded: includeFullCommentBodies,
bodyOmitted: !includeFullCommentBodies,
note: includeFullCommentBodies
? "issue comments returns a bounded recent-comment list with full bodies because --full or --raw was explicitly requested."
: "issue comments defaults to bounded recent-comment previews; use --full or --raw for full bodies, or issue comment view <commentId> --full for a single comment.",
},
compatibility: {
commentsPath: ".data.comments",
issuePath: ".data.issue",
authorField: "string|null",
previewField: includeFullCommentBodies ? null : "bodyPreview",
fullBodyField: includeFullCommentBodies ? "body" : null,
nestedIssueViewCommentsPath: ".data.json.comments",
},
readCommands: {
self: `bun scripts/cli.ts gh issue comments ${issueNumber} --repo ${repo}`,
full: `bun scripts/cli.ts gh issue comments ${issueNumber} --repo ${repo} --limit ${boundedLimit} --full`,
raw: `bun scripts/cli.ts gh issue comments ${issueNumber} --repo ${repo} --limit ${boundedLimit} --raw`,
comment: `bun scripts/cli.ts gh issue comment view <commentId> --repo ${repo} --full`,
issue: `bun scripts/cli.ts gh issue view ${issueNumber} --repo ${repo}`,
},
};
}