diff --git a/CLAUDE-ACTION.md b/CLAUDE-ACTION.md deleted file mode 100644 index 6fdb04a..0000000 --- a/CLAUDE-ACTION.md +++ /dev/null @@ -1,299 +0,0 @@ -# Claude Code Action Architecture & Flow - -This document provides a comprehensive overview of how the official (Anthropic) Claude Code Action works, from token exchange through post-run cleanup. - -## Overview - -The Claude Code Action is a sophisticated GitHub automation platform that enables Claude to interact with GitHub repositories through secure token exchange, intelligent mode detection, and comprehensive GitHub API integration. - -## High-Level Architecture - -```mermaid -graph TD - Start([GitHub Action Triggered]) --> Setup[Setup Environment
- Install Bun
- Install Dependencies] - - Setup --> ParseContext[Parse GitHub Context
- Extract event data
- Parse inputs] - - ParseContext --> ModeDetection{Mode Detection} - - ModeDetection -->|Has explicit prompt| AgentMode[AGENT MODE
Direct automation] - ModeDetection -->|@claude mention/assignment/label| TagMode[TAG MODE
Interactive response] - ModeDetection -->|No trigger| DefaultAgent[Default to Agent
(won't trigger)] - - %% Token Exchange Branch - AgentMode --> TokenExchange[Token Exchange Process] - TagMode --> TokenExchange - TokenExchange --> TokenMethod{Token Method} - - TokenMethod -->|Custom token provided| UseCustom[Use Custom GitHub Token] - TokenMethod -->|No custom token| OIDC[Generate OIDC Token
core.getIDToken()] - - OIDC --> Exchange[Exchange OIDC for App Token
api.anthropic.com/api/github/github-app-token-exchange] - Exchange --> CreateOctokit[Create Authenticated Octokit Client
REST + GraphQL] - UseCustom --> CreateOctokit - - %% Permission Checks - CreateOctokit --> PermCheck[Check Write Permissions
Only for entity contexts] - PermCheck -->|No permissions| PermFail[❌ Exit: No write access] - PermCheck -->|Has permissions| TriggerCheck{Check Trigger Conditions} - - %% Trigger Validation - TriggerCheck -->|Agent Mode| AgentTrigger{Has explicit prompt?} - TriggerCheck -->|Tag Mode| TagTrigger{Contains @claude mention
or assignment/label?} - - AgentTrigger -->|No prompt| NoTrigger[❌ Skip: No trigger found] - AgentTrigger -->|Has prompt| PrepareAgent[Prepare Agent Mode] - TagTrigger -->|No mention| NoTrigger - TagTrigger -->|Has mention| PrepareTag[Prepare Tag Mode] - - %% Mode-Specific Preparation - PrepareAgent --> AgentPrep[Agent Mode Preparation
- Create prompt file
- Setup MCP servers
- No tracking comment] - PrepareTag --> TagPrep[Tag Mode Preparation
- Create tracking comment
- Setup branches
- Fetch GitHub data
- Setup MCP servers] - - %% Data Fetching (Tag Mode) - TagPrep --> DataFetch[Fetch GitHub Data
GraphQL + REST API] - DataFetch --> FetchWhat{What to fetch?} - - FetchWhat -->|Pull Request| PRData[PR Data:
- Comments & reviews
- Changed files + SHAs
- Commit history
- Author info] - FetchWhat -->|Issue| IssueData[Issue Data:
- Comments
- Issue details
- Author info] - - PRData --> ProcessImages[Process Images
Download & convert to base64] - IssueData --> ProcessImages - ProcessImages --> SetupBranch[Setup Branch
- Create Claude branch
- Configure git auth] - - %% MCP Server Setup - AgentPrep --> MCPSetup[Setup MCP Servers] - SetupBranch --> MCPSetup - - MCPSetup --> MCPServers{MCP Servers} - MCPServers --> GitHubActions[GitHub Actions Server
- Workflow data
- CI results] - MCPServers --> GitHubComments[GitHub Comment Server
- Comment operations] - MCPServers --> GitHubFiles[GitHub File Ops Server
- File operations
- Branch management] - MCPServers --> GitHubInline[GitHub Inline Comment Server
- PR review comments] - - GitHubActions --> PromptGen[Generate Prompt] - GitHubComments --> PromptGen - GitHubFiles --> PromptGen - GitHubInline --> PromptGen - - %% Prompt Generation - PromptGen --> PromptType{Prompt Type} - PromptType -->|Agent Mode| AgentPrompt[Agent Prompt:
- Direct user prompt
- Minimal context] - PromptType -->|Tag Mode| TagPrompt[Tag Prompt:
- Rich GitHub context
- PR/Issue details
- Changed files
- Comments & reviews
- Commit instructions] - - AgentPrompt --> ClaudeRun[Run Claude Code] - TagPrompt --> ClaudeRun - - %% Claude Execution - ClaudeRun --> ClaudeExec[Claude Code Execution
base-action/src/index.ts] - ClaudeExec --> ClaudeArgs[Prepare Claude Args
- Prompt file path
- Custom claude_args
- Output format: stream-json] - - ClaudeArgs --> ClaudeProvider{Provider} - ClaudeProvider -->|Default| AnthropicAPI[Anthropic API
ANTHROPIC_API_KEY] - ClaudeProvider -->|Bedrock| AWSBedrock[AWS Bedrock
OIDC + AWS credentials] - ClaudeProvider -->|Vertex| GCPVertex[GCP Vertex AI
OIDC + GCP credentials] - - AnthropicAPI --> ClaudeProcess[Spawn Claude Process
- Named pipe for input
- Stream JSON output] - AWSBedrock --> ClaudeProcess - GCPVertex --> ClaudeProcess - - ClaudeProcess --> ClaudeTools[Claude Tool Usage
- MCP tools
- File operations
- GitHub API calls
- Bash commands] - - ClaudeTools --> ClaudeOutput[Claude Output Processing
- Capture execution log
- Parse JSON stream
- Extract metrics] - - %% Post-Run Actions - ClaudeOutput --> PostRun{Post-Run Actions} - - PostRun -->|Success| Success[✅ Success Path] - PostRun -->|Failure| Failure[❌ Failure Path] - - Success --> UpdateComment[Update Tracking Comment
- Job run link
- Branch link
- PR link (if created)
- Execution metrics] - Failure --> UpdateComment - - UpdateComment --> BranchCleanup[Branch Cleanup
- Check for changes
- Delete empty branches
- Keep branches with commits] - - BranchCleanup --> FormatReport[Format Execution Report
- Parse conversation turns
- Format tool usage
- Add to GitHub step summary] - - FormatReport --> RevokeToken[Revoke App Token
DELETE /installation/token] - - RevokeToken --> End([Action Complete]) -``` - -## Key Components - -### 1. Token Exchange Process - -The action uses a secure OIDC token exchange system: - -1. **OIDC Token Generation**: `core.getIDToken("claude-code-github-action")` -2. **Token Exchange**: POST to `https://api.anthropic.com/api/github/github-app-token-exchange` -3. **Authentication**: Creates authenticated Octokit clients for GitHub API access - -**Security Benefits:** -- Repository-scoped access -- Time-limited tokens -- Permission-limited (only configured GitHub App permissions) -- Automatic token masking in logs - -### 2. Mode Detection - -The action automatically detects the appropriate execution mode: - -#### **Agent Mode** -- **Trigger**: Explicit `prompt` input provided -- **Use Case**: Direct automation, custom workflows -- **Behavior**: Minimal context, direct execution -- **Tracking**: No tracking comments - -#### **Tag Mode** -- **Trigger**: @claude mentions, issue assignments, or labels -- **Use Case**: Interactive GitHub responses -- **Behavior**: Rich context, comprehensive GitHub data -- **Tracking**: Creates and updates tracking comments - -### 3. Data Fetching (Tag Mode) - -When in Tag Mode, the action fetches comprehensive GitHub context: - -#### **Pull Request Data:** -- Comments and reviews (including inline comments) -- Changed files with SHAs -- Commit history and metadata -- Author information -- File diff data - -#### **Issue Data:** -- Issue details and metadata -- All comments -- Author information -- Labels and assignments - -#### **Image Processing:** -- Downloads images from GitHub -- Converts to base64 for Claude -- Maps original URLs to processed content - -### 4. MCP Server Integration - -The action sets up multiple MCP (Model Context Protocol) servers to provide Claude with GitHub capabilities: - -#### **GitHub Actions Server** -- Access to workflow runs and CI data -- Build status and test results -- Artifact information - -#### **GitHub Comment Server** -- Comment creation and updates -- Issue and PR comment management - -#### **GitHub File Operations Server** -- File reading and writing -- Branch creation and management -- Commit operations - -#### **GitHub Inline Comment Server** -- PR review comment operations -- Line-specific feedback - -### 5. Prompt Generation - -The action generates context-rich prompts based on the detected mode: - -#### **Agent Mode Prompts:** -- Direct user prompt -- Minimal GitHub context -- Focused on specific task - -#### **Tag Mode Prompts:** -- Comprehensive GitHub context -- PR/Issue details and history -- Changed files and diffs -- Comment threads and reviews -- Commit instructions and guidelines - -### 6. Claude Execution - -The action runs Claude Code through multiple provider options: - -#### **Provider Support:** -- **Anthropic API** (default): Direct API access with API key -- **AWS Bedrock**: OIDC authentication with AWS credentials -- **GCP Vertex AI**: OIDC authentication with GCP credentials - -#### **Execution Process:** -1. **Named Pipe Setup**: Creates pipe for prompt input -2. **Process Spawning**: Spawns Claude Code process -3. **Stream Processing**: Captures JSON stream output -4. **Tool Integration**: Enables MCP tools and GitHub operations - -### 7. Post-Run Actions - -After Claude execution, the action performs comprehensive cleanup and reporting: - -#### **Comment Updates:** -- Updates tracking comments with results -- Adds job run links and execution metrics -- Includes branch and PR links when created - -#### **Branch Management:** -- Checks for actual changes in Claude branches -- Deletes empty branches to avoid clutter -- Preserves branches with meaningful commits - -#### **Report Generation:** -- Parses execution logs and conversation turns -- Formats tool usage and results -- Adds formatted report to GitHub step summary - -#### **Security Cleanup:** -- Revokes GitHub App installation token -- Cleans up temporary files and processes - -## Security Considerations - -### **Access Control:** -- Repository-scoped permissions only -- Write access validation for actors -- Bot user controls and allowlists - -### **Token Management:** -- Short-lived installation tokens -- Automatic token revocation after use -- Secure OIDC-based exchange - -### **Permission Boundaries:** -- Limited to configured GitHub App permissions -- No cross-repository access -- Scoped to specific repository operations - -## Integration Points - -### **With Pullfrog:** -The Claude Code Action can be integrated with Pullfrog's workflow system, providing: -- Standardized agent interaction patterns -- Consistent GitHub integration -- Reusable authentication flows -- Common MCP server infrastructure - -### **With GitHub:** -- Native GitHub Actions integration -- Comprehensive API coverage (REST + GraphQL) -- Proper webhook handling -- Standard GitHub UI integration - -## Development Notes - -### **Key Files:** -- `src/entrypoints/prepare.ts`: Main preparation logic -- `src/modes/`: Mode detection and handling -- `src/github/token.ts`: OIDC token exchange -- `src/mcp/`: MCP server implementations -- `base-action/`: Core Claude Code execution - -### **Testing:** -- Unit tests for individual components -- Integration tests for full workflows -- Local testing with `act` tool -- Comprehensive fixture support - -This architecture provides a robust, secure, and extensible foundation for Claude-GitHub integration while maintaining clear separation of concerns and comprehensive error handling. diff --git a/README.md b/README.md index d215ea3..d804de0 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,126 @@ # Pullfrog Action -GitHub Action for running Claude Code and other agents via Pullfrog. +GitHub Action for running AI agents via Pullfrog to automate development workflows. -> **📖 Claude Code Action Architecture**: For a detailed technical overview of how the Claude Code Action works (token exchange, modes, data fetching, execution flow), see [CLAUDE-ACTION.md](./CLAUDE-ACTION.md). +## What is Pullfrog? -## Quick Start +Pullfrog is a GitHub bot that brings the full power of your favorite coding agents into GitHub. It's open source and powered by GitHub Actions. -```bash -# Install dependencies -pnpm install +Once configured, you can start triggering agent runs. + +- **Tag `@pullfrog`** — Tag `@pullfrog` in a comment anywhere in your repo. It will pull in any relevant context using the action's internal MCP server and perform the appropriate task. +- **Prompt from the web** — Trigger arbitrary tasks from the Pullfrog dashboard +- **Automated triggers** — Configure Pullfrog to trigger agent runs in response to specific events. Each of these triggers can be associated with custom prompt instructions. + - issue created + - issue labeled + - PR created + - PR review created + - PR review requested + - and more... + +Pullfrog is the bridge between GitHub and your preferred coding agents and GitHub. Use it for: + +- **Coding tasks** — Tell `@pullfrog` to implement something and it'll spin up a PR. If CI fails, it'll read the logs and attempt a fix automatically. It'll automatically address any PR reviews too. +- **PR review** — Coding agents are great at reviewing PRs. Using the "PR created" trigger, you can configure Pullfrog to auto-review new PRs. +- **Auto-respond to issues** — Via the "issue created" trigger, Pullfrog can automatically respond to common questions, create implementation plans, and link to related issues/PRs. Or (if you're feeling lucky) you can prompt it to immediately attempt a PR addressing new issues. +- **Documentation** — +- **Enforce best practices** — Want to have the agent automatically add docs to all new PRs? + +Features +- **Agent-agnostic** — Switch between agents with the click of a radio button. +- ** + +## Get started + + +Install the Pullfrog GitHub App on your personal or organization account. During installation you can choose to limit access to a specific repo or repos. After installation, you'll be redirected to the Pullfrog dashboard where you'll see an onboarding flow. This flow will create your `pullfrog.yml` workflow and prompt you to set up API keys. Once you finish those steps (2 minutes) you're ready to rock 🐸 + +[Add to GitHub ➜]([https://](https://github.com/apps/pullfrog/installations/new)) + + +
+Manual Setup + +You can also use the `pullfrog/action` Action without a GitHub App installation. This is more time-consuming to set up, and it places limitations on the actions your Agent will be capable of performing. + +To manually set up the Pullfrog action, you need to set up two workflow files in your repository: `pullfrog.yml` (the execution logic) and `triggers.yml` (the event triggers). + +#### 1. Create `pullfrog.yml` + +Create a file at `.github/workflows/pullfrog.yml`. This is a reusable workflow that runs the Pullfrog action. + +```yaml +name: Pullfrog +on: + workflow_dispatch: + inputs: + prompt: + type: string + description: "Agent prompt" + workflow_call: + inputs: + prompt: + description: "Agent prompt" + type: string + +permissions: + id-token: write + contents: read + +jobs: + pullfrog: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: Run agent + uses: pullfrog/action@main # Use a specific version tag in production + with: + prompt: ${{ inputs.prompt }} + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + # Add other keys as needed: + # openai_api_key: ${{ secrets.OPENAI_API_KEY }} ``` -## Testing with `play.ts` +#### 2. Create `triggers.yml` -```bash -pnpm play # Uses fixtures/play.txt +Create a file at `.github/workflows/triggers.yml`. This workflow listens for GitHub events and calls the `pullfrog.yml` workflow with the event data. + +```yaml +name: Agent Triggers + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened, assigned] + pull_request_review: + types: [submitted] + # add other triggers as needed + + +jobs: + pullfrog: + + # trigger conditions (e.g. only run if @pullfrog is mentioned) + if: contains(github.event.comment.body, '@pullfrog') || contains(github.event.issue.body, '@pullfrog') + + permissions: + id-token: write + contents: write + issues: write + pull-requests: write + actions: read + checks: read + uses: ./.github/workflows/pullfrog.yml + with: + # pass the full event payload as the prompt + prompt: ${{ toJSON(github.event) }} + secrets: inherit ``` -- Clones the scratch repository to `.temp` -- Runs Claude Code directly on your machine -- Fast iteration for development + +