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
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,39 @@ jobs:
CI: "true"
run: tests/run-scenarios.sh npm-agent

# ── py-agent scenarios ──────────────────────────────────────────────
py-agent:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
# baseline: no optional python tools
- name: baseline
install_ruff: false

# with ruff
- name: with-ruff
install_ruff: true

name: "py-agent (${{ matrix.name }})"
steps:
- uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install ruff
if: matrix.install_ruff
run: pip install ruff

- name: Run py-agent scenarios
env:
CI: "true"
run: tests/run-scenarios.sh py-agent

# ── terra-agent scenarios ───────────────────────────────────────────
terra-agent:
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Read this file first, then open only the linked docs you need.
- Keep output concise and structured (`Step`, `Result`, `Fix`, `Overall`, log path).
- Support shared knobs (`RUN_<STEP>`, `MAX_LINES`, `KEEP_DIR`, `FAIL_FAST`, `CHANGED_FILES`).
- Every `Result: FAIL` must include a `Fix:` hint.
- The `help`/`--help`/`-h` command must work without project context — resolve it before any project-existence checks.
- `shellcheck --severity=warning` must pass on all scripts.
- Ship one backlog item per commit.

Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Standard build tools produce walls of text. Agents waste context window parsing
|-------|-----------|-------|
| `cargo-agent` | Rust | fmt, check, clippy, test (nextest) |
| `npm-agent` | Node.js | format, lint, typecheck, test, build |
| `py-agent` | Python | format (ruff/black), lint (ruff/flake8), typecheck (mypy/pyright), test (pytest) |
| `terra-agent` | Terraform | fmt (check/fix), safe init, plan-safe, validate, lint (tflint) |

## Quick Start
Expand Down Expand Up @@ -48,6 +49,9 @@ path/to/x-agent/skills/cargo-agent/scripts/cargo-agent.sh
# Node.js project
path/to/x-agent/skills/npm-agent/scripts/npm-agent.sh

# Python project
path/to/x-agent/skills/py-agent/scripts/py-agent.sh

# Terraform project
path/to/x-agent/skills/terra-agent/scripts/terra-agent.sh
```
Expand Down Expand Up @@ -75,6 +79,18 @@ npm-agent.sh typecheck # type checking only

npm-agent auto-detects your package manager (bun, pnpm, yarn, npm) and finds formatters/linters from package.json scripts or common tools (biome, eslint, prettier, tsc).

### py-agent

```sh
py-agent.sh # full suite: format + lint + typecheck + test
py-agent.sh format # format only (auto-fix locally, check in CI)
py-agent.sh lint # lint only
py-agent.sh test # tests only
py-agent.sh test -k login # tests matching "login"
```

py-agent auto-detects your runner (uv, poetry, or plain python) and finds tools (ruff, black, flake8, mypy, pyright, pytest).

### terra-agent

```sh
Expand Down Expand Up @@ -138,6 +154,7 @@ The `skills/` directory contains Claude Code skill definitions. After installing

- `/cargo-agent` — run Rust checks
- `/npm-agent` — run Node.js checks
- `/py-agent` — run Python checks
- `/terra-agent` — run Terraform checks/fixes

## License
Expand Down
2 changes: 1 addition & 1 deletion docs/agents/definition-of-done.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ An agent is done only when all items below are complete.
- `skills/<name>-agent/SKILL.md` `allowed-tools` includes patterns for all env knobs (`RUN_*`, `MAX_LINES`, `KEEP_DIR`, `FAIL_FAST`, plus any agent-specific knobs).
- `skills/<name>-agent/scripts/<name>-agent.sh` exists and is executable.
- Script starts with `set -euo pipefail`.
- Script has `--help`/`help`/`-h` usage output.
- Script has `--help`/`help`/`-h` usage output that works without project context (resolved before project-existence checks).

## Output Contract

Expand Down
21 changes: 20 additions & 1 deletion install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ SOURCE_DIR=""
SOURCE_MODE="remote"

# Available skills to install (each has its own scripts/ subdirectory)
SKILLS="cargo-agent npm-agent terra-agent"
SKILLS="cargo-agent npm-agent py-agent terra-agent"
SELECTED_SKILLS=""

