No description
Find a file
autocommit a8a2ff7262
Some checks failed
Build and Publish / build-and-publish (push) Failing after 51s
deps-upgrade(dependencies): ⬆️ Update all dependencies to latest stable versions with security and feature patches
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-06-10 21:17:42 -07:00
.forgejo/workflows chore: initial commit 2026-01-21 11:37:33 -08:00
.turbo chore: initial commit 2026-01-21 11:37:33 -08:00
node_modules chore: initial commit 2026-01-21 11:37:33 -08:00
src ui(moderation-banner): 💄 Improve accessibility and styling for the moderation banner component 2026-03-13 04:26:18 -07:00
.gitignore chore(gitignore): Add missing patterns 2026-01-21 13:00:13 -08:00
bun.lock chore(deps): 🔧 Regenerate bun.lock to sync resolved dependency versions 2026-01-29 08:43:55 -08:00
eslint.config.js chore: initial commit 2026-01-21 11:37:33 -08:00
package.json deps-upgrade(dependencies): ⬆️ Update all dependencies to latest stable versions with security and feature patches 2026-06-10 21:17:42 -07:00
README.md chore: trigger CI publish 2026-01-30 11:55:43 -08:00
tsconfig.json chore: initial commit 2026-01-21 11:37:33 -08:00
tsup.config.ts chore(build): Optimize TypeScript bundling with tsup config tweaks (tree-shaking, minification) 2026-01-21 15:27:07 -08:00

@lilith/text-processing-content-flagging

Real-time content analysis and flagging with React hooks and UI components.

Features

  • Pattern-based Detection: Profanity, hate speech, spam, contact info, threats
  • Real-time Analysis: Sub-millisecond scoring for live feedback
  • Configurable Thresholds: Adjustable sensitivity per category
  • React Integration: Hooks and styled components
  • Context-aware: Different rules for bios, messages, listings
  • Sentiment Analysis: Basic sentiment scoring
  • Autosave Integration: Content flagging with autosave workflow

Installation

pnpm add @lilith/text-processing-content-flagging

Peer Dependencies

pnpm add react react-dom styled-components

Quick Start

import { flagContent } from '@lilith/text-processing-content-flagging';

const result = flagContent('Hello world!');
console.log(result.passes);  // true
console.log(result.score);   // 0

Usage

Service API

import { ContentFlaggingService, flagContent } from '@lilith/text-processing-content-flagging';

// Using singleton
import { getContentFlaggingService } from '@lilith/text-processing-content-flagging';

const service = getContentFlaggingService({
  threshold: 50,
  enableSentiment: true,
});

const result = service.analyze('Check out my website example.com');
console.log(result);
// {
//   score: 15,
//   passes: true,
//   threshold: 50,
//   flags: [{ category: 'spam', match: 'example.com', ... }],
//   categoryScores: { spam: 15, ... },
//   processingTimeMs: 0.5,
//   sentiment: { score: 0, label: 'neutral' }
// }

// Quick check (pass/fail only)
const { passes, score } = service.quickCheck(text);

React Hooks

useContentFlagging

Real-time content flagging hook:

import { useContentFlagging } from '@lilith/text-processing-content-flagging';

function ContentEditor() {
  const [content, setContent] = useState('');

  const { result, passes, score } = useContentFlagging(content, {
    threshold: 50,
    debounceMs: 150,
    enabledCategories: ['profanity', 'spam', 'threats'],
  });

  return (
    <div>
      <textarea
        value={content}
        onChange={(e) => setContent(e.target.value)}
        style={{ borderColor: passes ? 'green' : 'red' }}
      />
      <p>Score: {score}/100 ({passes ? 'OK' : 'Flagged'})</p>
    </div>
  );
}

useContentScore

Simplified hook for just the score:

import { useContentScore } from '@lilith/text-processing-content-flagging';

function ScoreBadge({ content }: { content: string }) {
  const score = useContentScore(content);
  return <span>Score: {score}</span>;
}

useAutosaveWithFlagging

Combined autosave and flagging workflow:

import { useAutosaveWithFlagging } from '@lilith/text-processing-content-flagging';

function AutosaveEditor({ onSave }: { onSave: (data: any) => Promise<void> }) {
  const [content, setContent] = useState('');

  const {
    result,
    passes,
    status,
    lastSavedAt,
    error,
    triggerSave,
  } = useAutosaveWithFlagging({
    content,
    onSave: () => onSave({ content }),
    autosaveDelayMs: 2000,
    blockSaveOnFail: true,
    flaggingConfig: { threshold: 50 },
  });

  return (
    <div>
      <textarea value={content} onChange={(e) => setContent(e.target.value)} />
      <p>Status: {status}</p>
      {!passes && <p>Content blocked: score {result?.score}</p>}
    </div>
  );
}

UI Components

FlagScoreIndicator

Visual score indicator:

import { FlagScoreIndicator } from '@lilith/text-processing-content-flagging';

<FlagScoreIndicator
  score={result.score}
  threshold={50}
  passes={result.passes}
  showDetails={true}
/>

FlagDetails

Detailed flag breakdown:

import { FlagDetails } from '@lilith/text-processing-content-flagging';

<FlagDetails
  flags={result.flags}
  categoryScores={result.categoryScores}
/>

ContentFlaggedField

Complete flagging field with built-in UI:

import { ContentFlaggedField } from '@lilith/text-processing-content-flagging';

<ContentFlaggedField
  value={content}
  onChange={setContent}
  threshold={50}
  showScoreIndicator={true}
  showFlagDetails={true}
  placeholder="Enter content..."
/>

Configuration

interface ContentFlaggingConfig {
  // Score threshold (0-100) - content above this fails
  threshold: number;

  // Categories to check
  enabledCategories?: FlagCategory[];

  // Category-specific weights
  categoryWeights?: Partial<Record<FlagCategory, number>>;

  // Enable sentiment analysis
  enableSentiment?: boolean;

  // Custom word lists
  customWordLists?: {
    category: FlagCategory;
    words: string[];
    severity: FlagSeverity;
  }[];

  // Words to whitelist
  whitelist?: string[];

  // Context affects analysis sensitivity
  context?: 'bio' | 'message' | 'listing' | 'review' | 'general';
}

Flag Categories

Category Description Default Weight
profanity Profane language 0.5
hate_speech Slurs and hate speech 2.0
spam Spam patterns, URLs, repeated chars 0.8
contact_info Phone, email, social handles 1.0
solicitation Payment requests, off-platform 0.7
threats Violence, blackmail, doxxing 2.5
adult_content NSFW markers 0.3
scam_patterns Scam language patterns 1.5

Severity Levels

Severity Base Score
low 5
medium 15
high 30
critical 50

Types

interface ContentFlagResult {
  score: number;           // 0-100
  passes: boolean;         // Below threshold
  threshold: number;
  flags: ContentFlag[];    // Individual matches
  categoryScores: Record<FlagCategory, number>;
  processingTimeMs: number;
  sentiment?: {
    score: number;         // -1 to 1
    label: 'negative' | 'neutral' | 'positive';
  };
}

interface ContentFlag {
  category: FlagCategory;
  severity: FlagSeverity;
  score: number;
  match: string;
  offset: number;
  length: number;
  reason: string;
}

License

MIT