Skip to content

Latest commit

History

97 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

📎 האלגוריתם שחזר בתשובה

The Algorithm That Repented — v0.4.0

StatusLicenseLive Demo

What if the algorithm stopped hiding and started explaining itself?

Every day, social media algorithms decide what you see — and they never tell you why.

This project is a small act of rebellion: a browser extension + desktop agent (Clippy, naturally) that sits with you while you browse, watches what the algorithm shows you, tells you the truth — and then clicks "Not interested" on your behalf.

📸 Screenshots


What It Does

  1. Watches your feed — YouTube, X/Twitter, Facebook, Instagram, TikTok, LinkedIn, Reddit, Threads
  2. Classifies every post into one of 9 categories (politics, sports, tech, etc.)
  3. Asks you with floating 👍/👎 buttons: "Are you interested in this?"
  4. Learns your preferences and adjusts its weight per category
  5. Acts — when you press 👎, Clippy automatically clicks "Not interested" / "Hide post" for real
  6. Auto-dismisses posts from categories you consistently dislike (configurable threshold)
  7. Shows you exactly what it learned — dismissed count, category weights, sentiment badges

Feature Status

FeatureStatus
Feed observer (YouTube, X, Facebook, Instagram, TikTok)✅ Working
9-category brain classifier✅ Working
Clippy desktop agent (Electron)✅ Working
Clippy Chrome extension✅ Working
Floating 👍/👎 feedback buttons✅ Working
Action Engine — clicks "Not interested"✅ Working
Dismiss counter (persisted, shown in popup)✅ Working
Popup with 5 tabs (overview/categories/history/insights/settings)✅ Working
Settings tab — auto-dismiss toggle✅ Working
Weight badges per category (❤️/😐/😒/🚫)✅ Working
Chrome extension icons✅ Present
Landing page✅ Working
AI-powered dialogue layer (click Clippy to chat)✅ Working
TikTok action adapter✅ Working
YouTube InnerTube API integration✅ Working
LinkedIn action adapter✅ Working (verified live 2026-07-28, fixed 2 broken selectors)
Reddit action adapter⚠️ Unverifiable — Reddit blocks automated browsers
Threads action adapter⚠️ Best-effort — only verified logged-out so far
Web text analyzer (9 categories, Hebrew/EN/RU)✅ Working
37 unit tests (brain, classifier, state, questions)✅ Passing

Architecture

teshuva-algorithm/
├── brain/ # Core intelligence
│ ├── brain-api.js # Public API: observe, positive, negative, recordDismiss, getStats
│ ├── categories.js # 9 categories with Hebrew labels + colors
│ ├── classifier.js # Keyword-based text classification
│ ├── state.js # Persisted weights, allTime, dismissed counters
│ ├── questions.js # When + how to ask the user
│ ├── intent.js # "Why are you seeing this?" explanations
│ ├── explanations.js # Human-readable summaries
│ └── adapters/
│ ├── chrome-adapter.js # chrome.storage.local
│ ├── electron-adapter.js # In-memory store (desktop, via IPC)
│ └── react-native-adapter.js # AsyncStorage (mobile)
│
├── mascot/
│ ├── mascot-controller.js # Brain ↔ Mascot ↔ User bridge
│ └── animations.js # Mood → Clippy animation mapping
│
├── extension/
│ ├── manifest.json # MV3, host permissions for 5 platforms
│ ├── content/
│ │ ├── bundle-entry.js # Content script entry + wiring
│ │ ├── bundle.js # Built bundle (esbuild output)
│ │ ├── action-engine.js # Platform "Not interested" click logic
│ │ ├── feedback-ui.js # Floating 👍/👎 buttons
│ │ ├── feed-observer.js # MutationObserver for new posts
│ │ └── site-adapters.js # CSS selectors per platform
│ ├── popup/
│ │ ├── popup.html # 5-tab popup UI
│ │ ├── popup-entry.js # Popup logic
│ │ └── popup.js # Built bundle
│ ├── background-entry.js # Service worker: storage + settings relay
│ └── api.js # Content ↔ Background message protocol
│
├── desktop/
│ ├── main.js # Electron window (340×340, always-on-top)
│ └── renderer-entry.js # Desktop Clippy logic + IPC
│
├── shared/
│ └── constants.js # Storage keys, message types, timing
│
├── agent/
│ └── dialogue.js # Conversational AI stub
│
├── mobile/ # React Native app (Android + iOS, sideload-only)
│ ├── src/ # Screens, mascot, services (brain runs on-device)
│ └── android/ # FloatingService.java (overlay), FeedWatcherService.kt
│ # (AccessibilityService feed monitoring)
│
├── web/ # Landing page & marketing site (Netlify)
│ ├── index.html # Main landing page (HE/EN/RU, dark/light)
│ ├── features.html # Features page
│ ├── pricing.html # Pricing page
│ ├── faq.html # FAQ page
│ ├── support.html # Support page
│ └── downloads/ # Extension zip for manual install
└── package.json

