- wifi_share_test: [끄기] 뒤 · 저절로 꺼진 뒤 그 포트에 실제로 연결해 막히는지 (시험 망은 loopbackOnly 대신 지금의 주입 LoopbackNet)
- file_tools_test: 16진 보기 412 폭은 둘째 줄이 00000008, 960 폭은 00000010
- 코드 변경 없음 - 둘 다 2회 통과 (analyze 0)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- lib/ui/row_fit.dart: fitRow (판단만 - 82a87da 그대로) + FitButtonRows (그 판단대로 한 줄 / 두 줄로 그림, 단추 크기 그대로,
소리 막대만 남는 폭 최대 100). 재생 화면은 부르기만 한다 (player_page 580 → 576줄)
- 재생 목록 모듈 (core/playlist.dart): isPlayableFile · samePlayKind · folderPlaylist. buildPlaylist 의 형제는 고른 파일과 같은 종류만,
폴더 [재생] 은 동영상이 없으면 소리 파일 (안내 글 "이 폴더에 재생할 동영상 · 소리 파일이 없습니다." - en · ja · zh 사전 함께).
컨트롤러 (playback_prep) · 탐색기 (explorer_buttons · open_flow) 는 부르기만
- 시험: row_fit_contract_test (새) · player_test 약속 줄 · full_player_test 실제 mpv 장면 (82a87da 에서 옮김).
explorer_flows_contract_test 의 알림 글을 새 글로 (틀 것이 없으면 알림은 그대로)
- full_player_test: 앞 판은 mp3 목록이 [ep1.mkv, Other - Track 2.mp3] 로 실패 (결함 재현), 뒤 판은 목록은 통과하나
"audio 재생 시작" 에서 멈춤 - 이 PC 는 소리 출력 장치가 모두 꺼져 있음 (AudioEndpoint 모두 Unknown). 조절 줄 장면은 기기 (노트 10+) 확인 몫
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- lib/ui/jj_header_row.dart: 아이콘 · 제목 (titleLines 줄까지, "…") · 설명 (넓으면 옆, 좁으면 제목 아래 - 숨기지 않음) ·
단추 (늘 오른쪽 끝에 다 보임, 좁으면 narrowActions). 다운로드 창 · 재생 목록 판 · 즐겨찾기 판 · 작업 현황 판 ·
저장 공간 정리 창 · 화면 · 색 보정이 부르기만 한다
- F11 (7247aeb): 화면 · 색 보정 제목 줄 - 560 미만이면 안내 글은 제목 아래, [모두 초기화] 는 같은 이름의 아이콘 단추, ✕ 늘 보임
- G1 (a22832d): 다운로드 종료 창 제목 두 줄까지 · ✕ 늘 보임
- G2 (a22832d): jjTitleBar 에 lowerActions - AI 비교는 600 미만이면 원본 / 올린 것 고르기만 둘째 줄 가운데, [저장] 은 그대로.
앱 안 폴더 고르기는 단추 셋이 함께 둘째 줄로
- 시험: jj_header_row_contract_test · windows_hdr360_shot_test (a22832d 에서 옮김 - 앞 판은 360 에서 47px 넘쳐 실패)
- 캡처 흔들림 고정 (시험 쪽): bigtext (폴더 · 기록 시각 · 대상 디스크) · magnet (움직이는 "준비 중…" 막대, TickerMode)
- 주입: AppController.note(at:) (처음 값 지금) · PlatformServices.diskSpace + DiskSpaceInfo(space:) (처음 값 실제 디스크)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- lib/ui/jj_title_bar.dart: 제목은 늘 한 줄 (넘치면 "…", 경로는 TailText 로 끝이 보이게) · 넓은 단추를 가진 쪽은 좁으면
단추들을 제목 아래 둘째 줄로 (거기도 넘치면 그 줄만 줄임, 숨기지 않음). 휴지통 · 보관함 · 저장 공간 · 압축 · 글 보기 ·
찾기 결과 · DLNA (경로) · AI 비교 · 앱 안 폴더 고르기 등 17곳이 부르기만 한다
- 바뀐 동작: AI 올리기 비교 · 앱 안 폴더 고르기는 좁은 폭에서 단추가 제목 아래 줄로 (예전에는 412 ja 폴더 고르기가 넘쳤음)
- 주입: WifiSharePage.random (접속 코드 난수, 처음 값 안전한 난수) · Vault.add(added) (넣은 때, 처음 값 지금)
- 시험: jj_title_bar_contract_test · titlebar_places_shot_test. wifi (폴더 · 코드 · 스크롤 막대) · vault (폴더 · 넣은 날) 고정
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- lib/ui/jj_field.dart: 칸 이름 짧게 · 도움 글 칸 아래 3줄까지 (helperLines 로 늘림) · 오류 글 · 칸 끝 단추 · 여러 줄 · 테두리 · 가림.
WebDAV · FTP · SFTP · SMB 서버 창 · AI 서비스 · 해시 비교 · 시드 · 패턴으로 고르기 · 동기화 일정 · 이름 틀이 부르기만 한다.
SecretField 는 JjField 위에 눈 단추만 더한다
- 바뀐 동작: 패턴으로 고르기 · 동기화 일정 창의 도움 글이 한 줄에서 "…" 로 잘리던 것이 3줄까지 보임 (F2 와 같은 결함)
- 시험: jj_field_contract_test · field_places_shot_test (패턴 · 일정 창, 캡처가 없던 곳)
- 시험 쪽 고정: b6 · p3 · xptools 도 고정 폴더 · 시각 (pinTestTimes 가 만든 · 바뀐 · 열어 본 시각 모두)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- lib/ui/secret_field.dart: 비밀번호 · API 키 · 키 암호 칸 (처음 늘 가림, 눈 단추로 켜고 끄기, 자동 고침 · 추천 끔,
바깥 가리기로 칸 여럿을 단추 하나로). WebDAV · FTP · SFTP · SMB · AI 서비스 · 압축이 부르기만 한다
- 눈 단추 모양 · 툴팁을 하나로 (AI 창의 채운 24 아이콘 → 다른 곳과 같은 테두리 18, 툴팁 '보이기/가리기'),
쓰지 않게 된 사전 글 '비밀번호 보기/숨기기' 를 en · ja · zh 에서 뺌
- 시험: secret_field_contract_test (처음 가림 · 켜고 끄기 · 칸 여럿 · 300/412 · 배율 2 넘침 없음)
- 시험 쪽 고정: testFixedTempDir · pinTestTimes (폴더 이름 · 파일 · 폴더 시각), 시험 SFTP 서버 fixedPort · fixedHostKey
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 옮긴 곳: 실시간 동기화 카드 (멈춤 · 마스터 기다림) · AI 그림 화면 안내 2 · AI 서비스 창 경고 · FTP 평문 경고 · 동영상 오류 상자
- NoticeBand 더한 것: 설명은 없어도 됨 · selectable (오류 원문을 골라 복사 - 설명이 없으면 제목) · margin (부르는 쪽이 정함)
- 글 · 단추 · 색의 뜻은 그대로 (경고 = warning · 오류 = danger/alert · 안내 = accent). 새 화면 글 없음
- 범위 밖: Tor 상태 줄 · 브라우저 띠 (진행 막대가 든 상태 줄 - 안내 띠가 아님)
- 시험 기대값 바꿈 1곳: sync_problem_test 의 '대상 파일은 지우지 않았습니다.' 를 따로 된 글이 아니라 띠 설명 안의 글로 찾음
(textContaining - 그 문장이 보인다는 뜻은 그대로)
캡처 (바꾸기 전 판 dac47bd 2회 · 바꾼 판 2회, 전후 18장: M:\jj_tmp\dev\7f\nb_compare):
- 바뀐 것은 옮긴 화면 18장뿐 (AI 그림 4 · FTP 평문 6 · 새 캡처 notice_places 8), 다른 화면은 그대로. 412 폭 넘침 없음
- 새 캡처 8장은 바뀐 판 두 번 0px. AI 그림 넓은 2장 · FTP 평문 960 2장은 바꾸기 전에도 흔들리던 장 (글 칸 커서)
사용자가 보게 될 동작: 안내 띠가 모두 같은 모양 (연한 바탕 · 테두리 · 아이콘 · 굵은 제목 · 작은 설명 · 단추). FTP 평문 경고는 빨간 글 상자에서 빨간 띠로
확인: analyze 0 · 단위 1525 ×2 · 통합 6/6 ×2 (b · c) · base10 214장 0px
(nb3 통합 a 에서 412 지우기 "시험 휴지통 폴더가 없어짐" 이 다시 남 - 이 고침과 무관, 이제 step_check 가 늘 %TEMP% 감시를 켬)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- NoticeBand(icon, title, body, actions, color): 연한 바탕 · 테두리 · 둥근 띠, 제목 굵게 · 설명 작고 흐리게 · 단추는 넘치면 다음 줄 (Wrap).
탐색기 pane_notices 의 _noticeBox 와 같은 모양 (탐색기 캡처 214장 0px)
- 약속 시험 notice_band_contract (27): 폭 300 · 412 · 960 × 글자 배율 1 · 1.3 · 2 × ko · en · ja - 넘침 없음 · 단추가 띠 안 · 좁고 크면 다음 줄
- 캡처 시험 notice_places_shot (나머지 자리를 모으기 전후 견줄 것): 실시간 동기화 카드 (멈춤 · 마스터 기다림) · 동영상 자세히 오류 상자 · AI 서비스 경고
사용자가 보게 될 동작: 바뀌는 것 없음 (탐색기 띠 모양 그대로)
확인: analyze 0 · 단위 1525 ×2 · 통합 6/6 ×2 · base10 214장 0px
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- SecretGate.passIf(hasSecret, force): 비밀 값이 없으면 묻지 않고 지나감, 있으면 pass 의 답
- 모은 곳 (같은 꼴의 복사 9곳): 원격 등록 requireSecretGate · 플레이어 (WebDAV 머리) · 그림 AI (API 키) ·
WebDAV · FTP · SFTP · SMB 설정 · AI 서비스 설정 (저장된 비밀 값이 있는 것을 고치기 전). 오류 종류 · 닫기는 그대로
- 그대로 둔 것 (같은 꼴 아님): 사용자가 직접 누른 일 앞에서 다시 묻는 8곳 (탐색기 · 폴더 고르기 · 다시 시도 · 보관함 · 자막 찾기 등),
OpenSubtitles (비밀 값 조건 없이 늘 문 - 따로 보고)
- 약속 시험 한 줄 (remote_registry_contract: 묻는지 · 답 · force)
사용자가 보게 될 동작: 바뀌는 것 없음
확인: analyze 0 · 단위 1498 ×2 · 통합 6/6 ×2 · base10 214장 0px
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- lib/core/remote_registry.dart: RemoteRegistry<S, C> (configure · servers · server · client · closeAll, onDrop) - 서버마다 다른 것은
비밀 값 목록 · "설정 없음" 오류 · 만들기뿐. DavRegistry · SftpRegistry · SmbRegistry · FtpRegistry 는 같은 이름 그대로 이것을 부름
- 다시 접속하는 바뀜은 예전과 같게 (관리자 조건 ①): 지움 · 비밀이 아닌 칸 (toJson: 주소 · 포트 · 사용자 · 루트 · 보안 · 지문 · 공유 · 도메인 · insecure) ·
비밀 값 (WebDAV · SMB · FTP = 비밀번호, SFTP = 비밀번호 · 개인 키 · 키 암호). 접속에 쓰는 칸은 모두 이 둘 안 - 주소 · 사용자가 바뀌었는데
예전 클라이언트를 쓰는 경우는 예전에도 없음. SMB: 버린 연결의 서명 기록 지우기 · 서명 필수가 바뀌면 모두 닫기 그대로
- 문 (관리자 조건 ②, 보안): SecretGate.pass 를 부르는 곳은 requireSecretGate 하나 - 비밀 값이 있으면 연결 전에 마스터 확인
- 약속 시험 remote_registry_contract (7): 4종 등록 규칙 · SMB 서명 필수 · 4종 문 (거절이면 연결 전 DavLockedException, SFTP 는 키만 있어도) ·
비밀 값이 없으면 묻지 않음. 바꾸기 전 판 (fe8e5b7) 에서도 7개 모두 같게 통과 (동작 그대로임을 확인)
사용자가 보게 될 동작: 바뀌는 것 없음 (구조만)
확인: analyze 0 · 단위 1497 ×2 · 통합 6/6 ×2 · base10 214장 0px · ftp_shot · sshkey_shot · remote_idle_shot ×2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- lib/app/copy_error_text.dart: userErrorText · rsyncFailureText 를 transfer_job 에서 옮김 (transfer_job 은 다시 내보냄 - 부르는 곳 그대로)
- live_sync: 상태 글 = trf('실패: {0}', [userErrorText(e, sources: [원본])]) - 예외 이름 · Dart 의 영어 파일 오류 없이 화면 언어로.
작업 기록 (c.note) 에는 원문 그대로 (237 규칙)
- 고치기 전 판 (ecb2b9f) 에서 같은 실제 실패 (받는 쪽 폴더 자리에 파일) 의 상태 글이
"실패: PathExistsException: Creation failed, path = … errno = 183" 였음을 확인 (f18_before.log)
- 새 화면 글 없음 (있던 번역만) - en · ja · zh 사전 그대로
- 약속 시험: live_sync_error_text (실제 폴더 · 실제 실패)
사용자가 보게 될 동작: 실시간 동기화가 실패하면 "실패: 만들거나 쓰지 못했습니다 · 경로 · 이유" 처럼 짧은 말 (영어 예외 원문 없이)
확인: analyze 0 · 단위 1490 ×2 · 통합 6/6 ×2 · base10 214장 0px · lsync_p0_shot · live_excl_shot ×2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- remote_fs.dart: remoteMkdirs(client, rel, mkdirOne) - 없는 위 폴더까지 · 이미 폴더면 그대로 · 같은 이름의 파일이면 RemoteNameIsFile (파일은 그대로).
서버마다 다른 것은 한 칸 만들기뿐 (FTP MKD · SFTP mkdir (그 사이 다른 곳이 만들었으면 그대로) · SMB 채널 · WebDAV MKCOL).
위 폴더 계산 remoteParent 하나 (FTP · SFTP · SMB 의 _parent 복사 3벌 지움)
- 고치기 전 판 (bdea662) 에서 FTP 는 같은 이름의 파일 위 mkdirs 가 오류 없이 넘어감을 확인 (r6_before.log) - 뒤의 쓰기가 엉뚱한 오류로 끝났다.
WebDAV 는 서버 오류 글, SFTP · SMB 는 서버마다 다른 예외였다
- 약속 시험: 실제 시험 서버 WebDAV (TestDavServer) · FTP (pyftpdlib) · SFTP (asyncssh). SMB 는 Android 에서만 (기기 확인)
사용자가 보게 될 동작: 원격으로 복사 · 맞출 때 받는 쪽에 같은 이름의 파일이 있으면 서버와 상관없이 "같은 이름의 파일이 있어 폴더를 만들 수 없습니다"
확인: analyze 0 · 단위 1489 ×2 · 통합 6/6 ×2 · base10 214장 0px · windows_ftp_shot · windows_sshkey_shot ×2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- rsync_options.dart rsyncHasOption(words, short, long): 짧은 묶음은 한 글자씩, 값 자리 (값을 받는 글자 B e f M T @ 의 뒤 ·
값을 받는 긴 옵션의 다음 낱말) 는 옵션으로 보지 않음. rsyncShortWithArg 는 거르기 해석 (rsync_filter) 과 함께 씀
- "-u 가 있나" 세 곳 (transfer_job._update · withUpdateOption · optionsUpdate) 이 이것을 부름. 예전에는 "-로 시작하는 낱말에 u 가 있으면"
이라 -f'- build/' · -f "- run/" 를 -u 로 읽었다: 미리 보기는 "받는 쪽이 더 새것은 건너뜀", 실제 rsync 는 덮어씀 · 앱이 맞출 때도 건너뜀
- 고치기 전 판 (512d290) 에서 같은 시험이 틀리게 나옴을 먼저 확인: 판단 [true, true, true] (기대 [true, false, false]) ·
실제 rsync 는 -avf'- build/' 에서 build.txt 를 보내는데 앱은 -u 로 봄 (c3_before.log). 고친 판에서는 2회 통과
- 약속 시험: 판단 표 + 실제 rsync (받는 쪽이 더 새 파일, 옵션 5가지) - 앱의 -u 판단 = rsync 가 보내는지
사용자가 보게 될 동작: rsync 옵션의 거르기 값에 u 가 들어 있어도 "받는 쪽이 더 새것은 건너뜀" 으로 잘못 보거나 앱이 맞출 때 건너뛰지 않음 (실제 rsync 와 같게)
확인: analyze 0 · 단위 1486 ×2 · 통합 6/6 ×2 · base10 214장 0px · rsync_page ×2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- SameFile.keepNewer(skipNewer, targetModified, modified): 설정 (229) 이 켜져 있고 받는 쪽이 2초 넘게 새것일 때만 그대로 둠, 시각을 모르면 덮음
- 부르는 곳: 폴더 합치기 (로컬 isNewerThere · 원격 anyCopy) · 압축 풀기 덮어쓰기 (archive_ops). 같은 이름 창의 "더 새것" 표시 (name_clash) 도
SameFile.targetNewer - 2초 규칙을 따로 계산하던 곳이 없어짐 (robocopy 는 /XO, rsync 는 -u 로 같은 일)
- 동작은 그대로 (판단 모으기만). 약속 시험 한 줄 더함
확인: analyze 0 · 단위 1484 ×2 (c4_unit1 · c4_unit3) · 통합 6/6 ×2 · base10 214장 0px · move_left_shot · check_shot ×2
(c4_unit2 에서 ftp_test 1 · l10n_check 1 이 같은 때 실패 - 따로 3회 · 전체 다시 1회 모두 통과, 부하 때의 흔들림으로 보이며 따로 보고)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- FileOps.mirror 가 늘 anyMirror 를 부름. localMirror (거르기를 무시 · 같은 이름 폴더 충돌 (M1) 을 모름) 를 지움
- anyMirror 의 같은 파일 판단: SameFile.forAppSync(remote: 경로에 원격이 있는지, move: strict) - "받는 쪽이 더 새것도 같음" 은 원격일 때만
(로컬끼리는 크기 + ±2초 그대로)
- 약속 시험: mirror_one_impl (실제 폴더 - 거르기: 거른 것은 보내지 않고 받는 쪽의 거른 것은 지우지 않음 · 나머지는 --delete, 미리 보기와 같음 /
같은 이름 폴더: 지우기 없으면 건너뛰고 알림 · 있으면 파일로). same_file 의 원격 경우는 실제 WebDAV 시험 서버로
사용자가 보게 될 동작: 로컬끼리 맞추기 (현재 방식 · 실시간 동기화) 가 rsync 옵션의 거르기를 따름 - 미리 보기에서 빠진 것은 실제로도 보내지 않고
받는 쪽의 거른 것은 지우지 않음 (예전에는 미리 보기와 달리 다 보내고 다 지웠다). 받는 쪽의 같은 이름 폴더는 지우기 포함일 때만 바꿈
확인: analyze 0 · 단위 1484 ×2 · 통합 6/6 ×2 · base10 214장 0px · rsync_page · copy_sync_shot · lsync_p0_shot · live_excl_shot ×2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- core/sync_preview.dart runOptionsText: 실행 인수 (rsyncArgs · robocopyRuns) 와 같은 규칙 - 원본 지우기 옵션은 빼고 이동일 때만 그 방법의 것,
robocopy 는 앱이 붙이는 것 (이동의 /MOVE /IS /IT /IM · 링크 /XJ · 더 새것 건너뛰기 /XO) 까지
- 부르는 곳: 모니터링 "실제 실행" · 실행 전 미리 보기 (effectiveRunText) · 탐색기 복사 · 이동 확인 창 · 실시간 동기화 [최종 정리] 창
- 고친 어긋남 (15 검토 F5): 탐색기 확인 창이 robocopy 이동을 /MOVE 로만 보였다 · [최종 정리] 창이 모니터링에서 고친 옵션이 있어도 늘 -avHPOg 로 보였다
- 약속 시험: 보이는 글 = 실제 인수 (robocopy 4 · rsync 4 · 현재 방식)
사용자가 보게 될 동작: 탐색기의 robocopy 이동 확인 창에 실제 옵션이 모두 보임 · [최종 정리] 창에 실제로 실행할 옵션이 보임
확인: analyze 0 · 단위 1482 ×2 · 통합 6/6 ×2 · base10 214장 0px · lsync_p0_shot ×2 · rsync_page ×2
(rsync_page 1회는 시작 3초 만에 시험 앱이 끝남 - media_kit 디버그 기록 파일의 PID 겹침, 이 고침과 무관 · 따로 보고)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- lib/core/files/same_file.dart: 크기 + 바뀐 때 ±2초, 받는 쪽 시각이 올린 때인 곳 (원격이 낀 앱 맞추기, 이동 아님) 은 받는 쪽이 더 새것도 같음.
SameFile.forAppSync(remote, move) · targetNewer
- 부르는 곳: 로컬 맞추기 (local_transfer) · 원격 맞추기 (any_transfer) · 미리 보기 (sync_preview) · 실시간 동기화 기다림 (sync_diff) ·
-u 건너뛰기 · 폴더 합칠 때 더 새것 지키기
- 고친 어긋남 (15 검토 F2): 원격으로 앱이 직접 맞출 때 받는 쪽이 같은 크기에 더 새 파일이면 미리 보기에 "바뀜" 으로 나왔는데 실제로는
보내지 않았다. 이제 미리 보기도 실제와 같은 판단 (rsync_runner viaDav · sync_preview_view direct 가 SameFile.forAppSync 를 넘김)
- 약속 시험: 판단 표 + 실제 파일로 미리 보기와 실제 맞추기 (anyMirror · localMirror) 가 같은지 - 원격 규칙 · 이동 · 로컬
사용자가 보게 될 동작: 원격으로 앱이 직접 맞출 때 받는 쪽의 같은 크기 · 더 새 파일이 미리 보기에서 빠짐 (실제로도 보내지 않던 것). 로컬 · rsync · 이동은 그대로
확인: analyze 0 · 단위 1479 ×2 · 통합 6/6 ×2 · base10 214장 0px · rsync_page · copy_sync_shot · lsync_p0_shot · live_excl_shot ×2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- SubtitleFiles.pickFor (있는 경로 건너뜀 · 이름으로 언어, 더한 수) · saveAs (SRT 바이트 · 표현 못 한 글자 수) · canEdit (static)
- app_controller 는 부르기만 (알림 · 기록은 그대로)
- 약속 시험: 실제 파일 · 실제 SRT 바이트, 고르기 · 저장 창 대신 정한 것을 돌려주는 저장소 (사용자가 고른 것)
확인: analyze 0 · 단위 1475 ×2 · 통합 6/6 ×2 · base10 214장 0px
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 첫 창에 넘겨 본 결과를 셋으로: 받음 · 아직 준비 안 됨 (instance.json 없음 · 연결 안 됨) · 연결은 됐는데 답 없음
- 답 없음은 1초씩 3번이면 바로 unresponsive (관리자 결정 10/24). 첫 창이 정상이면 그 창에 넘기는 동작 · 막 뜨는 중이면
잠깐 다시 해 보는 동작은 그대로
- 약속 시험: 받기만 하고 답하지 않는 실제 소켓 - 5초 안에 unresponsive
확인: analyze 0 · 단위 1474 ×2 · player_test 17 ×2 · 통합 6/6 ×2 (a · c) · base10 214장 0px
(b 회차는 시험 도중 C: 임시 폴더의 시험 폴더 jj_usechk_fixed_412 와 시험 휴지통 폴더가 통째로 없어져 412 23장 벗어남 - 이 고침과 무관, 원인 미확인)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Tor: debugRunning · executable 없앰 → 떠난 뒤 잠시 켜 두기를 IdleStop 모듈로 (schedule · cancel · stopNow).
환경 설정 > Tor 는 IdleStop 을 받음 (처음 값 = 앱의 Tor), [지금 끄기] = stopNow
- Wi-Fi 공유: debugLoopbackOnly · debugAddresses · loopbackOnly 인자 없앰 → WifiShareNet 주입 (열 주소 · 설정 열기).
WifiSharePage(net:) 가 debugLaunch 를 대신함. debugFail 없앰 - 시험이 실제 다른 루프백 주소 (127.0.0.x) 에서 틀린 코드를 보냄
- 관리자 권한: Elevation.debugElevated 없앰 → PlatformInfo.elevated (조립 주입), CefView(elevated:)
- CEF 시작 시간: 바꿀 수 없게 (const) - 시험은 가짜 시간을 넘김
- 단일 실행: debugStopListening 없앰 - 시험이 instance.json 을 아무도 듣지 않는 포트로 (받는 곳이 죽은 첫 창)
- SMB 찾기: 전역 debugFindSmbServers 없앰 → PlatformServices.findLanSmb 주입
- 남은 @visibleForTesting (들여다보기만): browser_page · tor_page debugNav, secret_store dpapiAt, reader_page dropMissingFiles
확인: analyze 0 · 단위 1473 ×2 · 통합 6/6 ×2 · base10 214장 0px · windows_wifi_shot ×2 · windows_smbfind_shot ×2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- recycle_bin: RecycleBinBackend 약속 + WindowsRecycleBin (이 기기의 휴지통). 전역 recycleBinForTest · recycle() · restoreRecycled() 없앰
- delete_ops: deletePaths(bin:) · undoRecycle(bin:) - 처음 값 WindowsRecycleBin
- ExplorerDevice.recycleBin → ExplorerFlows · ExplorerDeleteFlow(recycleBin:)
- 시험: useTestRecycleBin(device) 가 시험 기기에 시험 폴더 안의 휴지통을 넣음. 영구 삭제만 하는 약속 시험 4개는
휴지통으로 보내면 실패하는 것을 넘김 (사용자 휴지통에 닿지 않게). 넘겨받은 휴지통 약속 시험 1개 더함
- 시험용 휴지통: 자기 폴더가 없어졌으면 다시 만들지 않고 그대로 알림 (진단)
- 전부터 있던 실패 2개 고침 (E6 부터 Windows 처음 모양이 Total Commander 라 이름 · 확장자가 다른 칸):
windows_check_shot_test · windows_b3_shot_test 가 X-plore 모양을 직접 고름
확인: analyze 0 · 단위 1472 ×2 · 통합 6/6 ×2 · base10 214장 0px · windows_check_shot ×2 · windows_b3_shot ×2
(첫 확인의 통합 1회에서 412 지우기가 '경로를 찾을 수 없음' 으로 11장 벗어남 - 다시 4회 모두 0px, 원인 미확인)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- lib/app/local_fs.dart: LocalFs 약속 (list · volumes · probe), RealLocalFs = 이 기기 그대로
- ExplorerDevice.listVolumes/probeDrive → ExplorerDevice.fs (LocalFs)
- ExplorerController(fs:) → loadDir(list:) (처음 값 listEntries)
- 빈 목록 경합: reloadOpen 이 끝날 때, 시작할 때 읽어 둔 것 중 닫힌 것만 잊음
(예전: 시작할 때 찍은 열린 목록으로 지워, 다시 읽는 동안 펼친 폴더가 비어 보였다)
- 결정적 시험 explorer_reload_race_test: 다시 읽기를 붙잡는 느린 LocalFs 를 생성자로 넘김
(실제 폴더 · 실제 목록). 예전 판에서는 실패 (펼친 폴더 [] ), 고친 판에서는 통과
확인: analyze 0 · 단위 1471 ×2 · 통합 6/6 ×2 · base10 214장 0px
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- MemorySecretStore.failRead/failWrite 를 없앰 → 시험 쪽 test/support/flaky_secret_store.dart
- WebProxy.debugAndroid/debugSetProxy 를 없앰 → WebViewProxyTarget 주입 (Android=ProxyController, 그 밖=없음)
- ExitGuard.forceAndroid 를 없앰 → PlatformServices.platform (PlatformInfo)
- JJ_NLLB_LOW_MEMORY 환경 변수를 없앰 → NllbTranslator(lowMemory:), 처음 값은 PlatformInfo.host
- archive_ops · rsync_launch · file_error 의 기본값을 PlatformInfo.host 로 모음
- 이름 바꿈: WebProxy.shownForTest → shown, debugReset → reset
- 보안: 남은 Tor 웹 뷰가 있는 동안에도 removeImplicitRules (localhost 까지 Tor 로)
- 약속 시험 platform_info_contract_test 3개
확인: analyze 0 · 단위 1470 ×2 · 통합 6/6 ×2 · base10 214장 0px
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
사용자가 보게 될 동작: 기기 안전 저장소를 읽지 못하면 저장된 비밀번호를 쓰는 기능이 열리지 않고, 환경 설정 > 보안에
까닭과 [다시 읽기] 가 보인다. 다시 읽히면 평소대로 마스터를 묻는다.
- 예전: 읽지 못하면 빈 것으로 보아 마스터가 없는 것처럼 문 (SecretGate) 이 열렸고, 그 상태에서 마스터를 정하면 진짜 값을 덮어쓸 수 있었다
- MasterLock.storeUnreadable: load 가 예외 대신 표시 (앱은 켜짐). ensure 는 한 번 다시 읽고 못 읽으면 false.
setMaster · setSuper · clearMaster · clearSuper · setAsk 는 MasterStoreUnreadable. reload()
- 보안 설정: 까닭 · [다시 읽기] (정하기 · 바꾸기 · 끄기 숨김). 보관함 [마스터로도 열기] 는 까닭을 알림
- 비밀번호 다시 저장 [다시 시도] 가 되면 마스터 잠금도 다시 읽음. settings_store 의 TODO(M0) 지움
- 약속 시험 master_store_unreadable_test 4 (읽기가 실제로 실패하는 저장소를 시험 파일 안에 - lib 흉내 플래그 쓰지 않음)
- 확인: 단위 1467 ×2 · 통합 6/6 ×2 · 캡처 214장 base10 과 같음
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 원인 (실제 앱): 목록 줄 (TC · '폴더 + 파일 목록') 의 폴더 · '..' 는 한 번에 열려, 두 번 누르면 두 번째 누르기가 같은 자리의 '..' 에
맞아 도로 나왔다
- TC 모양: 폴더 · '..' 도 한 번 = 고르기, 두 번 = 열기 (ClickPolicy doubleOpens - Total Commander 와 같게)
- TC 모양: Enter = 열기 (폴더는 들어가기, 파일은 열기) - 바꿀 수 있는 키 동작 'open', 처음 키는 TC 모양일 때만 Enter
- '폴더 + 파일 목록': 한 번 열기는 그대로, 연 직후 두 번 누르기 시간 (300ms) 안의 다음 누르기는 버림 (마지막 틀 시각으로 잼)
- 약속 시험: 누르기 표 (TC) · TC 한 번 / Enter / '..' 두 번 · 목록 배치 곧바로 두 번째 누르기 · 시간 지난 '..' 한 번
- 점검 시험: TC 를 두 번 누르기 · Enter 로 되돌림 (실제 시간에서 들어가기 · 나오기 됨), 목록 배치 단계 더함 - 214장 2회 같음 (base10)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 지운 뒤 초점: 지운 줄의 다음 줄로, 마지막이었으면 앞 줄로 (TC · X-plore 같음) - focus_after_delete (순수 함수, 약속 시험 4) +
지우기 흐름이 부름. 실제 화면 시험: TC 목록에서 F8 단추로 지우면 다음 줄이 지금 줄
- TC: 확장자 칸이 없으면 (좁은 줄 · 좁아 숨긴 열) 이름에 확장자를 붙인다 ('notes.txt') - 정보를 숨기지 않게.
기존 큰 글자 시험 3곳의 TC 기대를 'a' → 'a.txt' 로 (이 결정에 따른 것, 주석에 적음)
- 탐색기 점검 시험: TC 전용 단계 (Backspace 로 맨 위 · 메뉴 [열기] 로 들어가기 · Backspace 로 나오기 · F5 · F6 · F8 · 지운 뒤 초점,
단계마다 폴더 시각 다시 고정 + Ctrl+R). 두 번 누르기는 이 실제 시간 시험에서 열기로 잡히지 않아 단위 약속 시험이 본다
- 확인: 단위 1461 ×2 · 통합 6/6 ×2 · 캡처 201장 2회 0px 같음 (base9) · X-plore 는 '삭제 확인' 3장만 바뀜 (초점)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- TC 모양: 트리 대신 지금 폴더의 목록 (paneListRows - '폴더 + 파일 목록' 의 목록과 같은 함수, 목록의 스크롤).
사용자가 고른 '폴더 + 파일 목록' 배치 · Rsync 화면은 그대로 트리
- tc_key_bar: F3 보기 · F4 편집 · F5 복사 · F6 이동 · F7 새 폴더 · F8 삭제 - 이미 있는 동작을 부름
- tc_drive_space: 창 위 남은 공간 / 전체 - ExplorerDevice.diskSpace 로 받음 (시험은 TestExplorerDevice.space)
- 좁은 창 (창 폭 200 아래, narrowRowWidth): 아이콘 칸 줄임 · 끌기 손잡이 숨김 · 열 대신 이름 먼저 (크기 · 날짜는
두 줄이 들어가는 줄 높이에서 이름 아래 - TC 26 은 이름만) · 열 머리도 이름만. X-plore · TC 가 같은 ExplorerRowView
- 약속 시험 explorer_tc_look_test 4개. 점검 시험은 X-plore · TC 두 모양을 찍는다 (폴더 시각 · 남은 공간 고정)
- 확인: 단위 1456 ×2 · 통합 6/6 ×2 · 캡처 180장 2회 정확히 같음 (base8) · X-plore 1920 · 960 은 base7 과 같음
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ExplorerSettings: 처음 값 defaultStyle (Windows totalcmd · Android xplore). 예전 파일에 모양 키가 없으면 그때의 X-plore.
Windows 에서 저장된 xplore 이고 물었다는 표시 (explorerStyleV2) 가 없으면 styleAskPending (저장 안 함)
- style_ask: 탐색기를 열 때 한 번 [바꾸기] (Total Commander) / [그대로] (X-plore) - 창 밖으로 닫지 못함, 어느 쪽이든 다시 묻지 않음.
환경 설정에서 직접 고르면 묻지 않음
- 약속 시험 explorer_style_contract_test: 새 설치 · 저장된 xplore (키 없던 예전 파일 포함) · windows/totalcmd 안 물음 · [그대로] · [바꾸기]
- X-plore 모양 (트리) 을 보는 기존 시험 14개 파일 + 공용 하네스에 style = 'xplore' 를 밝힘 (기대값 그대로, 관리자 승인 10/23)
- 설정 JSON 골든: 새 키 explorerStyleV2 한 줄 · 처음 값 출력의 Windows 모양 totalcmd 만 바꿈. 사전 4개 (en · ja · zh-Hans)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- lib/ui/notice.dart 의 noticeDurationForTest 를 지움 (lib 에 시험 전용 길이를 두지 않음 - 관리자 10/23)
- 탐색기 점검 시험은 MaterialApp 을 NoticeTiming 으로 감싼다. 약속 시험: 감싸면 그 시간, 없으면 10초
- 확인: 캡처 2회 90/90 같음 · 앞 판 (5303663) 과도 90/90 같음 → base7
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- notice.dart: appNoticeDuration (10초, 앱의 값) · noticeDuration (읽기) · noticeDurationForTest (시험만, @visibleForTesting)
- 탐색기 점검 시험: 알림이 실제 시간으로 닫히지 않게 두고, 정한 자리 (복사 알림은 선택을 끈 뒤 · 휴지통 알림은 이동을
누르기 전) 에서 닫는다 - 찍는 때와 10초가 겹쳐 장면 14 · 27 이 실행마다 달라지던 것
- 확인: 같은 판 2회 90/90 픽셀까지 같음
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- app_actions.dart 는 AppActions (설정 · 종료 버튼) 만 두고 옮긴 것을 그대로 내보낸다 (부르는 곳 그대로)
- 약속 시험: AppNavButtons.homeId · isCompact
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Windows · Android 가 복사해 쓰던 시작 단계 (startCore) 와 다운로드 연결 (createDownloads) 을 하나로 - 차례는 그대로
- Windows 끝내기 (WindowsQuit) · 실행 요청 처리 (handleLaunchRequest) · Android 시작 · 두 번째 창 · 도우미
- main.dart 는 옮긴 공개 이름을 그대로 내보낸다 (시험 · 다른 곳)
- 약속 시험: createDownloads · lastWorkText
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 화면 조각은 공개 위젯 (key 받음), 일은 AppController 가 · 화면은 부르기만
- 약속 시험: LogPanel · LogStrip · JobStatusIcon
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 작업 대기열 (JobQueue) · 작업 기록 (AppLog) · 목록 공유 (VideoListShare) · 편집 목록 (VideoList)
- 동영상 분석 (VideoProbe) · 파일 옮기기 (VideoFiles) · 자막 파일 (SubtitleFiles) · 인터넷 자막 (SubtitleDownload)
- AI 자막 · 자막 번역 (AiSubtitleRunner) · MKV 묶음 (MkvBatch) · 인코딩 고르기 (EncodeChoice) · 재생 준비 (PlaybackPrep)
- 실행 중 설정 · 켤 때 정리 · 다운로드 드라이브 (app_runtime), AiOptions
- 공개 이름은 그대로 (화면 · 시험이 부르는 것), 같은 번역 줄 만들기 두 곳은 하나로
- 약속 시험: JobQueue · AppLog · EncodeChoice · VideoListShare · VideoFiles · VideoList
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 원인: until 이 횟수 (200번) 로 끊겨 부하 때 일이 덜 끝난 채 넘어갔고, 끝맺음의 '.tmp 없음' 한 번 확인이 목록 저장과
빈 폴더 목록 저장 사이에 맞아 folders.jjd.tmp 쓰기가 연 채 남아 임시 폴더를 지우지 못했다 (errno 32, 6/18 재현)
- until: 최대 60초 실제 시간, 안 되면 그 자리에서 실패 (조용히 넘어가지 않음). vaultQuiet: .tmp 없음이 10번 잇달아일 때
- 확인: 6개 동시 × 3회 18/18, 혼자 10회 연속 통과
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 로그인 쿠키 파일 쓰기 (Edge · Chrome 이 따로 하던 것) 를 writeLoginCookies 하나로
- 살려 둔 웹뷰 · Chrome 시작 제한 시간은 그 모듈이 갖는다 (CefView.startTimeout)
- 약속 시험: NavWatch · writeLoginCookies · deleteExportedCookies
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 일반: 즐겨찾기 · 저장 공간 정리 · 바뀐 기본값 알림 · 안쪽 → 바깥 · 비밀번호 기억 · 휴지통 · 모든 파일 안내 (allFilesHint2)
- imageExts 는 보기 화면 분야 (ReaderSettings) 로
- 표시 cookieScopeV2 → 다운로드, robocopyLinksV1 → 복사 분야로
- AppSettings 에 남은 것: 분야 목록 · 모르는 항목 보존 · 비밀 값 빼기 · 바뀐 기본값 알림 · 실행 중 값 (webViewDataDir)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 도구 고침: setter 안의 ' closeAction = v' 줄을 선언으로 잡던 것 (타입은 글자로 시작 · 첫 선언만)
- 문서 주석 [AppSettings.run.x] → [RunSettings.x]
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>