diff --git a/packages/loopover-mcp/README.md b/packages/loopover-mcp/README.md index 95cfd68df..fc26341c0 100644 --- a/packages/loopover-mcp/README.md +++ b/packages/loopover-mcp/README.md @@ -52,7 +52,7 @@ loopover-mcp notifications-read --login [--id ]... [ loopover-mcp watch [owner/repo] [--labels a,b] [--login ] [--json] loopover-mcp analyze-branch --login [--repo owner/repo] [--base origin/main] [--branch-eligibility eligible|ineligible|unknown] [--pending-merged-prs 3] [--expected-open-prs 0] [--projected-credibility 0.8] [--scenario-note "..."] [--validation "passed|npm test|summary"] [--format table] [--json] loopover-mcp preflight --login [--repo owner/repo] [--base origin/main] [--branch-eligibility eligible|ineligible|unknown] [--pending-merged-prs 3] [--expected-open-prs 0] [--projected-credibility 0.8] [--validation "passed|npm test|summary"] [--format table] [--json] -loopover-mcp review-pr --login [--repo owner/repo] [--base origin/main] [--commit ]... [--body ] [--body-file ] [--linked-issue ] [--json] +loopover-mcp review-pr --login [--repo owner/repo] [--base origin/main] [--commit ]... [--body ] [--body-file ] [--label ]... [--linked-issue ] [--issue ]... [--json] loopover-mcp lint-pr-text [--commit ]... [--body ] [--body-file ] [--linked-issue ] [--json] loopover-mcp validate-config --file [--source repo_file|api_record|none] [--json] loopover-mcp slop-risk [--description ] [--description-file ] [--changed-file ]... [--test ]... [--test-file ]... [--json] diff --git a/packages/loopover-mcp/bin/loopover-mcp.ts b/packages/loopover-mcp/bin/loopover-mcp.ts index c733a5e96..ee49fe792 100644 --- a/packages/loopover-mcp/bin/loopover-mcp.ts +++ b/packages/loopover-mcp/bin/loopover-mcp.ts @@ -302,7 +302,7 @@ const CLI_COMMAND_SPEC = { }, "review-pr": { subcommands: [], - usage: ["review-pr --login [--repo owner/repo] [--base origin/main] [--commit ]... [--body ] [--body-file ] [--linked-issue ] [--json]"], + usage: ["review-pr --login [--repo owner/repo] [--base origin/main] [--commit ]... [--body ] [--body-file ] [--label ]... [--linked-issue ] [--issue ]... [--json]"], }, "lint-pr-text": { subcommands: [], usage: ["lint-pr-text [--commit ]... [--body ] [--body-file ] [--linked-issue ] [--json]"] }, "validate-config": { subcommands: [], usage: ["validate-config --file [--source repo_file|api_record|none] [--json]"] }, @@ -3194,12 +3194,16 @@ function writeBranchAnalysisTable(result: any, command: string) { function printReviewPrHelp() { process.stdout.write( [ - "Usage: loopover-mcp review-pr --login [--repo owner/repo] [--base origin/main] [--commit ]... [--body ] [--body-file ] [--linked-issue ] [--json]", + "Usage: loopover-mcp review-pr --login [--repo owner/repo] [--base origin/main] [--commit ]... [--body ] [--body-file ] [--label ]... [--linked-issue ] [--issue ]... [--json]", "", "Compose the existing preflight + slop-risk + PR-text-lint checks into ONE pre-PR review report,", "so a contributor's own local agent can see everything the loopover gate would flag before ever opening a PR.", "Mirrors the loopover_review_pr_before_push MCP tool. Thin composition only — does not reimplement any check. No source upload.", "", + "Repeat --label to pass labels to the review request.", + "Repeat --issue as an alternate way to provide linked issue numbers.", + "When both --linked-issue and --issue are provided, --linked-issue takes precedence and --issue is ignored.", + "", "Pass --json for machine-readable output.", ].join("\n") + "\n", ); diff --git a/packages/loopover-mcp/test/review-pr-help.test.ts b/packages/loopover-mcp/test/review-pr-help.test.ts new file mode 100644 index 000000000..0ac93de45 --- /dev/null +++ b/packages/loopover-mcp/test/review-pr-help.test.ts @@ -0,0 +1,26 @@ +import { describe, expect, it, vi } from "vitest"; + +const BIN_MODULE = "../bin/loopover-mcp.ts"; +type BinModule = { runCli: (args: readonly string[]) => Promise }; + +describe("loopover-mcp review-pr help", () => { + it("documents the repeatable labels and issue flags and their precedence", async () => { + const { runCli } = (await import(BIN_MODULE)) as BinModule; + const chunks: string[] = []; + const stdout = vi.spyOn(process.stdout, "write").mockImplementation((chunk: string | Uint8Array): boolean => { + chunks.push(typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8")); + return true; + }); + + try { + await runCli(["review-pr", "--help"]); + } finally { + stdout.mockRestore(); + } + + const help = chunks.join(""); + expect(help).toContain("[--label ]..."); + expect(help).toContain("[--issue ]..."); + expect(help).toContain("--linked-issue takes precedence and --issue is ignored"); + }); +}); diff --git a/vitest.config.ts b/vitest.config.ts index fa983b972..1db98ee29 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -68,7 +68,7 @@ export default defineConfig({ // Codecov, or that PR's own Codecov bot comment). No dashboard is wired up to surface it proactively, // so check it deliberately if a retry shows up in CI output rather than assuming it's pure infra noise. retry: 1, - include: ["test/**/*.test.ts"], + include: ["test/**/*.test.ts", "packages/loopover-mcp/test/**/*.test.ts"], exclude: ["test/workers/**/*.test.ts"], reporters: junitPath ? ["default", "junit"] : ["default"], ...(junitPath ? { outputFile: { junit: junitPath } } : {}),