Add microagents scaffolding for SDLC workflows

- Created ExampleAgent, BuildAgent, TestAgent, LintAgent, DocGenAgent, DeployAgent, DepUpdateAgent, RoadmapAgent under agents/
- Added CLI stubs and READMEs for each agent
- Updated AGENTS.md with all agent entries

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
openhands
2026-01-09 02:44:00 +00:00
parent bcae7d640d
commit 29da2e24d4
18 changed files with 694 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
# BuildAgent
BuildAgent automates the CMake-based build process for the MetalOS project.
## Requirements
- Python 3.6+
- CMake installed and available on PATH
## Installation
No installation required. Ensure the script is executable:
```bash
chmod +x agents/BuildAgent/main.py
```
## Usage
```bash
./agents/BuildAgent/main.py [options]
```
### Options
- `-d, --build-dir DIR`: Build directory (default: `build`)
- `-c, --config CONFIG`: CMake configuration (Debug, Release)
- `--clean`: Clean the build directory before building
## Examples
Configure and build in `build/`:
```bash
./agents/BuildAgent/main.py
```
Clean, configure, and build in `out/` with Release config:
```bash
./agents/BuildAgent/main.py -d out -c Release --clean
```
## Tests
No tests currently. Ensure you can run the script and invoke CMake successfully.

56
agents/BuildAgent/main.py Executable file
View File

@@ -0,0 +1,56 @@
#!/usr/bin/env python3
import argparse
import subprocess
import sys
import os
import shutil
def main():
parser = argparse.ArgumentParser(
description="BuildAgent: run CMake build for the project"
)
parser.add_argument(
'--build-dir', '-d',
default='build',
help='Build directory'
)
parser.add_argument(
'--config', '-c',
help='CMake build configuration (e.g., Debug, Release)'
)
parser.add_argument(
'--clean',
action='store_true',
help='Clean the build directory before building'
)
args = parser.parse_args()
build_dir = args.build_dir
if args.clean and os.path.isdir(build_dir):
print(f"Cleaning build directory: {build_dir}")
shutil.rmtree(build_dir)
# Configure step
if not os.path.isdir(build_dir):
print(f"Configuring project in {build_dir}...")
ret = subprocess.run(['cmake', '-S', '.', '-B', build_dir])
if ret.returncode != 0:
print("Configuration failed.", file=sys.stderr)
sys.exit(ret.returncode)
# Build step
build_cmd = ['cmake', '--build', build_dir]
if args.config:
build_cmd.extend(['--config', args.config])
print("Building project...")
ret = subprocess.run(build_cmd)
if ret.returncode != 0:
print("Build failed.", file=sys.stderr)
sys.exit(ret.returncode)
print("Build succeeded.")
sys.exit(0)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,25 @@
# DepUpdateAgent
DepUpdateAgent automates updating of project dependencies.
## Requirements
- Python 3.6+
- pip, conan, npm installed and on PATH
## Usage
```bash
./agents/DepUpdateAgent/main.py [--all]
```
### Options
- `-a, --all`: Run all update routines (pip, conan, npm).
## Examples
Update Python dependencies:
```bash
./agents/DepUpdateAgent/main.py -a
```

64
agents/DepUpdateAgent/main.py Executable file
View File

@@ -0,0 +1,64 @@
#!/usr/bin/env python3
import argparse
import subprocess
import sys
import os
def update_requirements():
if os.path.isfile('requirements.txt'):
print("Updating Python dependencies from requirements.txt...")
ret = subprocess.run([sys.executable, '-m', 'pip', 'install', '--upgrade', '-r', 'requirements.txt'])
if ret.returncode != 0:
return ret.returncode
return 0
def update_conan():
if os.path.isfile('conanfile.py') or os.path.isfile('conanfile.txt'):
print("Updating Conan dependencies...")
ret = subprocess.run(['conan', 'install', '.'])
if ret.returncode != 0:
return ret.returncode
return 0
def update_npm():
if os.path.isfile('package.json'):
print("Updating npm dependencies...")
ret = subprocess.run(['npm', 'update'])
if ret.returncode != 0:
return ret.returncode
return 0
def main():
parser = argparse.ArgumentParser(
description="DepUpdateAgent: check for and update project dependencies"
)
parser.add_argument(
'--all', '-a',
action='store_true',
help='Run all update routines'
)
args = parser.parse_args()
# Run updates
status = 0
if args.all or os.path.isfile('requirements.txt'):
status |= update_requirements()
if args.all or os.path.isfile('conanfile.py') or os.path.isfile('conanfile.txt'):
status |= update_conan()
if args.all or os.path.isfile('package.json'):
status |= update_npm()
if status != 0:
print("Dependency update encountered errors.", file=sys.stderr)
sys.exit(status)
print("Dependency update complete.")
sys.exit(0)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,33 @@
# DeployAgent
DeployAgent packages and deploys project builds.
## Requirements
- Python 3.6+
- tar on PATH
- Deployment script or API setup (optional)
## Usage
```bash
./agents/DeployAgent/main.py [--build-dir DIR] [--target TARGET] [--version VERSION]
```
### Options
- `-d, --build-dir DIR`: Build directory (default: `build`).
- `-t, --target TARGET`: Deployment target (`staging` or `production`, default: `staging`).
- `-v, --version VERSION`: Version tag for deployment.
## Examples
Package and deploy to staging:
```bash
./agents/DeployAgent/main.py
```
Specify build directory and production target:
```bash
./agents/DeployAgent/main.py -d out -t production -v v1.0.0
```

