Skip to content

feat: add figure reference links, panel jumps, and crop flow#17

Open
enu3379 wants to merge 9 commits into
devfrom
feature/figure-ux
Open

feat: add figure reference links, panel jumps, and crop flow#17
enu3379 wants to merge 9 commits into
devfrom
feature/figure-ux

Conversation

@enu3379

@enu3379 enu3379 commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Summary

본문 피규어 참조(주입 링크·PDF 내장 링크·캡션 라벨)를 패널 경유 탐색으로 연결하고(DC-F1-B), 점프 정렬 규칙(텍스트 상단 1/8·피규어 세로 중앙)과 플래시, 수동 크롭 진입, 원점 칩(↩) 복귀 UX를 구현합니다. 설계 정본은 docs/figure-ux.md, 구현 리뷰는 §6.1, 실기기 QA 결과는 §7.1.

Changes

  • G1–G8: FigureEntry 영속화(manual region 보존 merge), 점프 유틸(jump.ts), 멘션 스캔·주입(mentions.ts), 내장 링크 인터셉트(MarginLinkService), 그림·표 탭 개편(언급 칩·원점 칩·크롭 아이콘), 수동 크롭 모드, 캡션 라벨 링크, 계획서 개정
  • FG-R1: 내장 링크 클릭 좌표(페이지+y)를 캡처 단계에서 기억했다가 nearestFigureMention으로 같은 페이지의 가장 가까운 언급을 원점 칩으로 지정 — arXiv처럼 참조가 hyperref인 문서에서도 복귀 UX 동작 (3초 TTL 일회성 소비)
  • dev 리베이스 1 — feature: start figure extraction when PDF loads #9 "로드 즉시 스캔"을 재작성된 피규어 아키텍처에 이식: 로드 직후 자동 ensureScanned, 스캔 세대 가드(탭), 문서 전환 시 엉뚱한 버킷 저장 방지 가드(scanFigures)
  • dev 리베이스 2 — fix: make figure previews retryable and accessible #15 "프리뷰 재시도·접근성"을 새 탭 구조에 이식: 스캔 실패 시 "다시 시도" 버튼, 상태 렌더 replaceChildren+textContent화, 실패 상태 렌더 가드. tab-figures.test.ts를 새 클래스(콜백 주입) 기준으로 재작성(3개 의도 유지), requireFigExtract·fig-engine.test.ts 수용
  • 실기기 QA F1 수정: 핀 해제 상태에서 카드 클릭이 패널을 닫아 ↩ 복귀 칩이 사라지던 문제 — jumpToFigureclosePanel() 제거 (§3 v1.1 규칙 준수; 언급 칩 복귀의 핀 OFF 닫힘은 유지)
  • 버그 수정: 텍스트 레이어 이중 표시(CSS), 캡션 라벨 언급 칩 누출(공백 무시 매칭 + 회귀 테스트)

Test plan

  • npm run typecheck · npm test · npm run build
  • dev 프리뷰 런타임 검증(표준 arXiv PDF 17p): 자동 스캔 → 내장 링크 → ↩ 칩 → 왕복 → 각주 기본 동작 → 다시 스캔
  • 실기기 QA(figure-ux.md §7.1, Mac Chrome): §7 시나리오 1·3·4·5·6 통과 — 내장 링크 무이동+↩칩(실확장 인터셉트 포함), 왕복 정렬(중앙 0.52/상단 0.17)+플래시+핀 규칙, 크롭 드래그→저장→재스캔 보존, 캡션 라벨, 줌 후 정렬 유지. F1 발견·수정. 잔여: 시나리오 2·7(링크 없는 PDF·스캔 PDF 샘플)
  • fix: make figure previews retryable and accessible #15 이식분(재시도·낡은 스캔 폐기)은 단위 테스트로 검증

Checklist

  • PR 제목이 Conventional Commits 형식 (feat: … — squash 커밋 메시지가 됨)
  • npm run typecheck · npm test 통과
  • AI-assisted (에이전트가 작성/보조한 PR이면 체크)

🤖 Generated with Claude Code

@enu3379
enu3379 requested a review from onetwothr1 as a code owner July 13, 2026 13:13
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

피규어 스캔·멘션 링크·PDF 목적지 이동·카드 UI·수동 크롭 기능을 새 구조로 통합했습니다. 캡션 앵커 및 수동 영역 병합, 세대 기반 스캔 가드, 접근성 동작과 관련 테스트·문서도 갱신됐습니다.

Changes

Figure UX 통합

