This skill should be used when the user asks to "create an angreal project", "initialize angreal", "set up angreal", "add angreal to project", "start new angreal project", "create .angreal...
Set up angreal task automation in a new or existing project.
An angreal project is any directory containing a .angreal/ subdirectory with task files. Angreal provides development task automation - think of it as your project's make or npm run.
For a fresh project or to add angreal to a directory you've already created, use one of the official templates:
# Fresh project (creates a new subdirectory)
angreal init python
# Add angreal into an existing project root (no extra subdir)
cd my-existing-project
angreal init python --in-place
--in-place / -i strips the template's top-level templated directory and renders directly into the current working directory ā this is the canonical path for "add angreal to my existing repo." Add --force if existing files would be overwritten, --defaults to skip prompts, or --values <file> to supply variables non-interactively. See the angreal-templates skill for the full template catalog (python, python-gh, python-gl, rust, data-science, airflow, ā¦).
If no template matches or you want full control:
mkdir .angreal
# .angreal/task_dev.py
import angreal
@angreal.command(name="hello", about="Test angreal setup")
def hello():
print("Angreal is working!")
return 0
angreal tree # Should show: hello - Test angreal setup
angreal hello # Should print: Angreal is working!
my-project/
āāā .angreal/
ā āāā task_dev.py # Start with one task file
āāā src/
āāā ...
my-project/
āāā .angreal/
ā āāā task_dev.py # Development utilities
ā āāā task_test.py # Testing commands
ā āāā task_build.py # Build commands
ā āāā task_docs.py # Documentation commands
āāā src/
āāā ...
my-project/
āāā .angreal/
ā āāā utils.py # Shared helper functions
ā āāā task_dev.py
ā āāā task_test.py
ā āāā task_build.py
āāā src/
āāā ...
# .angreal/task_dev.py
import angreal
import subprocess
import os
@angreal.command(name="check-deps", about="Verify development tools")
def check_deps():
"""Check that required tools are installed."""
tools = ["python", "git"]
missing = []
for tool in tools:
result = subprocess.run(
["which", tool],
capture_output=True
)
if result.returncode != 0:
missing.append(tool)
if missing:
print(f"Missing tools: {', '.join(missing)}")
return 1
print("All tools available!")
return 0
@angreal.command(name="setup", about="Set up development environment")
def setup():
"""Initialize development environment."""
project_root = angreal.get_root().parent
# Example: Create virtual environment
venv_path = project_root / ".venv"
if not venv_path.exists():
print("Creating virtual environment...")
subprocess.run(["python", "-m", "venv", str(venv_path)])
print("Development environment ready!")
return 0
# .angreal/task_test.py
import angreal
import subprocess
test = angreal.command_group(name="test", about="Testing commands")
@test()
@angreal.command(name="all", about="Run all tests")
def test_all():
project_root = angreal.get_root().parent
result = subprocess.run(
["pytest", "-v"],
cwd=project_root
)
return result.returncode
@test()
@angreal.command(name="unit", about="Run unit tests only")
def test_unit():
project_root = angreal.get_root().parent
result = subprocess.run(
["pytest", "tests/unit", "-v"],
cwd=project_root
)
return result.returncode
# .angreal/task_build.py
import angreal
import subprocess
@angreal.command(
name="build",
about="Build the project",
tool=angreal.ToolDescription("""
Build project artifacts.
## When to use
- Before releasing
- Testing production builds
## Examples
```
angreal build
angreal build --release
```
""", risk_level="safe")
)
@angreal.argument(
name="release",
long="release",
is_flag=True,
takes_value=False,
help="Build in release mode"
)
def build(release=False):
project_root = angreal.get_root().parent
cmd = ["python", "-m", "build"]
print(f"Building {'release' if release else 'debug'}...")
result = subprocess.run(cmd, cwd=project_root)
return result.returncode
# .angreal/utils.py
import angreal
import subprocess
from pathlib import Path
def get_project_root() -> Path:
"""Return the project root directory."""
return angreal.get_root().parent
def run_command(cmd, check=True, capture=False):
"""Run a command in the project root."""
result = subprocess.run(
cmd,
cwd=get_project_root(),
capture_output=capture,
text=True
)
if check and result.returncode != 0:
raise subprocess.CalledProcessError(
result.returncode, cmd
)
return result
def file_exists(relative_path: str) -> bool:
"""Check if a file exists relative to project root."""
return (get_project_root() / relative_path).exists()
.angreal/ directory at project root.angreal/ to version controlBefore (Makefile):
test:
pytest tests/
build:
python -m build
After (.angreal/task_build.py):
import angreal
import subprocess
@angreal.command(name="test", about="Run tests")
def test():
return subprocess.run(["pytest", "tests/"]).returncode
@angreal.command(name="build", about="Build package")
def build():
return subprocess.run(["python", "-m", "build"]).returncode
task_<domain>.py patterntask_test.py, task_build.pyutils.py or helpers.pyAdd to .gitignore:
# Don't ignore .angreal/ - it should be versioned
# But ignore any generated files within it
.angreal/__pycache__/
.angreal/*.pyc
After setup, verify:
angreal tree shows your commandsangreal <command> executes correctlyangreal.get_root().parent