appsok/agent-task/m-usb-install/02+01_adb_diagnostics/PLAN-local-G06.md
toki 9d91b947c6 feat: usb install feature implementation
- Add adb_service.dart with usb install capabilities
- Add adb_service_test.dart for testing
- Update project rules and phase documentation
- Update milestone documents for jenkins-credential and usb-install
- Add agent-task/m-usb-install/ directory with planning documents
2026-06-12 22:05:42 +09:00

11 KiB

Plan - API

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

구현이 끝나면 반드시 CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 검증을 실행하고, active 파일은 그대로 둔 채 리뷰 준비를 보고한다. 최종 판정, log rename, complete.log 작성, task archive 이동은 code-review 전용이다. 사용자만 결정할 수 있는 외부 환경, secret, 범위 충돌로 막히면 리뷰 stub의 사용자 리뷰 요청에 정확한 증거와 재개 조건을 남기고 멈춘다. 구현 중 사용자에게 직접 질문하거나 선택지를 제시하거나 request_user_input을 호출하지 않는다.

배경

ADB runtime resolution과 AppSok 전용 server port는 서비스 레벨에 들어갔다. 사용자가 실제로 어떤 ADB를 쓰는지, bundle fallback이 발생했는지, server port가 무엇인지 볼 수 있는 진단 표시는 아직 없다. 이 작업은 bundle 작업이 PASS된 뒤 실행 경로, version, hash, server port, fallback 여부를 settings/device surface에 노출한다.

사용자 리뷰 요청 흐름

구현 중 차단 사유는 active CODE_REVIEW-*-G??.md사용자 리뷰 요청 섹션에 기록한다. 직접 사용자 프롬프트는 금지이며, code-review가 요청 타당성과 USER_REVIEW.md 작성 여부를 판단한다.

Roadmap Targets

  • Milestone: agent-roadmap/phase/usable-mvp/milestones/usb-install.md
  • Task ids:
    • adb-diagnostics: ADB 실행 경로, bundled version, runtime hash, server port, fallback 여부를 진단 정보로 표시한다.
  • Completion mode: check-on-pass

분석 결과

읽은 파일

  • agent-roadmap/current.md
  • agent-roadmap/phase/usable-mvp/PHASE.md
  • agent-roadmap/phase/usable-mvp/milestones/usb-install.md
  • agent-ops/rules/project/domain/device-console/rules.md
  • agent-ops/rules/project/domain/macos-platform/rules.md
  • agent-test/local/rules.md
  • agent-test/local/device-console-smoke.md
  • agent-test/local/macos-platform-smoke.md
  • agent-test/local/macos-remote-build-smoke.md
  • lib/src/services/adb_service.dart
  • lib/src/features/settings/settings_page.dart
  • lib/src/features/app_shell.dart
  • test/adb_service_test.dart
  • test/widget_test.dart
  • pubspec.yaml
  • macos/Runner.xcodeproj/project.pbxproj
  • macos/Runner/DebugProfile.entitlements
  • macos/Runner/Release.entitlements

테스트 환경 규칙

  • test_env: local
  • env rules: agent-test/local/rules.md present and read. 기본 완료 evidence는 standard remote Mac runner toki@toki-labs.com checkout $HOME/docker/services/code-server/data/volume/workspace/appsok.
  • matched profiles:
    • agent-test/local/device-console-smoke.md: flutter analyze, flutter test; ADB runtime evidence는 remote runner 기준.
    • agent-test/local/macos-platform-smoke.md: macOS bundle/runtime 관련 확인이 남아 있으면 remote flutter build macos.
    • agent-test/local/macos-remote-build-smoke.md: predecessor bundle evidence를 신뢰하려면 remote checkout/build 상태를 확인.
  • 적용 명령:
    • flutter analyze
    • flutter test
    • flutter test test/adb_service_test.dart
    • flutter test test/widget_test.dart
    • remote runner: zsh -lc 'cd "$HOME/docker/services/code-server/data/volume/workspace/appsok" && flutter analyze'
    • remote runner: zsh -lc 'cd "$HOME/docker/services/code-server/data/volume/workspace/appsok" && flutter test'
  • <확인 필요> 값 없음. Hash 구현에 새 dependency가 필요하면 pubspec.yaml에 명시하고 flutter pub get 결과를 기록한다.

테스트 커버리지 공백

  • Runtime path/source/server port: test/adb_service_test.dart가 service-level behavior를 커버한다.
  • Runtime version/hash collection: 테스트 없음. 새 unit test가 필요하다.
  • Settings or status UI diagnostics display: 현재 test/widget_test.dartADB 대기 placeholder만 확인한다. 새 widget test가 필요하다.
  • Real bundled version/hash: predecessor 01_adb_bundle의 remote evidence와 이 작업의 service test를 함께 본다.

심볼 참조

  • Renamed/removed symbols: none expected.
  • Existing ADB UI references:
    • lib/src/features/settings/settings_page.dart:85-103: ADB section has only path field/search placeholder.
    • lib/src/features/app_shell.dart:313-316: top status pill is fixed ADB 대기.
    • test/widget_test.dart:780-782: status placeholder assertions.

분할 판단

  • split decision policy evaluated.
  • Shared task group: agent-task/m-usb-install/
  • This plan directory is 02+01_adb_diagnostics, so predecessor index 01 is required.
  • Required predecessor: agent-task/m-usb-install/01_adb_bundle/complete.log or matching archived agent-task/archive/*/*/m-usb-install/01_adb_bundle/complete.log.
  • Current state: predecessor complete.log missing. Do not implement until predecessor is PASS-complete.
  • Split is required because diagnostics should report the final bundle path/version/hash from the packaged runtime, not a speculative path.

