Skip to content

Phase 1 완성: 적응형 캡처 + 영역 자동화 + resume (A2~A6) - #5

Open
nemne-bot wants to merge 6 commits into
masterfrom
feat/phase1-a2-a3
Open

Phase 1 완성: 적응형 캡처 + 영역 자동화 + resume (A2~A6)#5
nemne-bot wants to merge 6 commits into
masterfrom
feat/phase1-a2-a3

Conversation

@nemne-bot

@nemne-bot nemne-bot commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

개요

고도화 로드맵 Phase 1 (Track A: UX 고도화) 전체를 담습니다. A1(CLI 재구조화)은 #4에서 머지됨.

기능

항목 내용
A3 적응형 루프 프레임 해시 비교로 페이지 확정 시점 감지, 고정 딜레이 제거, 마지막 페이지 자동 종료 (--pages auto)
A2 영역 자동화 --region auto (전경 창 좌표), 프리셋 저장·재사용 (--save-region/--list-regions)
A4 resume 중단 시 PNG 보존 → --resume으로 마지막 페이지 다음부터 이어서. 저장된 영역·앱 자동 재사용, 유실된 넘김 키 1회 재발송, 조기 종료 경고
A5 프로그레스 [12/300] 4% · 경과 1s · 예상 8s
A6 후처리 --resize 50 / --gray

검증 (smoke ALL PASS — 4 시나리오)

CLI 플래그 10/10 · SIGTERM 중단→부분 PDF+디렉토리 보존 · resume 재개 판정 · auto 종료+resize

하네스가 발견한 두 가지 (커밋 메시지에 상세):

  • 비대화형 셸의 백그라운드 잡은 SIGINT가 상속 무시되어 trap 도달 불가 → 하네스는 SIGTERM 사용 (실제 Ctrl-C는 INT/TERM 같은 핸들러)
  • Preview 대역은 → 키가 분할 스크롤이라 잔여 화면수가 페이지수와 불일치 → resume "진행 거리"는 이산 넘김인 실앱(real-e2e) 검증 항목으로 위임

남은 검증 (릴리스 게이트)

bash test/real-e2e.sh로 실교보 앱에서 resume 진행 확인 — 머지 전 권장

Generated with Claude Code
via Happy

NEM-NE and others added 2 commits August 17, 2026 21:06
A3 — the capture loop moves from AppleScript to bash and adapts:
- each frame is hashed (ImageMagick '%#'); a page commits only when
  pixels changed, so pace follows the reader instead of a fixed 1.5s
- 8 consecutive identical frames after a page-turn key = end of book
  -> --pages auto (0) captures until the end with no page count needed
- screencapture.applescript retired (loop now in lib/capture.sh);
  apple/activate.applescript + apple/next-page.applescript remain

A2 — region ergonomics:
- --region auto: derive from the frontmost window minus --region-margin
  (the technique proven by the E2E harnesses), no coordinate typing
- --region NAME loads a preset; --save-region NAME stores the region
  just used; --list-regions prints them (~/.config/ebook-script/regions.conf)
- prompts accept 'auto' for both pages and region

Tests: smoke now covers three scenarios — CLI flags (10/10), SIGINT
partial merge, and --pages auto end-of-book stop (ALL PASS; auto mode
overshoots ~2 frames at the end, tuning note).

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
A4 resume:
- interrupted runs keep their PNG dir; --resume continues from the last
  committed page (number + previous frame hash derived from existing PNGs)
- region/app stored in region.txt and auto-reused on resume
- lost page-turn key detected (frame matches last page with no pending
  turn) and re-sent once before giving up; early stop warns loudly when
  fewer pages than requested were captured
A5: per-page progress with percentage and ETA when a page total is known
A6: --resize N% / --gray post-processing (magick mogrify) before merge

Harness fixes found the hard way:
- a non-interactive shell backgrounds a job with SIGINT ignored at
  startup, making the trap unreachable from kill -INT — the harness now
  uses SIGTERM (same INT/TERM handler a real Ctrl-C hits)
- count committed pages only (pending.png is scratch), keep the resume
  log, and validate what the Preview stand-in can validate; per-page
  resume progression is delegated to real-e2e (Preview scrolls
  fractionally, so remaining-screen counts are stand-in-dependent)
- next-page.applescript: settle delay between activate and the key

Smoke: ALL PASS (CLI flags / interrupt+partial merge / resume detection
/ auto-stop + resize).

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
@nemne-bot nemne-bot changed the title Phase 1 A2+A3: 적응형 페이지넘김 감지 + 영역 자동화·프리셋 Phase 1 완성: 적응형 캡처 + 영역 자동화 + resume (A2~A6) Aug 17, 2026
NEM-NE and others added 4 commits August 17, 2026 22:06
User verification caught this: running from a terminal made the TERMINAL
the frontmost window, so auto region captured (nearly) the whole screen.

- auto_region(margin, app): query the front window of the named reader
  process; refuse with clear guidance when the reader has no open window
  (no silent fallback to whatever happens to be frontmost)
- app now resolves BEFORE the region in bin/ebook-capture (and the
  EBOOK_APP_NAME override moves up with it), so auto always knows which
  app to target
- real-e2e drives the tool's own --region auto instead of computing a
  frontmost-based region itself; smoke TEST 1 switches to --region auto
- smoke TEST 2 stdin lines reordered to the new prompt order
  (book -> pages -> app -> region)

Verified: with Finder frontmost and a Preview document open, region came
out exactly window-bounds minus 10px margin. Smoke: ALL PASS.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
User verification round two: with the Kyobo viewer open, auto region still
failed with "cannot find an open window". System Events' `whose name is`
compares bytes, and process names are NFD-normalized on macOS while script
constants are typically NFC — Korean app names never matched (ASCII ones
like Preview did, which is why the harness passed).

Resolve via `id of application <name>` (LaunchServices lookup, as tolerant
as activate) and match the process by bundle identifier instead.

Verified read-only against the live Kyobo viewer (region = window bounds
±10px exactly) and Preview. Smoke: ALL PASS.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
User feedback: auto region includes the app's title/tool bar at the top
of the window. auto_region now takes a separate top inset so the bar can
be cropped out while other sides keep the normal margin; typical Kyobo
viewer measures ~48pt (probed live: toolbar ends ~44pt from the window
top, page content starts ~46pt).

Pair with --save-region to make it a one-time setup.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
User follow-up: tool-bar height is not fixed, so a static margin-top is
only a stopgap. auto_region now probes one frame after activating the
reader and refines the window box to the actual page:

- rows/columns with a bright-pixel fraction >= 40% are page area; the
  tool bar and the gray surround are not, whatever their height
- validated live: 166pt page top detected in windowed mode (bar +
  surround above the page), full-window box in immersive mode — adapts
  per run instead of per preset
- falls back to window margins when detection is not confident (dark
  cover pages); an explicit --region-margin-top still pins the manual
  behavior

Smoke: ALL PASS (TEST 1 runs the detection path via Preview).

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants