- FIX-35: Narrowed suffix set from {ن,ت,ا,ي,ة,و,ه} to {ن,ت} only.
Only verb conjugation suffixes are blocked. ة/ا/ي/و/ه are legitimate
typo corrections that should not be blocked.
- FIX-37: Raised word threshold from 2 to 4. Prevents noisy period
suggestions while user is still typing short phrases.
- FIX-32b: Removed duplicate .sort() in applyAllSuggestions — already
sorted at line 679, second sort at 695 was redundant.
- Tests updated to match narrowed suffix expectations.
FIX-32b: Add missing reverse sort in applyAllSuggestions
Found during commit audit: the text-based replacement loop iterated
suggestions in original order instead of reverse-sorted by offset.
Without descending sort, applying a fix at offset 5 shifts all text
after it, causing fixes at offset 20+ to corrupt the text.
FIX-33: Grammar rules fix_prepositions_advanced was corrupting
الامتحان→الامتحين. The regex blindly replaced ان→ين after prepositions,
but الامتحان is a root noun not a dual. Added blocklist of ~60 common
root-form nouns and skip all ال-prefixed words ending in ان.
FIX-34: Remove auto-re-analysis from Apply All in editor.js.
When spelling and grammar disagree (spelling strips ذهبن→ذهب,
grammar re-adds ذهبوا→ذهبن), the auto-re-analysis creates an
infinite loop of contradictory suggestions.
FIX-35: Spelling no longer strips valid conjugation suffixes.
The insertion fix was accepting ذهبن→ذهب (removing final ن) as
'extra char removed'. But ن is a feminine plural verb suffix.
Now blocks removal of suffix chars (ن,ت,ا,ي,ة,و,ه) from word
endings, preventing spelling from undoing grammar corrections.
FIX-32: Fix word duplication bug in website frontend
Root cause: applyAllSuggestions used a mixed DOM+text fallback approach.
After DOM-based fixes shifted the editor text, the text-based fallback
used stale offsets from the original API response, inserting corrections
at wrong positions. This caused 'المشروعالمشروع.' (word duplication).
Fix:
1. applyAllSuggestions now uses PURE text-based reverse-order replacement.
Since patches are sorted highest-offset-first, each offset is valid
because nothing before it has been modified yet.
2. _isApplyingSuggestion guard now stays active 400ms (past the 300ms
re-analysis timeout) to prevent normalize()/input events from
triggering duplicate analysis calls.
feat: Complete ALL plan items — gradient tokens, nav scroll glow, focus rings, dropdown keyboard nav, color reset, network delay indicator
Grammar removes period, punctuation re-adds it. Auto re-analyze after apply
creates an infinite cycle. Analysis already auto-triggers when user types
(input event handler), which is the correct behavior.
fix: prevent analyze loop - skip redundant API calls when text unchanged
P1: Integrate fix_common_hamza into /api/analyze pipeline
- Standalone hamza-fix pass runs AFTER spelling, catches انت→أنت,
الان→الآن, ام→أم, انا→أنا in sentence context
- Works even when AraSpell is skipped (>300 chars)
P1: Split multi-word grammar diffs into individual suggestions
- Grammar corrections like 'الي المدرسه الاستاذ'→'إلى المدرسة الأستاذ'
now appear as 3 separate suggestions, not 1 merged block
- Users can accept/reject each correction individually
P2: Auto re-analyze after applying any suggestion (frontend)
- After applying single, alternative, or all suggestions,
editor automatically re-analyzes with 300ms delay
- Shows 'جار التحليل' without user needing to type anything
P3: Word truncation guard
- Reject spelling corrections that shorten valid words by 2+ chars
- Prevents الدمث→الدم (rare word truncation)
P3: CI/CD - regression tests on every push
- Added test job to GitHub Actions workflow
- Runs 120 tests before lint-and-validate
fix(autocomplete): only trigger after space - no partial words
- Added self.threshold=0.05 — suggestions with score < 0.05 are filtered
- Changed default n from 5 to 3 everywhere (service, API, frontend)
- Threshold applied in _bigram_predict, _hybrid_predict, and GPT-2 fallback
fix(autocomplete): 3 user-reported issues - last word only, dropdown position, cursor after accept
COMPLETELY INDEPENDENT from the correction pipeline. Zero interaction
with /api/analyze, StageLocker, OffsetMapper, PatchSet, or highlights.
Backend:
- src/nlp/autocomplete/ package (service, rules, init)
- HybridAutoComplete: lazy-loaded singleton, LRU cache, OOM fallback
- Bigram model from bayan10/AutoComplete (bigram_model_v4.pkl)
- GPT-2 from aubmindlab/aragpt2-base (optional, falls back to bigram)
- POST /api/autocomplete with {context, n} → {status, suggestions}
- /api/health now reports autocomplete status
Frontend:
- src/js/autocomplete.js — self-contained module
- Ghost text overlay (gray, semi-transparent, pointer-events:none)
- Dropdown with keyboard nav (↑/↓), TAB accept, ESC dismiss
- 400ms debounce, min 3 chars, cursor-aware context extraction
- CSS in components.css with dark/light theme support
59/59 existing pipeline tests passing
- Grammar service: transient errors (rate limiting, timeout) no longer cached permanently — next request will retry loading instead of failing forever
- Editor: cursor now placed right after corrected text instead of jumping to start — applied to all 3 code paths (UUID span, text-match fallback, offset fallback)
fix: New document starts empty instead of inheriting old content Previously createDocument() used getEditorText() to save current content into the new doc. Now it creates with empty string and calls loadDocumentText('') to clear the editor.
fix: Strip HTML formatting on paste into editor - Added paste event handler that converts clipboard to plain text - Prevents rich text styling (colors, opacity, fonts) from being carried over - Preserves paragraph structure with line breaks - Fixes ghost formatting when pasting from chat or web pages
fix: Re-index suggestion spans after dismiss (keep as-is) - After filtering dismissed suggestion from array, span data-suggestion-id indices became stale - Adjacent error words became unclickable because findSuggestionById used wrong index - Now re-indexes all remaining spans to match updated array positions
feat: Summary UI improvements + PDF fix - Swap short/long labels on summary length slider (RTL: long left, short right) - Remove 'تلخيص النص كاملاً' checkbox and button - Replace single export button with dropdown (TXT/DOCX/PDF) in summary - Hide format toolbar when on summary tab, show on writing tab - Fix PDF export freeze: use foreignObjectRendering:false + lower scale - Add loading toast during PDF export - Add summary DOCX and PDF export functions
fix: Undo/Redo inside editor only + auto-focus after corrections - Moved listener back to editor element (capture:true) as user requested - Added editor.focus() after applySuggestionAtOffsets (line 432) - Added editor.focus() after applyAlternativeCorrection (line 474) - Added editor.focus() after dismissSuggestion (line 518) - After any correction/dismiss, editor auto-focuses so Ctrl+Z works immediately
fix: Undo/Redo now works after spelling corrections - Moved keydown listener from editor to document with capture:true - Uses stopImmediatePropagation to prevent browser native undo - Auto-focuses editor after undo/redo - Works even when tooltip click steals focus from editor
fix: Use capture phase on editor for Ctrl+Z/Y to intercept before browser native undo - Listener now on editor element with capture:true instead of document - Added stopPropagation to prevent browser native undo from also firing - Ensures corrections/dismissals can be properly undone
feat: Add custom Undo/Redo for corrections and dismissals - Ctrl+Z undoes correction/dismiss (restores previous editor state) - Ctrl+Y or Ctrl+Shift+Z redoes - pushUndoState() called before every applyCorrection, applyAlternative, dismissSuggestion, applyAll - 50-level undo stack - Only intercepts when custom stack has entries (falls through to browser native otherwise)
UI: Remove logo icon from header + replace guest avatar with profile silhouette SVG - Header now shows just 'بيان' text (no ب icon) - Guest avatar shows person silhouette instead of 'ض' letter - Both HTML default and JS auth-ui.js updated
audit-v4: 10 fixes and improvements - FIX: Footer replaced with multi-column layout (Product + Resources) - FIX: cta_primary config now matches button text - FIX: Enterprise 'contact sales' button navigates to editor - FIX: Mock editor 'الكتابه' now has spelling-error class (3 errors) - FIX: Status bar updated to '٣ إملائي' - FIX: Scroll-to-top fallback to window.scrollY - FIX: Remove @view-transition experimental CSS - FIX: Remove injected Cloudflare challenge script - ADD: Toast on applyCorrection + applyAllSuggestions - ADD: confirm() on applyAllSuggestions - ADD: Smart empty state (no text vs no errors) - ADD: Toggle switch HTML for summary checkbox
audit: Fix 15+ issues across entire website - BUGS: Fix copySummary event.target crash, viewbox→viewBox SVGs - HERO: Replace fake stats (10M/99%/50K) with real features (3 types/instant/free) - HERO: 'شاهد العرض التوضيحي'→'استكشف الميزات' with onclick - HERO: Fix mock editor hardcoded light colors→CSS variables - HERO: animate-pulse→animate-fade-in on floating card - PRICING: All 3 buttons now have onclick (go to editor) - FOOTER: Replace dead #links with working page navigation - EDITOR: Confirm dialog before clearing content - CODE: Remove empty style tag and old comments
remove: List buttons + indent + all related CSS/JS - Remove bullet list and ordered list buttons from toolbar - Remove formatList() function from format.js - Remove blockquote/ul/ol/li CSS from components.css - Keep clear format button