<!-- task=m-product-baseline/02+01_responsive_ui plan=0 tag=RESPONSIVE_UI -->

# Plan - RESPONSIVE_UI

## 이 파일을 읽는 구현 에이전트에게

`CODE_REVIEW-local-G05.md`의 구현 에이전트 소유 섹션을 채우는 것이 구현의 필수 마지막 단계다. 구현 후 검증을 실행하고 실제 변경 내용, 검증 출력, 계획 대비 변경 사항을 기록한 뒤 active 파일을 그대로 둔 채 리뷰 준비를 보고한다. 사용자만 결정할 수 있는 차단, 사용자 소유 외부 환경, 범위 충돌이 생기면 리뷰 stub의 `사용자 리뷰 요청` 섹션에 근거를 남기고 멈춘다. 구현 중 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 닫을 수 있는 증거 공백은 사용자 리뷰 요청이 아니다.

## 배경

현재 placeholder 화면들은 desktop 기본 폭에서는 읽기 쉽지만 toolbar와 row가 고정 `Row` 중심이라 좁은 테스트 viewport에서 overflow 가능성이 있다. 첫 Epic의 responsive task는 실제 Jenkins/ADB 연결 전에 텍스트, 버튼, badge, toolbar가 layout을 흔들지 않는 기준선을 만드는 일이다.

## 사용자 리뷰 요청 흐름

구현 중 차단은 active `CODE_REVIEW-local-G05.md`의 `사용자 리뷰 요청` 섹션에 기록한다. 직접 사용자 prompt는 금지이며, code-review가 요청의 정당성을 판단하고 필요한 경우에만 `USER_REVIEW.md`를 작성한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/usable-mvp/milestones/product-baseline.md`
- Task ids:
  - `responsive-ui`: 기본 테스트 viewport에서 텍스트/버튼 overflow가 없도록 card, badge, toolbar 크기를 안정화한다.
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-roadmap/current.md`
- `agent-roadmap/phase/usable-mvp/PHASE.md`
- `agent-roadmap/phase/usable-mvp/milestones/product-baseline.md`
- `agent-ops/rules/project/domain/app-shell/rules.md`
- `agent-test/local/rules.md`
- `agent-test/local/app-shell-smoke.md`
- `analysis_options.yaml`
- `pubspec.yaml`
- `lib/main.dart`
- `lib/src/app.dart`
- `lib/src/features/app_shell.dart`
- `lib/src/features/builds/builds_page.dart`
- `lib/src/features/devices/devices_page.dart`
- `lib/src/features/console/console_page.dart`
- `lib/src/features/settings/settings_page.dart`
- `lib/src/theme/app_theme.dart`
- `test/widget_test.dart`

### 테스트 환경 규칙

- `test_env=local`.
- `agent-test/local/rules.md`를 읽었다.
- 매칭 profile은 `agent-test/local/app-shell-smoke.md`.
- 필수 검증은 remote Mac runner checkout에서 `flutter analyze`와 `flutter test`.
- 현재 checkout preflight로도 같은 명령을 사용할 수 있지만, 최종 완료 evidence는 remote runner 기준이다.
- `<확인 필요>` 값은 없다.

### 테스트 커버리지 공백

- overflow regression: 기존 `test/widget_test.dart`에는 작은 viewport를 설정하고 shell/toolbar/page를 렌더링하는 테스트가 없다.
- Builds toolbar: `lib/src/features/builds/builds_page.dart:17`-`54`가 고정 `Row`라 좁은 폭에서 입력 2개와 로그인 버튼이 겹칠 수 있다.
- Console toolbar: `lib/src/features/console/console_page.dart:16`-`48`가 fixed `Row`라 필터 입력, segmented control, icon button 조합이 좁은 폭에서 overflow할 수 있다.
- Settings form: `lib/src/features/settings/settings_page.dart:24`-`51`, `74`-`89`가 fixed `Row`라 좁은 폭에서 입력과 버튼이 overflow할 수 있다.

### 심볼 참조

- none. 이름 변경이나 제거 계획은 없다.

### 분할 판단

- split decision policy를 먼저 평가했다.
- 공유 task group은 `agent-task/m-product-baseline/`.
- `01_shell_nav_status`: 선행 shell 구조와 navigation/status 테스트를 고정한다.
- `02+01_responsive_ui`: 이 plan이며, directory 이름 기준으로 predecessor `01_shell_nav_status`의 `complete.log`가 필요하다.
- 현재 확인 시 predecessor `agent-task/m-product-baseline/01_shell_nav_status/complete.log`는 아직 없다. 구현 시작 전 runtime 또는 구현 에이전트는 해당 predecessor completion을 확인해야 한다.

### 범위 결정 근거

- 실제 Jenkins job/token/artifact 동작 구현은 `jenkins-credential`, `artifact-browser` Milestone 소관이므로 제외한다.
- 실제 ADB process/device install/logcat 구현은 `usb-install`, `logcat-console` Milestone 소관이므로 제외한다.
- visual redesign이나 feature completion이 아니라 overflow 없는 placeholder shell 기준선만 다룬다.

### 빌드 등급

- `local-G05`: 여러 placeholder 화면과 widget test를 건드리지만 app-shell UI 안정화로 범위가 제한되고 검증이 `flutter analyze/test`로 결정적이다.

