refactor: simplify mode system by removing Mode interface and registry (#899)

Replace the over-engineered Mode interface/registry/detector pattern with
straightforward inline logic. There are only 2 modes (tag and agent) and
the complexity wasn't justified.

- Delete Mode interface, registry, and prepare pass-through modules
- Export prepareTagMode() and prepareAgentMode() as standalone functions
- Inline trigger checking and mode dispatch in run.ts/prepare.ts
- Change generatePrompt/createPrompt to take modeName string instead of Mode
- Remove dead code (extractGitHubContext, unused detector helpers)
- Update CLAUDE.md to reflect new architecture
This commit is contained in:
Ashwin Bhat
2026-02-05 17:22:30 -08:00
committed by GitHub
parent f09dc9a6a3
commit 7057f3318b
16 changed files with 390 additions and 1300 deletions
+11 -84
View File
@@ -1,38 +1,10 @@
#!/usr/bin/env bun
import { describe, test, expect } from "bun:test";
import {
getEventTypeAndContext,
generatePrompt,
generateDefaultPrompt,
} from "../src/create-prompt";
import { getEventTypeAndContext, generatePrompt } from "../src/create-prompt";
import type { PreparedContext } from "../src/create-prompt";
import type { Mode } from "../src/modes/types";
describe("pull_request_target event support", () => {
// Mock tag mode for testing
const mockTagMode: Mode = {
name: "tag",
description: "Tag mode",
shouldTrigger: () => true,
prepareContext: (context) => ({ mode: "tag", githubContext: context }),
getAllowedTools: () => [],
getDisallowedTools: () => [],
shouldCreateTrackingComment: () => true,
generatePrompt: (context, githubData, useCommitSigning) =>
generateDefaultPrompt(context, githubData, useCommitSigning),
prepare: async () => ({
commentId: 123,
branchInfo: {
baseBranch: "main",
currentBranch: "main",
claudeBranch: undefined,
},
mcpConfig: "{}",
claudeArgs: "",
}),
};
const mockGitHubData = {
contextData: {
title: "External PR via pull_request_target",
@@ -126,12 +98,7 @@ describe("pull_request_target event support", () => {
},
};
const prompt = generatePrompt(
envVars,
mockGitHubData,
false,
mockTagMode,
);
const prompt = generatePrompt(envVars, mockGitHubData, false, "tag");
// Should contain pull request event type and metadata
expect(prompt).toContain("<event_type>PULL_REQUEST</event_type>");
@@ -165,12 +132,7 @@ describe("pull_request_target event support", () => {
},
};
const prompt = generatePrompt(
envVars,
mockGitHubData,
false,
mockTagMode,
);
const prompt = generatePrompt(envVars, mockGitHubData, false, "tag");
// Should include git commands for non-commit-signing mode
expect(prompt).toContain("git push");
@@ -196,7 +158,7 @@ describe("pull_request_target event support", () => {
},
};
const prompt = generatePrompt(envVars, mockGitHubData, true, mockTagMode);
const prompt = generatePrompt(envVars, mockGitHubData, true, "tag");
// Should include commit signing tools
expect(prompt).toContain("mcp__github_file_ops__commit_files");
@@ -246,13 +208,13 @@ describe("pull_request_target event support", () => {
pullRequestContext,
mockGitHubData,
false,
mockTagMode,
"tag",
);
const pullRequestTargetPrompt = generatePrompt(
pullRequestTargetContext,
mockGitHubData,
false,
mockTagMode,
"tag",
);
// Both should have the same event type and structure
@@ -293,37 +255,7 @@ describe("pull_request_target event support", () => {
},
};
// Use agent mode which passes through the prompt as-is
const mockAgentMode: Mode = {
name: "agent",
description: "Agent mode",
shouldTrigger: () => true,
prepareContext: (context) => ({
mode: "agent",
githubContext: context,
}),
getAllowedTools: () => [],
getDisallowedTools: () => [],
shouldCreateTrackingComment: () => true,
generatePrompt: (context) => context.prompt || "default prompt",
prepare: async () => ({
commentId: 123,
branchInfo: {
baseBranch: "main",
currentBranch: "main",
claudeBranch: undefined,
},
mcpConfig: "{}",
claudeArgs: "",
}),
};
const prompt = generatePrompt(
envVars,
mockGitHubData,
false,
mockAgentMode,
);
const prompt = generatePrompt(envVars, mockGitHubData, false, "agent");
expect(prompt).toBe(
"Review this pull_request_target PR for security issues",
@@ -343,12 +275,7 @@ describe("pull_request_target event support", () => {
},
};
const prompt = generatePrompt(
envVars,
mockGitHubData,
false,
mockTagMode,
);
const prompt = generatePrompt(envVars, mockGitHubData, false, "tag");
// Should generate default prompt structure
expect(prompt).toContain("<event_type>PULL_REQUEST</event_type>");
@@ -418,7 +345,7 @@ describe("pull_request_target event support", () => {
// Should not throw when generating prompt
expect(() => {
generatePrompt(minimalContext, mockGitHubData, false, mockTagMode);
generatePrompt(minimalContext, mockGitHubData, false, "tag");
}).not.toThrow();
});
@@ -476,13 +403,13 @@ describe("pull_request_target event support", () => {
internalPR,
mockGitHubData,
false,
mockTagMode,
"tag",
);
const externalPrompt = generatePrompt(
externalPR,
mockGitHubData,
false,
mockTagMode,
"tag",
);
// Should have same tool access patterns