Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions .claude/agents/agentready-dev.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
---
name: AgentReady Development
description: Specialized agent with deep knowledge of the AgentReady codebase for development, testing, and maintenance
tools: [Read, Write, Edit, Bash, Glob, Grep, WebSearch, WebFetch, TodoWrite]
---

# AgentReady Development Agent

**Purpose**: Specialized Claude Code agent with deep knowledge of the AgentReady codebase to assist with development, testing, and maintenance tasks.
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/agentready-assessment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:

steps:
- name: Post unauthorized message
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const user = context.payload.comment.user.login;
Expand Down Expand Up @@ -126,7 +126,7 @@ jobs:

- name: Checkout current repository
if: steps.parse.outputs.assess_current == 'true'
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.ref || github.ref }}

Expand All @@ -146,7 +146,7 @@ jobs:
echo "✅ Repository cloned successfully"

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.12'

Expand Down Expand Up @@ -205,7 +205,7 @@ jobs:
} >> "$GITHUB_OUTPUT"

- name: Upload Assessment Reports
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
if: always()
with:
name: agentready-reports-${{ github.run_id }}
Expand All @@ -214,7 +214,7 @@ jobs:

- name: Post assessment results
if: always()
uses: actions/github-script@v7
uses: actions/github-script@v8
env:
OUTPUT_DIR: ${{ steps.assessment.outputs.output_dir }}
REPO_URL: ${{ steps.parse.outputs.repo_url }}
Expand Down
91 changes: 91 additions & 0 deletions .github/workflows/agentready-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: Codebase Agent (agentready-dev)

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]

permissions:
contents: write
pull-requests: write
issues: write
id-token: write
actions: read

jobs:
agentready-dev:
# Trigger on @agentready-dev mentions in issues, PRs, and comments
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@agentready-dev')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@agentready-dev')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@agentready-dev')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@agentready-dev') || contains(github.event.issue.title, '@agentready-dev')))
runs-on: ubuntu-latest
steps:
- name: Get PR info for fork support
if: github.event.issue.pull_request
id: pr-info
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPOSITORY: ${{ github.repository }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
run: |
PR_DATA=$(gh api "repos/$REPOSITORY/pulls/$ISSUE_NUMBER")
{
echo "pr_head_owner=$(echo "$PR_DATA" | jq -r '.head.repo.owner.login')"
echo "pr_head_repo=$(echo "$PR_DATA" | jq -r '.head.repo.name')"
echo "pr_head_ref=$(echo "$PR_DATA" | jq -r '.head.ref')"
echo "is_fork=$(echo "$PR_DATA" | jq -r '.head.repo.fork')"
} >> "$GITHUB_OUTPUT"

- name: Extract user request
id: extract-request
env:
EVENT_NAME: ${{ github.event_name }}
COMMENT_BODY: ${{ github.event.comment.body }}
REVIEW_BODY: ${{ github.event.review.body }}
ISSUE_BODY: ${{ github.event.issue.body }}
run: |
case "$EVENT_NAME" in
issue_comment|pull_request_review_comment)
REQUEST="$COMMENT_BODY"
;;
pull_request_review)
REQUEST="$REVIEW_BODY"
;;
issues)
REQUEST="$ISSUE_BODY"
;;
*)
REQUEST="No request body found"
;;
esac

# Remove @agentready-dev mention from the request
REQUEST=$(echo "$REQUEST" | sed 's/@agentready-dev//g' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')

{
echo "request<<EOF"
echo "$REQUEST"
echo "EOF"
} >> "$GITHUB_OUTPUT"

- name: Checkout repository (fork-compatible)
uses: actions/checkout@v6
with:
repository: ${{ github.event.issue.pull_request && steps.pr-info.outputs.is_fork == 'true' && format('{0}/{1}', steps.pr-info.outputs.pr_head_owner, steps.pr-info.outputs.pr_head_repo) || github.repository }}
ref: ${{ github.event.issue.pull_request && steps.pr-info.outputs.pr_head_ref || github.ref }}
fetch-depth: 0

- name: Claude Code Action
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
prompt: |
@agentready-dev ${{ steps.extract-request.outputs.request }}
206 changes: 206 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
name: CI (Tests & Quality)

on:
pull_request:
push:
branches: [main, master]
workflow_dispatch:

jobs:
# Combined blocking tests and linting in one job to reduce CI runtime
blocking-checks:
name: Blocking Tests & Quality Checks
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.12', '3.13']

steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

# Run code quality checks (only on one Python version to save time)
- name: Code Quality Checks
if: matrix.python-version == '3.13'
run: |
black --check .
isort --check .
ruff check .

# Run critical tests
- name: Run Critical Tests
run: |
pytest tests/e2e/test_critical_paths.py tests/unit/cli/test_main.py tests/unit/test_models.py \
-v --no-cov --tb=short
timeout-minutes: 5

# Non-blocking comprehensive tests
comprehensive-tests:
name: Full Test Suite (Non-blocking)
runs-on: ubuntu-latest
continue-on-error: true # Don't fail CI

steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.13'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Run all tests with coverage
run: |
pytest tests/unit/ --cov=src --cov-report=xml --cov-report=html --cov-report=term
continue-on-error: true
timeout-minutes: 20

- name: Upload coverage
if: always()
uses: actions/upload-artifact@v5
with:
name: coverage-report
path: htmlcov/
retention-days: 30

# Platform testing (simplified to single job)
platform-test:
name: macOS Compatibility
runs-on: macos-latest
continue-on-error: true

steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.13'

- name: Install and test
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
pytest tests/e2e/test_critical_paths.py tests/unit/cli/test_main.py \
-v --no-cov --tb=short || echo "Tests failed but continuing"
timeout-minutes: 10

# Coverage reporting (PR only)
coverage-report:
name: Coverage Report
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write

steps:
- name: Checkout PR branch
uses: actions/checkout@v6

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.13'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Run tests with coverage
run: |
pytest tests/unit/ --cov=src/agentready --cov-report=xml --cov-report=term
continue-on-error: true

- name: Get coverage percentage
id: coverage
run: |
COVERAGE=$(python -c "import xml.etree.ElementTree as ET; tree = ET.parse('coverage.xml'); root = tree.getroot(); print(root.attrib['line-rate'])")
COVERAGE_PCT=$(python -c "print(f'{float(\"$COVERAGE\") * 100:.1f}')")
echo "coverage_pct=$COVERAGE_PCT" >> "$GITHUB_OUTPUT"

- name: Checkout main branch for comparison
run: |
git fetch origin main
git checkout origin/main

- name: Run tests on main branch
run: |
pytest tests/unit/ --cov=src/agentready --cov-report=xml --cov-report=term
continue-on-error: true

- name: Get main branch coverage
id: main_coverage
run: |
MAIN_COVERAGE=$(python -c "import xml.etree.ElementTree as ET; tree = ET.parse('coverage.xml'); root = tree.getroot(); print(root.attrib['line-rate'])")
MAIN_COVERAGE_PCT=$(python -c "print(f'{float(\"$MAIN_COVERAGE\") * 100:.1f}')")
echo "main_coverage_pct=$MAIN_COVERAGE_PCT" >> "$GITHUB_OUTPUT"

- name: Calculate diff
id: diff
env:
PR_COVERAGE: ${{ steps.coverage.outputs.coverage_pct }}
MAIN_COVERAGE: ${{ steps.main_coverage.outputs.main_coverage_pct }}
run: |
DIFF=$(python -c "print(f'{float(\"$PR_COVERAGE\") - float(\"$MAIN_COVERAGE\"):.1f}')")
echo "diff=$DIFF" >> "$GITHUB_OUTPUT"

- name: Post coverage comment
uses: actions/github-script@v8
env:
PR_COVERAGE: ${{ steps.coverage.outputs.coverage_pct }}
MAIN_COVERAGE: ${{ steps.main_coverage.outputs.main_coverage_pct }}
DIFF: ${{ steps.diff.outputs.diff }}
with:
script: |
const prCoverage = process.env.PR_COVERAGE;
const mainCoverage = process.env.MAIN_COVERAGE;
const diff = parseFloat(process.env.DIFF);

const emoji = diff >= 0 ? '📈' : '📉';
const diffText = diff >= 0 ? `+${diff}%` : `${diff}%`;
const status = diff >= 0 ? '✅' : '⚠️';

const body = `## ${emoji} Test Coverage Report\n\n` +
`| Branch | Coverage |\n` +
`|--------|----------|\n` +
`| **This PR** | ${prCoverage}% |\n` +
`| Main | ${mainCoverage}% |\n` +
`| **Diff** | ${status} ${diffText} |\n\n` +
`---\n\n` +
`*Coverage calculated from unit tests only*`;

const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});

const existingComment = comments.data.find(comment =>
comment.user.login === 'github-actions[bot]' &&
comment.body.includes('Test Coverage Report')
);

if (existingComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existingComment.id,
body: body
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
}
Loading
Loading