- Fix actor validation: "skipped entirely" → "bot-type check skipped; self-trigger guard active" - Fix permission check: document getCollaboratorPermissionLevel() primary with repos.get() fallback - Add platform detection cross-validation security note (rejects Forgejo override on github.com) - Fix update-with-branch.ts description: "PR compare URL" → "branch link" (URL is in update-comment-link.ts) - Add missing update-comment-link.ts to key integration points in CLAUDE.md - Fix test-action.yml description to match actual validation checks - Nuance troubleshooting guidance for # in workflow if: expressions - Verify all Known Limitations still accurate Progress: 100% complete — all 6 milestones done Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5.8 KiB
CLAUDE.md
Commands
bun test # Run tests
bun run typecheck # TypeScript type checking
bun run format # Format with prettier
bun run format:check # Check formatting
What This Is
A GitHub Action that lets Claude respond to @claude mentions on issues/PRs (tag mode) or run tasks via prompt input (agent mode). Mode is auto-detected: if prompt is provided, it's agent mode; if triggered by a comment/issue event with @claude, it's tag mode. See src/modes/detector.ts.
How It Runs
Single entrypoint: src/entrypoints/run.ts orchestrates everything — prepare (auth, permissions, trigger check, branch/comment creation), install Claude Code CLI, execute Claude via base-action/ functions (imported directly, not subprocess), then cleanup (update tracking comment, write step summary). SSH signing cleanup and token revocation are separate always() steps in action.yml.
base-action/ is also published standalone as @anthropic-ai/claude-code-base-action. Don't break its public API. It reads config from INPUT_-prefixed env vars (set by action.yml), not from action inputs directly.
Key Concepts
Auth priority: github_token input (user-provided) > GitHub App OIDC token (default). The claude_code_oauth_token and anthropic_api_key are for the Claude API, not GitHub. Token setup lives in src/github/token.ts.
Mode lifecycle: detectMode() in src/modes/detector.ts picks the mode name ("tag" or "agent"). Trigger checking and prepare dispatch are inlined in run.ts: tag mode calls prepareTagMode() from src/modes/tag/, agent mode calls prepareAgentMode() from src/modes/agent/.
Prompt construction: Tag mode's prepareTagMode() builds the prompt by fetching GitHub data (src/github/data/fetcher.ts), formatting it as markdown (src/github/data/formatter.ts), and writing it to a temp file via createPrompt(). Agent mode writes the user's prompt directly. The prompt includes issue/PR body, comments, diff, and CI status. This is the most important part of the action — it's what Claude sees.
Things That Will Bite You
- Strict TypeScript:
noUnusedLocalsandnoUnusedParametersare enabled. Typecheck will fail on unused variables. - Discriminated unions for GitHub context:
GitHubContextis a union type — callisEntityContext(context)before accessing entity-specific fields likecontext.issueorcontext.pullRequest. - Token lifecycle matters: The GitHub App token is obtained early and revoked in a separate
always()step inaction.yml. If you move token revocation intorun.ts, it won't run if the process crashes. Same for SSH signing cleanup. - Error phase attribution: The catch block in
run.tsusesprepareCompletedto distinguish prepare failures from execution failures. The tracking comment shows different messages for each. action.ymloutputs reference step IDs: Outputs likeexecution_file,branch_name,github_tokenreferencesteps.run.outputs.*. If you rename the step ID, update the outputs section too.- Integration testing happens in a separate repo (
install-test), not here. The tests in this repo are unit tests.
Forgejo Platform Support
This fork adds Forgejo support via a lean adapter pattern — only 4 genuinely different areas have Forgejo-specific code:
src/platform/detector.ts— Three-tier platform detection (explicit input >FORGEJOenv >GITHUB_SERVER_URLheuristic) with cross-validation that rejects Forgejo override on github.comsrc/forgejo/token.ts— Direct token handling (skips OIDC exchange)src/forgejo/data/fetcher.ts— REST-based data fetching (replaces 3 GraphQL queries with 5-8 parallel REST calls)src/forgejo/comment-logic.ts— Forgejo URL patterns for tracking comments
All other src/github/ modules work on Forgejo via Octokit REST as-is (permissions, comments, branches, git config, context, formatter).
Bot identity on Forgejo: A dedicated claude user provides bot identity (like GitHub's claude[bot]). The bot_id, bot_name, and bot_email action inputs control git commit attribution. When bot_email is set, it overrides the default noreply email format — set it to the bot user's registered email so Forgejo links commits to the profile. See docs/forgejo.md for setup.
Key integration points (these files have platform branches and are merge-conflict surface):
src/entrypoints/run.ts— Platform branch at top for token setupsrc/modes/tag/index.ts— Data fetcher swap (fetchForgejoDatavsfetchGitHubData)src/github/operations/comments/create-initial.ts— Platform-aware spinner/URL formatsrc/github/operations/comments/update-with-branch.ts— Forgejo branch link in tracking commentsrc/github/operations/branch.ts— Usesrepos.getBranch()on Forgejo (Forgejo has/git/refsnot/git/ref)src/github/validation/actor.ts— Bot-type check skipped on Forgejo; self-trigger guard activesrc/entrypoints/update-comment-link.ts— Forgejo PR compare URL (expand=1instead ofquick_pull=1)src/mcp/install-mcp-server.ts— Skips GitHub public MCP server on Forgejo
MCP server names stay the same (github_comment, github_ci, etc.) even on Forgejo — changing them would require updating hardcoded tool name lists in src/modes/tag/index.ts.
CI: .forgejo/workflows/ contains claude.yml (tag mode), ci.yml, test-action.yml, and upstream-sync.yml. Unit tests run with GITHUB_SERVER_URL=https://github.com override on Forgejo runners.
Code Conventions
- Runtime is Bun, not Node. Use
bun test, notjest. moduleResolution: "bundler"— imports don't need.jsextensions.- GitHub API calls should use retry logic (
src/utils/retry.ts). - MCP servers are auto-installed at runtime to
~/.claude/mcp/github-{type}-server/.