refactor: implement discriminated unions for GitHub contexts

Split ParsedGitHubContext into entity-specific and automation contexts:
- ParsedGitHubContext: For entity events (issues/PRs) with required entityNumber and isPR
- AutomationContext: For workflow_dispatch/schedule events without entity fields
- GitHubContext: Union type for all contexts

This eliminates ~20 null checks throughout the codebase and provides better type safety.
Entity-specific code paths are now guaranteed to have the required fields.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
km-anthropic
2025-07-29 13:09:01 -07:00
parent f1ce8b3d62
commit b1033b2ba1
14 changed files with 171 additions and 132 deletions

View File

@@ -1,15 +1,14 @@
import { describe, test, expect, beforeEach } from "bun:test";
import { agentMode } from "../../src/modes/agent";
import type { ParsedGitHubContext } from "../../src/github/context";
import { createMockContext } from "../mockContext";
import type { GitHubContext } from "../../src/github/context";
import { createMockContext, createMockAutomationContext } from "../mockContext";
describe("Agent Mode", () => {
let mockContext: ParsedGitHubContext;
let mockContext: GitHubContext;
beforeEach(() => {
mockContext = createMockContext({
mockContext = createMockAutomationContext({
eventName: "workflow_dispatch",
isPR: false,
});
});
@@ -34,30 +33,26 @@ describe("Agent Mode", () => {
test("agent mode only triggers for workflow_dispatch and schedule events", () => {
// Should trigger for automation events
const workflowDispatchContext = createMockContext({
const workflowDispatchContext = createMockAutomationContext({
eventName: "workflow_dispatch",
isPR: false,
});
expect(agentMode.shouldTrigger(workflowDispatchContext)).toBe(true);
const scheduleContext = createMockContext({
const scheduleContext = createMockAutomationContext({
eventName: "schedule",
isPR: false,
});
expect(agentMode.shouldTrigger(scheduleContext)).toBe(true);
// Should NOT trigger for other events
const otherEvents = [
"push",
"repository_dispatch",
// Should NOT trigger for entity events
const entityEvents = [
"issue_comment",
"pull_request",
"pull_request_review",
"issues",
];
] as const;
otherEvents.forEach((eventName) => {
const context = createMockContext({ eventName, isPR: false });
entityEvents.forEach((eventName) => {
const context = createMockContext({ eventName });
expect(agentMode.shouldTrigger(context)).toBe(false);
});
});