feat(cli): show candidate issue state reason and duplicate status in triage (#17676)

This commit is contained in:
Sehoon Shon
2026-01-27 13:07:52 -05:00
committed by GitHub
parent f03f2e8907
commit 50e4f9380b
@@ -16,6 +16,8 @@ interface Issue {
number: number; number: number;
title: string; title: string;
body: string; body: string;
state: string;
stateReason: string;
url: string; url: string;
author: { login: string }; author: { login: string };
labels: Array<{ name: string }>; labels: Array<{ name: string }>;
@@ -88,6 +90,13 @@ const getReactionCount = (issue: Issue | Candidate | undefined) => {
); );
}; };
const getStateColor = (state: string, stateReason?: string) => {
if (stateReason?.toLowerCase() === 'duplicate') {
return 'magenta';
}
return state === 'OPEN' ? 'green' : 'red';
};
export const TriageDuplicates = ({ export const TriageDuplicates = ({
config, config,
onExit, onExit,
@@ -146,7 +155,7 @@ export const TriageDuplicates = ({
'view', 'view',
String(number), String(number),
'--json', '--json',
'number,title,body,labels,url,comments,author,reactionGroups', 'number,title,body,state,stateReason,labels,url,comments,author,reactionGroups',
]); ]);
return JSON.parse(stdout) as Candidate; return JSON.parse(stdout) as Candidate;
} catch (err) { } catch (err) {
@@ -283,6 +292,8 @@ Return a JSON object with:
number: rec.canonical_issue_number, number: rec.canonical_issue_number,
title: 'Unknown', title: 'Unknown',
url: '', url: '',
state: 'UNKNOWN',
stateReason: '',
author: { login: 'unknown' }, author: { login: 'unknown' },
labels: [], labels: [],
comments: [], comments: [],
@@ -433,7 +444,7 @@ Return a JSON object with:
'--state', '--state',
'open', 'open',
'--json', '--json',
'number,title,body,labels,url,comments,author,reactionGroups', 'number,title,body,state,stateReason,labels,url,comments,author,reactionGroups',
'--limit', '--limit',
String(limit), String(limit),
]); ]);
@@ -916,6 +927,14 @@ Return a JSON object with:
) : ( ) : (
visibleCandidates.map((c: Candidate, i: number) => { visibleCandidates.map((c: Candidate, i: number) => {
const absoluteIndex = candidateListScrollOffset + i; const absoluteIndex = candidateListScrollOffset + i;
const isDuplicateOfCurrent =
currentIssue &&
c.comments.some((comment) =>
comment.body
.toLowerCase()
.includes(`duplicate of #${currentIssue.number}`),
);
return ( return (
<Box key={c.number} flexDirection="column" marginLeft={1}> <Box key={c.number} flexDirection="column" marginLeft={1}>
<Text <Text
@@ -932,8 +951,16 @@ Return a JSON object with:
} }
wrap="truncate-end" wrap="truncate-end"
> >
{absoluteIndex + 1}. <Text bold>#{c.number}</Text> -{' '} {absoluteIndex + 1}. <Text bold>#{c.number}</Text>{' '}
{c.title} (Score: {c.score}/100) <Text color={getStateColor(c.state, c.stateReason)}>
[{(c.stateReason || c.state).toUpperCase()}]
</Text>{' '}
{isDuplicateOfCurrent && (
<Text color="red" bold>
[DUPLICATE OF CURRENT]{' '}
</Text>
)}
- {c.title} (Score: {c.score}/100)
</Text> </Text>
<Box marginLeft={2}> <Box marginLeft={2}>
<Text color="gray" wrap="truncate-end"> <Text color="gray" wrap="truncate-end">