From cc3a273414243ab5d0f151e7ba2dbabef500d86a Mon Sep 17 00:00:00 2001 From: MervinPraison Date: Sun, 15 Jun 2025 05:55:55 +0100 Subject: [PATCH 1/2] Remove CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md as it is no longer needed for the integration of Claude Code with PraisonAI Agents. This deletion simplifies the documentation and reflects the current state of the project. --- .../praisonai/tests/CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md => src/praisonai/tests/CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md (100%) diff --git a/CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md b/src/praisonai/tests/CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md similarity index 100% rename from CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md rename to src/praisonai/tests/CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md From 73887137d74dc51643158d2bd867fb66a957ec9c Mon Sep 17 00:00:00 2001 From: MervinPraison Date: Sun, 15 Jun 2025 06:28:57 +0100 Subject: [PATCH 2/2] Update Claude Code integration to use Docker image and add GitHub token for authentication --- .github/actions/claude-code-action/Dockerfile | 9 ++ .github/actions/claude-code-action/action.yml | 17 +++ .../actions/claude-code-action/entrypoint.sh | 15 +++ .github/actions/claude-code/action.yml | 117 ++++++++++++++++++ .github/workflows/claude.yml | 3 +- 5 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 .github/actions/claude-code-action/Dockerfile create mode 100644 .github/actions/claude-code-action/action.yml create mode 100644 .github/actions/claude-code-action/entrypoint.sh create mode 100644 .github/actions/claude-code/action.yml diff --git a/.github/actions/claude-code-action/Dockerfile b/.github/actions/claude-code-action/Dockerfile new file mode 100644 index 000000000..29b895294 --- /dev/null +++ b/.github/actions/claude-code-action/Dockerfile @@ -0,0 +1,9 @@ +FROM node:20-alpine + +RUN npm install -g @anthropic-ai/claude-code + +WORKDIR /app +COPY entrypoint.sh . +RUN chmod +x entrypoint.sh + +ENTRYPOINT ["/app/entrypoint.sh"] \ No newline at end of file diff --git a/.github/actions/claude-code-action/action.yml b/.github/actions/claude-code-action/action.yml new file mode 100644 index 000000000..71866c20e --- /dev/null +++ b/.github/actions/claude-code-action/action.yml @@ -0,0 +1,17 @@ +name: "Claude Code Action" +description: "Custom Claude Code runner for PraisonAI" + +inputs: + anthropic_api_key: + required: true + description: "Anthropic API key" + github_token: + required: true + description: "GitHub token for repo access" + +runs: + using: "docker" + image: "ghcr.io/mervinpraison/praisonai-claude-code:latest" + args: + - "--anthropic-api-key=${{ inputs.anthropic_api_key }}" + - "--github-token=${{ inputs.github_token }}" \ No newline at end of file diff --git a/.github/actions/claude-code-action/entrypoint.sh b/.github/actions/claude-code-action/entrypoint.sh new file mode 100644 index 000000000..ca2af4fbd --- /dev/null +++ b/.github/actions/claude-code-action/entrypoint.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +set -e + +echo "Running Claude Code in CI mode..." + +# Extract GitHub context and create a smart prompt +PROMPT="Analyse the GitHub issue or PR context and generate a smart response based on the repository context." + +# Set environment variables +export ANTHROPIC_API_KEY="$1" +export GITHUB_TOKEN="$2" + +# Run Claude with the prompt +claude -p "$PROMPT" \ No newline at end of file diff --git a/.github/actions/claude-code/action.yml b/.github/actions/claude-code/action.yml new file mode 100644 index 000000000..b7f5156a3 --- /dev/null +++ b/.github/actions/claude-code/action.yml @@ -0,0 +1,117 @@ +name: "Claude Code Action" +description: "Run Claude Code in GitHub Actions workflows" + +inputs: + github_token: + description: "GitHub token with repo and issues permissions" + required: true + anthropic_api_key: + description: "Anthropic API key" + required: true + prompt: + description: "The prompt to send to Claude Code" + required: false + default: "" + prompt_file: + description: "Path to a file containing the prompt to send to Claude Code" + required: false + default: "" + allowed_tools: + description: "Comma-separated list of allowed tools for Claude Code to use" + required: false + default: "" + output_file: + description: "File to save Claude Code output to (optional)" + required: false + default: "" + timeout_minutes: + description: "Timeout in minutes for Claude Code execution" + required: false + default: "10" + install_github_mcp: + description: "Whether to install the GitHub MCP server" + required: false + default: "false" + +runs: + using: "composite" + steps: + - name: Install Claude Code + shell: bash + run: npm install -g @anthropic-ai/claude-code + + - name: Install GitHub MCP Server + if: inputs.install_github_mcp == 'true' + shell: bash + run: | + claude mcp add-json github '{ + "command": "docker", + "args": [ + "run", + "-i", + "--rm", + "-e", + "GITHUB_PERSONAL_ACCESS_TOKEN", + "ghcr.io/github/github-mcp-server:sha-ff3036d" + ], + "env": { + "GITHUB_PERSONAL_ACCESS_TOKEN": "${{ inputs.GITHUB_TOKEN }}" + } + }' + + - name: Prepare Prompt File + shell: bash + id: prepare_prompt + run: | + if [ -z "${{ inputs.prompt }}" ] && [ -z "${{ inputs.prompt_file }}" ]; then + echo "::error::Neither 'prompt' nor 'prompt_file' was provided. At least one is required." + exit 1 + fi + + if [ ! -z "${{ inputs.prompt_file }}" ]; then + if [ ! -f "${{ inputs.prompt_file }}" ]; then + echo "::error::Prompt file '${{ inputs.prompt_file }}' does not exist." + exit 1 + fi + PROMPT_PATH="${{ inputs.prompt_file }}" + else + mkdir -p /tmp/claude-action + PROMPT_PATH="/tmp/claude-action/prompt.txt" + echo "${{ inputs.prompt }}" > "$PROMPT_PATH" + fi + + if [ ! -s "$PROMPT_PATH" ]; then + echo "::error::Prompt is empty. Please provide a non-empty prompt." + exit 1 + fi + + echo "PROMPT_PATH=$PROMPT_PATH" >> $GITHUB_ENV + + - name: Run Claude Code + shell: bash + id: run_claude + run: | + timeout_seconds=$((${{ inputs.timeout_minutes }} * 60)) + + if [ -z "${{ inputs.output_file }}" ]; then + timeout $timeout_seconds claude \ + -p \ + --verbose \ + --output-format stream-json \ + "$(cat ${{ env.PROMPT_PATH }})" \ + ${{ inputs.allowed_tools != '' && format('--allowedTools "{0}"', inputs.allowed_tools) || '' }} + else + timeout $timeout_seconds claude \ + -p \ + --verbose \ + --output-format stream-json \ + "$(cat ${{ env.PROMPT_PATH }})" \ + ${{ inputs.allowed_tools != '' && format('--allowedTools "{0}"', inputs.allowed_tools) || '' }} | tee output.txt + + jq -s '.' output.txt > output.json + jq -r '.[-1].result' output.json > "${{ inputs.output_file }}" + echo "Complete output saved to output.json, final response saved to ${{ inputs.output_file }}" + fi + env: + ANTHROPIC_API_KEY: ${{ inputs.anthropic_api_key }} + GITHUB_TOKEN: ${{ inputs.github_token }} diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index bcd8ef593..7ed549274 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -31,7 +31,8 @@ jobs: - name: Run Claude Code id: claude - uses: anthropics/claude-code-action@beta + uses: docker://ghcr.io/mervinpraison/praisonai-claudecode:latest with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + github_token: ${{ secrets.GH_TOKEN }}