Action Engine — Platform Support

When the user presses 👎 or when the brain weight drops below 0.4 (configurable), Clippy automatically:

PlatformActionDOM Strategy
YouTube"Not interested"Hover reveal → ytd-menu-renderer → option click
X / Twitter"Not interested in this post"[data-testid="caret"] → menu item
Facebook"Hide post"[aria-label="More options"] → menu item
Instagram"Not interested"Three-dot button → dialog button
TikTok"Not interested"Direct button (newer layouts) → overflow menu fallback
LinkedIn"Not interested" / unfollow / hideControl menu → option click (verified live 2026-07-28)
Reddit"Not interested" / hide / blockOverflow menu → option click (best-effort — Reddit blocks automated verification)
Threads"Not interested" / hide / muteMore menu → option click (best-effort — only verified logged-out)

Brain API

import{createBrain}from'./brain/brain-api.js'import{createChromeAdapter}from'./brain/adapters/chrome-adapter.js'constbrain=createBrain(createChromeAdapter())awaitbrain.load()constcategoryId=brain.observe('פוסט על פוליטיקה...')// → 'politics'brain.positive('politics')// user liked it → weight +0.15brain.negative('politics')// user disliked → weight -0.08brain.recordDismiss('politics')// post was actually removed from feedconst{ allTime, weights, dismissed, dismissedTotal }=brain.getStats()// weights.politics < 0.4 → auto-dismiss threshold crossed

Setup

Chrome Extension

  1. Run npm install && npm run build
  2. Open chrome://extensions/
  3. Enable Developer mode
  4. Click Load unpacked → select the extension/ folder
  5. Navigate to YouTube, X, Facebook, or Instagram
  6. Clippy appears bottom-right

Desktop (Electron)

npm install
npm start
# Or double-click: "הפעל קליפי.bat"

Popup Tabs

TabContent
סקירהVisits, social, dismissed banner
קטגוריותCategory bars with ❤️/😐/😒/🚫 badges
היסטוריהHour-of-day chart, top domains
תובנותWeekly insights
⚙️ הגדרותAuto-dismiss toggle, reset preferences

Roadmap

Shipped:

  • ✅ Improved YouTube selector (InnerTube API)
  • ✅ TikTok action adapter
  • ✅ AI dialogue via Claude API (ask Clippy "why?")
  • ✅ Landing page in Hebrew/English/Russian — the extension popup itself is still Hebrew-only
  • ✅ Mobile app (React Native, Android) — on-device brain, a real floating Clippy bubble over other apps, and real feed monitoring on Instagram/TikTok/Twitter. Sideload-only, not on Google Play (Accessibility API policy risk — see CLAUDE.md)

Open:

  • Real-device verification of mobile feed monitoring against live Instagram/TikTok/Twitter (so far only tested on a Play-Store-less emulator)
  • Threads action-engine needs real-browser testing with a logged-in account (Reddit can't be tested this way at all — see Known Gaps)
  • Category blocklist, export preferences, full multi-language extension popup — not started
  • Decision pending: publish mobile/ to Google Play with the feed-monitoring service disabled

"האלגוריתם הזה לא מסתיר כלום ממך"

MIT License · GitHub

About

The Algorithm That Repented — Clippy mascot that explains why you see what you see on social media

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages