mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-22 22:44:13 +08:00
* feat: enhance mode routing with track_progress and context preservation This PR implements enhanced mode routing to address two critical v1 migration issues: 1. Lost GitHub context when using custom prompts in tag mode 2. Missing tracking comments for automatic PR reviews Changes: - Add track_progress input to force tag mode with tracking comments for PR/issue events - Support custom prompt injection in tag mode via <custom_instructions> section - Inject GitHub context as environment variables in agent mode - Validate track_progress usage (only allowed for PR/issue events) - Comprehensive test coverage for new routing logic Event Routing: - Comment events: Default to tag mode, switch to agent with explicit prompt - PR/Issue events: Default to agent mode, switch to tag mode with track_progress - Custom prompts can now be used in tag mode without losing context This ensures backward compatibility while solving context preservation and tracking visibility issues reported in discussions #490 and #491. * formatting * fix: address review comments - Simplify track_progress description to be more general - Move import to top of types.ts file * revert: keep detailed track_progress description The original description provides clarity about which specific event actions are supported. * fix: add GitHub CI MCP tools to tag mode allowed list Claude was trying to use CI status tools but they weren't in the allowed list for tag mode, causing permission errors. This fix adds the CI tools so Claude can check workflow status when reviewing PRs. * fix: provide explicit git base branch reference to prevent PR review errors - Tell Claude to use 'origin/{baseBranch}' instead of assuming 'main' - Add explicit instructions for git diff/log commands with correct base branch - Fixes 'fatal: ambiguous argument main..HEAD' error in fork environments - Claude was autonomously running git diff main..HEAD when reviewing PRs * fix prompt generation * ci pass --------- Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
230 lines
6.9 KiB
TypeScript
230 lines
6.9 KiB
TypeScript
import { describe, expect, it } from "bun:test";
|
|
import { detectMode } from "../../src/modes/detector";
|
|
import type { GitHubContext } from "../../src/github/context";
|
|
|
|
describe("detectMode with enhanced routing", () => {
|
|
const baseContext = {
|
|
runId: "test-run",
|
|
eventAction: "opened",
|
|
repository: {
|
|
owner: "test-owner",
|
|
repo: "test-repo",
|
|
full_name: "test-owner/test-repo",
|
|
},
|
|
actor: "test-user",
|
|
inputs: {
|
|
prompt: "",
|
|
triggerPhrase: "@claude",
|
|
assigneeTrigger: "",
|
|
labelTrigger: "",
|
|
branchPrefix: "claude/",
|
|
useStickyComment: false,
|
|
useCommitSigning: false,
|
|
allowedBots: "",
|
|
trackProgress: false,
|
|
},
|
|
};
|
|
|
|
describe("PR Events with track_progress", () => {
|
|
it("should use tag mode when track_progress is true for pull_request.opened", () => {
|
|
const context: GitHubContext = {
|
|
...baseContext,
|
|
eventName: "pull_request",
|
|
eventAction: "opened",
|
|
payload: { pull_request: { number: 1 } } as any,
|
|
entityNumber: 1,
|
|
isPR: true,
|
|
inputs: { ...baseContext.inputs, trackProgress: true },
|
|
};
|
|
|
|
expect(detectMode(context)).toBe("tag");
|
|
});
|
|
|
|
it("should use tag mode when track_progress is true for pull_request.synchronize", () => {
|
|
const context: GitHubContext = {
|
|
...baseContext,
|
|
eventName: "pull_request",
|
|
eventAction: "synchronize",
|
|
payload: { pull_request: { number: 1 } } as any,
|
|
entityNumber: 1,
|
|
isPR: true,
|
|
inputs: { ...baseContext.inputs, trackProgress: true },
|
|
};
|
|
|
|
expect(detectMode(context)).toBe("tag");
|
|
});
|
|
|
|
it("should use agent mode when track_progress is false for pull_request.opened", () => {
|
|
const context: GitHubContext = {
|
|
...baseContext,
|
|
eventName: "pull_request",
|
|
eventAction: "opened",
|
|
payload: { pull_request: { number: 1 } } as any,
|
|
entityNumber: 1,
|
|
isPR: true,
|
|
inputs: { ...baseContext.inputs, trackProgress: false },
|
|
};
|
|
|
|
expect(detectMode(context)).toBe("agent");
|
|
});
|
|
|
|
it("should throw error when track_progress is used with unsupported PR action", () => {
|
|
const context: GitHubContext = {
|
|
...baseContext,
|
|
eventName: "pull_request",
|
|
eventAction: "closed",
|
|
payload: { pull_request: { number: 1 } } as any,
|
|
entityNumber: 1,
|
|
isPR: true,
|
|
inputs: { ...baseContext.inputs, trackProgress: true },
|
|
};
|
|
|
|
expect(() => detectMode(context)).toThrow(
|
|
/track_progress for pull_request events is only supported for actions/,
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("Issue Events with track_progress", () => {
|
|
it("should use tag mode when track_progress is true for issues.opened", () => {
|
|
const context: GitHubContext = {
|
|
...baseContext,
|
|
eventName: "issues",
|
|
eventAction: "opened",
|
|
payload: { issue: { number: 1, body: "Test" } } as any,
|
|
entityNumber: 1,
|
|
isPR: false,
|
|
inputs: { ...baseContext.inputs, trackProgress: true },
|
|
};
|
|
|
|
expect(detectMode(context)).toBe("tag");
|
|
});
|
|
|
|
it("should use agent mode when track_progress is false for issues", () => {
|
|
const context: GitHubContext = {
|
|
...baseContext,
|
|
eventName: "issues",
|
|
eventAction: "opened",
|
|
payload: { issue: { number: 1, body: "Test" } } as any,
|
|
entityNumber: 1,
|
|
isPR: false,
|
|
inputs: { ...baseContext.inputs, trackProgress: false },
|
|
};
|
|
|
|
expect(detectMode(context)).toBe("agent");
|
|
});
|
|
});
|
|
|
|
describe("Comment Events (unchanged behavior)", () => {
|
|
it("should use tag mode for issue_comment with @claude mention", () => {
|
|
const context: GitHubContext = {
|
|
...baseContext,
|
|
eventName: "issue_comment",
|
|
payload: {
|
|
issue: { number: 1, body: "Test" },
|
|
comment: { body: "@claude help" },
|
|
} as any,
|
|
entityNumber: 1,
|
|
isPR: false,
|
|
};
|
|
|
|
expect(detectMode(context)).toBe("tag");
|
|
});
|
|
|
|
it("should use agent mode for issue_comment with prompt provided", () => {
|
|
const context: GitHubContext = {
|
|
...baseContext,
|
|
eventName: "issue_comment",
|
|
payload: {
|
|
issue: { number: 1, body: "Test" },
|
|
comment: { body: "@claude help" },
|
|
} as any,
|
|
entityNumber: 1,
|
|
isPR: false,
|
|
inputs: { ...baseContext.inputs, prompt: "Review this PR" },
|
|
};
|
|
|
|
expect(detectMode(context)).toBe("agent");
|
|
});
|
|
|
|
it("should use tag mode for PR review comments with @claude mention", () => {
|
|
const context: GitHubContext = {
|
|
...baseContext,
|
|
eventName: "pull_request_review_comment",
|
|
payload: {
|
|
pull_request: { number: 1, body: "Test" },
|
|
comment: { body: "@claude check this" },
|
|
} as any,
|
|
entityNumber: 1,
|
|
isPR: true,
|
|
};
|
|
|
|
expect(detectMode(context)).toBe("tag");
|
|
});
|
|
});
|
|
|
|
describe("Automation Events (should error with track_progress)", () => {
|
|
it("should throw error when track_progress is used with workflow_dispatch", () => {
|
|
const context: GitHubContext = {
|
|
...baseContext,
|
|
eventName: "workflow_dispatch",
|
|
payload: {} as any,
|
|
inputs: { ...baseContext.inputs, trackProgress: true },
|
|
};
|
|
|
|
expect(() => detectMode(context)).toThrow(
|
|
/track_progress is only supported for pull_request and issue events/,
|
|
);
|
|
});
|
|
|
|
it("should use agent mode for workflow_dispatch without track_progress", () => {
|
|
const context: GitHubContext = {
|
|
...baseContext,
|
|
eventName: "workflow_dispatch",
|
|
payload: {} as any,
|
|
inputs: { ...baseContext.inputs, prompt: "Run workflow" },
|
|
};
|
|
|
|
expect(detectMode(context)).toBe("agent");
|
|
});
|
|
});
|
|
|
|
describe("Custom prompt injection in tag mode", () => {
|
|
it("should use tag mode for PR events when both track_progress and prompt are provided", () => {
|
|
const context: GitHubContext = {
|
|
...baseContext,
|
|
eventName: "pull_request",
|
|
eventAction: "opened",
|
|
payload: { pull_request: { number: 1 } } as any,
|
|
entityNumber: 1,
|
|
isPR: true,
|
|
inputs: {
|
|
...baseContext.inputs,
|
|
trackProgress: true,
|
|
prompt: "Review for security issues",
|
|
},
|
|
};
|
|
|
|
expect(detectMode(context)).toBe("tag");
|
|
});
|
|
|
|
it("should use tag mode for issue events when both track_progress and prompt are provided", () => {
|
|
const context: GitHubContext = {
|
|
...baseContext,
|
|
eventName: "issues",
|
|
eventAction: "opened",
|
|
payload: { issue: { number: 1, body: "Test" } } as any,
|
|
entityNumber: 1,
|
|
isPR: false,
|
|
inputs: {
|
|
...baseContext.inputs,
|
|
trackProgress: true,
|
|
prompt: "Analyze this issue",
|
|
},
|
|
};
|
|
|
|
expect(detectMode(context)).toBe("tag");
|
|
});
|
|
});
|
|
});
|