info() {
Expand Down Expand Up @@ -285,6 +285,22 @@ check_optional_deps() {
fi
fi

if skill_selected "py-agent"; then
if command -v python3 >/dev/null 2>&1 || command -v python >/dev/null 2>&1; then
info " Found: python"
else
warn " Missing: python3 (needed by py-agent)"
all_ok=0
fi

for dep in ruff black; do
if command -v "$dep" >/dev/null 2>&1; then
info " Found: ${dep}"
break
fi
done
fi

if skill_selected "terra-agent"; then
if command -v terraform >/dev/null 2>&1; then
info " Found: terraform"
Expand Down Expand Up @@ -324,6 +340,9 @@ print_agents_md_snippet() {
npm-agent)
echo "- Node.js: use \`/npm-agent\` (format/lint/typecheck/test/build)."
;;
py-agent)
echo "- Python: use \`/py-agent\` (format/lint/typecheck/test)."
;;
terra-agent)
echo "- Terraform: use \`/terra-agent\` (fmt-check/fmt-fix/init/plan-safe/validate/lint)."
;;
Expand Down
84 changes: 84 additions & 0 deletions skills/py-agent/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
name: py-agent
description: |
Run py-agent.sh — a lean Python workflow runner that produces agent-friendly output.
Use when: running Python checks (format, lint, typecheck, test), verifying Python code before committing,
or when the user asks to run Python checks, lint, format, or test a Python project.
Triggers on: py agent, run python checks, python checks, ruff mypy pytest, verify python code, run py checks.
context: fork
allowed-tools:
- Bash(scripts/py-agent.sh*)
- Bash(RUN_*=* scripts/py-agent.sh*)
- Bash(MAX_LINES=* scripts/py-agent.sh*)
- Bash(KEEP_DIR=* scripts/py-agent.sh*)
- Bash(FAIL_FAST=* scripts/py-agent.sh*)
- Bash(CHANGED_FILES=* scripts/py-agent.sh*)
---

# Py Agent

Run the `py-agent.sh` script for lean, structured Python workflow output designed for coding agents.

## Script Location

```
scripts/py-agent.sh
```

## Usage

### Run Full Suite (format + lint + typecheck + test)
```bash
scripts/py-agent.sh
```

### Run Individual Steps
```bash
scripts/py-agent.sh format # format (auto-fix locally, check in CI)
scripts/py-agent.sh lint # lint only
scripts/py-agent.sh typecheck # typecheck only
scripts/py-agent.sh test # tests only
scripts/py-agent.sh all # full suite (default)
```

### Pass Args to Tests
```bash
scripts/py-agent.sh test -k test_login # filter by name
scripts/py-agent.sh test tests/unit/ # specific directory
```

## Environment Knobs

| Variable | Default | Description |
|----------|---------|-------------|
| `RUN_FORMAT` | `1` | Set to `0` to skip format |
| `RUN_LINT` | `1` | Set to `0` to skip lint |
| `RUN_TYPECHECK` | `1` | Set to `0` to skip typecheck |
| `RUN_TESTS` | `1` | Set to `0` to skip tests |
| `MAX_LINES` | `40` | Max output lines printed per step (unlimited in CI) |
| `KEEP_DIR` | `0` | Set to `1` to keep temp log dir on success |
| `FAIL_FAST` | `0` | Stop after first failing step; passes `-x` to pytest |
| `CHANGED_FILES` | _(empty)_ | Space-separated changed file paths; scopes format/lint to affected `.py` files |

## Auto-Detection

- **Runner**: detects uv, poetry, or plain python from lock files
- **Format**: tries ruff format, then black
- **Lint**: tries ruff check, then flake8
- **Typecheck**: tries mypy, then pyright
- **Tests**: tries pytest, then python -m unittest discover
- **CI mode**: format runs `--check` in CI, auto-fixes locally

## Output Format

- Each step prints a header (`Step: format`, `Step: lint`, etc.)
- Results are `PASS`, `FAIL`, or `SKIP`
- On failure, output is truncated to `MAX_LINES` with full logs on disk
- `Fix:` hint after each failure (suggests auto-fix commands where available)
- Overall result is printed at the end: `Overall: PASS` or `Overall: FAIL`

## Important Notes

- The script must be run from within a Python project directory (requires pyproject.toml, setup.py, setup.cfg, or requirements.txt)
- Steps are skipped gracefully if no matching tool is found
- On failure, the temp log directory is preserved automatically for inspection
Loading