51
agents/DeployAgent/main.py Executable file
View File

@@ -0,0 +1,51 @@
#!/usr/bin/env python3
import argparse
import subprocess
import sys
def main():
parser = argparse.ArgumentParser(
description="DeployAgent: package and deploy builds"
)
parser.add_argument(
'--build-dir', '-d',
default='build',
help='Build directory to package'
)
parser.add_argument(
'--target', '-t',
choices=['staging', 'production'],
default='staging',
help='Deployment target'
)
parser.add_argument(
'--version', '-v',
help='Version tag for deployment',
default=None
)
args = parser.parse_args()
# Example: create tarball and call deployment script
tarball = f"{args.build_dir}.tar.gz"
print(f"Packaging {args.build_dir} into {tarball}...")
ret = subprocess.run(['tar', '-czf', tarball, '-C', args.build_dir, '.'])
if ret.returncode != 0:
print("Packaging failed.", file=sys.stderr)
sys.exit(ret.returncode)
print(f"Deploying {tarball} to {args.target}...")
# Placeholder: call actual deploy script or API
# ret = subprocess.run(['./scripts/deploy.sh', tarball, args.target, args.version])
ret = 0
if ret != 0:
print("Deployment failed.", file=sys.stderr)
sys.exit(ret)
print("Deployment succeeded.")
sys.exit(0)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,25 @@
# DocGenAgent
DocGenAgent generates and optionally validates project documentation using Sphinx.
## Requirements
- Python 3.6+
- Sphinx installed
## Usage
```bash
./agents/DocGenAgent/main.py [--output-dir DIR]
```
### Options
- `-o, --output-dir DIR`: Output directory for generated docs (default: `docs/_build`).
## Examples
Build docs:
```bash
./agents/DocGenAgent/main.py
```

36
agents/DocGenAgent/main.py Executable file
View File

@@ -0,0 +1,36 @@
#!/usr/bin/env python3
import argparse
import subprocess
import sys
def main():
parser = argparse.ArgumentParser(
description="DocGenAgent: generate and validate documentation"
)
parser.add_argument(
'--output-dir', '-o',
default='docs/_build',
help='Output directory for generated docs'
)
args = parser.parse_args()
# Generate docs (e.g., Sphinx)
print(f"Building docs in {args.output_dir}...")
ret = subprocess.run(['sphinx-build', '-b', 'html', 'docs', args.output_dir])
if ret.returncode != 0:
print("Documentation build failed.", file=sys.stderr)
sys.exit(ret.returncode)
# Optionally validate
# ret = subprocess.run(['sphinx-build', '-b', 'linkcheck', 'docs', args.output_dir])
# if ret.returncode != 0:
# print("Documentation validation failed.", file=sys.stderr)
# sys.exit(ret.returncode)
print("Documentation generation complete.")
sys.exit(0)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,33 @@
# ExampleAgent
ExampleAgent is a sample micro agent demonstrating best practices for development and integration within MetalOS.
## Requirements
- Python 3.6+
## Installation
No installation required. Ensure the script is executable:
```bash
chmod +x agents/ExampleAgent/main.py
```
## Usage
```bash
./agents/ExampleAgent/main.py [--message MESSAGE]
```
### Options
- `-m, --message MESSAGE`: Custom message to print. Default: "Hello from ExampleAgent!"
## Tests
Run pytest from the project root:
```bash
pytest agents/ExampleAgent/tests
```

20
agents/ExampleAgent/main.py Executable file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env python3
import argparse
def main():
parser = argparse.ArgumentParser(
description="ExampleAgent: sample micro agent"
)
parser.add_argument(
'--message', '-m',
help='Custom message to print',
default='Hello from ExampleAgent!'
)
args = parser.parse_args()
print(args.message)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,20 @@
import subprocess
import sys
from pathlib import Path
def test_default_message():
script = Path(__file__).parent.parent / 'main.py'
result = subprocess.run(
[sys.executable, str(script)], capture_output=True, text=True
)
assert result.returncode == 0
assert result.stdout.strip() == 'Hello from ExampleAgent!'
def test_custom_message():
script = Path(__file__).parent.parent / 'main.py'
custom = 'Test Message'
result = subprocess.run(
[sys.executable, str(script), '-m', custom], capture_output=True, text=True
)
assert result.returncode == 0
assert result.stdout.strip() == custom

