feat: add issue blocks and blocked-by (task 0007)
All checks were successful
CI / test (pull_request) Successful in 35s
CI / test (push) Successful in 35s

This commit was merged in pull request #10.
This commit is contained in:
2026-07-13 19:41:04 -04:00
parent 16d2f29f19
commit 6c15e6082f
4 changed files with 590 additions and 16 deletions

View File

@@ -129,6 +129,24 @@ function withArticle(noun: string): string {
return /^[aeiou]/i.test(noun) ? `an ${noun}` : `a ${noun}`;
}
/**
* Validate a single raw argument as a positive issue number. `noun` names what
* the number identifies ("issue", "target") in the error; `suggestions` carries
* the caller's help line. Shared by the single-positional parser and the
* two-positional dependency parser so the rule and its message live in one place.
*/
export function parseIssueNumber(raw: string, noun: string, suggestions: string[]): number {
const number = Number(raw);
if (!Number.isInteger(number) || number < 1) {
throw axiError(
`Invalid ${noun} number: ${raw} (expected a positive integer)`,
"VALIDATION_ERROR",
suggestions,
);
}
return number;
}
/**
* Parse the single positional number of a `<command> <number>` invocation.
* `noun` names what the number identifies ("issue", "pull request") and appears
@@ -150,16 +168,7 @@ export function parsePositionalNumber(
if (positionals.length > 1) {
throw axiError(`Unexpected argument: ${positionals[1]}`, "VALIDATION_ERROR", helpSuggestion);
}
const raw = positionals[0]!;
const number = Number(raw);
if (!Number.isInteger(number) || number < 1) {
throw axiError(
`Invalid ${noun} number: ${raw} (expected a positive integer)`,
"VALIDATION_ERROR",
helpSuggestion,
);
}
return number;
return parseIssueNumber(positionals[0]!, noun, helpSuggestion);
}
export function parseFlags(