diff --git a/src/create-prompt/index.ts b/src/create-prompt/index.ts index 7b332f4..d498cf9 100644 --- a/src/create-prompt/index.ts +++ b/src/create-prompt/index.ts @@ -418,6 +418,7 @@ ${ } ${context.claudeCommentId} ${context.triggerUsername ?? "Unknown"} +${githubData.triggerDisplayName ?? context.triggerUsername ?? "Unknown"} ${context.triggerPhrase} ${ (eventData.eventName === "issue_comment" || @@ -503,12 +504,14 @@ ${context.directPrompt ? ` - DIRECT INSTRUCTION: A direct instruction was prov ? ` - Push directly using mcp__github_file_ops__commit_files to the existing branch (works for both new and existing files). - Use mcp__github_file_ops__commit_files to commit files atomically in a single commit (supports single or multiple files). - - When pushing changes with this tool and TRIGGER_USERNAME is not "Unknown", include a "Co-authored-by: ${context.triggerUsername} <${context.triggerUsername}@users.noreply.github.com>" line in the commit message.` + - When pushing changes with this tool and the trigger user is not "Unknown", include a Co-authored-by trailer in the commit message. + - Use: "Co-authored-by: ${githubData.triggerDisplayName ?? context.triggerUsername} <${context.triggerUsername}@users.noreply.github.com>"` : ` - You are already on the correct branch (${eventData.claudeBranch || "the PR branch"}). Do not create a new branch. - Push changes directly to the current branch using mcp__github_file_ops__commit_files (works for both new and existing files) - Use mcp__github_file_ops__commit_files to commit files atomically in a single commit (supports single or multiple files). - - When pushing changes and TRIGGER_USERNAME is not "Unknown", include a "Co-authored-by: ${context.triggerUsername} <${context.triggerUsername}@users.noreply.github.com>" line in the commit message. + - When pushing changes and the trigger user is not "Unknown", include a Co-authored-by trailer in the commit message. + - Use: "Co-authored-by: ${githubData.triggerDisplayName ?? context.triggerUsername} <${context.triggerUsername}@users.noreply.github.com>" ${ eventData.claudeBranch ? `- Provide a URL to create a PR manually in this format: diff --git a/src/entrypoints/prepare.ts b/src/entrypoints/prepare.ts index 6b240d8..f8b5dc2 100644 --- a/src/entrypoints/prepare.ts +++ b/src/entrypoints/prepare.ts @@ -59,6 +59,7 @@ async function run() { repository: `${context.repository.owner}/${context.repository.repo}`, prNumber: context.entityNumber.toString(), isPR: context.isPR, + triggerUsername: context.actor, }); // Step 8: Setup branch diff --git a/src/github/api/queries/github.ts b/src/github/api/queries/github.ts index 20b5db9..e0e4c25 100644 --- a/src/github/api/queries/github.ts +++ b/src/github/api/queries/github.ts @@ -104,3 +104,11 @@ export const ISSUE_QUERY = ` } } `; + +export const USER_QUERY = ` + query($login: String!) { + user(login: $login) { + name + } + } +`; diff --git a/src/github/data/fetcher.ts b/src/github/data/fetcher.ts index a5b0b0a..b1dc26d 100644 --- a/src/github/data/fetcher.ts +++ b/src/github/data/fetcher.ts @@ -1,6 +1,6 @@ import { execSync } from "child_process"; import type { Octokits } from "../api/client"; -import { ISSUE_QUERY, PR_QUERY } from "../api/queries/github"; +import { ISSUE_QUERY, PR_QUERY, USER_QUERY } from "../api/queries/github"; import type { GitHubComment, GitHubFile, @@ -18,6 +18,7 @@ type FetchDataParams = { repository: string; prNumber: string; isPR: boolean; + triggerUsername?: string; }; export type GitHubFileWithSHA = GitHubFile & { @@ -31,6 +32,7 @@ export type FetchDataResult = { changedFilesWithSHA: GitHubFileWithSHA[]; reviewData: { nodes: GitHubReview[] } | null; imageUrlMap: Map; + triggerDisplayName?: string | null; }; export async function fetchGitHubData({ @@ -38,6 +40,7 @@ export async function fetchGitHubData({ repository, prNumber, isPR, + triggerUsername, }: FetchDataParams): Promise { const [owner, repo] = repository.split("/"); if (!owner || !repo) { @@ -191,6 +194,12 @@ export async function fetchGitHubData({ allComments, ); + // Fetch trigger user display name if username is provided + let triggerDisplayName: string | null | undefined; + if (triggerUsername) { + triggerDisplayName = await fetchUserDisplayName(octokits, triggerUsername); + } + return { contextData, comments, @@ -198,5 +207,27 @@ export async function fetchGitHubData({ changedFilesWithSHA, reviewData, imageUrlMap, + triggerDisplayName, }; } + +export type UserQueryResponse = { + user: { + name: string | null; + }; +}; + +export async function fetchUserDisplayName( + octokits: Octokits, + login: string, +): Promise { + try { + const result = await octokits.graphql(USER_QUERY, { + login, + }); + return result.user.name; + } catch (error) { + console.warn(`Failed to fetch user display name for ${login}:`, error); + return null; + } +} diff --git a/src/github/types.ts b/src/github/types.ts index 28c4aa1..c46c29f 100644 --- a/src/github/types.ts +++ b/src/github/types.ts @@ -1,6 +1,7 @@ // Types for GitHub GraphQL query responses export type GitHubAuthor = { login: string; + name?: string; }; export type GitHubComment = { diff --git a/test/create-prompt.test.ts b/test/create-prompt.test.ts index 65c5625..472ff65 100644 --- a/test/create-prompt.test.ts +++ b/test/create-prompt.test.ts @@ -316,7 +316,7 @@ describe("generatePrompt", () => { expect(prompt).toContain("johndoe"); expect(prompt).toContain( - "Co-authored-by: johndoe ", + 'Use: "Co-authored-by: johndoe "', ); });