Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/mcp/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2343,16 +2343,18 @@
}

private async explainScoreBreakdown(input: z.infer<z.ZodObject<typeof scorePreviewShape>>): Promise<ToolPayload> {
if (!input.contributorLogin) throw new Error("contributorLogin is required for score breakdown.");

Check notice on line 2346 in src/mcp/server.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Issue discovery is disabled for this repo

This repo is configured for direct contribution review rather than issue-discovery flow.

Check notice on line 2346 in src/mcp/server.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

PR author has maintainer association

This PR appears to come from a maintainer-associated account.
this.requireContributorAccess(input.contributorLogin);
await this.requireRepoAccess(input.repoFullName);
const [repo, snapshot, evidence] = await Promise.all([
const [repo, snapshot, evidence, contributorIssues] = await Promise.all([
getRepository(this.env, input.repoFullName),
getOrCreateScoringModelSnapshot(this.env),
getContributorEvidence(this.env, input.contributorLogin),
listContributorIssues(this.env, input.contributorLogin),
]);
const openIssueCount = contributorOpenIssueCount(contributorIssues, input.repoFullName);
// Time-decay (#703) is an owner-gated global, injected server-side (not caller-controllable).
const scoreInput = { ...input, applyTimeDecay: isTimeDecayEnabled(this.env) };
const scoreInput = { ...input, openIssueCount, applyTimeDecay: isTimeDecayEnabled(this.env) };
const preview = buildScorePreview({ input: scoreInput, repo, snapshot, contributorEvidence: evidence });
const breakdown = explainScoreBreakdown(preview);
return {
Expand Down
52 changes: 52 additions & 0 deletions test/unit/mcp-output-schemas.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,61 @@
const data = result.structuredContent as Record<string, unknown>;
expect(data.repoFullName).toBe("octo/demo");
expect(Array.isArray(data.components)).toBe(true);
expect(data.highestLeverageLever).toBeTruthy();

Check notice on line 271 in test/unit/mcp-output-schemas.test.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Issue discovery is disabled for this repo

This repo is configured for direct contribution review rather than issue-discovery flow.

Check notice on line 271 in test/unit/mcp-output-schemas.test.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

PR author has maintainer association

This PR appears to come from a maintainer-associated account.
});

it("gittensory_explain_score_breakdown applies trusted open-issue counts", async () => {
const env = createTestEnv();
await upsertRepositoryFromGitHub(env, { name: "demo", full_name: "octo/demo", private: false, owner: { login: "octo" }, default_branch: "main" });
for (const number of [1, 2, 3]) {
await upsertIssueFromGitHub(env, "octo/demo", {
number,
title: `Open contributor issue ${number}`,
state: "open",
user: { login: "alice" },
labels: [],
body: "Issue body",
});
}
await upsertIssueFromGitHub(env, "octo/other", {
number: 99,
title: "Other repo issue",
state: "open",
user: { login: "alice" },
labels: [],
body: "Issue body",
});
await upsertIssueFromGitHub(env, "octo/demo", {
number: 4,
title: "Closed contributor issue",
state: "closed",
user: { login: "alice" },
labels: [],
body: "Issue body",
});

const { client } = await connectTestClient(env);
const result = await client.callTool({
name: "gittensory_explain_score_breakdown",
arguments: {
repoFullName: "octo/demo",
contributorLogin: "alice",
sourceTokenScore: 40,
totalTokenScore: 60,
sourceLines: 80,
openPrCount: 0,
credibility: 1,
},
});

expect(result.isError).toBeFalsy();
const data = result.structuredContent as Record<string, unknown>;
expect(data.effectiveEstimatedScore).toBe(0);
expect(data.gateHighlights).toEqual(
expect.arrayContaining([expect.objectContaining({ gate: "open_issue_threshold" })]),
);
});

it("gittensory_explain_score_breakdown requires contributorLogin", async () => {
const env = createTestEnv();
await upsertRepositoryFromGitHub(env, { name: "demo", full_name: "octo/demo", private: false, owner: { login: "octo" }, default_branch: "main" });
Expand Down
Loading