From e20134ad90e41944b60d66c7bec644ee6962aed1 Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 3 Jun 2026 05:38:09 +0000 Subject: [PATCH] fix(gh): support owner/repo#number shorthand for issue write commands gh issue comment create/delete, close, reopen, update, edit, and board-row all now accept the owner/repo#number positional shorthand that gh issue read/view and gh pr * already accept. This removes the friction of having to split shorthand into a separate --repo flag and a bare number, and keeps error messages consistent with the existing shorthand validation. Discovered during HWLAB #621 CLI acceptance: posting the acceptance results to the issue required gh issue comment create pikasTech/HWLAB#621, which previously failed with 'issue comment create must be a positive integer' and forced a separate --repo flag. --- scripts/src/gh.ts | 94 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 13 deletions(-) diff --git a/scripts/src/gh.ts b/scripts/src/gh.ts index bd9d0844..422891bf 100644 --- a/scripts/src/gh.ts +++ b/scripts/src/gh.ts @@ -906,6 +906,32 @@ function resolvePositionalPrReference(args: string[], startIndex: number, label: return { repo: options.repo, number }; } +function resolvePositionalIssueReference(args: string[], startIndex: number, label: string, options: GitHubOptions): GitHubResolvedNumberReference | GitHubCommandResult { + const targets = positionalArgs(args.slice(startIndex)); + if (targets.length !== 1) { + return validationError(label, options.repo, `${label} requires exactly one positive integer or owner/repo#number positional argument`, { + supportedCommands: [ + `bun scripts/cli.ts gh ${label} --repo ${options.repo}`, + `bun scripts/cli.ts gh ${label} ${options.repo}#`, + ], + }); + } + const shorthand = parseOwnerRepoNumberShorthand(targets[0]); + if (shorthand !== null) { + const explicitRepo = optionValue(args, "--repo"); + if (explicitRepo !== undefined && explicitRepo !== shorthand.repo) { + return validationError(label, explicitRepo, `${label} target ${shorthand.input} resolves to repo ${shorthand.repo}, but --repo ${explicitRepo} was also provided.`, { + shorthand, + explicitRepo, + }); + } + return { repo: shorthand.repo, number: shorthand.number, shorthand }; + } + const number = parseNumberForCommand(options.repo, targets[0], label); + if (typeof number !== "number") return number; + return { repo: options.repo, number }; +} + function parseOwnerRepoNumberShorthand(raw: string | undefined): GitHubShorthandReference | null { if (raw === undefined) return null; const match = /^([^/#\s]+)\/([^/#\s]+)#([1-9]\d*)$/u.exec(raw); @@ -6533,7 +6559,9 @@ export async function runGhCommand(args: string[]): Promise