Layer / File(s) Summary
Figure 데이터 및 멘션 인덱싱
src/core/figures.ts, src/core/mentions.ts, src/core/types.ts, test/figures.test.ts
캡션 앵커 정규화, figure 병합, 본문 멘션 검색·필터링·링크 주입을 추가하고 수동 영역 보존 및 캡션 회귀를 테스트합니다.
이동·목적지·크롭 primitives
src/viewer/jump.ts, src/viewer/pdf-host.ts, src/viewer/crop-mode.ts
텍스트/region 점프, PDF 목적지 해석과 내부 링크 인터셉트, 드래그 기반 PDF 영역 선택을 구현합니다.
Viewer 및 카드 UI 통합
src/viewer/main.ts, src/viewer/panel/tab-figures.ts, src/core/render-region.ts, src/viewer/viewer.css
문서 초기화부터 figure 스캔·멘션 갱신·패널 이동·크롭 저장·region 미리보기까지 연결하고 카드 중심 UI와 상태 스타일을 추가합니다.
검증 및 UX 명세 갱신
test/jump.test.ts, test/mentions.test.ts, test/tab-figures.test.ts, docs/figure-ux.md, docs/implementation-plan.md, docs/progress.md
점프 계산, 멘션 선택, 접근 가능한 카드, 재시도, 스테일 스캔 폐기를 검증하고 UX 규칙 및 QA 결과를 갱신합니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related issues

  • enu3379/PDFViewer#13 — figure 스캔 재시도, 키보드 접근성, 포커스 스타일, 관련 FiguresTab 테스트와 직접 연결됩니다.

Possibly related PRs

  • enu3379/PDFViewer#2FiguresTab의 기존 직접 추출 흐름을 callback 기반 FigureEntry 구조로 전환한 변경과 연결됩니다.
  • enu3379/PDFViewer#9ensureScanned()와 스캔 세대 가드가 PDF 로드 시점의 추출 흐름과 연결됩니다.

Sequence Diagram(s)

sequenceDiagram
  participant PDF
  participant PdfHost
  participant Viewer
  participant FiguresTab
  participant CropMode
  PDF->>PdfHost: 내부 destination 전달
  PdfHost->>Viewer: resolved destination 전달
  Viewer->>FiguresTab: figure 패널 열기 및 활성 상태 갱신
  FiguresTab->>Viewer: figure 또는 mention 점프 요청
  Viewer->>CropMode: 크롭 모드 시작
  CropMode->>Viewer: 선택한 PDF region 전달
  Viewer->>FiguresTab: crop preview 및 저장 결과 반영
Loading

Suggested reviewers: onetwothr1

Poem

토끼가 카드 위를 깡충,
캡션 길을 찾아 총총.
크롭한 풀밭 반짝반짝,
멘션 칩은 돌아왔네.
스캔 세대 헷갈리지 말고,
당근처럼 깔끔하게! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 79.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed 문서 참조·내장 링크·크롭·멘션·스테일 스캔·접근성·테스트 요구가 코드와 테스트로 반영되었습니다.
Out of Scope Changes check ✅ Passed 문서, 핵심 유틸, 뷰어, 패널, 테스트가 모두 #21의 피규어 UX 범위에 맞게 변경되었습니다.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 피규어 참조 링크, 패널 점프, 크롭 흐름이라는 핵심 변경을 간결하게 잘 요약합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/figure-ux

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

enu3379 and others added 5 commits July 13, 2026 22:24
Static + runtime review of G1-G8 passed (arXiv test paper: scan, ref
click panel flow, origin chip return, region/band flashes, crop
enter/Esc, no console errors). Card-click now keeps the panel open by
spec (v1.1) so the return chip stays reachable. Follow-ups recorded:
origin chip for hyperref-mediated opens, render-region page LRU.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The text layer is a transparent copy of the canvas glyphs; giving
mgn-ref links a text color made that copy visible and it rendered as
smeared double text over the real glyphs (and the opaque hover/active
background hid them). Keep link text transparent and mark references
with a dotted underline plus translucent tint only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The scan text concatenates pdf.js items with no separator, so page text
can lose inter-word spaces ("threereviewers" on the test paper's p.15).
Caption matching then failed, captionAnchor stayed undefined, and the
figure's own caption label was counted as a body mention (Figure 2
showed 2 mentions instead of 1). Match captions ignoring whitespace
entirely, mapping back to original offsets; add a regression test with
the measured page text. Remaining word-boundary limitation recorded as
FG-R4 in docs/figure-ux.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@enu3379
enu3379 force-pushed the feature/figure-ux branch from 554e8b7 to 5a30249 Compare July 13, 2026 13:25
enu3379 and others added 2 commits July 13, 2026 22:34
Capture the clicked annotation link's page+y in a capture-phase listener,
match it to the nearest same-page mention of the resolved figure, and pass
it as originRefKey so hyperref-opened panels get the return chip too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@enu3379
enu3379 force-pushed the feature/figure-ux branch from 5a30249 to 6fb1b66 Compare July 13, 2026 13:35
enu3379 and others added 2 commits July 13, 2026 23:27
Real-device QA: with the panel unpinned, clicking a card closed the
panel and took the return chip with it - violating the amended v1.1
pin rule (card jumps keep the panel; mention-chip return still closes
when unpinned).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
docs/progress.md (1)

74-75: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

"실기기 QA" 잔여 표현이 다소 부정확함.

figure-ux.md §7.1(같은 날짜 2026-07-13 갱신)은 이미 QA 항목 1·3·4·5·6을 통과하고 F1 버그도 수정 완료했다고 기록합니다. 실제 잔여는 §7의 2·7(샘플 미확보)뿐인데, 이 줄의 "남은 것: PR 머지, 실기기 QA"라는 표현은 실기기 QA가 전혀 진행되지 않은 것처럼 읽힐 수 있습니다. "§7 2·7(샘플 미확보) 잔여"처럼 구체화하면 더 명확할 것 같습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/progress.md` around lines 74 - 75, Update the “피규어 UX 개정” entry in
docs/progress.md to replace the broad “실기기 QA” remaining-work wording with a
precise reference to figure-ux.md §7 items 2 and 7, which remain pending because
samples are unavailable. Preserve the existing PR merge note and links.
test/tab-figures.test.ts (1)

148-148: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

console.error spy가 복원되지 않음.

vi.spyOn(console, 'error').mockImplementation(...)이 이 테스트 안에서 mockRestore()되지 않습니다. 전역 afterEachvi.restoreAllMocks() 설정이 없다면 같은 파일의 이후 테스트로 spy가 새어 나갈 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/tab-figures.test.ts` at line 148, Restore the console.error spy created
in the test around the `vi.spyOn(console, 'error')` call by invoking
`mockRestore()` during cleanup, or use the file’s existing cleanup mechanism if
one is present. Ensure the spy is restored before subsequent tests run, without
changing the test’s assertions.
src/viewer/panel/tab-figures.ts (1)

200-217: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

role="button" 요소 안에 네이티브 <button> 중첩.

