Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
2cc4131
chore: add AI workflow infrastructure
jay9297 May 25, 2026
2c0aea1
chore: enable coverage and add luacheck to test pipeline
jay9297 May 25, 2026
82af09a
docs: add AI workflow escape hatches to README
jay9297 May 25, 2026
227a786
fix: use correct busted-tests service name in CI
jay9297 May 25, 2026
20fb9e3
fix: use entrypoint so extra args append to busted command
jay9297 May 26, 2026
6ff663f
fix: move build/data tag exclusion from .busted to CI step
jay9297 May 26, 2026
2b78d6d
chore: add ai-fix issue template for automated agent workflow
jay9297 May 26, 2026
61e7159
Merge branch 'PathOfBuildingCommunity:dev' into dev
jay9297 May 26, 2026
3033c49
Refactor AI fix workflow for better metadata handling
jay9297 May 26, 2026
c5e018d
Enhance AI review workflow with concurrency and caching
jay9297 May 26, 2026
de39800
Merge branch 'PathOfBuildingCommunity:dev' into dev
jay9297 May 26, 2026
f5593b3
Refactor CI workflow to use matrix strategy for tests
jay9297 May 27, 2026
0618345
Update spellcheck workflow configuration
jay9297 May 27, 2026
328d20b
Refactor CI workflow for Docker image caching
jay9297 May 27, 2026
b5b4cdf
Increase max turns for AI agent script to 80
jay9297 May 27, 2026
1976ae4
Enhance verify job with caching and image handling
jay9297 May 27, 2026
c7c988b
Merge branch 'PathOfBuildingCommunity:dev' into dev
jay9297 May 27, 2026
58a0c84
Merge branch 'PathOfBuildingCommunity:dev' into dev
jay9297 May 27, 2026
fb08cf5
Add agent execution library with retry logic
jay9297 May 27, 2026
be88ab5
Refactor ai-fix workflow for better resilience
jay9297 May 27, 2026
305cb30
Adjust AI review timeout and prompt format
jay9297 May 27, 2026
fa7d54d
Refactor agent-lib.sh for clarity and retry logic
jay9297 May 27, 2026
b1ad041
Increase fallback run limit from 40 to 80
jay9297 May 27, 2026
322de84
Merge branch 'PathOfBuildingCommunity:dev' into dev
jay9297 May 27, 2026
1f8788a
Update AI fix workflow for branch handling and prompts
jay9297 May 27, 2026
4226fb7
Refactor AI agent commit handling in workflow
jay9297 May 27, 2026
2c0242c
Merge branch 'PathOfBuildingCommunity:dev' into dev
jay9297 May 28, 2026
3c6e7e2
Fix Hollow Palm Technique parsing and add Spectral Ward support
jay9297 May 29, 2026
df7f76f
Fix/hollow palm technique (#58)
jay9297 May 29, 2026
baef281
Merge remote-tracking branch 'origin/dev' into dev
jay9297 May 29, 2026
cb0960e
Merge remote-tracking branch 'fork/dev' into dev
jay9297 May 29, 2026
6faa62b
chore: add local dev files and fix GGPK gitignore casing
jay9297 May 29, 2026
a854ee5
fix: regenerate ModCache and fix spellcheck workflow
jay9297 May 29, 2026
0e779dd
docs: add fork rules to AGENTS.md
jay9297 May 30, 2026
0dbb7ed
Merge branch 'PathOfBuildingCommunity:dev' into dev
jay9297 May 31, 2026
42c2728
fix: correct WardCoverOnMinionDeath stat ID (cover_ → recover_)
jay9297 May 31, 2026
99235d3
feat: add Runic Ward defense calculations and display
jay9297 May 31, 2026
9948842
feat: add ward and runic ward stat-ID mappings
jay9297 May 31, 2026
cab08e4
feat: strip Runeforged prefix from base items on import
jay9297 May 31, 2026
c745ceb
docs: add test instructions to README
jay9297 May 31, 2026
61ebbe3
test: add Runeforged item parse test
jay9297 May 31, 2026
7d8b46a
feat: complete ward mechanic wiring (TotalNetRegen, absorption, EHP, …
jay9297 Jun 1, 2026
95693aa
feat: add ward display stats, breakdown rows, and strengthen TotalNet…
jay9297 Jun 1, 2026
f7c0cca
fix: correct ward_rune MORE type, add flat WardRegen base, harden Tot…
jay9297 Jun 1, 2026
dcffcbe
feat: add ward sidebar display stats and breakdown rows
jay9297 Jun 1, 2026
a2ba265
feat: implement Way of the Stonefist ascendancy mechanics
jay9297 Jun 1, 2026
3021f58
fix: correct Runic Ward import, double-count, and EHP operator preced…
jay9297 Jun 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .busted
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
return {
_all = {
coverage = false,
coverage = true,
verbose = true,
},
default = {
directory = "src",
lpath = "../runtime/lua/?.lua;../runtime/lua/?/init.lua",
helper = "HeadlessWrapper.lua",
ROOT = { "../spec" },
["exclude-tags"] = "builds",
}
}
59 changes: 59 additions & 0 deletions .github/ISSUE_TEMPLATE/ai_fix.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: AI fix request
description: Report a well-scoped bug or task for the AI agent to fix automatically.
labels: [ai-fix]
body:
- type: markdown
attributes:
value: |
Issues with this template are automatically picked up by the AI agent when labelled **ai-fix**.
Keep the description concrete and focused — the agent works best with a single, well-defined task.

- type: checkboxes
id: scope
attributes:
label: Confirm scope
options:
- label: This is a single, well-scoped task (not a broad refactor or multi-feature request)
required: true
- label: I've checked there are no open PRs already addressing this
required: true

- type: textarea
id: description
attributes:
label: What needs to be fixed or done?
description: Be specific. Include file names, function names, or error messages where possible.
placeholder: |
e.g. The Boneshatter damage calculation in `src/Modules/CalcOffence.lua` does not account for
the stun threshold modifier added in 0.2.0. Expected value: X, actual value: Y.
validations:
required: true

- type: textarea
id: acceptance
attributes:
label: Acceptance criteria
description: How will you know the fix is correct? What should the tests verify?
placeholder: |
- Calculation matches expected value from PoE2 tooltip
- Existing busted tests still pass
- New test added covering the stun threshold case
validations:
required: true

- type: textarea
id: build_code
attributes:
label: PoB build code (if relevant)
description: A build code that reproduces the issue helps the agent verify the fix.
render: shell
validations:
required: false

- type: textarea
id: context
attributes:
label: Additional context
description: Screenshots, error messages, or links to PoE2 patch notes.
validations:
required: false
305 changes: 305 additions & 0 deletions .github/workflows/ai-fix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,305 @@
name: AI Fix
on:
issues:
types: [labeled]

jobs:
apply-fix:
if: github.event.label.name == 'ai-fix'
runs-on: ubuntu-latest
timeout-minutes: 60
permissions:
contents: write
issues: write
env:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
EMERGENCY_ANTHROPIC_API_KEY: ${{ secrets.EMERGENCY_ANTHROPIC_API_KEY }}
outputs:
branch: ${{ steps.push.outputs.branch }}
issue_num: ${{ steps.meta.outputs.issue_num }}
issue_title: ${{ steps.meta.outputs.issue_title }}
steps:
- uses: actions/checkout@v4
with:
ref: dev
fetch-depth: 0

- name: Verify ANTHROPIC_API_KEY is NOT set
run: |
if [[ -n "${ANTHROPIC_API_KEY:-}" ]]; then
echo "::error::ANTHROPIC_API_KEY is set; would override Pro subscription auth and incur PAYG charges"
exit 1
fi

- name: Extract issue metadata
id: meta
run: |
echo "issue_num=$(jq -r '.issue.number' "$GITHUB_EVENT_PATH")" >> "$GITHUB_OUTPUT"
echo "issue_title=$(jq -r '.issue.title' "$GITHUB_EVENT_PATH")" >> "$GITHUB_OUTPUT"

- name: Install agent tooling if missing
run: |
command -v claude || npm install -g @anthropic-ai/claude-code
command -v opencode || curl -fsSL https://opencode.ai/install | bash

- name: Checkout or create fix branch
id: branch_setup
run: |
BRANCH="ai-fix/issue-${{ steps.meta.outputs.issue_num }}"
echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"

if git ls-remote --exit-code --heads origin "$BRANCH" > /dev/null 2>&1; then
echo "is_retry=true" >> "$GITHUB_OUTPUT"
echo "Branch $BRANCH exists — checking out for retry"
git checkout -b "$BRANCH" "origin/$BRANCH"
else
echo "is_retry=false" >> "$GITHUB_OUTPUT"
echo "Branch $BRANCH does not exist — creating fresh from dev"
git checkout -b "$BRANCH"
fi

- name: Build agent prompt
run: |
ISSUE_BODY=$(jq -r '.issue.body' "$GITHUB_EVENT_PATH")

# If resuming an existing branch, include prior commit context so the
# agent knows what was already attempted and can build on or correct it
RETRY_CONTEXT=""
if [[ "${{ steps.branch_setup.outputs.is_retry }}" == "true" ]]; then
PREV_COMMITS=$(git log "origin/dev..HEAD" --oneline 2>/dev/null || echo "none")
RETRY_CONTEXT="
NOTE: A previous fix attempt exists on this branch. Prior commits:
${PREV_COMMITS}

Review the existing changes and either build on them or correct them.
Do not revert work that is already correct."
fi

cat > /tmp/fix-prompt.txt << PROMPT_EOF
You are resolving GitHub issue #${{ steps.meta.outputs.issue_num }} in jay9297/PathOfBuilding-PoE2.

Title: ${{ steps.meta.outputs.issue_title }}

Body:
${ISSUE_BODY}
${RETRY_CONTEXT}

Follow the rules in CLAUDE.md. Make the minimal correct change.
Add or update tests to cover your fix. Do NOT run tests yourself.
PROMPT_EOF

- name: Run AI agent
run: |
source scripts/agent-lib.sh
run_agent_with_fallback /tmp/fix-prompt.txt fix 80

- name: Commit and push branch
id: push
run: |
BRANCH="${{ steps.branch_setup.outputs.branch }}"
git config user.name "ai-agent[bot]"
git config user.email "ai-agent@users.noreply.github.com"
git add -A

if git diff --cached --quiet; then
# Agent made no new changes — check if prior work already exists on the branch
AHEAD=$(git rev-list --count "origin/dev..HEAD" 2>/dev/null || echo "0")
if [[ "${{ steps.branch_setup.outputs.is_retry }}" == "true" && "$AHEAD" -gt 0 ]]; then
echo "Agent made no new changes but branch has $AHEAD existing commit(s) — proceeding with existing work"
echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "::error::No changes produced by agent and no existing commits on branch"
exit 1
fi

git commit -m "fix: resolve issue #${{ steps.meta.outputs.issue_num }}

Generated by AI agent. Requires human review before merge."

source scripts/agent-lib.sh
retry_op 5 10 git push -u origin "$BRANCH"
echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"

- name: Post failure comment
if: failure()
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
source scripts/agent-lib.sh
retry_op 3 10 gh issue comment ${{ steps.meta.outputs.issue_num }} \
--body "⚠️ **AI Fix Failed**

The \`apply-fix\` job failed after exhausting all agent tiers and retry cycles.
This likely indicates an API outage or expired credentials.

**What to check:**
- \`CLAUDE_CODE_OAUTH_TOKEN\` — is the Pro subscription active?
- \`OPENCODE_API_KEY\` — is the key valid?
- \`EMERGENCY_ANTHROPIC_API_KEY\` — set this secret for last-resort fallback.

Re-add the \`ai-fix\` label once credentials are restored to retry." || true

verify-and-fix:
needs: apply-fix
runs-on: ubuntu-latest
timeout-minutes: 90
permissions:
contents: write
env:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
EMERGENCY_ANTHROPIC_API_KEY: ${{ secrets.EMERGENCY_ANTHROPIC_API_KEY }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.apply-fix.outputs.branch }}
fetch-depth: 0

- name: Configure git
run: |
git config user.name "ai-agent[bot]"
git config user.email "ai-agent@users.noreply.github.com"

- name: Install agent tooling if missing
run: |
command -v claude || npm install -g @anthropic-ai/claude-code
command -v opencode || curl -fsSL https://opencode.ai/install | bash

- name: Cache test image
id: image-cache
uses: actions/cache@v4
with:
path: /tmp/pob-test-image.tar
key: pob-test-image-${{ hashFiles('docker-compose.yml') }}
restore-keys: pob-test-image-

- name: Pull or restore image
run: |
if [[ "${{ steps.image-cache.outputs.cache-hit }}" == "true" ]]; then
docker load < /tmp/pob-test-image.tar
else
docker pull ghcr.io/pathofbuildingcommunity/pathofbuilding-tests:latest
docker save ghcr.io/pathofbuildingcommunity/pathofbuilding-tests:latest \
-o /tmp/pob-test-image.tar
fi

# Separated into its own step — no ${{ }} expressions here so the heredoc
# delimiter is never mangled by GitHub Actions' format() evaluator
- name: Build verify-fix prompt template
run: |
cat > /tmp/verify-fix-prompt-template.txt << 'PROMPT_EOF'
The AI agent previously made changes to fix a GitHub issue, but the test
suite is now failing. Fix the failing tests without reverting the original
fix. Make the minimal change needed. Follow CLAUDE.md.

Failing test output:
PROMPT_EOF

- name: Verify and auto-fix loop
run: |
source scripts/agent-lib.sh

MAX_RETRIES=3
ATTEMPT=0

run_tests() {
local output_file="$1"
local failed=0
echo "--- unit ---" | tee -a "$output_file"
docker compose run --rm busted-tests --exclude-tags builds,data \
2>&1 | tee -a "$output_file" || failed=1
echo "--- builds ---" | tee -a "$output_file"
docker compose run --rm busted-tests --tags builds \
2>&1 | tee -a "$output_file" || failed=1
echo "--- data ---" | tee -a "$output_file"
docker compose run --rm busted-tests --tags data \
2>&1 | tee -a "$output_file" || failed=1
return $failed
}

while [ $ATTEMPT -lt $MAX_RETRIES ]; do
ATTEMPT=$((ATTEMPT + 1))
OUTPUT_FILE="/tmp/test-output-attempt-${ATTEMPT}.txt"
> "$OUTPUT_FILE"

echo "::group::Test attempt $ATTEMPT of $MAX_RETRIES"
if run_tests "$OUTPUT_FILE"; then
echo "✅ Tests passed on attempt $ATTEMPT"
echo "::endgroup::"
exit 0
fi
echo "::endgroup::"
echo "::warning::Tests failed on attempt $ATTEMPT"

cp "$OUTPUT_FILE" "/tmp/test-failures-attempt-${ATTEMPT}.txt"

if [ $ATTEMPT -ge $MAX_RETRIES ]; then
echo "::error::Tests still failing after $MAX_RETRIES fix attempts"
exit 1
fi

# Rebuild prompt fresh each iteration with the latest failure output
cp /tmp/verify-fix-prompt-template.txt /tmp/verify-fix-prompt-current.txt
cat "$OUTPUT_FILE" >> /tmp/verify-fix-prompt-current.txt

echo "🤖 Running agent to fix test failures (attempt $ATTEMPT)..."
run_agent_with_fallback /tmp/verify-fix-prompt-current.txt fix 20

if git diff --quiet && git diff --cached --quiet; then
echo "::error::Agent produced no changes — cannot recover from test failures"
exit 1
fi

git add -A
retry_op 5 10 git commit -m "fix(tests): address failures — attempt $ATTEMPT [ai-agent]

Issue: #${{ needs.apply-fix.outputs.issue_num }}"
retry_op 5 10 git push
done

- name: Upload test failure logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: test-failures-issue-${{ needs.apply-fix.outputs.issue_num }}
path: /tmp/test-failures-attempt-*.txt
retention-days: 7

open-pr:
needs: [apply-fix, verify-and-fix]
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.apply-fix.outputs.branch }}

- name: Create pull request
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
source scripts/agent-lib.sh

# If a PR already exists for this branch (from a previous run), skip creation
EXISTING_PR=$(gh pr list \
--head "${{ needs.apply-fix.outputs.branch }}" \
--json number --jq '.[0].number' 2>/dev/null || echo "")

if [[ -n "$EXISTING_PR" ]]; then
echo "PR #${EXISTING_PR} already exists for this branch — skipping creation"
exit 0
fi

retry_op 5 15 gh pr create \
--base dev \
--head "${{ needs.apply-fix.outputs.branch }}" \
--title "${{ needs.apply-fix.outputs.issue_title }}" \
--body "Closes #${{ needs.apply-fix.outputs.issue_num }}

🤖 Generated by AI agent. Automated review will follow.
Final approval required from @jay9297." \
--label "ai-generated"
Loading