Extract the PR detail screen's logic into an @Observable PullRequestDetailViewModel, following the MVVM direction in CONTRIBUTING. The view dropped from ~576 lines to a thin renderer: it now owns layout and bindings while the view model owns loading, state, and actions.
What moved:
PullRequestDetailViewModel holds the load/refresh/action logic and state, talking to the API through narrow PullRequestDetailServiceProtocols so it is testable in isolation.
PullRequestDetailView+Sections.swift splits the section-building helpers out of the main view body.
PullRequestDetailViewModelTests cover the view model against the new service protocols.
Behavior-preserving refactor, no UI or API changes. Build and the ForjiTests unit suite pass (220 passing, 0 failing).
Extract the PR detail screen's logic into an `@Observable` `PullRequestDetailViewModel`, following the MVVM direction in CONTRIBUTING. The view dropped from ~576 lines to a thin renderer: it now owns layout and bindings while the view model owns loading, state, and actions.
What moved:
- `PullRequestDetailViewModel` holds the load/refresh/action logic and state, talking to the API through narrow `PullRequestDetailServiceProtocols` so it is testable in isolation.
- `PullRequestDetailView+Sections.swift` splits the section-building helpers out of the main view body.
- `PullRequestDetailViewModelTests` cover the view model against the new service protocols.
Behavior-preserving refactor, no UI or API changes. Build and the `ForjiTests` unit suite pass (220 passing, 0 failing).