preview(role=button, tabindex=0) 내부에 크롭 <button>을 넣어 인터랙티브 요소가 중첩됩니다. 이는 HTML/ARIA상 유효하지 않은 중첩으로, 스크린리더에서 크롭 버튼 인식/포커스 처리가 불안정할 수 있습니다. 크롭 버튼을 preview의 형제 요소로 분리하는 것을 권장합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/viewer/panel/tab-figures.ts` around lines 200 - 217, In the figure
preview construction, separate the crop button from the interactive preview
element created in the surrounding render logic. Keep preview as the jump target
and make the crop button its sibling rather than appending it inside preview,
preserving the existing crop action, figure identifier, label, and button
accessibility attributes.
src/core/render-region.ts (1)

19-31: 🚀 Performance & Scalability | 🔵 Trivial | 🏗️ Heavy lift

페이지 전체 렌더 대신 영역 렌더로 메모리 피크를 줄이세요

pageCanvas를 페이지 전체 크기로 만든 뒤 drawImage로 잘라내고 있어, 작은 figure도 고배율 렌더 시 큰 캔버스 메모리를 불필요하게 씁니다. pdf.js의 offset/transform viewport로 대상 영역만 렌더하면 crop 크기로 캔버스를 제한할 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/render-region.ts` around lines 19 - 31, Update the rendering flow
around pageCanvas and page.render to render only the normalized target region
using pdf.js offset/transform viewport options, rather than allocating a
full-page canvas and cropping afterward. Size the canvas directly from the
target crop dimensions while preserving the existing normalized rectangle
orientation and output behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/implementation-plan.md`:
- Around line 265-267: 상단 상호작용 규칙 R8의 크롭 진입 설명을 그림·표 탭의 ‘영역 지정’ 버튼이 아니라 카드 이미지
우상단 호버 크롭 아이콘(⌗)을 사용하는 방식으로 수정하세요. 상태 머신과 §8에 반영된 진입 동작과 일치시키고, R8의 나머지 규칙은
유지하세요.

In `@src/viewer/viewer.css`:
- Line 373: Rename the mgnJumpFlash keyframe to a kebab-case name and update
every corresponding animation reference, including the declarations near the
highlighted lines, so the `@keyframes` definition and all usages remain consistent
and pass stylelint.

---

Nitpick comments:
In `@docs/progress.md`:
- Around line 74-75: Update the “피규어 UX 개정” entry in docs/progress.md to replace
the broad “실기기 QA” remaining-work wording with a precise reference to
figure-ux.md §7 items 2 and 7, which remain pending because samples are
unavailable. Preserve the existing PR merge note and links.

In `@src/core/render-region.ts`:
- Around line 19-31: Update the rendering flow around pageCanvas and page.render
to render only the normalized target region using pdf.js offset/transform
viewport options, rather than allocating a full-page canvas and cropping
afterward. Size the canvas directly from the target crop dimensions while
preserving the existing normalized rectangle orientation and output behavior.

In `@src/viewer/panel/tab-figures.ts`:
- Around line 200-217: In the figure preview construction, separate the crop
button from the interactive preview element created in the surrounding render
logic. Keep preview as the jump target and make the crop button its sibling
rather than appending it inside preview, preserving the existing crop action,
figure identifier, label, and button accessibility attributes.

In `@test/tab-figures.test.ts`:
- Line 148: Restore the console.error spy created in the test around the
`vi.spyOn(console, 'error')` call by invoking `mockRestore()` during cleanup, or
use the file’s existing cleanup mechanism if one is present. Ensure the spy is
restored before subsequent tests run, without changing the test’s assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 16973b91-cd24-4672-adf3-bac4e27266de

📥 Commits

Reviewing files that changed from the base of the PR and between f8bfc5b and 8ae72a4.

📒 Files selected for processing (17)
  • docs/figure-ux.md
  • docs/implementation-plan.md
  • docs/progress.md
  • src/core/figures.ts
  • src/core/mentions.ts
  • src/core/render-region.ts
  • src/core/types.ts
  • src/viewer/crop-mode.ts
  • src/viewer/jump.ts
  • src/viewer/main.ts
  • src/viewer/panel/tab-figures.ts
  • src/viewer/pdf-host.ts
  • src/viewer/viewer.css
  • test/figures.test.ts
  • test/jump.test.ts
  • test/mentions.test.ts
  • test/tab-figures.test.ts

Comment on lines 265 to +267
상태 머신: `idle → armed(figId) → dragging → preview → idle`

- 진입: 그림·표 탭 상세의 버튼 — region 있으면 "영역 다시 지정", 없으면 "영역 지정". 진입 시 대상 페이지로 스크롤(기존 region 또는 캡션 위치).
- 진입: 그림·표 카드 이미지 우상단 호버 크롭 아이콘(⌗). 진입 시 대상 페이지로 스크롤(기존 region 또는 캡션 위치).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

R8(27행대) 규칙이 이번에 갱신된 크롭 진입 방식과 불일치.

이 구간에서 크롭 진입을 "카드 이미지 우상단 호버 크롭 아이콘"으로 명시했고 289행의 §8도 같은 방식으로 갱신됐지만, 상단의 상호작용 규칙 R8(변경되지 않은 27-41행 구간)은 여전히 "그림·표 탭의 '영역 지정' 버튼으로 진입"이라고 서술되어 있습니다. figure-ux.md도 "§8의 '영역 지정/다시 지정' 텍스트 버튼은 아이콘으로 대체... 계획서 §8 서술 개정 필요(G8)"라고 명시했는데, §8은 갱신됐으나 R8은 빠진 것으로 보입니다. R8 문구도 아이콘 진입 방식으로 맞춰주세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/implementation-plan.md` around lines 265 - 267, 상단 상호작용 규칙 R8의 크롭 진입 설명을
그림·표 탭의 ‘영역 지정’ 버튼이 아니라 카드 이미지 우상단 호버 크롭 아이콘(⌗)을 사용하는 방식으로 수정하세요. 상태 머신과 §8에 반영된
진입 동작과 일치시키고, R8의 나머지 규칙은 유지하세요.

Comment thread src/viewer/viewer.css
position: absolute;
z-index: 5;
pointer-events: none;
animation: mgnJumpFlash 1.2s ease-out forwards;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

stylelint 실패 방지: keyframe 이름을 kebab-case로 변경하세요.

