import * as github from "@actions/github"; import type { IssuesEvent, IssuesAssignedEvent, IssueCommentEvent, PullRequestEvent, PullRequestReviewEvent, PullRequestReviewCommentEvent, } from "@octokit/webhooks-types"; export type ParsedGitHubContext = { runId: string; eventName: string; eventAction?: string; repository: { owner: string; repo: string; full_name: string; }; actor: string; payload: | IssuesEvent | IssueCommentEvent | PullRequestEvent | PullRequestReviewEvent | PullRequestReviewCommentEvent; entityNumber: number; isPR: boolean; inputs: { triggerPhrase: string; assigneeTrigger: string; labelTrigger: string; allowedTools: string[]; disallowedTools: string[]; customInstructions: string; directPrompt: string; baseBranch?: string; branchPrefix: string; useStickyComment: boolean; }; }; export function parseGitHubContext(): ParsedGitHubContext { const context = github.context; const commonFields = { runId: process.env.GITHUB_RUN_ID!, eventName: context.eventName, eventAction: context.payload.action, repository: { owner: context.repo.owner, repo: context.repo.repo, full_name: `${context.repo.owner}/${context.repo.repo}`, }, actor: context.actor, inputs: { triggerPhrase: process.env.TRIGGER_PHRASE ?? "@claude", assigneeTrigger: process.env.ASSIGNEE_TRIGGER ?? "", labelTrigger: process.env.LABEL_TRIGGER ?? "", allowedTools: parseMultilineInput(process.env.ALLOWED_TOOLS ?? ""), disallowedTools: parseMultilineInput(process.env.DISALLOWED_TOOLS ?? ""), customInstructions: process.env.CUSTOM_INSTRUCTIONS ?? "", directPrompt: process.env.DIRECT_PROMPT ?? "", baseBranch: process.env.BASE_BRANCH, branchPrefix: process.env.BRANCH_PREFIX ?? "claude/", useStickyComment: process.env.STICKY_COMMENT === "true", }, }; switch (context.eventName) { case "issues": { return { ...commonFields, payload: context.payload as IssuesEvent, entityNumber: (context.payload as IssuesEvent).issue.number, isPR: false, }; } case "issue_comment": { return { ...commonFields, payload: context.payload as IssueCommentEvent, entityNumber: (context.payload as IssueCommentEvent).issue.number, isPR: Boolean( (context.payload as IssueCommentEvent).issue.pull_request, ), }; } case "pull_request": { return { ...commonFields, payload: context.payload as PullRequestEvent, entityNumber: (context.payload as PullRequestEvent).pull_request.number, isPR: true, }; } case "pull_request_review": { return { ...commonFields, payload: context.payload as PullRequestReviewEvent, entityNumber: (context.payload as PullRequestReviewEvent).pull_request .number, isPR: true, }; } case "pull_request_review_comment": { return { ...commonFields, payload: context.payload as PullRequestReviewCommentEvent, entityNumber: (context.payload as PullRequestReviewCommentEvent) .pull_request.number, isPR: true, }; } default: throw new Error(`Unsupported event type: ${context.eventName}`); } } export function parseMultilineInput(s: string): string[] { return s .split(/,|[\n\r]+/) .map((tool) => tool.replace(/#.+$/, "")) .map((tool) => tool.trim()) .filter((tool) => tool.length > 0); } export function isIssuesEvent( context: ParsedGitHubContext, ): context is ParsedGitHubContext & { payload: IssuesEvent } { return context.eventName === "issues"; } export function isIssueCommentEvent( context: ParsedGitHubContext, ): context is ParsedGitHubContext & { payload: IssueCommentEvent } { return context.eventName === "issue_comment"; } export function isPullRequestEvent( context: ParsedGitHubContext, ): context is ParsedGitHubContext & { payload: PullRequestEvent } { return context.eventName === "pull_request"; } export function isPullRequestReviewEvent( context: ParsedGitHubContext, ): context is ParsedGitHubContext & { payload: PullRequestReviewEvent } { return context.eventName === "pull_request_review"; } export function isPullRequestReviewCommentEvent( context: ParsedGitHubContext, ): context is ParsedGitHubContext & { payload: PullRequestReviewCommentEvent } { return context.eventName === "pull_request_review_comment"; } export function isIssuesAssignedEvent( context: ParsedGitHubContext, ): context is ParsedGitHubContext & { payload: IssuesAssignedEvent } { return isIssuesEvent(context) && context.eventAction === "assigned"; }