Skip to content

Commit dee57ea

Browse files
committed
fix(mcp): honor --help on the contributor-profile CLI command
contributorProfileCli had no `if (options.help === true)` short-circuit, unlike every sibling command around it (decisionPackCli, monitorOpenPrsCli, repoDecisionCli). `loopover-mcp contributor-profile --help` fell through to login resolution and threw "Pass --login ..." instead of printing usage. Add printContributorProfileHelp() and the --help guard at the top of the command, mirroring decisionPackCli. Closes #6992
1 parent a752b8f commit dee57ea

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

packages/loopover-mcp/bin/loopover-mcp.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3865,12 +3865,27 @@ function printDecisionPackHelp() {
38653865
);
38663866
}
38673867

3868+
function printContributorProfileHelp() {
3869+
process.stdout.write(
3870+
[
3871+
"Usage: loopover-mcp contributor-profile --login <github-login> [--json]",
3872+
"",
3873+
"Fetch the contributor profile for a GitHub login.",
3874+
"Mirrors the loopover_get_contributor_profile MCP tool and GET /v1/contributors/{login}/profile. No source upload.",
3875+
"",
3876+
"Login resolves from --login, the active session, LOOPOVER_LOGIN, then GITHUB_LOGIN.",
3877+
"Pass --json for machine-readable output.",
3878+
].join("\n") + "\n",
3879+
);
3880+
}
3881+
38683882
// #6737: CLI mirror of the loopover_get_contributor_profile MCP tool and GET /v1/contributors/{login}/profile
38693883
// (requireContributorAccess-gated -- the same gate decision-pack/repo-decision already satisfy). Login resolves
38703884
// from --login / the active session / LOOPOVER_LOGIN / GITHUB_LOGIN, exactly like the sibling contributor
38713885
// commands, so an already-logged-in contributor never retypes their own login. Named `contributor-profile`
38723886
// because the top-level `profile` command already manages MCP client profiles.
38733887
async function contributorProfileCli(options) {
3888+
if (options.help === true) return printContributorProfileHelp();
38743889
const login = options.login ?? activeProfile.session?.login ?? process.env.LOOPOVER_LOGIN ?? process.env.GITHUB_LOGIN;
38753890
if (!login) throw new Error("Pass --login <github-login>, log in with `loopover-mcp login`, or set LOOPOVER_LOGIN.");
38763891
const payload = await apiGet(`/v1/contributors/${encodeURIComponent(login)}/profile`);

test/unit/mcp-cli-contributor-profile.test.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { mkdtempSync, rmSync } from "node:fs";
22
import { tmpdir } from "node:os";
33
import { join } from "node:path";
44
import { afterEach, describe, expect, it } from "vitest";
5-
import { closeFixtureServer, runAsync, runExpectingFailure, startFixtureServer } from "./support/mcp-cli-harness";
5+
import { closeFixtureServer, run, runAsync, runExpectingFailure, startFixtureServer } from "./support/mcp-cli-harness";
66

77
describe("loopover-mcp CLI — contributor-profile (#6737)", () => {
88
let tempDir: string | null = null;
@@ -49,4 +49,13 @@ describe("loopover-mcp CLI — contributor-profile (#6737)", () => {
4949
expect(`${failure.stdout}${failure.stderr}`).toMatch(/Pass --login/);
5050
expect(requests.filter((url) => url.includes("/profile"))).toHaveLength(0);
5151
});
52+
53+
it("prints usage for --help without resolving a login or hitting the network (#6992)", () => {
54+
// --help must short-circuit BEFORE login resolution, so this succeeds with no --login and no server --
55+
// previously it fell through and threw the "Pass --login" error instead of printing usage.
56+
const help = run(["contributor-profile", "--help"], { LOOPOVER_LOGIN: "", GITHUB_LOGIN: "" });
57+
expect(help).toContain("Usage: loopover-mcp contributor-profile --login <github-login> [--json]");
58+
expect(help).toContain("Mirrors the loopover_get_contributor_profile MCP tool");
59+
expect(help).not.toMatch(/Pass --login/);
60+
});
5261
});

0 commit comments

Comments
 (0)