fix: address PR review feedback

- Use path.dirname() instead of manual string slicing for executable path
- Differentiate prepare vs execution errors in catch block so tracking
  comment accurately reflects which phase failed
- Rewrite CLAUDE.md to focus on mental model, key concepts, and gotchas
  instead of exhaustive file listings
This commit is contained in:
Ashwin Bhat 2026-02-03 18:53:35 -08:00
parent 0f45be3f67
commit 87d760a977
No known key found for this signature in database

149
CLAUDE.md
View File

@ -1,143 +1,44 @@
# CLAUDE.md # CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Commands
## Development Tools
- Runtime: Bun 1.2.11
- TypeScript with strict configuration
## Common Development Tasks
### Available npm/bun scripts from package.json:
```bash ```bash
# Test bun test # Run tests
bun test bun run typecheck # TypeScript type checking
bun run format # Format with prettier
# Formatting bun run format:check # Check formatting
bun run format # Format code with prettier
bun run format:check # Check code formatting
# Type checking
bun run typecheck # Run TypeScript type checker
``` ```
## Architecture Overview ## What This Is
This is a GitHub Action that enables Claude to interact with GitHub PRs and issues. The action runs through a unified entrypoint (`src/entrypoints/run.ts`) that orchestrates four internal phases within a single composite step: 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/registry.ts`.
### Phase 1: Prepare ## How It Runs
1. **Authentication Setup**: Establishes GitHub token via OIDC or GitHub App 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`.
2. **Permission Validation**: Verifies actor has write permissions
3. **Trigger Detection**: Uses mode-specific logic to determine if Claude should respond
4. **Context Creation**: Prepares GitHub context, initial tracking comment, and branch
### Phase 2: Install `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.
1. **Claude Code CLI**: Installs the CLI (with retry logic), or uses a custom executable path ## Key Concepts
### Phase 3: Execute **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`.
Imports `base-action/` functions directly (no subprocess) to run Claude: **Mode lifecycle**: Modes implement `shouldTrigger()``prepare()``prepareContext()``getSystemPrompt()`. The registry in `src/modes/registry.ts` picks the mode based on event type and inputs. To add a new mode, implement the `Mode` type from `src/modes/types.ts` and register it.
1. **Environment Setup**: Validates env vars, configures Claude Code settings, installs plugins **Prompt construction**: `src/prepare/` 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. 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.
2. **Prompt Preparation**: Writes the context-rich prompt to a temp file
3. **Claude Integration**: Executes via multiple providers (Anthropic API, AWS Bedrock, Google Vertex AI)
The `base-action/` directory is also published separately as `@anthropic-ai/claude-code-base-action` for standalone use. ## Things That Will Bite You
### Phase 4: Cleanup (always runs) - **Strict TypeScript**: `noUnusedLocals` and `noUnusedParameters` are enabled. Typecheck will fail on unused variables.
- **Discriminated unions for GitHub context**: `GitHubContext` is a union type — call `isEntityContext(context)` before accessing entity-specific fields like `context.issue` or `context.pullRequest`.
1. **Comment Update**: Updates the tracking comment with job link, branch, and status - **Token lifecycle matters**: The GitHub App token is obtained early and revoked in a separate `always()` step in `action.yml`. If you move token revocation into `run.ts`, it won't run if the process crashes. Same for SSH signing cleanup.
2. **Step Summary**: Formats Claude's output into the GitHub Actions step summary - **Error phase attribution**: The catch block in `run.ts` uses `prepareCompleted` to distinguish prepare failures from execution failures. The tracking comment shows different messages for each.
3. **SSH Signing Cleanup**: Removes SSH signing key (separate composite step, runs with `always()`) - **`action.yml` outputs reference step IDs**: Outputs like `execution_file`, `branch_name`, `github_token` reference `steps.run.outputs.*`. If you rename the step ID, update the outputs section too.
4. **Token Revocation**: Revokes the GitHub App installation token (separate composite step, runs with `always()`) - **Integration testing** happens in a separate repo (`install-test`), not here. The tests in this repo are unit tests.
### Key Architectural Components
#### Mode System (`src/modes/`)
- **Tag Mode** (`tag/`): Responds to `@claude` mentions and issue assignments
- **Agent Mode** (`agent/`): Direct execution when explicit prompt is provided
- Extensible registry pattern in `modes/registry.ts`
#### GitHub Integration (`src/github/`)
- **Context Parsing** (`context.ts`): Unified GitHub event handling
- **Data Fetching** (`data/fetcher.ts`): Retrieves PR/issue data via GraphQL/REST
- **Data Formatting** (`data/formatter.ts`): Converts GitHub data to Claude-readable format
- **Branch Operations** (`operations/branch.ts`): Handles branch creation and cleanup
- **Comment Management** (`operations/comments/`): Creates and updates tracking comments
#### MCP Server Integration (`src/mcp/`)
- **GitHub Actions Server** (`github-actions-server.ts`): Workflow and CI access
- **GitHub Comment Server** (`github-comment-server.ts`): Comment operations
- **GitHub File Operations** (`github-file-ops-server.ts`): File system access
- Auto-installation and configuration in `install-mcp-server.ts`
#### Authentication & Security (`src/github/`)
- **Token Management** (`token.ts`): OIDC token exchange and GitHub App authentication
- **Permission Validation** (`validation/permissions.ts`): Write access verification
- **Actor Validation** (`validation/actor.ts`): Human vs bot detection
### Project Structure
```
src/
├── entrypoints/ # Action entry points
│ ├── run.ts # Unified entrypoint (orchestrates all phases)
│ ├── update-comment-link.ts # Post-execution comment updates
│ └── format-turns.ts # Claude conversation formatting
├── github/ # GitHub integration layer
│ ├── api/ # REST/GraphQL clients
│ ├── data/ # Data fetching and formatting
│ ├── operations/ # Branch, comment, git operations
│ ├── validation/ # Permission and trigger validation
│ └── utils/ # Image downloading, sanitization
├── modes/ # Execution modes
│ ├── tag/ # @claude mention mode
│ ├── agent/ # Automation mode
│ └── registry.ts # Mode selection logic
├── mcp/ # MCP server implementations
├── prepare/ # Preparation orchestration
└── utils/ # Shared utilities
```
## Important Implementation Notes
### Authentication Flow
- Uses GitHub OIDC token exchange for secure authentication
- Supports custom GitHub Apps via `APP_ID` and `APP_PRIVATE_KEY`
- Falls back to official Claude GitHub App if no custom app provided
### MCP Server Architecture
- Each MCP server has specific GitHub API access patterns
- Servers are auto-installed in `~/.claude/mcp/github-{type}-server/`
- Configuration merged with user-provided MCP config via `mcp_config` input
### Mode System Design
- Modes implement `Mode` interface with `shouldTrigger()` and `prepare()` methods
- Registry validates mode compatibility with GitHub event types
- Agent mode triggers when explicit prompt is provided
### Comment Threading
- Single tracking comment updated throughout execution
- Progress indicated via dynamic checkboxes
- Links to job runs and created branches/PRs
- Sticky comment option for consolidated PR comments
## Code Conventions ## Code Conventions
- Use Bun-specific TypeScript configuration with `moduleResolution: "bundler"` - Runtime is Bun, not Node. Use `bun test`, not `jest`.
- Strict TypeScript with `noUnusedLocals` and `noUnusedParameters` enabled - `moduleResolution: "bundler"` — imports don't need `.js` extensions.
- Prefer explicit error handling with detailed error messages - GitHub API calls should use retry logic (`src/utils/retry.ts`).
- Use discriminated unions for GitHub context types - MCP servers are auto-installed at runtime to `~/.claude/mcp/github-{type}-server/`.
- Implement retry logic for GitHub API operations via `utils/retry.ts`