refactor: reorganize into monorepo with separate subprojects
Structure webber into three independent subprojects: - webber-api/: FastAPI backend server with all agent code - webber-cli/: Standalone CLI client (renamed from cli/ to webber_cli/) - webber-sandbox/: Test project for functional testing Key changes: - Each subproject has its own .venv (Python 3.12+) - Added sandbox.sh for managing test project templates - Created sandbox-templates/ with calculator-cli and empty starter - Updated CI/CD for prefixed tags (api/v*, cli/v*) - Added comprehensive AGENTS.md with operational instructions - Added gitignore filtering to glob and grep tools - Created pyproject.toml for each subproject Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
dist/
|
||||
*.egg-info/
|
||||
|
||||
# Virtual environments
|
||||
.venv/
|
||||
venv/
|
||||
|
||||
# Testing
|
||||
.pytest_cache/
|
||||
.coverage
|
||||
htmlcov/
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
|
||||
# Project
|
||||
.current_template
|
||||
@@ -0,0 +1,64 @@
|
||||
# Calculator CLI - Tasks for Webber
|
||||
|
||||
A simple calculator with intentional bugs and missing features for testing Webber's capabilities.
|
||||
|
||||
## Bugs to Fix
|
||||
|
||||
### High Priority
|
||||
- [ ] **Division by zero** - `operations.py:divide()` crashes when dividing by zero instead of returning an error
|
||||
- [ ] **Invalid operation name** - `main.py:get_operation()` raises KeyError for unknown operations instead of helpful error message
|
||||
|
||||
### Medium Priority
|
||||
- [ ] **Power function broken** - `operations.py:power()` doesn't handle negative exponents or fractional exponents correctly
|
||||
- [ ] **No input validation** - `main.py` doesn't validate that command-line arguments are valid numbers
|
||||
|
||||
## Missing Tests
|
||||
|
||||
- [ ] Add `TestDivide` class with tests for:
|
||||
- Normal division
|
||||
- Division by zero (should test error handling once bug is fixed)
|
||||
- Division with negative numbers
|
||||
|
||||
- [ ] Add `TestPower` class with tests for:
|
||||
- Positive integer exponents
|
||||
- Zero exponent (should return 1)
|
||||
- Negative exponents
|
||||
|
||||
- [ ] Complete existing test classes:
|
||||
- `test_add_zero`
|
||||
- `test_add_floats`
|
||||
- `test_subtract_negative`
|
||||
- `test_multiply_by_zero`
|
||||
|
||||
## Features to Add
|
||||
|
||||
- [ ] **Expose power operation** - Add 'pow' to the operations dictionary in `main.py`
|
||||
- [ ] **Add modulo operation** - Implement `modulo(a, b)` in operations.py
|
||||
- [ ] **Add --verbose flag** - Show step-by-step calculation
|
||||
- [ ] **Add history command** - Track and display recent calculations
|
||||
- [ ] **Add REPL mode** - Interactive calculator loop
|
||||
|
||||
## Code Quality
|
||||
|
||||
- [ ] Add type hints to all functions
|
||||
- [ ] Add docstrings following Google style
|
||||
- [ ] Fix any linting errors (run `ruff check src/`)
|
||||
|
||||
## How to Run
|
||||
|
||||
```bash
|
||||
# Setup
|
||||
python3.12 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Run calculator
|
||||
python -m calculator.main 10 5 add
|
||||
python -m calculator.main 10 5 div
|
||||
|
||||
# Run tests
|
||||
pytest tests/ -v
|
||||
|
||||
# See failing tests (division by zero)
|
||||
python -m calculator.main 10 0 div
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
[project]
|
||||
name = "calculator"
|
||||
version = "0.1.0"
|
||||
description = "A simple calculator CLI with some bugs"
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=75.0"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["src"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
pythonpath = ["src"]
|
||||
addopts = "-v"
|
||||
@@ -0,0 +1,2 @@
|
||||
# Calculator CLI dependencies
|
||||
pytest>=8.0.0
|
||||
@@ -0,0 +1,3 @@
|
||||
"""Calculator CLI - A simple calculator with some bugs for testing."""
|
||||
|
||||
__version__ = "0.1.0"
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Calculator CLI - A simple command-line calculator.
|
||||
|
||||
NOTE: This file contains intentional bugs for testing purposes.
|
||||
|
||||
Usage:
|
||||
python -m calculator.main 10 5 add
|
||||
python -m calculator.main 10 5 sub
|
||||
python -m calculator.main 10 5 mul
|
||||
python -m calculator.main 10 5 div
|
||||
"""
|
||||
import sys
|
||||
|
||||
from calculator.operations import add, subtract, multiply, divide
|
||||
|
||||
|
||||
def get_operation(op_name: str):
|
||||
"""
|
||||
Get the operation function by name.
|
||||
|
||||
BUG: No validation - invalid operation names cause KeyError!
|
||||
"""
|
||||
operations = {
|
||||
"add": add,
|
||||
"sub": subtract,
|
||||
"mul": multiply,
|
||||
"div": divide,
|
||||
# BUG: 'power' is implemented in operations.py but not exposed here
|
||||
}
|
||||
# BUG: Should handle KeyError gracefully
|
||||
return operations[op_name]
|
||||
|
||||
|
||||
def main():
|
||||
"""Main entry point."""
|
||||
if len(sys.argv) != 4:
|
||||
print("Usage: python -m calculator.main <a> <b> <operation>")
|
||||
print("Operations: add, sub, mul, div")
|
||||
sys.exit(1)
|
||||
|
||||
# BUG: No validation that a and b are valid numbers
|
||||
a = float(sys.argv[1])
|
||||
b = float(sys.argv[2])
|
||||
op_name = sys.argv[3]
|
||||
|
||||
# BUG: This will crash with KeyError for invalid operation
|
||||
operation = get_operation(op_name)
|
||||
result = operation(a, b)
|
||||
|
||||
print(f"Result: {result}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,43 @@
|
||||
"""
|
||||
Math operations for the calculator.
|
||||
|
||||
NOTE: This file contains intentional bugs for testing purposes.
|
||||
"""
|
||||
|
||||
|
||||
def add(a: float, b: float) -> float:
|
||||
"""Add two numbers."""
|
||||
return a + b
|
||||
|
||||
|
||||
def subtract(a: float, b: float) -> float:
|
||||
"""Subtract b from a."""
|
||||
return a - b
|
||||
|
||||
|
||||
def multiply(a: float, b: float) -> float:
|
||||
"""Multiply two numbers."""
|
||||
return a * b
|
||||
|
||||
|
||||
def divide(a: float, b: float) -> float:
|
||||
"""
|
||||
Divide a by b.
|
||||
|
||||
BUG: Does not handle division by zero!
|
||||
"""
|
||||
# BUG: No check for b == 0
|
||||
return a / b
|
||||
|
||||
|
||||
def power(a: float, b: float) -> float:
|
||||
"""
|
||||
Raise a to the power of b.
|
||||
|
||||
BUG: Negative exponents not handled correctly for some cases.
|
||||
"""
|
||||
# BUG: This naive implementation has issues with negative bases and fractional exponents
|
||||
result = 1
|
||||
for _ in range(int(b)):
|
||||
result *= a
|
||||
return result
|
||||
@@ -0,0 +1 @@
|
||||
"""Calculator tests."""
|
||||
@@ -0,0 +1,46 @@
|
||||
"""
|
||||
Tests for calculator operations.
|
||||
|
||||
NOTE: Test coverage is intentionally incomplete for testing purposes.
|
||||
"""
|
||||
import pytest
|
||||
|
||||
from calculator.operations import add, subtract, multiply
|
||||
|
||||
|
||||
class TestAdd:
|
||||
"""Tests for add operation."""
|
||||
|
||||
def test_add_positive_numbers(self):
|
||||
assert add(2, 3) == 5
|
||||
|
||||
def test_add_negative_numbers(self):
|
||||
assert add(-2, -3) == -5
|
||||
|
||||
# MISSING: test_add_zero, test_add_floats
|
||||
|
||||
|
||||
class TestSubtract:
|
||||
"""Tests for subtract operation."""
|
||||
|
||||
def test_subtract_positive(self):
|
||||
assert subtract(5, 3) == 2
|
||||
|
||||
# MISSING: test_subtract_negative, test_subtract_resulting_negative
|
||||
|
||||
|
||||
class TestMultiply:
|
||||
"""Tests for multiply operation."""
|
||||
|
||||
def test_multiply_positive(self):
|
||||
assert multiply(3, 4) == 12
|
||||
|
||||
# MISSING: test_multiply_by_zero, test_multiply_negative
|
||||
|
||||
|
||||
# MISSING: TestDivide class entirely!
|
||||
# - test_divide_positive
|
||||
# - test_divide_by_zero (should test error handling)
|
||||
# - test_divide_negative
|
||||
|
||||
# MISSING: TestPower class entirely!
|
||||
Reference in New Issue
Block a user