# Architecture Improvement Tasks

Tasks derived from architecture audit, ranked by priority.

---

## Priority 1: Immediate (Quick Wins)

### Task 1.1: Fix version mismatch ✅
**File:** `agr/__init__.py:3`

Update `__version__` from `"0.2.0"` to `"0.5.2"` to match `pyproject.toml`.

**Acceptance criteria:**
- [ ] Version in `__init__.py` matches `pyproject.toml`
- [ ] Add test to verify versions stay in sync

---

### Task 1.2: Delete deprecated modules ✅
**Files:** `agr/discovery.py`, `agr/local_sync.py`

Remove deprecated modules that are explicitly marked as unused. Both files contain deprecation notices stating they are no longer called by `agr sync`.

**Acceptance criteria:**
- [ ] Delete `agr/discovery.py`
- [ ] Delete `agr/local_sync.py`
- [ ] Verify no imports reference these modules
- [ ] All tests pass

---

### Task 1.3: Remove swallowed exceptions ✅
**Files:** `agr/cli/common.py:425`, `agr/cli/common.py:939`

Replace bare `except Exception: pass` blocks with proper error handling. These silently swallow errors when updating `agr.toml`.

**Acceptance criteria:**
- [ ] Add logging for caught exceptions
- [ ] Or propagate errors appropriately
- [ ] Document why errors are non-fatal (if intentional)

---

## Priority 2: Short-term

### Task 2.1: Split `common.py` into focused modules ✅
**File:** `agr/cli/common.py` (1221 lines)

Break the monolithic `common.py` into smaller, cohesive modules:

| New Module | Lines to Extract | Responsibility |
|------------|------------------|----------------|
| `cli/paths.py` | 54-196 | Path utilities, base path computation |
| `cli/discovery.py` | 677-906 | Local resource discovery functions |
| `cli/handlers.py` | 283-671 | Generic add/remove/bundle handlers |

Keep `common.py` with only:
- `console` instance
- `TYPE_TO_SUBDIR` constant
- Small shared utilities

**Acceptance criteria:**
- [ ] Create `agr/cli/paths.py` with path utilities
- [ ] Create `agr/cli/discovery.py` with discovery functions
- [ ] Create `agr/cli/handlers.py` with resource handlers
- [ ] `common.py` reduced to <200 lines
- [ ] All imports updated across CLI modules
- [ ] All tests pass

---

### Task 2.2: Consolidate duplicate code ✅
**Files:** Multiple

Eliminate code duplication across the codebase:

| Duplicate | Locations | Action |
|-----------|-----------|--------|
| `TYPE_TO_SUBDIR` | `common.py:46`, `local_sync.py:21` | Single source in `config.py` |
| `_remove_path` | `sync.py:125`, `local_sync.py:94` | Single function in paths module |
| Path building logic | `common.py`, `sync.py`, `add.py` | Extend `ParsedHandle` in `handle.py` |

**Acceptance criteria:**
- [ ] `TYPE_TO_SUBDIR` defined in one place only
- [ ] `_remove_path` defined in one place only
- [ ] Path building uses `handle.py` methods
- [ ] No duplicate function implementations remain

---

### Task 2.3: Add comprehensive tests for `handle.py`
**File:** `tests/test_handle.py`

The new centralized handle module lacks comprehensive test coverage.

**Test cases needed:**
- [ ] `parse_handle()` with all input formats (simple, slash, colon, nested)
- [ ] `ParsedHandle.to_toml_handle()` round-trip conversions
- [ ] `ParsedHandle.to_skill_dirname()` conversions
- [ ] `ParsedHandle.matches_toml_handle()` matching logic
- [ ] `skill_dirname_to_toml_handle()` edge cases
- [ ] `toml_handle_to_skill_dirname()` edge cases

**Acceptance criteria:**
- [ ] >90% coverage on `handle.py`
- [ ] All conversion methods tested bidirectionally
- [ ] Edge cases documented and tested

---

### Task 2.4: Mock subprocess calls in `github.py` tests
**Files:** `agr/github.py`, `tests/test_github_username.py`

Add fixtures to mock subprocess calls for environment-independent testing.

**Acceptance criteria:**
- [ ] Create pytest fixtures for mocking `subprocess.run`
- [ ] Test `get_username_from_git_remote()` with mock
- [ ] Test `check_gh_cli()` with mock
- [ ] Test `get_github_username()` with mock
- [ ] Tests run without requiring git or gh CLI

---

## Priority 3: Long-term (Strategic)

### Task 3.1: Refactor `fetcher.py` into smaller modules ✅
**File:** `agr/fetcher.py` (707 lines)

Split into focused modules under `agr/fetcher/`:

```
agr/fetcher/
├── __init__.py      # Re-exports for backward compatibility
├── types.py         # ResourceType, ResourceConfig, RESOURCE_CONFIGS
├── download.py      # HTTP/tarball operations, downloaded_repo context
├── resource.py      # fetch_resource, fetch_resource_from_repo_dir
└── bundle.py        # Bundle-related classes and functions
```

**Acceptance criteria:**
- [ ] Create `agr/fetcher/` package structure
- [ ] Move types/enums to `types.py`
- [ ] Move download logic to `download.py`
- [ ] Move resource operations to `resource.py`
- [ ] Move bundle operations to `bundle.py`
- [ ] Backward-compatible imports via `__init__.py`
- [ ] All tests pass without modification

---

### Task 3.2: Introduce repository abstraction for testability
**New files:** `agr/interfaces.py` or `agr/protocols.py`

Create interface abstractions to enable testing without network access:

```python
from typing import Protocol

class ResourceRepository(Protocol):
    def fetch_resource(self, username: str, repo: str, name: str, ...) -> Path: ...
    def discover_resource(self, repo_dir: Path, name: str) -> DiscoveryResult: ...

class ConfigStore(Protocol):
    def load(self, path: Path) -> AgrConfig: ...
    def save(self, config: AgrConfig, path: Path) -> None: ...
```

**Acceptance criteria:**
- [ ] Define `ResourceRepository` protocol
- [ ] Define `ConfigStore` protocol
- [ ] Create mock implementations for testing
- [ ] Refactor CLI to use protocols via dependency injection
- [ ] Add tests using mock repositories

---

### Task 3.3: Create integration test suite with HTTP mocking
**New file:** `tests/test_fetcher_integration.py`

Add integration tests for `fetcher.py` network code using `respx` or similar HTTP mocking library.

**Test scenarios:**
- [ ] Successful tarball download and extraction
- [ ] 404 response handling (RepoNotFoundError)
- [ ] Network timeout handling
- [ ] Invalid tarball handling
- [ ] Resource discovery in extracted repo

**Acceptance criteria:**
- [ ] No real HTTP requests in tests
- [ ] All error paths tested
- [ ] Tests document expected GitHub API behavior

---

## Notes

- Tasks within each priority level can be done in parallel
- Priority 1 tasks are low-risk, high-value fixes
- Priority 2 tasks require more careful refactoring
- Priority 3 tasks are architectural improvements that may span multiple PRs