mgnJumpFlashkeyframes-name-pattern 규칙 위반으로 stylelint 에러입니다. @keyframes 이름과 참조를 함께 변경하세요.

🔧 제안 수정
-  animation: mgnJumpFlash 1.2s ease-out forwards;
+  animation: mgn-jump-flash 1.2s ease-out forwards;
-@keyframes mgnJumpFlash {
+@keyframes mgn-jump-flash {
   0% { opacity: 1; }
   100% { opacity: 0; }
 }

Also applies to: 389-389

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/viewer/viewer.css` at line 373, Rename the mgnJumpFlash keyframe to a
kebab-case name and update every corresponding animation reference, including
the declarations near the highlighted lines, so the `@keyframes` definition and
all usages remain consistent and pass stylelint.

Source: Linters/SAST tools

onetwothr1 added a commit that referenced this pull request Jul 15, 2026
## Summary

figure-preview-test 엔진 **v2.5.1**을 byte-identical 벤더링. PDFViewer#12 메모리
대응의 **엔진 측** 작업을 land.

## Changes

- `src/core/fig-extract.js` — v2.5.1 byte-identical 복사 (엔진 repo에서만 수정,
여기선 복사)
- `figure.canvas`(페이지 전체 렌더 보관) 폐지 → `figure.cropCanvas`(그림 영역만 즉시 크롭).
figure마다 ~9.4MB scale-2.2 페이지 캔버스를 물던 상주 구조 제거 → 스캔 중 페이지 캔버스 동시 상주 **최대
1장**
  - 페이지 스캔 상한 기본값(60) 제거 — 미지정 시 전체 페이지 스캔, `opts.maxPages`는 선택적 상한으로 유지
- `opts.signal` abort 시 진행 중 페이지 렌더도 `RenderTask.cancel()`로 즉시 중단 (페이지
경계 대기 제거)
- `src/core/fig-engine.ts` — `EngineFigure.canvas`→`cropCanvas`,
`maxPages`·`signal` 주석 동기화
- `docs/fig-extract-integration.md` — 크롭 캔버스 수명·취소 가이드 갱신 (호스트가 문서 교체 시
signal abort 필수임을 명시)
- `test/*` — mock figure의 `canvas`→`cropCanvas`

## #12 acceptance criteria

- [x] Full-page canvases are not retained for every figure-bearing page
after previews are produced — `cropCanvas`로 대체, 페이지 캔버스 미보관
- [x] Engine changes are made upstream first, then vendored
byte-identically with a version bump — 엔진 repo v2.5.1 후 byte-identical
벤더링
- [x] `npm run typecheck` · `npm test`(25) · `npm run build` 통과
- [ ] Peak retained page render surfaces bounded (LRU) — 엔진 피크는 1장으로
bound. Margin `render-region.ts` LRU 3장은 후속
- [ ] Document replacement cancels the previous extraction — 엔진 메커니즘
완비(signal + in-flight 렌더 취소). **`main.ts`가 `AbortController`로 signal
전달·abort하는 wiring은 후속** (#17 머지 후)
- [ ] Preview Blob/Object URLs revoked — Margin 측 (현행 dataURL 캐시
`setDocument` clear로 충족 검토)
- [ ] Long figure-heavy PDF memory QA documented — 후속

## Test plan

- [x] `npm run typecheck`
- [x] `npm test` (6 files, 25 tests)
- [x] `npm run build`
- [ ] 런타임 스캔 검증 — 벤더 엔진은 탐지·bbox 로직 무변경(엔진 repo에서 patch로 판정, 물리 diff 0
기대). Margin 통합 런타임은 후속 wiring PR에서

## Notes

후속 Margin wiring(`main.ts` signal 전달, `render-region.ts` LRU, 메모리 QA)은
**#17(figure-ux) 머지 후** 별도 PR. 이 PR은 엔진 vendoring + 타입/문서 동기화만.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **개선 사항**
  * 문서 전체 페이지를 기본으로 스캔하도록 `maxPages` 동작을 개선했습니다.
  * 작업 취소 시 진행 중인 페이지 렌더링이 즉시 중단됩니다.
  * 그림별 크롭 캔버스를 사용해 미리보기 생성과 메모리 관리 효율을 높였습니다.
  * 중복 그림을 더 일찍 제거하고, 불필요한 페이지 전체 캔버스 보관을 줄였습니다.
* **문서**
  * 취소 처리와 캔버스 수명 관리 규칙을 최신 동작에 맞게 업데이트했습니다.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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.

1 participant