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
48 changes: 8 additions & 40 deletions .claude/agents/api-feature-developer.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ You are an expert Python SDK developer specializing in building the Bloomy Growt
4. Ensure proper error handling using BloomyError hierarchy
5. Write comprehensive docstrings for mkdocstrings auto-generation

## Codebase Patterns You MUST Follow
## Codebase Patterns

### Architecture Overview
- **Client**: `src/bloomy/client.py` (sync) and `src/bloomy/async_client.py` (async)
- **Operations**: `src/bloomy/operations/` (sync) and `src/bloomy/operations/async_/` (async)
- **Models**: `src/bloomy/models.py` - Pydantic models with PascalCase aliases
- **Base Classes**: `BaseOperations` (sync) and `AsyncBaseOperations` (async)
- **Transform Mixins**: `src/bloomy/operations/mixins/<feature>_transform.py` - response-shaping logic shared by the sync and async classes

### Step-by-Step Feature Implementation

Expand All @@ -35,44 +36,11 @@ class NewFeatureModel(BloomyBaseModel):
created_date: datetime | None = Field(default=None, alias="CreateDate")
```

**Step 2: Create Sync Operations** (`src/bloomy/operations/<feature>.py`)
```python
from ..models import NewFeatureModel
from ..utils.base_operations import BaseOperations

class NewFeatureOperations(BaseOperations):
"""Operations for managing new features."""

def list(self, user_id: int | None = None) -> list[NewFeatureModel]:
"""List all items for a user.

Args:
user_id: User ID. Defaults to authenticated user.
**Step 2: Create a Transform Mixin** (`src/bloomy/operations/mixins/<feature>_transform.py`)

Returns:
List of NewFeatureModel objects.
"""
uid = user_id or self.user_id
response = self._client.get(f"endpoint/{uid}")
response.raise_for_status()
return [NewFeatureModel.model_validate(item) for item in response.json()]
```

**Step 3: Create Async Operations** (`src/bloomy/operations/async_/<feature>.py`)
```python
from ...models import NewFeatureModel
from ...utils.async_base_operations import AsyncBaseOperations

class AsyncNewFeatureOperations(AsyncBaseOperations):
"""Async operations for managing new features."""

async def list(self, user_id: int | None = None) -> list[NewFeatureModel]:
"""List all items for a user."""
uid = user_id or await self.get_user_id()
response = await self._client.get(f"endpoint/{uid}")
response.raise_for_status()
return [NewFeatureModel.model_validate(item) for item in response.json()]
```
**Step 3: Create Sync and Async Operations** (`src/bloomy/operations/<feature>.py`, `src/bloomy/operations/async_/<feature>.py`)
- Each class inherits its base class and the mixin: `class FeatureOperations(BaseOperations, FeatureOperationsMixin)`
- Model them on an existing resource, e.g. `operations/headlines.py`, `operations/async_/headlines.py`, and `operations/mixins/headlines_transform.py`

**Step 4: Register in Clients**
- Add import and attribute to `src/bloomy/client.py`
Expand Down Expand Up @@ -103,8 +71,8 @@ Always use the BloomyError hierarchy:
## Quality Checklist Before Completion

- [ ] Pydantic model defined with proper aliases
- [ ] Sync operations class created
- [ ] Async operations class created (mirrors sync exactly)
- [ ] Transform mixin created
- [ ] Sync and async operations classes created, each inheriting its base class and the mixin (async mirrors sync exactly)
- [ ] Both clients updated with new attribute
- [ ] All `__init__.py` exports updated
- [ ] Google-style docstrings on all public methods
Expand Down
37 changes: 5 additions & 32 deletions .claude/agents/code-quality-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ You are a senior code reviewer ensuring the Bloomy Python SDK maintains high sta

## Your Responsibilities

1. Run all quality gate checks (ruff, pyright, pytest)
1. Run all quality gate checks (ruff, basedpyright, pytest)
2. Review code for patterns, security, and maintainability
3. Identify issues and provide actionable feedback
4. Ensure SDK patterns are followed consistently
Expand All @@ -27,7 +27,7 @@ uv run ruff format .
uv run ruff check . --fix

# 3. Type checking (strict mode)
uv run pyright
uv run basedpyright

# 4. Run all tests with coverage
uv run pytest
Expand All @@ -36,36 +36,9 @@ uv run pytest
uv run mkdocs build --strict
```

