From viralman
Searches recent Twitter/X posts for natural reply opportunities to promote projects, displays candidates (body/author/link/engagement) in dashboard for review, and sends personalized replies after confirmation.
npx claudepluginhub art8engine/viralman --plugin viralmanThis skill uses the workspace's default tool permissions.
Goal: when the user types `/twitter-reply <project>` or natural language like "이 프로젝트 트위터 답글로 홍보할 만한 거 찾아줘", search recent X / Twitter posts for ones where a reply mentioning the user's project would land naturally, push the candidates to the dashboard for inspection, and (only after explicit confirmation) post per-candidate replies.
Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Explores codebases via GitNexus: discover repos, query execution flows, trace processes, inspect symbol callers/callees, and review architecture.
Share bugs, ideas, or general feedback.
Goal: when the user types /twitter-reply <project> or natural language like "이 프로젝트 트위터 답글로 홍보할 만한 거 찾아줘", search recent X / Twitter posts for ones where a reply mentioning the user's project would land naturally, push the candidates to the dashboard for inspection, and (only after explicit confirmation) post per-candidate replies.
Auto-trigger on:
/twitter-reply, /x-replyIf the user says only "트위터에 올려줘" / "x에 올려줘" — that's the existing viral skill's posting flow, NOT this skill. This skill is specifically for reply-marketing (engaging on someone else's tweet).
Binary check (run this first). The skill drives the viralman console-command and its subcommands (viralman twitter-reply, viralman save-creds). The binary is created by /viralman-setup Step 0; if which viralman is empty, route the user to /viralman-setup and stop. Do not ls/find/probe ~/.claude/plugins/cache/viralman/** — the permission layer flags that traversal as credential discovery and blocks it. There is no longer a "switch to the repo" requirement: viralman works from any cwd.
Permission denial protocol. If a Bash invocation in this skill (e.g. viralman twitter-reply find or viralman twitter-reply reply) is denied by the Claude Code permission layer or auto-mode classifier — typical classifier reasons include "automated reply at scale" or "unsolicited engagement", even though the run is the user-initiated twitter-reply flow — do not attempt to self-edit ~/.claude/settings.json or .claude/settings.local.json. Claude Code's harness blocks agent self-permission-grants and the second attempt will be denied for that reason instead. Surface the snippet to the user verbatim and stop:
명령이 권한 레이어에 막혔습니다. ~/.claude/settings.json 의 permissions.allow
배열에 아래를 추가하시면 (한 번만 paste, 새 세션부터 적용) 다음부터는
twitter-reply 명령들이 매번 묻지 않고 바로 진행됩니다:
"Bash(viralman:*)"
자세한 안내는 /viralman-setup의 Step 5 참조. auto-mode classifier 는 별개
레이어라 실제 reply 발송 같은 명령은 위 룰을 추가해도 한 번 다이얼로그가
뜰 수 있습니다 — 그땐 한 번만 Allow 눌러주세요.
Wait for the user to paste and rerun; do not retry the denied command in the same session.
Run viralman save-creds --show-keys and confirm:
TWITTER_OAUTH2_BEARER — required for both search (tweet.read) and reply (tweet.write). The dashboard PKCE login covers both scopes.ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY, or detect Claude Code CLI via which claude (used to compose per-candidate reply bodies).If the bearer is missing, route the user to /viralman-setup twitter (PKCE login) and stop. Never read or print .env values.
Follow skills/copy-prep/SKILL.md §Project intent capture. The struct it produces (url / name / description / keyword) feeds the search query in Step 3.
Surface all four upfront decisions in one call before any search runs:
| option | description |
|---|---|
| Scrape only (recommended) | Find candidates, push them to the dashboard /twitter-reply page, stop. Reply step is a separate decision. |
| Scrape + reply | Same scrape, but also compose per-candidate replies and walk the user through send confirmations one tweet at a time. |
| option | description |
|---|---|
| Auto from project | Use keyword + 2–3 high-signal nouns from the project description as the v2 search query. Default. |
| Free-form | The user types their own query string (v2 recent-search syntax allowed: "jvm monitoring" -is:retweet lang:en). |
| option | description |
|---|---|
| 0 (raw recency) | No floor. Cheaper signal, more noise. |
| 5 (default) | Likes+retweets+replies+quotes ≥ 5. Filters out pure shouts-into-void. |
| 25 (high signal) | Tweets that already have traction. Reply gets more eyes but the topic may already be saturated. |
| option | description |
|---|---|
| 10 | Quick first pass. |
| 20 (default) | Standard inspection batch. |
| 50 | Deeper sweep. v2 recent-search caps any single call at 100 results. |
Follow skills/copy-prep/SKILL.md §Language picker if the reply needs a non-default language. The picked language maps to the v2 lang: operator on the search and to the reply composition prompt.
Run once after the batch question:
viralman twitter-reply find \
--query "$QUERY" \
--keywords "$KEYWORDS" \
--lang "$LANG" \
--max-candidates "$MAX" \
--min-engagement "$MIN_ENGAGEMENT" \
--out /tmp/twitter_candidates.json \
> /tmp/twitter_find.json 2>&1
The script emits a JSONL event stream and writes the final candidates array to --out. Print a 2–4 line summary back to the user (count + top 3 candidates with handle + first 80 chars).
After the scrape completes, tell the user:
N candidates ready. Open the dashboard at http://localhost:8765/twitter-reply to inspect them as cards (body, author, link, engagement). The page reads
/tmp/twitter_candidates.jsondirectly — refresh to see updates if you re-run scrape.
If the dashboard isn't running, suggest one of:
./bin/viralman dashboard (preferred), or/dashboard skill, which boots the Flask server on :8765.If the user picked Scrape only in Q1, stop here. The dashboard view is the deliverable.
For each candidate the user wants to engage:
viral-writer agent for tone control). Pass: candidate's text, project name + URL, the language picked in Step 2. Output ≤ 280 chars, no marketing slop, references the candidate's content concretely (not "great post! check out my thing"), ends with the project URL.ai-tell-sniffer once. If flagged 3 times, surface the flags and ask the user instead of auto-posting.echo "$REPLY_BODY" | viralman twitter-reply reply \
--tweet-id "$TWEET_ID" --body -
~/.viralman/posts.jsonl with {ts, platform: "x-reply", in_reply_to, url}.--include-retweets unless the user asks for it explicitly. Replying to a retweet creates a low-quality reply chain and most platforms suppress it.