Alias and dedupe pdfjs-dist so GlobalWorkerOptions.workerSrc set in main.tsx
reaches getDocument in the linked evidence-source package; allow sibling fs roots.
Cut review mode over to the extracted citation-work package instead of a local
src/work/ implementation.
- Add @citation-evidence/work as a link: dependency
- Repoint the @work alias (tsconfig + vite) to ../citation-work/src/work and
allow vite fs access to the sibling
- Remove the local src/work/ implementation (now owned by citation-work)
Typecheck, lint, and the full test suite (51 tests) pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cut over the binder subsystem to the extracted @citation-evidence/
evidence-binder repo. The @binder alias (tsconfig + vite) now points at
../evidence-binder/src, the duplicate src/binder/ tree is deleted, and
vite fs.allow is widened to serve the sibling checkout.
No app code changed — all imports were already via the @binder alias.
typecheck + lint green, 58 tests passing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the in-repo src/anchor/ slice with a dependency on the extracted
@citation-evidence/evidence-anchor package (link:../evidence-anchor).
- package.json: add the link dependency
- repoint all @anchor/{index,selectors,types} imports and vi.mock targets to
the package barrel; the node-env anchor-source-roundtrip test uses the pure
./selectors and ./types subpaths (no pdfjs pulled into a node environment)
- drop the @anchor alias from tsconfig paths and vite resolve
- delete src/anchor/ (behavior now owned by evidence-anchor)
Verified green: pnpm typecheck, pnpm test (26 files / 95 tests), pnpm build.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Strong likelihood that the "text layer is misplaced / body text not
selectable" symptoms across multiple PDFs come from PDF.js falling
back to substitute font metrics. Without the cmaps directory (CID
character maps for non-Latin fonts) and the standard_fonts directory
(Helvetica/Times/Courier metrics for unembedded standard fonts), the
canvas glyphs use embedded font data while the text-layer span
positions are computed from fallback metrics. The two diverge — text
spans land in the wrong place, or text content can't be decoded at
all, leaving the body unselectable.
Both directories are now copied into the served root by
vite-plugin-static-copy and passed to pdfjs.getDocument() as
`cMapUrl: "/cmaps/"` + `cMapPacked: true` + `standardFontDataUrl:
"/standard_fonts/"` via PdfLoader's `document` prop (which accepts a
full DocumentInitParameters object).
If this is the right diagnosis, the textLayer overlay should now line
up with the visible glyphs on the same PDFs that were producing
fragmented captures. If the body text is still unselectable, the PDF
genuinely lacks a text layer for those glyphs (image-only content)
and OCR would be the only path forward.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
T01: shared engine types (Document, Selector union, Annotation, EvidenceItem,
branded IDs with newId factory) per wiki/SharedContracts.md §1-§3.
T02: react-pdf-highlighter-plus v1.1.4 spike behind the §5
DocumentViewerAdapter contract in src/anchor/. Pure round-trip math
extracted to pdf-selector-math.ts with 11 unit tests proving lossless
capture → selectors → JSON → restored-rects. ADR-0004 accepted; full
user-flow Playwright verification deferred to T09.
Adds Vite app shell (index.html, src/app/SpikeApp.tsx) so the spike is
exercisable via pnpm dev. tsconfig --noEmit prevents tsc -b from
littering src/ with stray .js outputs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>