## 구현 체크리스트

- [ ] `agent-task/m-product-baseline/01_shell_nav_status/complete.log`가 존재하는지 확인하고 없으면 이 plan 구현을 시작하지 않는다.
- [ ] top bar, toolbar, card, badge, button layout이 기본 테스트 viewport에서 overflow를 내지 않도록 `AppSokShell`과 placeholder page layout을 안정화한다. 검증: `flutter test`가 overflow exception 없이 통과한다.
- [ ] `test/widget_test.dart`에 작은 viewport smoke test를 추가하고 build/device/console/settings 화면을 순회해 overflow exception이 없음을 검증한다.
- [ ] `dart format lib/src/features/app_shell.dart lib/src/features/builds/builds_page.dart lib/src/features/devices/devices_page.dart lib/src/features/console/console_page.dart lib/src/features/settings/settings_page.dart test/widget_test.dart`를 실행한다.
- [ ] `flutter analyze`와 `flutter test`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [RESPONSIVE_UI-1] Overflow-safe shell and placeholder screens

#### 문제

- `lib/src/features/app_shell.dart:151`-`162`의 top bar는 fixed `Row`와 status pill 2개를 사용해 좁은 폭에서 title/status가 밀릴 수 있다.
- `lib/src/features/builds/builds_page.dart:17`-`54`의 toolbar는 `TextField` 2개와 `FilledButton`을 fixed `Row`에 둔다.
- `lib/src/features/console/console_page.dart:16`-`48`의 toolbar는 필터 입력, segmented control, icon button 2개를 fixed `Row`에 둔다.
- `lib/src/features/settings/settings_page.dart:24`-`51`, `74`-`89`의 form row는 입력과 버튼이 좁은 폭에서 줄바꿈되지 않는다.
- `test/widget_test.dart:19`-`35`는 overflow를 잡는 viewport test가 없다.

#### 해결 방법

LayoutBuilder, Wrap, ConstrainedBox, Flexible을 사용해 toolbar와 form row가 좁은 폭에서 자연스럽게 줄바꿈되도록 한다. 버튼은 icon+label이 필요한 곳만 유지하고, compact 영역에서는 icon button 또는 fixed min width로 layout shift를 줄인다.

Before:

```dart
// lib/src/features/builds/builds_page.dart:17
Row(
  children: [
    Expanded(
      flex: 3,
      child: TextField(
        decoration: InputDecoration(
          labelText: 'Jenkins job URL',
```

#### 수정 파일 및 체크리스트

- [ ] `lib/src/features/app_shell.dart`: top bar title/status pill 영역을 overflow-safe하게 만든다.
- [ ] `lib/src/features/builds/builds_page.dart`: toolbar와 build row action 버튼이 좁은 폭에서 overflow 없이 배치되도록 조정한다.
- [ ] `lib/src/features/devices/devices_page.dart`: filter/action row와 tile chip/button row가 안정적인 크기를 유지하는지 확인하고 필요 시 보강한다.
- [ ] `lib/src/features/console/console_page.dart`: filter/level/action toolbar가 줄바꿈 또는 compact 배치되도록 조정한다.
- [ ] `lib/src/features/settings/settings_page.dart`: form row를 좁은 폭에서 세로 배치 또는 wrap으로 전환한다.
- [ ] `test/widget_test.dart`: 작은 viewport smoke test를 추가한다.

#### 테스트 작성

- 작성한다.
- 경로: `test/widget_test.dart`
- 테스트명 후보: `renders shell pages without overflow at compact viewport`
- assertion 목표: `tester.view.physicalSize`와 `devicePixelRatio`를 설정한 뒤 빌드, 디바이스, 콘솔, 설정 화면을 순회하고 `tester.takeException()`이 null임을 확인한다.

#### 중간 검증

```bash
flutter test
```

기대 결과: compact viewport smoke를 포함한 모든 widget test가 통과한다.

## 의존 관계 및 구현 순서

- 이 plan은 directory 이름 `02+01_responsive_ui` 기준으로 `01_shell_nav_status`에 의존한다.
- 구현 시작 전 `agent-task/m-product-baseline/01_shell_nav_status/complete.log` 또는 archive의 같은 predecessor complete log를 확인한다.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `lib/src/features/app_shell.dart` | RESPONSIVE_UI-1 |
| `lib/src/features/builds/builds_page.dart` | RESPONSIVE_UI-1 |
| `lib/src/features/devices/devices_page.dart` | RESPONSIVE_UI-1 |
| `lib/src/features/console/console_page.dart` | RESPONSIVE_UI-1 |
| `lib/src/features/settings/settings_page.dart` | RESPONSIVE_UI-1 |
| `test/widget_test.dart` | RESPONSIVE_UI-1 |

## 최종 검증

```bash
dart format lib/src/features/app_shell.dart lib/src/features/builds/builds_page.dart lib/src/features/devices/devices_page.dart lib/src/features/console/console_page.dart lib/src/features/settings/settings_page.dart test/widget_test.dart
flutter analyze
flutter test
```

Remote Mac runner 최종 evidence:

```bash
zsh -lc 'cd "$HOME/docker/services/code-server/data/volume/workspace/appsok" && flutter analyze'
zsh -lc 'cd "$HOME/docker/services/code-server/data/volume/workspace/appsok" && flutter test'
```

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
