feat(citation): add ≈ approximate-match marker and popover polish#428
feat(citation): add ≈ approximate-match marker and popover polish#428bensonwong merged 11 commits intomainfrom
Conversation
… contain Drops acquireScrollLock/releaseScrollLock from usePopoverViewState (and the isOpen param that gated it). The popover now sets overscrollBehavior: contain on its container, which natively absorbs wheel/touch momentum at its edges without layout shifts or body padding hacks. Removes SCROLL_LOCK_LAYOUT_SHIFT_EVENT listener from Popover.tsx and cleans up scroll lock tests and mocks. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces a boolean `isApproximate` prop (claimText !== sourceMatch) that flows from DefaultPopoverContent/CitationDrawer down to HighlightedSourceContext. When set, a ≈ glyph appears beside the highlight span and turns amber on hover (via Tailwind's named group-hover/anchor variant). The annotation row now reads "claimed as …" instead of "(displayed as …)" to better reflect intent. Renames i18n key `popover.displayedAs` → `popover.claimedAs` across all locale files (en, es, fr, vi). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove border-radius from cowork notice and claim blocks for a sharper, document-like appearance. Change claim left-border and label color from --dc-primary to --dc-foreground / --dc-muted-foreground to reduce visual noise on the static HTML export. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ed step fns capture-snapshot.ts: uploads a source PDF, re-keys fixture citations onto the fresh attachmentId, calls verifyAttachment, and writes a *-snapshot.json to output/ so template.ts can re-render without hitting the API again. template.ts: loads a snapshot (newest by mtime, by safeName, or by explicit path), calls renderVerifiedHtml, and writes an HTML file. Accepts --md= to substitute hand-edited visible text for quick copy iteration. shared.ts: exports stepUpload / stepWrapPrompts / stepCallLlm so both step-runner and capture-snapshot share the same pipeline logic. Also replaces report.shareUrl with a constructed deepcitation.com portal URL. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- DefaultPopoverContent/PopoverFallbackView: align isApproximate to use citation.sourceMatch (not verification.sourceSnippet) so both code paths compare the same field - DefaultPopoverContent/PopoverFallbackView: use precomputed isApproximate in annotation row instead of inline condition - DefaultPopoverContent: incorporate annotation div layout polish (flex items-center, adjusted margins, text-md ≈ glyph) - HighlightedSourceContext: motion-safe:transition-colors + group-focus-within so ≈ marker respects prefers-reduced-motion and responds to keyboard focus - capture-snapshot: whitelist allowed providers before path interpolation to prevent directory traversal Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 4 Skipped Deployments
|
✅ Playwright Test ReportStatus: Tests passed 📊 Download Report & Snapshots (see Artifacts section) What's in the Visual SnapshotsThe gallery includes visual snapshots for:
Run ID: 24472095998 |
Code ReviewOverall this is a clean, well-scoped PR. The approximate-match marker idea is solid, the Tailwind Bug:
|
…ortBody Render remaining report sections flat instead of inside a <details> wrapper. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ndering Details wrapper and "Full Report" summary were removed; tests now assert flat section order and the absence of <details>. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add ./html-utils package export for generateReviewVariants and ReportStyle, making the report generation API accessible without importing from the CLI path. Also make the approximate citation marker (≈) always amber rather than revealing only on hover/focus. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tsup.config.ts and package.json exports reference html-utils but the source file was missing from this branch (added on main in #428). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(deepcitation): export renderVerifiedHtml from public API * feat(sdk): replace publishVerificationReport with createReport; add report CLI command * fix(viewTransition): defer CDN repositioning until animation completes; fix transitionDepth decrement timing CDN scheduleReposition now polls isViewTransitioning() in a rAF loop instead of firing reposition() immediately — prevents a mid-animation reposition that was snapping the popover before the collapse ghost finished. _transitionDepth is now decremented inside the onDone callback fired when both animations (ghost + content reveal) finish, rather than before the animation starts. This means isViewTransitioning() stays true for the full duration of the collapse, keeping the CDN deferral loop active throughout. * feat(markdownToHtml): add claim card + MODEL meta item; remove audience preset Header now renders an optional claim card (blockquote with eyebrow label) between the H1 and the meta strip when options.claim is provided. Inline markdown (bold/italic/code) is formatted; HTML is escaped; whitespace-only values are silently ignored. The AUDIENCE meta item is replaced by MODEL, shown when options.model is set. The audience feature (AUDIENCE_PRESETS, AudiencePreset, AUDIENCE_CONFIG, --audience CLI flag) is removed entirely — width and tier2Open are hardcoded to their general-preset values (960px / true), keeping the output unchanged for existing callers. * chore: delete teardown-v14.png; downgrade tsconfig.jest ignoreDeprecations to 5.0 teardown-v14.png was a leftover debugging screenshot. ignoreDeprecations "6.0" was a forward-looking value that TS 5.x doesn't recognize — reverted to "5.0" which matches the installed compiler. * fix: make onDone required in runPageCollapseGhostAnimation; add scheduleReposition circuit-breaker onDone was optional but the only call site always passes it — optional chaining was masking an invariant. Making it required lets TypeScript enforce that _transitionDepth will always be decremented by callers. scheduleReposition now accepts a retriesLeft counter (default 30 ≈ 500 ms at 60fps) so the rAF polling loop self-terminates if _transitionDepth ever gets stuck, falling through to reposition() rather than looping indefinitely. Update cdnPopover source-invariant test to match the new call-site signature. * refactor: fix scheduleReposition event-handler bug; clean up minor quality issues scheduleReposition was used as an event listener for resize/ResizeObserver. The default-parameter circuit breaker (retriesLeft = 30) was bypassed because event listeners receive an Event object as the first argument — Event > 0 is NaN, so the retry condition was always false during resize-triggered repositions. Split into a clean public scheduleReposition() (no params) and a private deferReposition(retriesLeft) that owns the retry loop. Also: remove unnecessary `as boolean` cast from cfg literal; fix leading whitespace in claimCard template literal (would have been emitted verbatim in HTML output); remove stale "AUDIENCE hidden on default general" comment from test (audience feature was removed on this branch). * fix(ci): resolve lint-and-validate and test failures - Replace deprecated moduleResolution "node10" with "node16" in tsconfig.jest.json to fix TS5107 errors with TypeScript 6.x in CI - Fix biome formatting: remove trailing blank lines, sort imports - Complete markdownToHtml CSS token refactor (DC_ROOT_TOKENS variables) - Add Test Failure Policy to engineering-rules.md * fix(ci): restore ignoreDeprecations "6.0" for TS6 moduleResolution compat TypeScript 6.x normalizes module:CommonJS + any nodeX resolution to node10 semantics internally and emits TS5107. The only suppressor is "ignoreDeprecations": "6.0" — as the error message itself instructs. Reverts the node16 attempt (no effect on TS5107 with CommonJS module). * fix(animation): anchor page-expand ghost to annotation position via data attrs - EvidenceKeyhole now sets data-dc-source-anchor-x/y on the keyhole element so buildGhostTarget can compute imageOffsetLeft + anchorX×imageW instead of always using the viewport center (srcW/2, srcH/2). Fixes ghost overshoot when a width-filled image has annotation off-center. - buildGhostTargetFromViewport keeps viewport-center anchor (miss/not_found has no annotation; fall through to srcW/2 is correct there). - Add will-change: filter to ghost container for blur compositor hint; add will-change: transform to ghost img to avoid per-frame repaints. - Locate-icon pulse: slower timing (120/80ms), neutral --dc-muted-foreground color, style moved to button so transform applies at button level. - Pulse stage renamed grow→flash; update Playwright assertions accordingly. - tsconfig.jest.json: upgrade moduleResolution to node16, drop ignoreDeprecations. * wip: animation debug tooling (taking over from worktree) * fix(animation-debug): address review findings - Remove vt-expand/vt-collapse from FROZEN_KINDS (no call sites yet) - Drop NODE_ENV guard from installConsoleApi so CT env installs it - Add define to playwright-ct.config.ts to ensure dev mode in Vite - Add evidence.textItems + verifiedSourceMatch to harness fixture so resolveEvidenceSourceAnchorRatio returns a non-null anchor ratio - Switch toBeVisible → toBeAttached for 0×0 aim overlay container - Rename misleading test name for scaleDuration edge-case test - Delete src/html-utils.ts (dead re-export, no importers) * refactor(animation-debug): simplify debug store and harness - Export stepAnimation/pauseAnimation/playAnimation from store directly - Replace window.__dcAnimationDebug casts in ControlBar with store calls - Remove redundant serverSnapshot wrappers; pass getDebugSnapshot directly - Inline serverFalse lambda in AimOverlay - Replace useState+useEffect imageSrc with useMemo in AnimationDebugHarness - Add RAF equality guard to prevent spurious re-renders in AimAlignmentPanel * fix(animation-debug): add missing type field to harness citation fixture * fix: add missing src/html-utils.ts entry point tsup.config.ts and package.json exports reference html-utils but the source file was missing from this branch (added on main in #428). * fix(ci): restore ignoreDeprecations "6.0" for TS6 moduleResolution compat
Summary
≈marker to citation highlights, keyhole strips, and drawer items when the model's inline display text (claimText) differs from the matched source text (sourceMatch) — surfaces approximate citation matches visually without hiding thempopover.displayedAs→popover.claimedAsand updates copy to "claimed as …" across all locales (en, es, fr, vi)≈hover effect inHighlightedSourceContextusing a Tailwindgroup/anchorpattern so the marker dims at rest and turns amber on hover/focusmarkdownToHtmlreport shell: removesborder-radiusfrom cowork notice, removesborder-radius+border-leftprimary color accent from the claim block (uses--dc-foregroundinstead), and drops the unusedtier2Openprogressive-disclosure flagusePopoverPositionandEvidenceTrayin favor ofoverscroll-behavior: containcapture-snapshot.tsandtemplate.tstoexamples/basic-verificationfor one-shot snapshot capture and local re-render of verified output (debugging/dev aid); exports shared step helpers fromshared.tsusePopoverViewStateunit tests that duplicated integration-level coverageTest plan
claimTextdiffers fromsourceMatch— confirm≈appears beside the highlight in the popover and keyhole strip, and "claimed as …" annotation appears belowclaimTextequalssourceMatch— confirm no≈marker appears anywhere≈turns amber; move away — confirm it returns to subtle≈and "claimed as …" appear in the drawer item footer when applicablemarkdownToHtmlreport output and confirm claim block has no rounded corners and uses foreground accent colornpm test— all remaining tests pass