7-task plan for bottom-sheet responsive redesign covering HTML restructuring,
desktop/mobile CSS, sheet snap behavior, tab switching, and integration.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Add touch-action: none to #right-panel for reliable custom
touch handling
- Show delete button on mobile (no hover state on touch devices)
Co-Authored-By: Claude Opus 4.6 <[email protected]>
CSS-responsive approach with tab-based navigation at ≤768px,
full-screen solver modal, and single-finger touch pan.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Replace redaction marker span with editable input for manual guesses
- Typing in the guess field sets r.preview and shows Accept button
- drawRedactionPreview now renders left+guess+right as continuous text
with natural font kerning (no fixed gap width during preview)
- Active preview: green left, yellow highlighted guess, green right
- Inactive preview: full merged text in yellow
Co-Authored-By: Claude Opus 4.6 <[email protected]>
The approved draw function was only drawing text with no overlay on the
redaction box area, making it look like the redaction disappeared.
Now draws a blue semi-transparent box over the redaction area (like
other states) plus the merged blue text along the line.
Also made the approved CSS badge green (--accent) to distinguish it
from the blue analyzed badge.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Delete inline-edit.js and all references
- Remove backspace/delete key handler for redaction deletion
- Clean up popover.js syncInlineEdit references
Co-Authored-By: Claude Opus 4.6 <[email protected]>
analyze_spot_redaction is now async and calls identify_boundary_text()
to use Claude Haiku for clean left/right text extraction instead of
center-point character filtering. Falls back to center-point if LLM
is unavailable.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Missed files from the inline text editing task — adds the inline-edit
module and wires up bidirectional sync between popover text bar and
inline canvas inputs.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Enrich POST /api/doc/{doc_id}/page/{page}/spot to call
analyze_spot_redaction when OCR data is cached, returning full
analysis JSON (segments, gap, font, line, offsets) alongside the
bounding box. This makes spot redactions first-class, matching the
analysis format returned by get_page_data for auto-detected redactions.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add a synchronous function that runs the analysis mini-pipeline on a
single known bounding box using cached OCR data. This enables spot
redaction endpoints to get full analysis (font, left/right context text,
pixel alignment offsets) without needing LLM detection.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add an ocr_lines slot (initially None) to each page's data dictionary
in the upload endpoint. This prepares for OCR caching so results can
be reused between the auto-detect and spot-redaction pipelines.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Captures the plan to decouple auto-detection from upload, make manual
(double-click) redactions first-class with full analysis, and move to
inline-on-canvas editing.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
The rename from solveFilterPrefix/Suffix to solveKnownStart/End missed
associates.js, breaking the entire JS module tree and disabling upload.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Replaced test_solve_endpoint_dictionary and test_dictionary_crud with
test_solve_endpoint_name_mode testing the new name mode.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Modes: name (default), full_name, email, enumerate
Renamed filter_prefix/suffix to known_start/known_end
Removed DictionaryStore and dictionary API endpoints
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Renamed solveFilterPrefix/Suffix to solveKnownStart/End. Word filter
label hidden by default, shown only when enumerate mode is selected.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Modes: Name (default), Full Name, Email, Enumerate
Charsets: lowercase, UPPERCASE, Capitalized
Renamed filter prefix/suffix to known start/end
Word filter hidden by default (shown only for enumerate mode)
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Replaces uppercase_only bool with casing string parameter. Adds
known_start/known_end support for filtering and gap-width measurement.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Supports casing (lowercase/uppercase/capitalized), known_start/known_end
filtering with gap-width measurement of the unknown portion only.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Generate first x last name combinations from associate lists, apply
Title Case or UPPER casing, measure rendered widths, and return matches
within tolerance. Also checks associate name variants (initials,
nicknames) with deduplication.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
The full-name solver collected all results into a Vec with no limit,
causing OOM crashes for realistic targets where millions of valid
first×last combinations exist. Thread max_results through
solve_subtree, dfs_first, and the Cartesian product loop so the
search stops early once enough results are found.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Thread EquivClasses and deduped_allowed through solve_subtree, dfs,
generate_prefixes, handle_solve, and dfs_first (full_name). The DFS
hot loop now iterates deduped representatives instead of all allowed
chars, and expand_match restores full class-member variants at match
time. This reduces branching factor for charsets with metrically
identical glyphs while preserving complete result sets.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Foundation for glyph equivalence class optimization. Groups charset
characters with identical metric signatures (width table columns/rows,
left/right edges, optional extra columns) into equivalence classes
using exact f64::to_bits() comparison. Includes 3 unit tests covering
duplicate detection, all-unique case, and extra column splitting.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Group metrically identical characters into equivalence classes to reduce
the DFS branching factor from N to K per node, with Cartesian product
expansion on matches to recover all solutions.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Replace the click-to-analyze and spot-detection flows with an automatic
SSE-driven analysis pipeline. After upload, an EventSource connects to
/api/doc/{id}/analyze and reloads page data as each page completes,
consuming pre-computed analysis from the page data endpoint.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Replace the old /api/redaction/analyze and /api/redaction/spot endpoints
with a new /api/doc/{id}/analyze SSE endpoint that pre-computes all
analysis during upload. The page data endpoint now returns pre-computed
analysis results instead of requiring per-redaction API calls.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Wire together the per-page pipeline: OCR -> LLM redaction detection ->
guided OpenCV search -> font detection with masking -> pixel alignment.
Includes font caching per line and progress callbacks.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Adds a new detect_font_masked() function that masks redaction boxes to
white (255) before running pixel-based font detection on the full line
crop. This replaces the fragile approach of cropping just the left/right
portion of a line, which lost signal from narrow crops and coordinate
mismatches. The Dice-based scoring naturally ignores masked (white)
regions since they contain no ink pixels.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add find_redaction_in_region() that searches for a black rectangle
within a specific page region identified by the LLM. Uses a lower
minimum area threshold (100px vs 500px) since the LLM provides
spatial guidance, preventing merged redactions and false positives.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Introduce llm_detect.py that sends OCR lines to Claude Haiku to identify
redaction locations via broken text patterns (garbled chars, brackets,
pipes). The LLM returns boundary words which are mapped back to pixel
positions using OCR character data. Includes comprehensive tests covering
single/multiple redactions, line start/end edge cases, and error handling.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Instead of using a neighboring line (which may have a different font/size,
e.g. email header vs body text), crop the non-redacted left or right
portion of the actual redacted line for font detection. Falls back to
clean neighbor lines only when neither side has enough text (>=50px).
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Replace OCR-based offset calculation with pixel alignment that slides
rendered text across the page image to find the exact position with
maximum Dice overlap. Also fix char filtering to use center-point
(c.x + c.w/2) instead of right-edge, recovering characters like "nt"
in "Sent" that partially overlap the redaction box.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Redaction boxes corrupt OCR text and add spurious dark pixels that
break pixel-based font scoring. Now uses wider crop padding (3x)
and prefers the nearest non-overlapping line for font detection.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Replace word-width MAE scoring with pixel-overlap Dice scoring in both
_full_search() and _fine_search(). Both functions now accept a line_crop
parameter and use _score_font_line_pixel() instead of _score_font_line().
Comparisons are flipped (higher is better). The size range is now derived
from the OCR line height instead of the fixed SIZE_RANGE constant, and
uses step=1 since pixel scoring has sharp peaks at the exact font size.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add _score_font_line_pixel() which renders candidate text and compares
pixels against the actual page image using Dice coefficient overlap.
This captures glyph shape differences that the old word-width MAE
approach cannot distinguish (e.g. serif vs sans-serif).
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Centralize 21 repeated color values into :root variables.
Makes theme changes trivial and improves readability.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Reorganize the monolithic 1,436-line frontend into 9 focused modules:
types, state, dom, canvas, viewport, associates, popover, solver, main.
No build step — browsers load ES modules natively. JSDoc @typedef
annotations provide type safety via @ts-check + jsconfig.json.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Without flex properties, #viewer-section collapsed to content
height (just the controls bar), giving the workspace 0 height
and causing zoom to compute as 0%.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Remove unused detect_redactions import from app.py
- Add de-duplication check in dblclick handler to prevent
creating duplicate redaction entries for the same dark region
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Shift+drag now adjusts gap width (was ctrl+shift+drag).
Manual redaction marking via shift+drag is removed;
users now double-click to spot-detect redactions.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Extract inline analysis logic from the analyze endpoint into a reusable
_run_analysis() helper function, then add a new /api/redaction/spot
endpoint that chains spot_redaction detection with analysis in one call.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Uses OpenCV connected components to find a dark region at a specific
click point, complementing the existing detect_redactions() which
auto-detects all redaction bars via morphological operations.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Adds green segment overlay, floating font toolbar, bottom text edit
bar, and backend offset guess to the redaction-centric UI.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Hold Shift and drag on the canvas to draw a custom redaction
rectangle. Creates an unanalyzed redaction entry that triggers
on-demand OCR when clicked.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Replace line list with redaction list, add canvas-native redaction
overlays with hit-testing, popover with on-demand analysis and
solver integration. Remove old font/segment/overlay controls.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
When a user clicks a redaction, this endpoint crops the surrounding line,
runs Tesseract OCR, detects the font, and returns text segments (before/after
the redaction), gap width, font info, and character-level bounding boxes.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Replace upfront OCR + font detection + overlay rendering with lightweight
OpenCV-based redaction detection. Upload now just rasterizes and detects
black rectangles, making it significantly faster. Remove the overlay
endpoint and update the data endpoint to return redaction bboxes.
Co-Authored-By: Claude Opus 4.6 <[email protected]>