Files
issue-core/CLAUDE.md
tegwick 35daa514e5 refactor: align with ReusableCapabilitiesArchitecture v0.1
Refactor issue-facade to conform to the new ReusableCapabilitiesArchitecture
specification, improving discoverability and establishing consistent patterns
for capability integration.

Architecture Changes:
- Rename .feedback/ → feedback/ (visible user interface)
- Rename CAPABILITY.yaml → CAPABILITY-issue-tracking.yaml (explicit family)
- Keep .capability/ hidden (evolving implementation infrastructure)

File Updates:
- Updated all documentation references (.feedback → feedback)
- Updated .capability/feedback script paths
- Updated Makefile, README.md, CLAUDE.md, examples
- Fixed CAPABILITY.yaml → CAPABILITY-issue-tracking.yaml references

New Tools:
- Created .capability/detach script for clean capability removal
- Supports git submodule and directory-based integrations
- Generates detachment manifest for re-integration guidance

Rationale:
- feedback/ is visible: encourages user participation, shows capability identity
- .capability/ is hidden: implementation details that will evolve
- CAPABILITY-<family>.yaml: explicit family declaration, supports multiple capabilities per repo
- Underscore prefix pattern: flatter hierarchy, clear signal of integration

This aligns with the principle that capabilities are conceptual units
designed for natural language integration by devhumans and devagents,
not just technical libraries.

See ReusableCapabilitiesArchitecture.md for complete specification.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 22:22:47 +01:00

