# Task ID: 8

**Title:** Implement OutputFormatter

**Status:** pending

**Dependencies:** 1

**Priority:** medium

**Description:** Create the OutputFormatter for rich table display, JSON output, progress bars, and formatted error messages.

**Details:**

Create `src/teams_phone/infrastructure/output_formatter.py`:
```python
from rich.console import Console
from rich.table import Table
from rich.progress import Progress

class OutputFormatter:
    def __init__(self, console: Console | None = None, json_mode: bool = False, no_color: bool = False): ...
    
    def table(self, data: list[dict], columns: list[str], title: str | None = None) -> None: ...
    def json(self, data: Any) -> None: ...
    def success(self, message: str) -> None: ...
    def error(self, message: str, remediation: str | None = None) -> None: ...
    def warning(self, message: str) -> None: ...
    def info(self, message: str) -> None: ...
    def progress(self, total: int, description: str) -> Progress: ...
```

JSON mode outputs ONLY valid JSON to stdout.
Color respects --no-color flag and NO_COLOR env var.
Error messages include remediation guidance.

**Test Strategy:**

Unit tests capturing stdout: verify table formatting, valid JSON output, color codes presence/absence, progress bar updates.

---

## Implementation Notes

### Session: 2026-01-28 12:15 - Agent: claude-sonnet-4-5-20250929

**Status:** Implemented

#### What Was Done
- Created `src/teams_phone/infrastructure/output_formatter.py` with full `OutputFormatter` class
- Implemented all required methods: `__init__`, `table`, `json`, `success`, `error`, `warning`, `info`, `progress`
- Exported `OutputFormatter` from `src/teams_phone/infrastructure/__init__.py`
- Created comprehensive unit tests in `tests/unit/test_output_formatter.py` (32 tests)

#### Key Decisions Made
- **JSON output via plain print()**: Used `json.dumps()` with `print()` to stdout rather than Rich's `print_json()` to ensure no ANSI codes in JSON mode output
- **Progress context manager pattern**: Returns Rich's Progress context manager directly for simplicity, with a disabled Progress instance in JSON mode
- **NO_COLOR handling**: Checks both the `no_color` constructor flag AND `os.environ.get("NO_COLOR") is not None` per the spec
- **Error remediation format**: Uses "To fix:" prefix matching the exception hierarchy format from `exceptions.py:42-43`

#### Patterns Discovered
- Rich interprets `...` as an ellipsis and applies styling - test strings should avoid trailing ellipses
- Console output capture for testing: Use `Console(file=StringIO(), force_terminal=True)` pattern
- For pure JSON output, bypass Rich entirely to avoid any ANSI code contamination

#### Files Created/Modified
| Action | File | Purpose |
|--------|------|---------|
| Created | `src/teams_phone/infrastructure/output_formatter.py` | Main implementation |
| Modified | `src/teams_phone/infrastructure/__init__.py` | Export OutputFormatter |
| Created | `tests/unit/test_output_formatter.py` | 32 unit tests |

#### Test Coverage Summary
- 7 initialization tests (console, json_mode, no_color, NO_COLOR env var)
- 4 table output tests (rendering, title, missing data, JSON mode)
- 4 JSON output tests (valid JSON, lists, indentation, no ANSI)
- 3 success message tests
- 4 error message tests (with/without remediation)
- 2 warning message tests
- 2 info message tests
- 3 progress bar tests
- 3 color control tests

#### Open Items for Next Agent
- None - task fully implemented

#### Gotchas and Warnings
- Rich interprets certain patterns like `...` and applies auto-styling; test assertions should avoid these
- When testing console output capture, use `force_terminal=True` to get ANSI codes for color testing

---