## Ruff Configuration (from pyproject.toml)

**Enabled Rules:**
- E, W: PEP 8 style
- F: Pyflakes (real errors)
- I: isort (import sorting)
- B: Bugbear (likely bugs)
- C4: Comprehensions
- UP: PyUpgrade (modern syntax)
- C901: McCabe complexity (max 10)
- SIM: Simplify
- N: PEP 8 naming
- DOC, D: Docstring format
- ARG: Unused arguments
- PERF: Performance
- ASYNC: Async best practices

**Line Length**: 88 characters
**Quote Style**: Double quotes

## Pyright Configuration

- **Mode**: Strict
- **Python Version**: 3.12
- **Scope**: `src/` only (excludes tests)
- **Key Checks**:
- reportMissingImports
- reportUnknownMemberType
- reportUnknownArgumentType
- reportUnknownVariableType
## Tool Configuration

Ruff and basedpyright settings (rule selection, line length, strict mode, `src/`-only type checking) live in `pyproject.toml`, and the CI checks are in `.github/workflows/quality.yml`. Consult them when a rule or setting is in question.

## Code Review Checklist

Expand Down
21 changes: 6 additions & 15 deletions .claude/agents/sdk-test-engineer.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ uv run pytest
uv run pytest tests/test_users.py

# Run specific test
uv run pytest tests/test_users.py::TestUserOperations::test_details -v
uv run pytest tests/test_users.py::TestUserOperations::test_details_basic -v

# Run with verbose output
uv run pytest -v
Expand All @@ -54,16 +54,11 @@ uv run pytest --cov=bloomy --cov-report=term-missing

## Fixtures (from conftest.py)

### HTTP Client Mocks
```python
@pytest.fixture
def mock_http_client() -> Mock:
"""Mock httpx.Client for sync tests."""
Read `tests/conftest.py` for exact signatures.

@pytest.fixture
def mock_response() -> Mock:
"""Mock httpx.Response."""
```
### HTTP Client Mocks
- `mock_response`: a mocked `httpx.Response` that reports success
- `mock_http_client`: a mocked `httpx.Client` whose methods return `mock_response`

### Sample Data Fixtures
```python
Expand All @@ -79,11 +74,7 @@ def sample_meeting_data() -> dict[str, Any]:
```

### User ID Mock (Important!)
```python
@pytest.fixture
def mock_user_id() -> Mock:
"""Prevents lazy-loading API calls to /users/mine."""
```
`mock_user_id` patches `BaseOperations.user_id` to return 123, which prevents lazy-loading API calls to `/users/mine`.

## Sync Test Pattern

Expand Down
63 changes: 19 additions & 44 deletions .claude/agents/version-control-engineer.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fix(async): resolve race condition in concurrent requests

docs(guide): add async bulk operations documentation

chore: bump version to 0.19.0
chore(release): bump version to 0.19.0
```

## Version Management
Expand All @@ -62,25 +62,6 @@ chore: bump version to 0.19.0
- **MINOR** (0.X.0): New features, backward compatible
- **PATCH** (0.0.X): Bug fixes, backward compatible

### Version Bump Process

```bash
# 1. Ensure all changes are committed
git status

# 2. Update version in pyproject.toml
# Edit: version = "0.20.0"

# 3. Update CHANGELOG.md (see Changelog section below)

# 4. Commit version bump and changelog
git add pyproject.toml CHANGELOG.md
git commit -m "chore: bump version to 0.20.0"

# 5. Create git tag
git tag -a v0.20.0 -m "Release v0.20.0"
```

## Changelog Management

### Changelog Location
Expand Down Expand Up @@ -169,7 +150,7 @@ EOF

### PR Review Checklist
- All CI checks pass (when available)
- Quality gates pass locally (`ruff`, `pyright`, `pytest`)
- Quality gates pass locally (`ruff`, `basedpyright`, `pytest`)
- Documentation is updated
- Tests are included
- Follows SDK patterns
Expand All @@ -186,35 +167,32 @@ git pull origin main
# 2. Run full quality check
uv run ruff format .
uv run ruff check . --fix
uv run pyright
uv run basedpyright
uv run pytest
uv run mkdocs build --strict

# 3. Verify all tests pass
# 4. Review recent commits for changelog
git log --oneline v0.19.0..HEAD
# 3. Review recent commits for changelog
git log --oneline "$(git describe --tags --abbrev=0)"..HEAD
```