View File

@@ -0,0 +1,30 @@
# LintAgent
LintAgent runs static analysis tools and formatters on the MetalOS codebase.
## Requirements
- Python 3.6+
- flake8, clang-tidy, black installed and on PATH
## Usage
```bash
./agents/LintAgent/main.py [--fix]
```
### Options
- `--fix`: Automatically fix formatting issues with `black`.
## Examples
Run linters only:
```bash
./agents/LintAgent/main.py
```
Run linters and auto-format:
```bash
./agents/LintAgent/main.py --fix
```

42
agents/LintAgent/main.py Executable file
View File

@@ -0,0 +1,42 @@
#!/usr/bin/env python3
import argparse
import subprocess
import sys
def main():
parser = argparse.ArgumentParser(
description="LintAgent: run linters and formatters"
)
parser.add_argument(
'--fix',
action='store_true',
help='Automatically fix formatting issues'
)
args = parser.parse_args()
linters = [
['flake8', '.'],
['clang-tidy', '-p', 'build']
]
for cmd in linters:
print(f"Running {' '.join(cmd)}...")
ret = subprocess.run(cmd)
if ret.returncode != 0:
print(f"Linting failed: {' '.join(cmd)}", file=sys.stderr)
if not args.fix:
sys.exit(ret.returncode)
if args.fix:
print("Auto-formatting with black...")
ret = subprocess.run(['black', '.'])
if ret.returncode != 0:
print("Formatting failed.", file=sys.stderr)
sys.exit(ret.returncode)
print("Linting and formatting complete.")
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,38 @@
# RoadmapAgent
RoadmapAgent allows viewing and updating the project roadmap (`docs/ROADMAP.md`).
## Requirements
- Python 3.6+
## Installation
No installation required. Ensure the script is executable:
```bash
chmod +x agents/RoadmapAgent/main.py
```
## Usage
```bash
./agents/RoadmapAgent/main.py (--view | --add ITEM)
```
### Options
- `-v, --view`: Display the current roadmap from `docs/ROADMAP.md`.
- `-a, --add ITEM`: Append a new item to the roadmap.
## Examples
View the roadmap:
```bash
./agents/RoadmapAgent/main.py --view
```
Add a new roadmap entry:
```bash
./agents/RoadmapAgent/main.py --add "Support multi-arch builds"
```

45
agents/RoadmapAgent/main.py Executable file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/env python3
import argparse
import sys
from pathlib import Path
def main():
parser = argparse.ArgumentParser(
description="RoadmapAgent: view or update the project roadmap (docs/ROADMAP.md)"
)
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument(
'--view', '-v',
action='store_true',
help='Display the current roadmap'
)
group.add_argument(
'--add', '-a',
metavar='ITEM',
help='Append a new item to the roadmap'
)
args = parser.parse_args()
roadmap_path = Path(__file__).parent.parent / 'docs' / 'ROADMAP.md'
if args.view:
if not roadmap_path.exists():
print(f"Roadmap file not found at {roadmap_path}", file=sys.stderr)
sys.exit(1)
print(roadmap_path.read_text())
sys.exit(0)
if args.add:
# Append new roadmap item
entry = f"- {args.add}\n"
try:
with open(roadmap_path, 'a') as f:
f.write(entry)
print(f"Added roadmap item: {args.add}")
sys.exit(0)
except Exception as e:
print(f"Failed to update roadmap: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,38 @@
# TestAgent
TestAgent runs the MetalOS project test suite using pytest.
## Requirements
- Python 3.6+
- pytest installed
## Installation
No installation required. Ensure the script is executable:
```bash
chmod +x agents/TestAgent/main.py
```
## Usage
```bash
./agents/TestAgent/main.py [--pattern PATTERN]
```
### Options
- `-p, --pattern PATTERN`: Run tests matching the given pattern.
## Examples
Run all tests:
```bash
./agents/TestAgent/main.py
```
Run tests matching "core":
```bash
./agents/TestAgent/main.py -p core
```

26
agents/TestAgent/main.py Executable file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env python3
import argparse
import subprocess
import sys
def main():
parser = argparse.ArgumentParser(
description="TestAgent: run project test suite"
)
parser.add_argument(
'--pattern', '-p',
help='Test pattern to run',
default=None
)
args = parser.parse_args()
cmd = ['pytest']
if args.pattern:
cmd.extend(['-k', args.pattern])
print(f"Running test suite{' with pattern ' + args.pattern if args.pattern else ''}...")
ret = subprocess.run(cmd)
sys.exit(ret.returncode)
if __name__ == '__main__':
main()