범위 결정 근거

  • Include: diagnostics data model/service method, version command, runtime hash, fallback/source/server port display, focused tests.
  • Exclude: actual bundle copy, nested binary signing, device list from live ADB, logcat console, custom adb picker persistence.
  • Keep UI restrained: settings page or ADB status area should show compact technical diagnostics, not a landing or explanatory page.

빌드 등급

  • local-G06: bounded service/UI/test work after bundle predecessor completes; process and hash behavior need explicit tests but do not require broad architecture changes.

구현 체크리스트

  • 01_adb_bundle predecessor complete.log가 active 또는 archive 경로에 있는지 확인한다.
  • ADB diagnostics model/service method를 추가해 executable path, source, version, runtime hash, server port, fallback 여부를 수집한다.
  • settings 또는 shell ADB surface에 diagnostics를 표시하고 compact viewport overflow가 없도록 한다.
  • version/hash collection unit test와 diagnostics UI widget test를 추가한다.
  • flutter analyze, flutter test, flutter test test/adb_service_test.dart, flutter test test/widget_test.dart를 실행한다.
  • CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

의존 관계 및 구현 순서

02+01_adb_diagnostics는 directory name 기준으로 01_adb_bundle에 의존한다. 구현 시작 전 다음 중 하나를 확인한다.

  • active: agent-task/m-usb-install/01_adb_bundle/complete.log
  • archive: agent-task/archive/*/*/m-usb-install/01_adb_bundle/complete.log

둘 다 없으면 구현하지 말고 review stub의 사용자 리뷰 요청이 아니라 계획 대비 변경 사항에 "predecessor incomplete"를 기록하고 멈춘다.

[API-1] Collect ADB Runtime Diagnostics

문제

  • lib/src/services/adb_service.dart:231-250 has path/source/server port/fallback fields but no version/hash diagnostics.
  • pubspec.yaml currently has no hash helper dependency, so runtime hash needs either a new package or a deterministic implementation.

해결 방법

Before:

// lib/src/services/adb_service.dart:231
class AdbRuntime {
  const AdbRuntime({
    required this.executablePath,
    required this.source,
    required this.serverPort,

After:

class AdbRuntimeDiagnostics {
  const AdbRuntimeDiagnostics({
    required this.runtime,
    required this.version,
    required this.sha256,
    required this.versionError,
  });
}
  • Add AdbRuntimeDiagnostics and AdbService.collectDiagnostics().
  • Run adb version through the resolved executable and same ADB_SERVER_PORT environment.
  • Compute SHA-256 of the resolved executable. If adding package:crypto, update pubspec.yaml and pubspec.lock intentionally; otherwise keep implementation small and tested.
  • Redact nothing except avoid logging private paths outside diagnostics UI/task logs if a user-owned custom path contains sensitive account names.

수정 파일 및 체크리스트

  • lib/src/services/adb_service.dart: add diagnostics model and collection method.
  • test/adb_service_test.dart: add version/hash/failure tests.
  • pubspec.yaml, pubspec.lock: update only if using a hash dependency.

테스트 작성

  • Add unit tests in test/adb_service_test.dart:
    • successful adb version is captured.
    • hash is stable for a temp executable file.
    • non-zero adb version records error without throwing if UI should still show path/source.

중간 검증

flutter test test/adb_service_test.dart

Expected: all ADB service tests pass.

[API-2] Display Diagnostics

문제

  • lib/src/features/settings/settings_page.dart:85-103 shows an ADB path text field and search button, but no resolved path, source, version, hash, server port, or fallback state.
  • lib/src/features/app_shell.dart:313-316 shows fixed ADB 대기, so users cannot see fallback/system mode.
  • test/widget_test.dart:780-782 asserts only the placeholder label.

해결 방법

Before:

// lib/src/features/settings/settings_page.dart:85
Text('ADB', style: Theme.of(context).textTheme.titleMedium),
const SizedBox(height: 14),
Row(
  children: [
    Expanded(
      child: TextField(

After:

SettingsPage(
  adbDiagnosticsLoader: () => AdbService().collectDiagnostics(),
)
  • Inject a diagnostics loader with a deterministic test fake.
  • Show compact rows for executable source/path, version, SHA-256 short prefix, server port, fallback state.
  • Keep controls stable at compact viewport; use ellipsis for paths/hash.
  • If diagnostics collection fails, show a concise failure state while preserving path/source if available.

수정 파일 및 체크리스트

  • lib/src/features/settings/settings_page.dart: add diagnostics loader and display.
  • lib/src/features/app_shell.dart: pass diagnostics loader or ADB summary if needed.
  • test/widget_test.dart: add diagnostics display and compact viewport coverage.

테스트 작성

  • Add widget tests in test/widget_test.dart:
    • settings page renders source/path/version/hash/port/fallback from fake diagnostics.
    • compact viewport has no Flutter overflow exception.
    • existing ADB 대기 assertion is updated only if the top status label intentionally changes.

중간 검증

flutter test test/widget_test.dart

Expected: widget tests pass without overflow exceptions.

수정 파일 요약

파일 항목
lib/src/services/adb_service.dart API-1
test/adb_service_test.dart API-1
pubspec.yaml API-1, only if hash dependency is added
pubspec.lock API-1, only if hash dependency is added
lib/src/features/settings/settings_page.dart API-2
lib/src/features/app_shell.dart API-2, only if shell summary changes
test/widget_test.dart API-2

최종 검증

flutter analyze
flutter test
flutter test test/adb_service_test.dart
flutter test test/widget_test.dart

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