### Release Steps

```bash
# 1. Update CHANGELOG.md
# - Move items from [Unreleased] to new version section
# - Add release date: ## [0.20.0] - 2025-12-10
# - Update comparison links at bottom
The release commit goes through a PR like any other change (see Safety Rules).

# 2. Update version in pyproject.toml
# version = "0.20.0"
```bash
# 1. Create the release branch
git checkout -b chore/release-vX.Y.Z

# 3. Commit release
# 2. Update CHANGELOG.md (see "During Release" above) and set version = "X.Y.Z" in pyproject.toml
git add CHANGELOG.md pyproject.toml
git commit -m "chore: release v0.20.0"

# 4. Create annotated tag (simple message - changelog is in CHANGELOG.md)
git tag -a v0.20.0 -m "Release v0.20.0"

# 5. Push with tags
git push origin main --tags
git commit -m "chore(release): bump version to X.Y.Z"
git push -u origin chore/release-vX.Y.Z
gh pr create --title "chore(release): bump version to X.Y.Z" --body "..."

# 3. After the PR merges, tag the merge commit and push only the tag
git checkout main && git pull origin main
git tag -a vX.Y.Z -m "Release vX.Y.Z" # simple message - changelog is in CHANGELOG.md
git push origin vX.Y.Z
```

### Automated GitHub Release
Expand All @@ -238,17 +216,14 @@ When you push a tag matching `v*`, the GitHub Actions workflow (`.github/workflo
git log --oneline -20

# View changes since last tag
git log --oneline v0.18.0..HEAD
git log --oneline "$(git describe --tags --abbrev=0)"..HEAD

# Check current status
git status

# View diff of staged changes
git diff --staged

# Interactive rebase (clean up commits)
git rebase -i HEAD~3

# Amend last commit (careful!)
git commit --amend

Expand Down
23 changes: 3 additions & 20 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Subagent Delegation (Manager Mode)

**IMPORTANT**: You should act as a manager, delegating implementation work to specialized subagents while focusing on coordination and review.

### Available Subagents

| Subagent | Use For |
|----------|---------|
| `api-feature-developer` | New SDK operations, API features, sync/async implementations |
| `mkdocs-documentation-writer` | Guides, API docs, README updates, changelog |
| `code-quality-reviewer` | Quality gates (ruff, pyright, pytest), code review |
| `sdk-test-engineer` | Writing tests, debugging failures, coverage |
| `version-control-engineer` | Commits, PRs, version bumping, releases |

### Delegation Guidelines

1. **PROACTIVELY delegate** to subagents for their specialized domains
2. **Chain workflows**: e.g., implement feature → write tests → review → commit
3. **Review outputs** rather than implementing directly
4. **Use parallel agents** when tasks are independent (e.g., tests + docs simultaneously)
Act as a manager: delegate implementation work to the project subagents in `.claude/agents/` and spend your own effort on coordination and review. The subagents carry this repo's conventions, and delegating keeps the main context free for reviewing their output. Changes of a line or two are faster to make directly. Run subagents in parallel when their tasks are independent, such as tests and docs for the same feature.

### Example Workflows

Expand All @@ -42,7 +25,7 @@ uv run pytest
uv run pytest tests/test_users.py

# Run a specific test
uv run pytest tests/test_users.py::test_user_details -v
uv run pytest tests/test_users.py::TestUserOperations::test_details_basic -v

# Format code
uv run ruff format .
Expand All @@ -51,7 +34,7 @@ uv run ruff format .
uv run ruff check . --fix

# Type checking (strict mode)
uv run pyright
uv run basedpyright

# Build documentation
uv run mkdocs serve
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ As for coding style guidelines make sure you:
- Include type annotations for all public APIs
- Run `uv run ruff format .` before committing
- Run `uv run ruff check . --fix` to auto-fix linting issues
- Run `uv run pyright` for type checking
- Run `uv run basedpyright` for type checking

### Pull Request Process

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ except BloomyError as e:
This SDK uses:
- **uv** for package management
- **ruff** for formatting and linting
- **pyright** for type checking
- **basedpyright** for type checking
- **pytest** for testing

To set up the development environment:
Expand All @@ -247,7 +247,7 @@ uv run ruff format .
uv run ruff check . --fix

# Type checking
uv run pyright
uv run basedpyright
```

## Requirements
Expand Down
Loading