Complete offline rewriting with enhanced detection and UI improvements#8
Merged
Conversation
- Implement runCase() helper function for table-driven testing - Add 5 baseline test cases covering profanity, insults, and phrase replacements - All tests pass (22 tests total) - Fulfills ws-qmw.1 acceptance criteria
Extended the masked-text strategy in detector.ts to mask protected tokens (URLs, @Handles, #channels) so they are never modified by the text replacement system. Protected tokens are treated as ineligible zones, similar to quoted email threads and fenced code blocks. Added comprehensive test coverage for: - Profanity adjacent to protected tokens - Profanity inside URL paths - Multiple protected tokens in the same text - Both http and https URLs - Edge cases with profanity-like strings in handles/channels Closes ws-qmw.3
- Add segmentSentences() function that operates on eligible text only - Segments on sentence boundaries (. ! ? and newlines) - Respects excluded zones (quoted lines and fenced code blocks) - Treats protected tokens (URLs/@handles/#channels) as atomic - Add comprehensive test coverage for all edge cases - All 28 tests passing Closes ws-qmw.4
- Fixed isInExcludedZone check that was incorrectly marking sentences with trailing newlines as excluded - Added logic to track clause-rewrite-candidate sentences with protected tokens - These sentences are now skipped entirely (no phrase/word replacements) - This prevents partial rewrites of sentences that should be clause-rewritten but can't be due to protected tokens - Fixed test expectation for protected token preservation (should contain @alice) - Updated detector tests to reflect clause rewrites now having higher priority than phrase matches - All 90 lib tests passing Task: ws-qmw.6
- Fixed isInExcludedZone check that was incorrectly marking sentences with trailing newlines as excluded - Added logic to track clause-rewrite-candidate sentences with protected tokens - These sentences are now skipped entirely (no phrase/word replacements) - This prevents partial rewrites of sentences that should be clause-rewritten but can't be due to protected tokens - Fixed test expectation for protected token preservation (should contain @alice) - Updated detector tests to reflect clause rewrites now having higher priority than phrase matches - All 90 lib tests passing Task: ws-qmw.6
Replaces exact regex patterns with sliding window adjacency analysis for clause rewrites, increasing recall beyond exact phrase matches. Core Implementation: - Tokenization with position tracking (raw, normalized, startIndex, endIndex) - Sliding window analysis (default 6 tokens) with distance-weighted scoring - Deterministic score formula: 1/(1+distance) - Protected token barriers (URLs, @Handles, #channels) - Excluded zone support (code blocks, quoted lines) Integration: - Clause rewrites trigger when adjacency score >= 0.2 threshold - Falls back to word-level replacements when score < threshold - Replaces previous exact regex matching for attack/frustration patterns Testing: - 8 tokenization unit tests (position tracking, protected tokens, excluded zones) - 7 adjacency scoring unit tests (distance scoring, barriers, determinism) - 8 integration tests (clause rewrites via adjacency, window enforcement) - All 110 detector/replacer tests passing - No type errors, no lint warnings Addresses: ws-qmw.7
…atterns - Implement multi-token sequence matching for passive-aggressive phrases - Add adjacency detection for 'just checking in', 'per my last email', 'friendly reminder' - Support obfuscated patterns with extra words/punctuation between tokens - Skip adjacency detection when exact phrase regex matches - Add comprehensive tests for adjacency detection with various patterns - Ensure existing phrase-regex behavior remains intact Closes ws-qmw.8
Add user-facing toggle for sarcasm detection mode: - Default OFF, persists to localStorage - UI toggle in settings panel (minimal design) - Comprehensive unit tests for persistence - Only affects dictionary mode (offline processing) Tests: All 132 tests pass including 4 new persistence tests Refs: ws-qmw.10
- Add sarcasm dictionary with 15 curated phrases using punctuation cues - Add 'sarcasm' detection type to Detection interface - Refactor detectIssues to accept DetectionOptions with sarcasmMode flag - Implement sarcasm detection that only runs when sarcasmMode is enabled - Update state management to pass sarcasmMode from global state - Add comprehensive test suite: * Tests with sarcasm OFF (no rewrite) * Tests with sarcasm ON (detects and rewrites) * 4+ negative tests (genuine praise not modified) * Excluded zones and protected tokens respected - Clean up debug test files - All tests pass (149/149) Closes ws-qmw.11
- Add 5 performance tests for 10K+ character inputs - Test scenarios: mixed content, protected tokens, excluded zones, adjacency rules, pathological nested zones - All tests complete within 5 seconds - Verify all new behaviors covered: excluded zones, protected tokens, clause rewrites, adjacency - All toolchain checks pass: 154 tests, 0 type errors, 0 lint warnings Closes ws-qmw.12
- Implement Levenshtein distance algorithm for edit-distance matching - Add feature flag ENABLE_FUZZY_MATCHING with configurable MAX_EDIT_DISTANCE - Create curated list of high-impact terms for fuzzy matching - Add comprehensive safe word blacklist to prevent false positives - Constrain matching with minimum length (3 chars) and max length diff (1 char) - Add 8 comprehensive tests (3 positive typo detection, 5 negative safe word protection) - All tests passing (36/36) Resolves: ws-qmw.9
- Add minimum length requirement (3 chars) for substring matching - Add common words to safe list: hello, help, sure, yeah - Prevents single/short words from matching profanity substrings - All 162 tests now passing Closes ws-qmw
All 162 tests passing. Fuzzy matching false positives fixed. Dictionary mode remains 100% offline and deterministic.
- Move settings panel above input section for better workflow - Add Ctrl+Enter auto-scroll to output section - Make textarea cursor more visible with red caret color - Replace person/jerk with friend/friends in all dictionaries - Add retard variants to insults dictionary - Replace [removed] fallback with friend
- Move settings to 240px fixed sidebar on right with grid layout - Reduce whitespace with compact padding and spacing - Add post-it note rotation (0.8deg) to match theme - Show API config only when Lundberg AI toggle is enabled - Implement mobile drawer that slides from right - Reverse green output post-it rotation to -1.5deg - Reposition TPS Report flair to left of output section
- Remove unused _targetTerm parameter from isSubstringOfSafeWord - Add safe localStorage wrappers with proper error logging - Update README with new UI features and sarcasm detection All tests pass, linting clean, type checking successful.
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
Complete offline rewriting epic (ws-qmw) with advanced profanity/insult detection, sarcasm support, and redesigned UI layout.
Key Changes
Detection Engine:
Replacement Logic:
UI/UX:
Testing:
Files Changed
src/lib/detector.ts: Fuzzy matching, adjacency engine, sentence segmentationsrc/lib/dictionaries/*: Updated replacement mappings, added sarcasm.tssrc/lib/components/SettingsPanel.vue: Redesigned as compact sidebarsrc/lib/components/App.vue: Grid layout with right sidebarTesting
Manual testing verified fuzzy matching edge cases, sarcasm detection toggle, mobile drawer, and Ctrl+Enter scroll behavior.