feat(review): local browser review app + demo release candidate#24
Open
shaypal5 wants to merge 4 commits into
Open
feat(review): local browser review app + demo release candidate#24shaypal5 wants to merge 4 commits into
shaypal5 wants to merge 4 commits into
Conversation
- Add `hletterscriptgen review <letter_set.json>` CLI subcommand that serves
a single-page review UI at localhost:8765 (configurable with --port).
- `src/hletterscriptgen/reviewer.py`: builds an HTML page that embeds all
glyph images as base64 data URIs; no external CDN deps, pure stdlib HTTP
server.
UI features:
- Sticky header with writer ID, generation date, and live progress bar
- Sticky letter sidebar with per-variant verdict dots (green/red/orange)
- Per-variant cards: pixelated glyph image, metadata table (size, ink_ratio,
source entry, bbox, license), verdict buttons (Accept/Reject/Changes),
comment textarea, Save button
- `GET /feedback` / `POST /feedback` auto-persist to
`.review_feedback.json` next to the letter-set file
- "Export" button downloads feedback JSON; "Accept all unreviewed" bulk action
- IntersectionObserver-driven sidebar highlight on scroll
- Unsaved-changes guard on page unload
- `scripts/make_demo_candidate.py`: stdlib-only synthetic glyph generator
(zero extra deps beyond what the project already uses for tests). Draws
15 Hebrew letter shapes (Alef–Tav) using Bresenham line strokes, produces
29 PNG crops across 2-3 size variants per letter, writes a schema-valid
`letter_set.v1` document.
Usage:
python3 scripts/make_demo_candidate.py
hletterscriptgen review examples/demo_candidate/demo_writer_0001/letter_set.json
- `tests/test_reviewer.py`: 37 tests covering utility functions, HTML
builders, HTTP GET/POST handler, and CLI error paths; no flaky threading
issues (one-shot `handle_request()` per test).
- `pyproject.toml`: suppress RUF001 on reviewer.py (intentional Hebrew
character dict keys).
Tests: 175 pass, coverage 91.26%, ruff+mypy clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ns to hash (#25) HeOCR/public-domain-hand-written-hebrew-scans was renamed to HeOCR/hash (HASH — Hebrew Archive of Scanned Handwriting). Update all references across source, tests, fixtures, docs, and examples. Also update segmentation-approach.md with current corpus size: 373 entries, 111 sources, 48 unique creators (was 60 entries at spike time). Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix class-level shared state on _ReviewHandler: create a fresh _Handler subclass inside serve() per invocation so state is never shared across server runs or concurrent tests. - Fix atomic feedback write: write to a .tmp sibling then replace() so a killed process never leaves a corrupt .review_feedback.json. - Fix HTML/JS injection: replace all inline onclick/oninput handlers with event delegation driven by data-vid/data-verdict attributes; HTML-escape all user-controlled values with html.escape() in attribute contexts. - Remove dead feedback_path parameter from _build_html(); it was accepted but never referenced inside the function. - Serve images via /image/<vid> HTTP endpoint instead of base64-embedding every asset into the HTML; _build_sections now returns an images_map and the handler routes /image/* lookups through it (dict lookup prevents path traversal). - Wrap bare dict key access in _build_variant_card with try/except raising ValueError with a descriptive message. - Drain POST body before sending 404 to avoid TCP RST / ConnectionResetError on unknown paths. - Fix tests: fresh per-test handler subclass in _start_one_shot_server so no state leaks between cases; update all callers for new API signatures; add tests for /image/ endpoint, atomic write, data-attribute HTML, and malformed variant error. - make_demo_candidate.py: import __version__ instead of hardcoding "0.1.0.dev0"; remove redundant inline imports (zlib/struct already at module top); remove unused letters_dir variable; clarify why _ink_ratio is not imported from extractor (stdlib-only constraint). - cli.py: replace unreachable parser.error() with AssertionError to satisfy mypy while making the invariant explicit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a fully-featured local browser review UI for surveying a
letter_set.jsonrelease candidate, plus a synthetic demo candidate to review immediately.New:
hletterscriptgen reviewCLI subcommandhletterscriptgen review examples/demo_candidate/demo_writer_0001/letter_set.json # → opens http://localhost:8765/Review UI features
.review_feedback.jsonnext to the letter-set on every SaveNo external CDN deps — single-page app, all images inline as base64, pure stdlib HTTP server.
New:
scripts/make_demo_candidate.pyGenerates
examples/demo_candidate/with 29 synthetic PNG glyph crops across 15 Hebrew letters (Alef–Tav), drawing each with a stdlib-only Bresenham line renderer (zero extra deps). The resultingletter_set.jsonis schema-valid and ready to review.Files changed
src/hletterscriptgen/reviewer.pysrc/hletterscriptgen/cli.pyreviewsubcommandtests/test_reviewer.pyscripts/make_demo_candidate.pyexamples/demo_candidate/letter_set.json)pyproject.tomlTest results
🤖 Generated with Claude Code