From d2b0a43e2e3e0541b5f65575d7f20affff52fea2 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 9 Feb 2026 17:01:33 +0000 Subject: [PATCH 1/2] Add Checkpoint AI fix workflow --- .github/workflows/checkpoint-fix.yml | 232 +++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 .github/workflows/checkpoint-fix.yml diff --git a/.github/workflows/checkpoint-fix.yml b/.github/workflows/checkpoint-fix.yml new file mode 100644 index 0000000..e0242a7 --- /dev/null +++ b/.github/workflows/checkpoint-fix.yml @@ -0,0 +1,232 @@ +name: Checkpoint AI Fix + +on: + repository_dispatch: + types: [checkpoint-fix] + +permissions: + contents: write + pull-requests: write + +jobs: + fix: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: dev + token: ${{ secrets.GH_PAT }} + + - name: Notify running + run: | + curl -s -X POST "${{ github.event.client_payload.callbackUrl }}" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${{ secrets.CHECKPOINT_SECRET }}" \ + -d '{ + "reportId": "${{ github.event.client_payload.reportId }}", + "status": "running" + }' + + - name: Setup branch + id: branch + run: | + SESSION_BRANCH="${{ github.event.client_payload.meta.sessionBranch }}" + if [ -n "$SESSION_BRANCH" ] && git ls-remote --exit-code --heads origin "$SESSION_BRANCH" >/dev/null 2>&1; then + git fetch origin "$SESSION_BRANCH" + git checkout "$SESSION_BRANCH" + echo "name=$SESSION_BRANCH" >> $GITHUB_OUTPUT + echo "is_new=false" >> $GITHUB_OUTPUT + else + BRANCH="checkpoint/${{ github.event.client_payload.reportId }}" + git checkout -b "$BRANCH" + echo "name=$BRANCH" >> $GITHUB_OUTPUT + echo "is_new=true" >> $GITHUB_OUTPUT + fi + + - name: Write context + run: | + cat > /tmp/checkpoint-context.json << 'CONTEXT_EOF' + ${{ toJSON(github.event.client_payload) }} + CONTEXT_EOF + + - name: Download screenshots + run: | + mkdir -p /tmp/checkpoint-screenshots + URLS=$(echo '${{ toJSON(github.event.client_payload.screenshots) }}' | jq -r '.[]? | .screenshotUrl // empty') + if [ -n "$URLS" ]; then + i=1 + while IFS= read -r url; do + if [ -n "$url" ]; then + curl -sL "$url" -o "/tmp/checkpoint-screenshots/screenshot-${i}.png" 2>/dev/null || true + echo "Downloaded screenshot $i" + i=$((i+1)) + fi + done <<< "$URLS" + ls -la /tmp/checkpoint-screenshots/ + else + echo "No screenshots to download" + fi + + - name: Cache Amp CLI + id: amp-cache + uses: actions/cache@v4 + with: + path: | + ~/.amp + ~/.local/bin/amp + key: amp-cli-${{ runner.os }} + + - name: Install Amp + if: steps.amp-cache.outputs.cache-hit != 'true' + run: curl -fsSL https://ampcode.com/install.sh | bash + + - name: Build prompt + id: prompt + run: | + SCREENSHOT_FILES=$(ls /tmp/checkpoint-screenshots/ 2>/dev/null | head -5) + SCREENSHOT_NOTE="" + if [ -n "$SCREENSHOT_FILES" ]; then + SCREENSHOT_NOTE="Screenshots of the element/area are in /tmp/checkpoint-screenshots/. Look at these images first to understand visually what needs to change." + fi + + cat > /tmp/checkpoint-prompt.txt << 'PROMPT_EOF' + You are implementing a specific change requested via Checkpoint. Read AGENTS.md first for codebase structure. Then read /tmp/checkpoint-context.json for the full element context (selectors, styles, DOM). + PROMPT_EOF + + cat >> /tmp/checkpoint-prompt.txt << PROMPT_VARS_EOF + + Request: ${{ github.event.client_payload.title }} + Details: ${{ github.event.client_payload.description }} + Page URL: ${{ github.event.client_payload.url }} + + ${SCREENSHOT_NOTE} + + Instructions: + 1. Read AGENTS.md for project structure + 2. Read /tmp/checkpoint-context.json for element context + 3. Use the CSS selector or React component name from context to grep for the source file + 4. Make the minimal change to implement exactly what was requested + 5. Do not refactor, do not add comments, do not touch unrelated code + PROMPT_VARS_EOF + + - name: Run AI Agent + env: + AMP_API_KEY: ${{ secrets.AMP_API_KEY }} + run: | + cat /tmp/checkpoint-prompt.txt | amp --dangerously-allow-all -x + + - name: Commit and push + id: commit + run: | + REPORTER="${{ github.event.client_payload.meta.reporter }}" + if [ -n "$REPORTER" ] && [ "$REPORTER" != "Anonymous" ]; then + git config user.name "$REPORTER (via Checkpoint)" + git config user.email "checkpoint@tempo.xyz" + else + git config user.name "checkpoint-bot" + git config user.email "checkpoint@tempo.xyz" + fi + if git diff --quiet; then + echo "No changes to commit" + curl -s -X POST "${{ github.event.client_payload.callbackUrl }}" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${{ secrets.CHECKPOINT_SECRET }}" \ + -d '{ + "reportId": "${{ github.event.client_payload.reportId }}", + "status": "failed", + "error": "Agent produced no changes" + }' + exit 0 + fi + git add -A + git commit -m "checkpoint: ${{ github.event.client_payload.title }} + + Checkpoint Report: ${{ github.event.client_payload.reportId }} + Linear: ${{ github.event.client_payload.issue.id }}" + git push origin ${{ steps.branch.outputs.name }} + echo "pushed=true" >> $GITHUB_OUTPUT + + - name: Build screenshot markdown + id: screenshots + run: | + SCREENSHOTS=$(echo '${{ toJSON(github.event.client_payload.screenshots) }}' | jq -r '[.[]? | select(.screenshotUrl) | "![" + (.note // "Screenshot") + "](" + .screenshotUrl + ")"] | join("\n\n")') + if [ -n "$SCREENSHOTS" ] && [ "$SCREENSHOTS" != "" ]; then + echo "markdown<> $GITHUB_OUTPUT + echo "$SCREENSHOTS" >> $GITHUB_OUTPUT + echo "SCREENSHOTS_EOF" >> $GITHUB_OUTPUT + fi + + - name: Create PR + id: create_pr + if: steps.commit.outputs.pushed == 'true' && steps.branch.outputs.is_new == 'true' + env: + GH_TOKEN: ${{ secrets.GH_PAT }} + run: | + PR_URL=$(gh pr create \ + --title "checkpoint: ${{ github.event.client_payload.title }}" \ + --body "## Checkpoint AI Change + + **Reported by:** ${{ github.event.client_payload.meta.reporter }} + **Linear:** [${{ github.event.client_payload.issue.id }}](${{ github.event.client_payload.issue.url }}) + **Report ID:** \`${{ github.event.client_payload.reportId }}\` + **URL:** ${{ github.event.client_payload.url }} + + --- + + This PR was automatically generated by [Checkpoint](https://tempo-qa-xi.vercel.app) in response to a request. + + ### Request + ${{ github.event.client_payload.description }} + + ### Screenshots + ${{ steps.screenshots.outputs.markdown || '_No screenshots_' }} + + ### Context + See the linked Linear issue for full element context." \ + --head "${{ steps.branch.outputs.name }}" \ + --base dev) + + PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$') + echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT + echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT + + - name: Notify PR opened + if: steps.create_pr.outputs.pr_url + run: | + curl -s -X POST "${{ github.event.client_payload.callbackUrl }}" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${{ secrets.CHECKPOINT_SECRET }}" \ + -d '{ + "reportId": "${{ github.event.client_payload.reportId }}", + "status": "pr_opened", + "prUrl": "${{ steps.create_pr.outputs.pr_url }}", + "prNumber": ${{ steps.create_pr.outputs.pr_number }}, + "branch": "${{ steps.branch.outputs.name }}", + "issueId": "${{ github.event.client_payload.issue.id }}" + }' + + - name: Notify commit added + if: steps.commit.outputs.pushed == 'true' && steps.branch.outputs.is_new == 'false' + run: | + curl -s -X POST "${{ github.event.client_payload.callbackUrl }}" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${{ secrets.CHECKPOINT_SECRET }}" \ + -d '{ + "reportId": "${{ github.event.client_payload.reportId }}", + "status": "committed", + "branch": "${{ steps.branch.outputs.name }}" + }' + + - name: Notify failure + if: failure() + run: | + curl -s -X POST "${{ github.event.client_payload.callbackUrl }}" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${{ secrets.CHECKPOINT_SECRET }}" \ + -d '{ + "reportId": "${{ github.event.client_payload.reportId }}", + "status": "failed", + "error": "Workflow failed" + }' From 064fbc17a4fbf374e4fd609bb6a712cbc4a1e4e7 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 9 Feb 2026 17:49:47 +0000 Subject: [PATCH 2/2] Update workflow to use default branch --- .github/workflows/checkpoint-fix.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checkpoint-fix.yml b/.github/workflows/checkpoint-fix.yml index e0242a7..4076169 100644 --- a/.github/workflows/checkpoint-fix.yml +++ b/.github/workflows/checkpoint-fix.yml @@ -16,7 +16,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 with: - ref: dev + ref: ${{ github.event.repository.default_branch }} token: ${{ secrets.GH_PAT }} - name: Notify running @@ -186,7 +186,7 @@ jobs: ### Context See the linked Linear issue for full element context." \ --head "${{ steps.branch.outputs.name }}" \ - --base dev) + --base ${{ github.event.repository.default_branch }}) PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$') echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT