Skip to content

Review: LexiconForge recent 41 commits#28

Merged
anantham merged 54 commits intoreview/recent-developmentfrom
main
Apr 4, 2026
Merged

Review: LexiconForge recent 41 commits#28
anantham merged 54 commits intoreview/recent-developmentfrom
main

Conversation

@anantham
Copy link
Copy Markdown
Owner

@anantham anantham commented Apr 3, 2026

Summary

Retroactive review of 41 recent commits including:

  • Translation engine: read-only language fields, diff markers fix
  • Auto-generate images toggle
  • Provider panel tests
  • Prompt amendment proposals

@codex please review

🤖 Generated with Claude Code

orpheuslummis and others added 30 commits February 4, 2026 17:16
crypto.randomUUID() requires a secure context (HTTPS or localhost).
Add a typeof check with Date.now + Math.random fallback so the app
loads when accessed via plain HTTP on a network IP.
Add a "Paste Text" tab to InputBar alongside the existing "From URL"
tab. Users can paste raw text with a title and source language for
reading and translation, bypassing the URL fetch pipeline entirely.

The new importCustomText store action constructs an ImportedChapter
with a synthetic URL (custom.lexiconforge.local), runs it through
the existing transformImportedChapters pipeline, persists to IndexedDB,
and merges into the Zustand store — same path as URL-fetched chapters.
The heading, subtitle, and divider were all URL-specific, which
doesn't make sense when the Paste Text tab is active.

- "OR START FROM A URL" → "OR START FROM SCRATCH"
- "Translate Any Web Novel Chapter" → "Translate Any Text"
- "Paste a URL from supported sites..." → "Fetch from a supported
  site or paste your own text"
The default viewMode is 'english', which shows translationResult.translation.
Since freshly imported custom text has no translation yet, the content area
appeared empty. Now we switch to 'original' view after import so the user
immediately sees their pasted text.
MOTIVATION:
- Doc audit revealed 45 findings (1 P0, 12 P1, 29 P2, 3 P3) including
  contradictory file-size policies, stale architecture docs describing
  completed decompositions as pending, dead links in onboarding, broken
  test manifest, and orphaned plan files.

APPROACH:
- Reconcile the three-way file-size policy conflict (AGENTS.md hard limit
  vs CONVENTIONS.md friction-based vs check-loc.js thresholds) — friction-
  based policy in CONVENTIONS.md is now authoritative.
- Update ARCHITECTURE.md §4.5/§5/§7 to reflect completed decompositions
  (compiler, navigation, adapters, demoPacket) and fix ghost component
  references (ParagraphRenderer, IllustrationPlaceholder, etc.).
- Migrate active REFACTOR_CANDIDATES watchlist items into ARCHITECTURE.md
  §7 before archiving; update all referencing docs.
- Rebuild TEST_MANIFEST.md from scratch: 122 test files cataloged
  (was 47 with 74 missing and 13 ghost entries).

CHANGES:
- AGENTS.md: Fix STOP_CONDITIONS, REQUIRED_READING, bump to v2.1.0
- docs/CONVENTIONS.md: Fix §11 stale entries, add PascalCase divergences
- docs/ONBOARDING.md: Fix dead links, align LOC guidance
- docs/START_HERE.md: Fix LOC claim, expand ADR index
- docs/architecture/ARCHITECTURE.md: Rewrite §4.5, §5, §7, §8
- docs/adr/FEAT-001: Add missing Status header
- docs/adr/SUTTA-006: Fix title (was "SUTTA-004"), status → Implemented
- docs/features/NOVEL_LIBRARY.md: Document hybrid registry/catalog state
- docs/features/IMG2IMG_TESTING.md: Fix steering image path
- docs/guides/META_ADAPTER.md: Fix adapter file paths
- docs/infrastructure/TEST_MANIFEST.md: Full rebuild from disk scan
- docs/roadmaps/README.md: Mark completed/archived items
- docs/roadmaps/TECH-DEBT-STATUS.md: Update REFACTOR_CANDIDATES ref
- scripts/check-loc.js: Add clarifying comment re: policy authority
- Archive: COMPONENT-DECOMPOSITION-PLAN, REFACTOR_CANDIDATES, 3 plans

IMPACT:
- Agents now receive consistent file-size guidance
- New contributors hit no dead links in onboarding flow
- Architecture docs accurately reflect current codebase state
- Test manifest is a complete, trustworthy inventory

TESTING:
- All changes are documentation-only (no logic changes)
- Verified file moves via git status
- TEST_MANIFEST count (122) verified against disk scan

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- SUTTA-003: Status → Implemented (MVP), add implementation notes
  listing all key files (compiler, UI components, caching, benchmarks)
- SUTTA-005: Status → Implemented, add impl notes (leaderboard.json,
  generate-leaderboard.ts, benchmark UI all confirmed)
- FEAT-003: Add implementation notes confirming architecture as-built
- ImageGeneration.md: Update steering image list from 4 → 21 (loaded
  from public/steering-images.json manifest)
- STEERING_IMAGE_TEST.md: Archive to diagnostics (one-time test result)
- MEMORY_OPTIMIZATION_ROADMAP.md: Verify against code — Phase 1+2
  mostly implemented (telemetryService, imageCacheService used by 17
  files, imageMigrationService with tests, storage diagnostics UI).
  LRU eviction (Task 10) and isBlobUrl type flag (Task 3) not adopted.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace derived `hasSession` screen routing with explicit `appScreen`
state machine (`library | reader-loading | reader`). Split initializeStore
into named phases (settings, boot repairs, deep-link intent, hydration,
services). Cold boot always lands on library — no auto-resume.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add libraryScope.ts for consistent novelId::versionId key generation.
Schema v15 adds novelId indexes on chapters and url_mappings (also fixes
v13 omission). Scoped stableIds prevent cross-version chapter/translation
aliasing. ChapterRecord.novelId is now `string | null`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Single readerHydrationService replaces 4 duplicated hydration paths.
ImportService threads registryNovelId and registryVersionId through
the full import pipeline. Scoped storage URLs prevent cross-version
cache collisions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BookshelfStateService manages per-novel (per-version) reading position
with stale-bookmark fallback chain (lastChapterId -> lastChapterNumber
-> chapter 1). Debounced 2s auto-save on chapter change in chaptersSlice.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Continue Reading section shows shelved novels sorted by last read time.
Home/Library button in reader header shelves active novel and returns to
library. InputBar auto-shelves active novel before URL-paste. NovelCard
gains progress badge and resume label. Version picker backed by real
storage isolation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Navigation layer respects activeNovelId and libraryVersionId. Scoped
cache lookups prevent cross-version bleed — a cache miss for Version A
won't silently serve Version B's chapters. Deep links compose
sequentially: ?novel imports, then ?chapter navigates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CLI scripts for building library session files from raw + fan translation
sources. Chapter alignment discovery matches chapters across sources by
number and content similarity. Independent from the shelf UI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update test fixtures to include libraryVersionId on EnhancedChapter and
related types. Assertion updates for schema v15.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Record book-switching shelf design spec, implementation plan, and
raw-source-discovery spec. WORKLOG entries for version-aware storage
work and git cleanup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update TECH-DEBT-STATUS with comprehensive audit. Add status headers
to FEAT-001 and SUTTA-007 ADRs. Minor fixes to CONVENTIONS, ONBOARDING,
START_HERE, ARCHITECTURE, TEST_MANIFEST, and ADDITIONAL-ARCHITECTURAL-ISSUES.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds the ability to switch between library novels without clearing cache.
9 commits: app shell routing, version-aware storage, centralized hydration,
bookshelf persistence, library UI with Continue Reading section, navigation
version-scoping, importer tooling, test fixtures, and documentation.

974 tests passing. Schema v15.

# Conflicts:
#	docs/WORKLOG.md
Adds Mahāsatipaṭṭhānasutta (MN 10) as a built-in library card that
routes to /sutta/demo on click. Appears alongside remote registry
novels. Uses the existing interactive Pāli study interface.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add splitPdfParagraphs() heuristic that distinguishes real paragraph
  breaks from soft wraps in pdftotext output by checking punctuation,
  capitalization, and line length.
- Add rejoinBrokenPdfHeadings() to handle chapter titles split across
  PDF page/line boundaries.
- PDF adapter now uses parseEnglishPdfText() with pdfMode.
- Session builder uses fan translation title when available, falling
  back to raw Chinese title.

Before: Chapter 1 had 10 mega-paragraphs (wall of text)
After:  Chapter 1 has 95 proper paragraphs matching the PDF layout

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- findEnglishBodyStartIndex now checks body length between headings
  (TOC entries have <500 chars, real chapters have 1000+)
- parseEnglishPdfText deduplicates by chapter number, keeping the
  version with more paragraphs (body > TOC ghost)
- Result: 2382 clean chapters from FMC PDF (was 3111 with 730 ghosts)
- Only 2 edge-case ghosts remain (chapters 1887, 1915)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The selection popover (thumbs up/down, edit, compare) was gated behind
viewMode === 'english', hiding it on the fan translation tab. Changed
to only hide on 'original' (raw source text) so users can annotate
both fan and AI translations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The toolbar only listened for mouseup events, which don't fire when
users select text via native touch handles. Added selectionchange
listener with 200ms debounce to detect touch selections.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- After clicking like/dislike/question, a comment input appears (Save/Skip)
- Feedback items render as colored dots in the left gutter near matched text
- Click a dot to expand and see the quoted text + comment
- Settings toggle: "Show inline feedback markers in left gutter" (default on)
- Also: scroll to top on chapter navigation (next/prev)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
npm audit fix resolved all 8 vulnerabilities (rollup, happy-dom,
tar, minimatch, picomatch, flatted, brace-expansion, yaml).
Project .npmrc adds save-exact, engine-strict, and audit defaults.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… off

- Added Part C (Glossary) to default system prompt — starts empty,
  AI proposes term additions via the existing amendment review flow
- Added section 4 to Part A instructing AI when to propose glossary entries
- Changed includeFanTranslationInPrompt default from true to false
  across all providers and settings — fan translation can pollute
  quality; glossary provides consistency without the noise

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Default debug level changed from 'full' to 'off'
- Default pipeline selection returns false (no pipelines) instead of
  true (all pipelines) when unconfigured
- Gated AutoTranslate, App:init, and DefaultKeyBanner logs through
  debugLog/debugWarn so they respect the settings panel toggles

Console is now quiet by default. Enable logging via Settings > Debug.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cheaper default for new users on the trial key.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary-level logs (high-level events like chapter counts, hydration
complete, RAM usage) show by default. Full-level verbose spam is
suppressed until user enables specific pipelines in Settings > Debug.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…etime

Counter now stores the date alongside usage count. If the date
doesn't match today, counter resets to 0. Users get 10 free
translations per day. Updated banner and error messages accordingly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
anantham and others added 14 commits April 1, 2026 14:00
Two causes:
1. Auto-focusing the input collapses the DOM text selection, which
   triggers selectionchange → checkSelection → setSelection(null)
   → popover unmounts. Fixed by skipping selection checks when
   activeElement is an INPUT/TEXTAREA.
2. Parent div's onMouseDown preventDefault blocks the input from
   receiving focus on click. Fixed with stopPropagation on the input.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two issues fixed:

1. Grey diff marker explanations (inline "No Change: No explanation
   provided." text) were captured by window.getSelection() when users
   selected across paragraphs. Added select-none + aria-hidden so they
   are excluded from text selections and comparison requests.

2. Comparison card was placed after the selection anchor (first
   paragraph) instead of the focus (last paragraph). When selecting
   across two paragraphs, the card appeared between them. Now uses
   range.endContainer to place the card after the last selected text.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Schema migration v16 adds the api_metrics object store to the
centralized DB. Previously apiMetricsService opened its own connection
at hardcoded version 14, causing NotFoundError on image generation
timing stats. Now uses getConnection() from the shared pool.

Converted ~77 raw console.log/console.warn calls to debugLog/debugWarn
across 8 files: settingsSlice, openrouterService, importService,
navigation/*, apiKeyValidation. All gated by the debug pipeline
system — silent by default, visible when user enables the pipeline
in Settings > Debug.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fetchAllNovelMetadata() prepends BUILT_IN_ENTRIES (sutta-mn10) to
remote novels. Tests expected counts based only on remote data.
Updated 6 assertions to add +1 for the built-in entry.

14/14 tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Migration test expected 10 stores at version 15. Updated to 11 stores
at version 16 after api_metrics addition.

973/974 tests pass (1 pre-existing navigation test failure).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The utils/debug mock only exported debugLog, not debugWarn. When our
log gating changes added debugWarn to converters.ts, the missing mock
caused a silent TypeError caught by hydration.ts's try-catch, making
adaptTranslationRecordToResult appear to return null.

All 974 tests now pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- AGENTS.md: added DEBT_CAPTURE_PROTOCOL (two-stage debt system)
- docs/WORKLOG.md: session notes
- .gitignore: added .superpowers/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- OpenAI adapter now records `duration` (seconds) in api_metrics for
  translation calls, enabling empirical time estimates
- New getAverageTranslationTime() method with ensemble fallback:
  exact model → same provider → all translations → 30s default
- TranslationCountdownLoader replaces the plain spinner — shows
  progress bar, estimated time remaining, elapsed time, and sample
  count from historical data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a model hits its token output limit (length_cap) and retries
with doubled maxOutputTokens also fail, the Translator now
automatically splits the chapter into 2-3 chunks at paragraph
boundaries and translates each sequentially.

Each chunk receives the previous chunk's translation as context
for continuity. Results are stitched with merged footnotes
(re-numbered), illustrations, usage metrics, and amendments.

Also gated all Translator.ts console.log/warn/error calls through
debugLog/debugWarn for the translation pipeline.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Flipped enableAmendments default from false to true across all
providers, settings UI, store, and promptUtils. The glossary
system depends on amendments to grow organically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Users can now select an image model without triggering automatic
illustration generation after every translation. Toggle appears
below the image model selector when a model is selected (hidden
when model is "none"). Default: on (preserves existing behavior).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Source and target language are book properties, not engine settings.
They now display as read-only text in the Translation Engine section
with "Edit in Settings > Metadata" hint. Editable only in the
Metadata panel where they belong.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two bugs causing all diff markers to be grey no-change:

1. The translation:complete event read fanTranslation from a stale
   state snapshot captured at the start of handleTranslate. Now reads
   from live store state via get() to ensure current fanTranslation.

2. Stale cache served results computed without fan translation even
   after fan translation became available. Added cache invalidation:
   if cached result has fanHash=null but current request has a real
   fanHash, the cache is bypassed and diff re-runs with fan text.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Language inputs became read-only text (editable in Metadata only).
Tests now check for text content instead of input values/labels.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lexicon-forge Ready Ready Preview, Comment Apr 4, 2026 8:15pm

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

anantham added 8 commits April 3, 2026 23:30
Context: the custom text import flow swallowed persistence failures in the store layer, but the paste form still cleared its fields unconditionally.\n\nChanges: wait for importCustomText to return a chapter id before resetting the pasted title, language, and body fields.\n\nImpact: failed custom-text imports now preserve the user\'s pasted content for retry or manual recovery.\n\nTests: /Users/aditya/Documents/Ongoing Local/LexiconForge.worktrees/pr25-fixes/node_modules/.bin/vite build\n\nDocs: none
# Conflicts:
#	components/InputBar.tsx
#	store/slices/chaptersSlice.ts
…into codex/pr25-fixes

# Conflicts:
#	components/InputBar.tsx
#	docs/WORKLOG.md
#	tests/components/InputBar.test.tsx
feat: add custom text input via tabbed InputBar
@anantham
Copy link
Copy Markdown
Owner Author

anantham commented Apr 4, 2026

Review-only PR — closing, all code is on main

@anantham anantham closed this Apr 4, 2026
@anantham anantham merged commit f1654bf into review/recent-development Apr 4, 2026
3 checks passed
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.

2 participants