TikTok Shop Video Generator
Turn any viral TikTok video into an ad for your own product in one click. For TikTok Shop sellers and affiliates — no filming, no editing. Free to try.
Category-based Instagram follower/following curation, dry-run first — Follower Centrifuge 6000
Translation pending
MarketingTypeScript · HTMLGitHub @faissalooOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗An Instagram list-curation tool that runs as a browser console script. It scans both the accounts you follow and the accounts that follow you, classifies each account into a category from its public details (username, display name, and optionally its public profile photo), and lets you review the result before unfollowing anything — with dry runs always first and live unfollows gated behind an explicit typed approval.
The default category set is broad and balanced — Female, Male, Bots & AI, Brands & orgs, Unsure — and the wizard asks which category you want to remove. Nothing in the product is specific to one category: the same flow, safety gates and review tools apply to whichever category (or categories, by repeated runs) you pick.
Live page: https://faissaloo.github.io/follower-centrifuge/ · Repo: https://github.com/faissaloo/follower-centrifuge
Fork of davidarroyo1234/InstagramUnfollowers (MIT). The original tool finds accounts that don't follow you back. This fork repurposes the same Instagram private-API client for category-based account curation, swaps the classifier to TypeSafe AI's Jev model (DeepSeek as fallback, plus an optional vision pass for profile photos), and adds a safety-first review/approval workflow.
Runs in your browser. No downloads, no backend account access, no credentials leave your machine except the public names sent to the classifier you configure.
The review is where the tool earns its keep: target tabs (including the followers side), an Include Unsure accounts for manual sorting option, a free 0–100% confidence number box, per-row via main / via fallback provenance, and a dry-run action that changes nothing until you explicitly choose a live run.
Checks the relay first. On instagram.com the launch screen verifies that the local relay is actually reachable (and, in Firefox, that the local CA is trusted) before any category can be picked. If it is down, the screen explains how to start it (npm run proxy), how to retry, and how to fix Firefox trust.
Asks what to nuke. A three-step wizard starts with one question — which category do you want out of your lists: Female, Male, Bots & AI, Brands & orgs, or Unsure? — then scans and offers a dry run. The list of categories is a neutral default set, not a product focus: the same pipeline handles any category you pick. Advanced configuration (classifier keys, pacing, protection list) lives behind a quiet Advanced link and is only needed once in a while.
Scans two lists with the Instagram session already open in the tab:
Merges them into one audited list with You follow / Follows you / Mutual badges. Live runs show a cooldown countdown during deliberate pacing pauses and an estimated time to completion, so long 5-minute safety pauses don’t look like a frozen tab.
Reuses fresh lists. After a completed scan, the raw following/followers lists are cached for 30 minutes. A repeat scan (for example, choosing a different category) replays the cached lists instead of paginating Instagram again; classification results are reused too unless the classifier prompt/model settings changed. Changing only the target category is just a local re-filter. A live run interleaves unfollows and follower removals instead of exhausting one queue first, then invalidates the cache, and cached lists carry their original fetch time so stale lists cannot loosen the live-action freshness gates.
Classifies accounts into one of five default categories — female, male, machine (bots/AI feeds), organization (brands/media/teams) and ambiguous — with a confidence score and reason. It uses usernames, display names and (when enabled) public profile photos: a vision model turns photos into neutral visual cues, and TypeSafe Jev remains the main category decision-maker, with DeepSeek as the fallback. Profile photos are downscaled to small thumbnails before leaving the browser, and vision requests are chunked; transient classifier failures are retried once. Each review row is labelled or so you can see which classifier produced the guess. Photo cues are explicitly weighted as strong evidence by the Jev prompt, not just attached as decoration.
| Guarantee | How it is enforced |
|---|---|
| Dry runs never write to Instagram | Dry-run and live actions are different TypeScript types (DryRunPlan vs LivePlan); the dry-run executor never receives the unfollow transport or timers. Tests spy-assert zero transport/network calls. |
| Live needs explicit approval | A LivePlan only exists with the exact phrase UNFOLLOW <count> typed in a modal behind an "I understand" checkbox. The executor re-validates the approval, and the plan is bound to the exact account ids the dialog displayed. |
| Actions match the connection direction | Following/mutual accounts are unfollowed (with an isStillFollowing preflight); followers-only accounts are removed from your followers list (with an isStillFollower preflight). Both fail closed before writing. Follower removal mirrors instagram.com's own remove_follower request (endpoint target id, fb_dtsg/jazoest body, web-app headers) and only counts {"status":"ok"} as success. |
| Whitelisted accounts are untouchable | Protection matches account id and normalized username (so bulk-pasted/imported entries protect the real account). Checked at display, plan build, and again immediately before every live write — including accounts protected during a running queue. |
| No action on incomplete scans | Truncated pagination / failed lists mark the review incomplete and hard-lock live unfollowing. |
| No stale or cross-account actions | Cached reviews are viewer-scoped (stored ds_user_id must match), expire after 24 h, cannot drive live actions, and a live run requires the same viewer and a review younger than 30 minutes. |
| No accidental real-account runs | Localhost is a fully synthetic offline demo with live unfollowing disabled; tests globally block fetch/XHR/WebSocket/EventSource/sendBeacon; a second independent review pass audited the destructive paths. |
| Guesses are estimates | Every row shows a category, confidence, reason and classifier provenance. ambiguous accounts are separated; they are only removable through the explicit Include Unsure accounts for manual sorting option, and still go through dry run + typed live approval. |
Requires Node 22.
Important: on instagram.com the classifier needs the bundled local relay.
Instagram's page Content-Security-Policy blocks direct fetch calls to the
classifier APIs, but allows ws://localhost:*. The proxy therefore also serves a
WebSocket relay; start it once in a terminal and keep it running while you scan:
npm ci
DEEPSEEK_API_KEY=... npm run proxy # key optional: the browser can send its own
The relay forwards only api.typesafe.ai / api.deepseek.com, only over HTTPS,
and only accepts instagram.com or localhost as the browser origin. It is
loopback-only — never expose it.
Firefox one-time step: Instagram's CSP sends upgrade-insecure-requests, which
upgrades ws://localhost to wss://localhost; the script then uses the secure
relay on wss://localhost:8788. The proxy generates a local CA and, on start,
installs it as a trusted CA into every Firefox profile's NSS database (and
Chrome's ~/.pki/nssdb) using certutil — the same approach as mkcert. No
"Accept the Risk" dialog is involved; just restart Firefox once so it reloads
the trust store. Manual re-install: npm run trust:relay (it auto-downloads
libnss3-tools into the gitignored .tools/ when needed). Chrome/Edge use the
plain ws://localhost:8787 relay automatically.
npm run build # public build: embeds the app into public/index.html (NO API keys)
Open public/index.html from the repo (or the GitHub Pages deployment at https://faissaloo.github.io/follower-centrifuge/) and press COPY in the page. This public script contains no credentials: if it has no baked-in API keys, the wizard asks for them on first run and keeps them only in that tab's sessionStorage (they can also be entered later in Settings).
Optional personal keyed build (no proxy, no setup when pasting — for your own use only):
# put keys in gitignored files (or export the env vars)
printf '%s' 'apikey_…' > .typesafe-key # TypeSafe Jev (primary)
printf '%s' 'sk-…' > .deepseek-key # DeepSeek (fallback, optional)
npm run build:local-key # -> dist/critical-relations-local.js (gitignored)
The keyed file has the keys compiled in and defaults to TypeSafe Jev with DeepSeek fallback. Never commit, publish or share it — regenerate it with npm run build:local-key, and rotate the keys if it may have leaked. public/index.html, dist/dist.js and every normal build never embed a key: the embed is gated behind the IU_ALLOW_EMBEDDED_KEY flag that only build:local-key sets.
In the wizard's set up the classifier panel (or later in Settings → Name classifier):
jev-latest and the base URL is https://api.typesafe.ai. Keys stay in this tab's sessionStorage and are never written to localStorage.npm run proxy (keep it running).npm run build-dev
Open http://localhost:8080/?preview=review, press COPY, and paste the script into the console on that page. On localhost the app runs in fully offline demo mode with synthetic accounts; live unfollowing is disabled.
npm test # 859 tests / 51 files (unit, component, integration, safety)
npm run test:coverage # coverage thresholds
npm run verify # typecheck app + tests, lint, tests
npm run check:classifier # MANUAL real-API check (synthetic names only; uses .typesafe-key/.deepseek-key)
npm run check:classifier is the deliberate exception: it reads your gitignored keys and runs the real classifier prompt end-to-end with synthetic names. It verifies the five-category output and both providers..github/workflows/tests.yaml) runs typechecks, lint, tests and a production bundle on every push/PR.src/
model/ # contracts (categories/target, audit, plans, provider config)
utils/
friendships-list.ts # paginated Instagram list walker (retries/backoff/abort)
account-audit.ts # scan both lists, merge relationships, stream-classify
typesafe-client.ts # TypeSafe Jev System One client (choice questions, retries, timeouts)
gender-classifier.ts # provider router: Jev main -> DeepSeek fallback; vision photo cues; cache+prompt+parser
deepseek-client.ts # OpenAI-compatible chat client (proxy/direct)
gender-cache.ts # versioned local guess cache
action-plan.ts # selection -> plan (eligibility + approval phrase)
unfollow-executor.ts # dry-run vs live executors (separate paths)
approval.ts # shared live-confirmation helpers
audit-display.ts # target tabs / other / search / pagination / summary
whitelist-match.ts # id + username protection matching
review-cache.ts # viewer-scoped, expiring review cache
deepseek-settings.ts # provider/keys persistence (session-only; embedded-key merge)
audit-preferences.ts # persisted category preference
i18n.ts # EN/ES
components/
NukeWizard.tsx # wizard step 1: pick the category to nuke
WizardSteps.tsx # pick -> dry run -> nuke step indicator
Centrifuge.tsx # decorative enrichment-cascade animation
preview/demo-data.ts # synthetic offline dataset
App.tsx / main.tsx # wiring + bootstrap
server/deepseek-proxy.mjs # optional local DeepSeek proxy (zero dependencies)
docs/classifier-setup.md # provider setup, keys, privacy, cost, troubleshooting
tests/ # automated tests (network-free)
connect-src) blocks direct API requests to both classifier providers, but allows ws://localhost:*; npm run proxy serves that relay (plain ws for Chrome/Edge, secure wss for Firefox, which upgrades ws because of upgrade-insecure-requests). It is loopback-only, allowlists only the two classifier hosts, and only accepts Instagram/localhost browser origins. Never expose it publicly. The local CA is installed automatically by npm run proxy; restart Firefox once
after installing. npm run trust:relay re-installs it manually (e.g. after a new
profile is created). Without the relay, the review shows an actionable “classifier couldnt reach the provider” banner instead of silently leaving accounts unclassified.MIT, same as the original InstagramUnfollowers project. See LICENSE.
The primary classifier is TypeSafe AI Jev (jev-latest), which is fast and cheap; DeepSeek is the fallback when Jev fails and can be configured for the local proxy or direct browser mode. Results are cached, batched, retried and strictly validated.
Dry run first, then confirm. The wizard runs a clearly-labelled dry run that changes nothing; only after reviewing it can you promote the exact same list to a live "nuke" with the typed approval. Categories other than the chosen one stay in Other / uncertain. Ambiguous guesses can be shown as manually selectable by default (Include Unsure accounts for manual sorting) so you can review and pick them yourself; the choice still goes through the same dry-run and typed live approval. The confidence floor is a free 0–100% number box, not a dropdown, so you can deliberately go below 50% when widening the net. The dry-run executor has no unfollow transport, so it makes zero Instagram write requests; live requires a typed UNFOLLOW <n> phrase plus an "I understand" checkbox.
Protects you. Whitelist (matched by account id and username), eligibility checks, incomplete-scan locks, per-account pacing, a still-followed preflight before every write, mid-run whitelist enforcement, and an automatic stop on Instagram action blocks (feedback_required / 429).
Nuclear, but tasteful. The interface is a restrained atomic-age test instrument with a live gas-centrifuge enrichment animation (counter-rotating rotors + cascade bars, reduced-motion aware): charcoal ground, uranium amber, olive, dosimeter green, engraved trefoil seal, tactile nu-skeuomorphic panels and hazard-stripe accents (no neon, no glows).