401 lines
16 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Issue Facade is a universal CLI for issue tracking that provides a unified interface to multiple issue tracking backends (GitHub, GitLab, Gitea, local SQLite). It implements the **Facade Pattern** to abstract away differences between various issue tracking systems, providing developers with a consistent CLI experience regardless of the underlying backend.
## Development Commands
### Installation & Setup
- Install for development: `pip install -e ".[dev]"`
- Install production: `pip install -e .`
- Clean build artifacts: `make issue-facade-clean`
### Testing
- Run all tests: `pytest tests/`
- Run specific test file: `pytest tests/test_gitea_backend.py`
- Run with coverage: `pytest tests/ --cov=issue_tracker --cov-report=html --cov-report=term`
- Run integration tests: `pytest tests/test_gitea_integration.py -v`
### Code Quality
- Run linter: `make issue-facade-lint`
- Format code: `black issue_tracker/ tests/` (line length: 100)
- Sort imports: `isort issue_tracker/ tests/`
### CLI Usage
The project provides two entry points: `issue` and `issue-tracker` (both execute `issue_tracker.cli.main:main`)
Common commands:
- `issue list` - List issues
- `issue show <number>` - Show issue details
- `issue create "Title"` - Create new issue
- `issue close <number>` - Close issue
- `issue backend list` - List configured backends
- `issue sync` - Synchronize with remote backend
## Architecture
### Core Design Pattern: Facade with Plugin Architecture
The codebase implements a **plugin-based facade pattern** with clear separation of concerns:
```
┌─────────────────────────────────────────┐
│ CLI Layer (Click) │
│ issue_tracker/cli/*.py │
└───────────────┬─────────────────────────┘
┌───────────────▼─────────────────────────┐
│ Core Domain Models │
│ issue_tracker/core/models.py │
│ (Issue, Label, User, etc.) │
└───────────────┬─────────────────────────┘
┌───────────────▼─────────────────────────┐
│ Backend Interface (ABC) │
│ issue_tracker/core/interfaces.py │
│ IssueBackend, LocalBackend, │
│ RemoteBackend, SyncableBackend │
└───────────────┬─────────────────────────┘
┌───────┴────────┐
│ │
┌───────▼──────┐ ┌──────▼───────┐
│Local Backend │ │Gitea Backend │
│ (SQLite) │ │ (REST API) │
└──────────────┘ └──────────────┘
```
### Key Components
#### 1. Core Domain Models (`issue_tracker/core/models.py`)
- **Issue**: Universal issue model with state management, label categorization, and domain logic
- **Label**: Supports categorization (priority/type/status/other) with cached properties
- **User, Milestone, Comment**: Supporting models
- **IssueState, Priority, IssueType**: Enumerations with backend mapping
The Issue model uses `@cached_property` for performance optimization and includes domain logic methods (`close()`, `reopen()`, `add_label()`, etc.) that enforce business rules.
#### 2. Backend Interface (`issue_tracker/core/interfaces.py`)
- **IssueBackend (ABC)**: Defines the contract all backends must implement
- **LocalBackend, RemoteBackend**: Marker interfaces for backend categorization
- **SyncableBackend**: Interface for backends supporting synchronization
- **BackendCapabilities**: Describes feature support per backend
- **BackendFactory**: Registry pattern for backend creation
**Critical**: All backends MUST implement the full `IssueBackend` interface. The interface includes:
- Connection management: `connect()`, `disconnect()`, `test_connection()`
- CRUD operations: `create_issue()`, `get_issue()`, `update_issue()`, `delete_issue()`
- Query operations: `list_issues()`, `search_issues()`
- Label, User, Milestone, Comment operations
- Optional: `bulk_update_issues()` (if capabilities support it)
#### 3. Backend Implementations
**Local Backend** (`issue_tracker/backends/local/backend.py`):
- Uses SQLite with schema defined in `schema.sql`
- Full offline functionality
- Serves as synchronization source of truth
- Implements `LocalBackend` and `SyncableBackend`
**Gitea Backend** (`issue_tracker/backends/gitea/backend.py`):
- REST API integration with Gitea instances
- Rate limiting and error handling
- ID mapping between local and remote issues
- Implements `RemoteBackend` and `SyncableBackend`
#### 4. CLI Layer (`issue_tracker/cli/`)
- **main.py**: Entry point, Click group setup, command registration
- **commands.py**: Core issue operations (list, show, create, close)
- **backend_commands.py**: Backend management (add, list, switch)
- **sync_commands.py**: Synchronization operations
- **utils.py**: Helper functions for formatting and backend access
### ID Mapping Strategy
The system uses a **dual-ID approach** for cross-backend synchronization:
- `id`: Universal ID (UUID for local, external ID for remote)
- `number`: Human-readable sequential number (user-facing)
- `backend_id`: Backend-specific identifier for sync
When syncing, backends maintain mappings between local numbers and remote IDs. The Gitea backend stores this in `sync_metadata` on the Issue model.
### State Management
`IssueState` enum provides universal states with backend-specific mapping via `to_backend_string()`:
- OPEN, CLOSED, IN_PROGRESS, BLOCKED
- Some backends (like Gitea) only support OPEN/CLOSED, so IN_PROGRESS and BLOCKED map to OPEN
## Testing Strategy
### Test Organization
- `test_gitea_backend.py`: Unit tests for Gitea backend with mocked API
- `test_gitea_integration.py`: Full integration tests with real Gitea instance
- `test_cli_commands.py`: CLI command testing
### Integration Tests
The integration tests (`test_gitea_integration.py`) expect a Gitea instance at `http://localhost:3000` with test credentials. They create a temporary test repository, run full CRUD operations, and clean up afterwards.
**Important**: Integration tests use pytest markers:
- `@pytest.mark.integration` - Integration tests (slower)
- `@pytest.mark.unit` - Unit tests (fast)
Run only unit tests: `pytest -m unit`
Run only integration tests: `pytest -m integration`
## Common Development Tasks
### Adding a New Backend
1. Create backend package in `issue_tracker/backends/<name>/`
2. Implement `IssueBackend` interface (or extend `LocalBackend`/`RemoteBackend`)
3. Implement all abstract methods from the interface
4. Define `BackendCapabilities` to specify supported features
5. Register backend in `BackendFactory` (typically in `__init__.py`)
6. Add configuration handling in CLI backend commands
7. Write unit tests with mocked external dependencies
8. Write integration tests if applicable
### Modifying the Issue Model
When changing `issue_tracker/core/models.py`:
1. Update the `Issue` dataclass definition
2. Update `to_dict()` serialization method
3. Invalidate caches if adding/modifying label-dependent properties
4. Update all backend implementations to handle new fields
5. Update database schema in `backends/local/schema.sql`
6. Write migration logic if modifying existing fields
### Adding CLI Commands
1. Add command function in appropriate file (`commands.py`, `backend_commands.py`, etc.)
2. Use `@click.command()` decorator with appropriate options
3. Call `get_backend(ctx)` to retrieve the active backend
4. Use `format_issue()` or `format_issue_list()` from `utils.py` for consistent output
5. Handle errors with `raise click.ClickException(message)`
6. Register command in `main.py` if creating new command group
## Configuration
### Project Configuration (`pyproject.toml`)
- Entry points: `issue` and `issue-tracker` commands
- Dependencies: click, requests, python-dateutil
- Optional dependencies: dev, docs, gitea, github, jira
- Code style: Black (line-length=100), isort (profile="black")
- Test markers: unit, integration, slow
### Makefile Integration
The capability integrates with the parent markitect project via `Makefile`:
- Prefixed targets: `issue-facade-*` for development commands
- Unprefixed targets: `issue-*` for user-facing CLI operations
- Uses `pip install -e` for editable installation
## Important Patterns and Conventions
### Error Handling
- Backend-specific errors inherit from base exceptions (e.g., `GiteaAPIError`)
- CLI commands convert exceptions to `click.ClickException` with user-friendly messages
- Use specific exception types for rate limiting, authentication, network issues
### Type Hints
- Mypy strict mode enabled (`disallow_untyped_defs = true`)
- All functions must have type annotations
- Use `Optional[T]` for nullable types
- Use `List[T]`, `Dict[K, V]` from `typing` module (Python 3.8 compatibility)
### Performance Optimizations
- Use `@cached_property` for expensive computations (e.g., label categorization)
- Call `invalidate_cache()` when modifying cached data
- Single-pass algorithms for label categorization in Issue model
### Synchronization
When implementing sync:
1. Local backend is source of truth
2. Remote backends track last sync timestamp
3. Use `get_issues_modified_since()` for incremental sync
4. Handle conflicts via `SyncableBackend.resolve_sync_conflict()`
5. Store sync metadata in Issue.sync_metadata dict
## Dependencies and External Systems
### Runtime Dependencies
- **click**: CLI framework (>=8.0.0)
- **requests**: HTTP client for remote backends (>=2.25.0)
- **python-dateutil**: Date/time parsing (>=2.8.0)
### Development Dependencies
- **pytest**: Testing framework with markers support
- **pytest-cov**: Coverage reporting
- **pytest-mock**: Mocking utilities
- **black, isort, flake8, mypy**: Code quality tools
### External Systems
- **Gitea API**: REST API at `/api/v1/` endpoints
- **SQLite**: Local database (no server required)
- Future: GitHub API, GitLab API, JIRA API
## Repository Context
This is a capability within the larger markitect project (`/capabilities/issue-facade/`). The capability:
- Can be installed independently via `pip install -e .`
- Integrates with parent project via Makefile targets
- Follows markitect capability conventions for structure and naming
## Feedback and Continuous Improvement
This capability implements the **feedback pattern** - a lightweight, unstructured feedback loop for continuous improvement based on real-world usage from master projects integrating this capability.
### Overview
The feedback system consists of:
- **`feedback/` directory**: Stores all feedback with minimal organization
- **`.capability/feedback` CLI tool**: Standalone tool for submitting and managing feedback
- **No structure imposement**: Accept any text/markdown format
- **Capability-owned**: Maintainers organize and prioritize feedback
### Directory Structure
```
.feedback/
├── inbound/ # New feedback from users (unreviewed)
├── reviewed/ # Feedback reviewed by maintainers
├── archived/ # Resolved or outdated feedback
└── README.md # Complete documentation
```
### For Users: Submitting Feedback
Users of issue-facade (master projects integrating it) can submit feedback in multiple ways:
**Option 1: Using feedback CLI**
```bash
# Quick text feedback
./.capability/feedback submit "The sync command is slow with 1000+ issues"
# From a file
./.capability/feedback submit detailed-feedback.md
# With metadata
./.capability/feedback submit "Bug report" --category=bug --contact=me@email.com
```
**Option 2: Direct file drop (no CLI needed)**
```bash
# Just create a markdown file in inbound/
cat > feedback/inbound/$(date +%Y%m%d)-sync-issue.md << 'EOF'
The sync is taking 10+ minutes with our 5000-issue repo.
Would love to see progress indicators or batch processing.
EOF
```
**Option 3: From master project**
```bash
cd my-master-project
echo "Feedback about issue-facade..." > feedback.md
cp feedback.md capabilities/issue-facade/feedback/inbound/$(date +%Y%m%d)-feedback.md
```
### For Maintainers: Processing Feedback
**List and review feedback:**
```bash
# List pending feedback
./.capability/feedback list
# Show specific feedback
./.capability/feedback show 20251217-103045-abc12345.md
# Show statistics
./.capability/feedback stats
```
**Process feedback:**
```bash
# Mark as reviewed
./.capability/feedback review 20251217-103045-abc12345.md
# Create issue from feedback
./.capability/feedback review 20251217-103045-abc12345.md --create-issue
# Archive when resolved
./.capability/feedback archive 20251217-103045-abc12345.md
```
**Manual workflow (without CLI):**
```bash
# 1. List new feedback
ls -lt feedback/inbound/
# 2. Read feedback
cat feedback/inbound/20251217-103045-sync-issue.md
# 3. Take action (create issue, fix, document)
issue create "Feature: Show sync progress" \
--description "$(cat feedback/inbound/20251217-103045-sync-issue.md)" \
--label=feedback --label=feature
# 4. Move to reviewed
mv feedback/inbound/20251217-103045-sync-issue.md feedback/reviewed/
```
### Integration with Development Workflow
Feedback informs:
- **Roadmap prioritization**: Most requested features get priority
- **Bug triage**: Real-world issues from production usage
- **Documentation improvements**: Where users struggle
- **UX enhancements**: Friction points in actual usage
**Review rhythm:**
- Daily: Quick scan of new feedback
- Weekly: Deep review, create issues, respond to users
- Monthly: Archive old feedback, analyze trends
### Feedback Pattern (Reusable Across Capabilities)
The feedback system is **capability-agnostic** and can be copied to any markitect capability:
1. **Copy the pattern:**
```bash
mkdir -p feedback/inbound feedback/reviewed feedback/archived
cp /path/to/feedback-template/README.md .feedback/
cp /path/to/feedback-template/feedback .capability/
chmod +x .capability/feedback
```
2. **Document in CAPABILITY-issue-tracking.yaml:**
```yaml
feedback:
enabled: true
method: feedback-capability
submission:
cli: ".capability/feedback submit 'Your feedback'"
directory: "feedback/inbound/"
```
3. **Add to Makefile (optional):**
```makefile
feedback:
@./.capability/feedback submit "$(MSG)"
```
**Future Evolution:**
- When capability becomes a service, add API endpoint: `POST /api/feedback`
- API writes to same `feedback/inbound/` directory
- Maintains consistency across CLI, file drop, and API submission
### Why This Pattern?
- **Decentralized**: Each capability owns its feedback
- **Flexible**: No forms, no required structure
- **Durable**: Plain files survive system changes
- **Auditable**: Git tracks all feedback
- **Actionable**: Feedback lives where maintainers work
- **Scalable**: Works for 1 user or 1000 users
- **Future-proof**: Can evolve to CLI/API while maintaining structure
See `feedback/README.md` for complete documentation.