mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-08-22 03:18:54 +08:00
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:
+12
-90
@@ -7,22 +7,17 @@ import {
|
||||
spyOn,
|
||||
mock,
|
||||
} from "bun:test";
|
||||
import { agentMode } from "../../src/modes/agent";
|
||||
import type { GitHubContext } from "../../src/github/context";
|
||||
import { createMockContext, createMockAutomationContext } from "../mockContext";
|
||||
import { prepareAgentMode } from "../../src/modes/agent";
|
||||
import { createMockAutomationContext } from "../mockContext";
|
||||
import * as core from "@actions/core";
|
||||
import * as gitConfig from "../../src/github/operations/git-config";
|
||||
|
||||
describe("Agent Mode", () => {
|
||||
let mockContext: GitHubContext;
|
||||
let exportVariableSpy: any;
|
||||
let setOutputSpy: any;
|
||||
let configureGitAuthSpy: any;
|
||||
|
||||
beforeEach(() => {
|
||||
mockContext = createMockAutomationContext({
|
||||
eventName: "workflow_dispatch",
|
||||
});
|
||||
exportVariableSpy = spyOn(core, "exportVariable").mockImplementation(
|
||||
() => {},
|
||||
);
|
||||
@@ -45,84 +40,11 @@ describe("Agent Mode", () => {
|
||||
configureGitAuthSpy?.mockRestore();
|
||||
});
|
||||
|
||||
test("agent mode has correct properties", () => {
|
||||
expect(agentMode.name).toBe("agent");
|
||||
expect(agentMode.description).toBe(
|
||||
"Direct automation mode for explicit prompts",
|
||||
);
|
||||
expect(agentMode.shouldCreateTrackingComment()).toBe(false);
|
||||
expect(agentMode.getAllowedTools()).toEqual([]);
|
||||
expect(agentMode.getDisallowedTools()).toEqual([]);
|
||||
test("prepareAgentMode is exported as a function", () => {
|
||||
expect(typeof prepareAgentMode).toBe("function");
|
||||
});
|
||||
|
||||
test("prepareContext returns minimal data", () => {
|
||||
const context = agentMode.prepareContext(mockContext);
|
||||
|
||||
expect(context.mode).toBe("agent");
|
||||
expect(context.githubContext).toBe(mockContext);
|
||||
// Agent mode doesn't use comment tracking or branch management
|
||||
expect(Object.keys(context)).toEqual(["mode", "githubContext"]);
|
||||
});
|
||||
|
||||
test("agent mode only triggers when prompt is provided", () => {
|
||||
// Should NOT trigger for automation events without prompt
|
||||
const workflowDispatchContext = createMockAutomationContext({
|
||||
eventName: "workflow_dispatch",
|
||||
});
|
||||
expect(agentMode.shouldTrigger(workflowDispatchContext)).toBe(false);
|
||||
|
||||
const scheduleContext = createMockAutomationContext({
|
||||
eventName: "schedule",
|
||||
});
|
||||
expect(agentMode.shouldTrigger(scheduleContext)).toBe(false);
|
||||
|
||||
const repositoryDispatchContext = createMockAutomationContext({
|
||||
eventName: "repository_dispatch",
|
||||
});
|
||||
expect(agentMode.shouldTrigger(repositoryDispatchContext)).toBe(false);
|
||||
|
||||
// Should NOT trigger for entity events without prompt
|
||||
const entityEvents = [
|
||||
"issue_comment",
|
||||
"pull_request",
|
||||
"pull_request_review",
|
||||
"issues",
|
||||
] as const;
|
||||
|
||||
entityEvents.forEach((eventName) => {
|
||||
const contextNoPrompt = createMockContext({ eventName });
|
||||
expect(agentMode.shouldTrigger(contextNoPrompt)).toBe(false);
|
||||
});
|
||||
|
||||
// Should trigger for ANY event when prompt is provided
|
||||
const allEvents = [
|
||||
"workflow_dispatch",
|
||||
"repository_dispatch",
|
||||
"schedule",
|
||||
"issue_comment",
|
||||
"pull_request",
|
||||
"pull_request_review",
|
||||
"issues",
|
||||
] as const;
|
||||
|
||||
allEvents.forEach((eventName) => {
|
||||
const contextWithPrompt =
|
||||
eventName === "workflow_dispatch" ||
|
||||
eventName === "repository_dispatch" ||
|
||||
eventName === "schedule"
|
||||
? createMockAutomationContext({
|
||||
eventName,
|
||||
inputs: { prompt: "Do something" },
|
||||
})
|
||||
: createMockContext({
|
||||
eventName,
|
||||
inputs: { prompt: "Do something" },
|
||||
});
|
||||
expect(agentMode.shouldTrigger(contextWithPrompt)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test("prepare method passes through claude_args", async () => {
|
||||
test("prepare passes through claude_args", async () => {
|
||||
// Clear any previous calls before this test
|
||||
exportVariableSpy.mockClear();
|
||||
setOutputSpy.mockClear();
|
||||
@@ -156,7 +78,7 @@ describe("Agent Mode", () => {
|
||||
},
|
||||
},
|
||||
} as any;
|
||||
const result = await agentMode.prepare({
|
||||
const result = await prepareAgentMode({
|
||||
context: contextWithCustomArgs,
|
||||
octokit: mockOctokit,
|
||||
githubToken: "test-token",
|
||||
@@ -186,7 +108,7 @@ describe("Agent Mode", () => {
|
||||
process.env.GITHUB_REF_NAME = originalRefName;
|
||||
});
|
||||
|
||||
test("prepare method rejects bot actors without allowed_bots", async () => {
|
||||
test("prepare rejects bot actors without allowed_bots", async () => {
|
||||
const contextWithPrompts = createMockAutomationContext({
|
||||
eventName: "workflow_dispatch",
|
||||
});
|
||||
@@ -206,7 +128,7 @@ describe("Agent Mode", () => {
|
||||
} as any;
|
||||
|
||||
await expect(
|
||||
agentMode.prepare({
|
||||
prepareAgentMode({
|
||||
context: contextWithPrompts,
|
||||
octokit: mockOctokit,
|
||||
githubToken: "test-token",
|
||||
@@ -216,7 +138,7 @@ describe("Agent Mode", () => {
|
||||
);
|
||||
});
|
||||
|
||||
test("prepare method allows bot actors when in allowed_bots list", async () => {
|
||||
test("prepare allows bot actors when in allowed_bots list", async () => {
|
||||
const contextWithPrompts = createMockAutomationContext({
|
||||
eventName: "workflow_dispatch",
|
||||
});
|
||||
@@ -237,7 +159,7 @@ describe("Agent Mode", () => {
|
||||
|
||||
// Should not throw - bot is in allowed list
|
||||
await expect(
|
||||
agentMode.prepare({
|
||||
prepareAgentMode({
|
||||
context: contextWithPrompts,
|
||||
octokit: mockOctokit,
|
||||
githubToken: "test-token",
|
||||
@@ -245,7 +167,7 @@ describe("Agent Mode", () => {
|
||||
).resolves.toBeDefined();
|
||||
});
|
||||
|
||||
test("prepare method creates prompt file with correct content", async () => {
|
||||
test("prepare creates prompt file with correct content", async () => {
|
||||
const contextWithPrompts = createMockAutomationContext({
|
||||
eventName: "workflow_dispatch",
|
||||
});
|
||||
@@ -268,7 +190,7 @@ describe("Agent Mode", () => {
|
||||
},
|
||||
},
|
||||
} as any;
|
||||
const result = await agentMode.prepare({
|
||||
const result = await prepareAgentMode({
|
||||
context: contextWithPrompts,
|
||||
octokit: mockOctokit,
|
||||
githubToken: "test-token",
|
||||
|
||||
Reference in New Issue
Block a user