Felo Twitter Writer
/install felo-twitter-writer
\r \r
Felo Twitter Writer Skill\r
\r
Constraints (MUST READ FIRST)\r
\r These rules are mandatory. Violating any of them will produce incorrect behavior.\r \r
- This skill uses SuperAgent directly. All generation is handled by
felo-superAgent/scripts/run_superagent.mjswith--skill-id twitter-writer. Do NOT attempt to generate tweet content yourself.\r \r - ALWAYS use
--jsonflag when calling SuperAgent. In Claude Code's Bash tool, stdout is always captured — it never streams directly to the user. JSON mode returns the full answer in a structured response. After the script finishes, readdata.answerfrom the JSON output and print it verbatim as your response text.\r \r - ALWAYS output
data.answerverbatim. After the script finishes, printdata.answerexactly as-is as your response text. Do NOT summarize, paraphrase, or add commentary around it.\r \r --live-doc-idis REQUIRED for every SuperAgent call. Follow these rules strictly:\r- Reuse any
live_doc_idalready available in this session (from a prior SuperAgent or livedoc call)\r - If none: run
node felo-livedoc/scripts/run_livedoc.mjs list --json, then find the first item whereis_shared === falseindata.items(list is sorted by modification time descending, so this gives the most recently modified private LiveDoc). Use itsshort_id.\r - If no
is_shared === falseitem exists (or list is empty): runnode felo-livedoc/scripts/run_livedoc.mjs create --name "Twitter Writer" --json, usedata.short_id\r - NEVER use a LiveDoc where
is_shared === true— shared LiveDocs belong to other projects and will cause a 502 error.\r \r
- Reuse any
- Always persist state. After every SuperAgent call, extract
thread_short_idandlive_doc_short_idfrom the JSON response fieldsdata.thread_short_idanddata.live_doc_short_id. Use them in subsequent calls.\r \r - Output language follows the user's input language. Default is
en. Detect the user's language and pass the matching--accept-languagevalue:jafor Japanese,enfor English,kofor Korean,zhfor Chinese. If unsure, useen.\r \r - Do NOT pass
--timeoutto the SuperAgent script. The script manages its own connection lifecycle.\r \r - Brand style selection for Mode 2 new conversations only. When starting a new conversation for content creation (Mode 2, no
thread_short_id), you MUST attempt to fetch the TWITTER style library and offer the user a style choice BEFORE calling SuperAgent. The style is passed via--ext '{"brand_style_requirement":"..."}'. Full procedure in the Style Selection section below.\r \r- Style category is always
TWITTER(hardcoded — this skill only writes tweets).\r --extis only valid for new conversations. Never pass it in follow-up mode (--thread-id).\r- If the style library returns no entries, skip silently and proceed without
--ext.\r - Mode 1 (style DNA extraction) does NOT use this step.\r \r
- Style category is always
When to Use\r
\r Trigger this skill when the user wants to:\r \r
- Analyze a Twitter/X account's writing style\r
- Extract a writing style DNA document from tweets\r
- Write, draft, or compose tweets / X posts\r
- Write a Twitter thread (multi-tweet series)\r
- Write an X long-form article / long post\r
- Imitate or mimic someone's tweet style\r
- Ghostwrite tweets on behalf of someone\r
- Understand how a specific account writes\r \r Trigger keywords:\r \r
- English:
analyze twitter style,twitter style analysis,extract writing style,style DNA,write a tweet,write tweets,draft a tweet,write a thread,twitter thread,X article,X long post,imitate tweet style,mimic tweet style,tweet in the style of,write like [account],X account analysis,analyze X account,ghostwrite tweets,how does [account] write\r - 日本語:
ツイートを書く,ツイートスタイル分析,スタイルDNA,ツイートを模倣,Xアカウント分析,ツイートのスタイルを抽出,〇〇風のツイートを書く,ツイートを代筆,Xアカウントを分析,このアカウントはどう書いている\r \r Explicit commands:/felo-twitter-writer,use felo twitter writer\r \r Do NOT use for:\r \r - General Twitter/X search only (use
felo-x-search)\r - General SuperAgent conversation (use
felo-superAgent)\r - Web search (use
felo-search)\r \r
Two Modes\r
\r
Mode 1 — Style DNA Extraction\r
\r When: User provides a Twitter/X account name and wants to understand or extract its writing style.\r \r Steps:\r \r
Step 1: Fetch tweets via felo-x-search\r
\r
node felo-x-search/scripts/run_x_search.mjs --id "USERNAME" --user --tweets --limit 30\r
```\r
\r
Also fetch the account profile:\r
\r
```bash\r
node felo-x-search/scripts/run_x_search.mjs --id "USERNAME" --user\r
```\r
\r
#### Step 2: Obtain live_doc_id\r
\r
Follow Constraint #4 above.\r
\r
#### Step 3: Call SuperAgent with tweet content\r
\r
Determine conversation mode first:\r
- If **no** `thread_short_id` exists in this session → new conversation (pass `--skill-id twitter-writer`)\r
- If `thread_short_id` **already exists** in this session → follow-up (pass `--thread-id`)\r
\r
Replace `LANG` with the user's language: `en` (English), `zh` (Chinese), `ja` (Japanese), `ko` (Korean). See Constraint #6.\r
\r
**New conversation (first call in session):**\r
\r
```bash\r
node felo-superAgent/scripts/run_superagent.mjs \\r
--query "/twitter-writer ENRICHED_QUERY_WITH_TWEET_CONTENT" \\r
--live-doc-id "LIVE_DOC_ID" \\r
--skill-id twitter-writer \\r
--accept-language LANG \\r
--json\r
```\r
\r
**Follow-up (thread_short_id already exists):**\r
\r
```bash\r
node felo-superAgent/scripts/run_superagent.mjs \\r
--query "/twitter-writer ENRICHED_QUERY_WITH_TWEET_CONTENT" \\r
--thread-id "THREAD_SHORT_ID" \\r
--live-doc-id "LIVE_DOC_ID" \\r
--accept-language LANG \\r
--json\r
```\r
\r
**Query construction example:**\r
\r
> Please analyze the following tweets from @USERNAME and extract a writing style DNA document. Cover dimensions such as: tone, sentence structure, opening hooks, closing calls-to-action, frequently used words, hashtag strategy, emoji usage, and any other distinctive patterns.\r
>\r
> Account bio: [BIO]\r
>\r
> Tweets:\r
> [TWEET_1]\r
> [TWEET_2]\r
> ...\r
\r
Keep the query under 2000 characters. If tweet content is too long, include the most representative 10–15 tweets.\r
\r
#### Step 4: Save state\r
\r
Extract `thread_short_id` and `live_doc_short_id` from the JSON response fields `data.thread_short_id` and `data.live_doc_short_id`. Save for follow-up calls.\r
\r
---\r
\r
### Mode 2 — Content Creation\r
\r
**When:** User wants to create tweets, threads, or X long-form posts (with or without a style DNA).\r
\r
**Steps:**\r
\r
#### Step 1: Determine if style DNA is available\r
\r
- If Mode 1 was just run in this session → style DNA is already in the LiveDoc canvas, use follow-up mode\r
- If user provides a style DNA directly → include it in the query\r
- If user provides an account name → run Mode 1 first, then continue with Mode 2\r
- If no style DNA → proceed to style library selection (Step 1.5)\r
\r
#### Step 1.5: Brand Style Selection (new conversations only)\r
\r
**Only run this step when:**\r
- This is a **new conversation** (no `thread_short_id` in session), AND\r
- Mode 1 was NOT just run (i.e., there is no existing thread carrying style DNA context)\r
\r
**Skip this step entirely when:**\r
- `thread_short_id` already exists (follow-up) — `--ext` has no effect in follow-up mode\r
- Mode 1 was just run in this session — style context is already in the thread\r
\r
**1.5a. Check if user already specified a style:**\r
\r
If the user mentioned a style by name (e.g., "use my Bold Voice style") or pasted a style block, note it and skip to step 1.5d.\r
\r
**1.5b. Fetch the TWITTER style library (names only):**\r
\r
IMPORTANT: The style library output is very large (each Style DNA can be thousands of characters). Always use `--json` and extract only names/labels to avoid Bash tool output truncation. Never call `run_style_library.mjs` without `--json` for listing purposes.\r
\r
```bash\r
node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language LANG --json | node -e "\r
const d=require('fs').readFileSync('/dev/stdin','utf8');\r
const j=JSON.parse(d);\r
const list=j.list||[];\r
const user=list.filter(s=>!s.recommended);\r
const rec=list.filter(s=>s.recommended);\r
if(user.length) { console.log('[Your styles]'); user.forEach((s,i)=>{ const labels=(s.content?.labels?.LANG||s.content?.labels?.en||[]).join(', '); console.log((i+1)+'. '+s.name+(labels?' — '+labels:'')); }); }\r
if(rec.length) { console.log('[Recommended styles]'); rec.forEach((s,i)=>{ const labels=(s.content?.labels?.LANG||s.content?.labels?.en||[]).join(', '); console.log((user.length+i+1)+'. '+s.name+(labels?' — '+labels:'')); }); }\r
if(!list.length) console.log('(No styles found)');\r
"\r
```\r
\r
Replace `LANG` with the user's language value (`zh`, `ja`, `ko`, `en`) in both `--accept-language` and inside the node script's `labels?.LANG` references.\r
\r
Always pass `--accept-language` matching the user's language (same value used for SuperAgent).\r
\r
**1.5c. Handle the result:**\r
\r
**If the list is empty:** Skip silently. Proceed to Step 2 without `--ext`.\r
\r
**If styles are available:** Output the COMPLETE list as plain text — every style returned by the API, grouped by type, numbered sequentially. NEVER use `AskUserQuestion` tool (it limits to 4 options and will silently drop styles). NEVER pre-select or filter styles on behalf of the user. Always append a "no preference" option as the last item. Then wait for the user's plain-text reply before proceeding.\r
\r
Example presentation (adapt language to match user's language):\r
```\r
Here are the available Twitter writing styles — choosing one will make the output more accurate:\r
\r
[Your styles]\r
1. My Bold Voice\r
\r
[Recommended styles]\r
2. elonmusk — Shitposting provocateur\r
3. naval — Pithy aphorism master\r
...(list ALL styles, do not omit any)\r
\r
0. No preference — use default style\r
```\r
\r
**1.5d. Build `--ext` from the chosen style:**\r
\r
After the user selects a style, fetch the full Style DNA for that specific style using `--json` and extract it in Node.js. Do NOT re-read the full text output — it will be truncated by the Bash tool.\r
\r
```bash\r
node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language LANG --json | node -e "\r
const d=require('fs').readFileSync('/dev/stdin','utf8');\r
const j=JSON.parse(d);\r
const s=(j.list||[]).find(s=>s.name==='CHOSEN_STYLE_NAME');\r
if(!s){process.stderr.write('Style not found\
');process.exit(1);}\r
const labels=(s.content?.labels?.LANG||s.content?.labels?.en||[]).join(', ');\r
const dna=s.content?.styleDna||'';\r
const block='Style name: '+s.name+'\
Style labels: '+labels+'\
Style DNA: '+dna;\r
console.log(JSON.stringify({brand_style_requirement:block}));\r
"\r
```\r
\r
Replace `CHOSEN_STYLE_NAME` with the style name the user selected, and `LANG` with the language code.\r
\r
Pass the output JSON directly as the `--ext` value:\r
\r
```bash\r
--ext "$(node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language LANG --json | node -e "\r
const d=require('fs').readFileSync('/dev/stdin','utf8');\r
const j=JSON.parse(d);\r
const s=(j.list||[]).find(s=>s.name==='CHOSEN_STYLE_NAME');\r
const labels=(s.content?.labels?.LANG||s.content?.labels?.en||[]).join(', ');\r
const dna=s.content?.styleDna||'';\r
const block='Style name: '+s.name+'\
Style labels: '+labels+'\
Style DNA: '+dna;\r
console.log(JSON.stringify({brand_style_requirement:block}));\r
")"\r
```\r
\r
If the user chose "no preference" (option 0), do NOT pass `--ext`.\r
\r
#### Step 2: Obtain live_doc_id\r
\r
Follow Constraint #4. If Mode 1 was already run, reuse the same `live_doc_id`.\r
\r
#### Step 3: Determine conversation mode\r
\r
| Condition | Mode | What to pass |\r
|-----------|------|--------------|\r
| No `thread_short_id` in this session (truly first call) | New conversation | `--live-doc-id` + `--skill-id twitter-writer` + `--ext` (if style chosen) |\r
| `thread_short_id` already exists in this session (all subsequent inputs, including after Mode 1) | Follow-up | `--thread-id` + `--live-doc-id` (NO `--ext`) |\r
| User says "new topic" / "start over" (clear `thread_short_id`) | New conversation | `--live-doc-id` + `--skill-id twitter-writer` + `--ext` (repeat Step 1.5) |\r
\r
#### Step 4: Call SuperAgent\r
\r
Replace `LANG` with the user's language: `en`, `zh`, `ja`, `ko`. See Constraint #6.\r
\r
**New conversation without style (no `thread_short_id`, user chose no preference or list was empty):**\r
\r
```bash\r
node felo-superAgent/scripts/run_superagent.mjs \\r
--query "/twitter-writer ENRICHED_QUERY" \\r
--live-doc-id "LIVE_DOC_ID" \\r
--skill-id twitter-writer \\r
--accept-language LANG \\r
--json\r
```\r
\r
**New conversation with brand style:**\r
\r
```bash\r
node felo-superAgent/scripts/run_superagent.mjs \\r
--query "/twitter-writer ENRICHED_QUERY" \\r
--live-doc-id "LIVE_DOC_ID" \\r
--skill-id twitter-writer \\r
--ext '{"brand_style_requirement":"Style name: darioamodei\
Style labels: Thoughtful long-form essays\
Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA\
\
## Style Overview\
Dario writes like a serious intellectual...(full content, do NOT truncate)"}' \\r
--accept-language LANG \\r
--json\r
```\r
\r
**Follow-up (`thread_short_id` already exists in session):**\r
\r
```bash\r
node felo-superAgent/scripts/run_superagent.mjs \\r
--query "/twitter-writer USER_FOLLOW_UP" \\r
--thread-id "THREAD_SHORT_ID" \\r
--live-doc-id "LIVE_DOC_ID" \\r
--accept-language LANG \\r
--json\r
```\r
\r
**Query construction guidelines:**\r
\r
- Specify the content type: single tweet / thread / X long-form post\r
- Specify the topic clearly\r
- Include style DNA or reference account if available\r
- Default to 3 versions unless the user specifies otherwise\r
- Preserve the user's core intent; only add context and clarity\r
\r
**Query examples:**\r
\r
> Please write 3 versions of a tweet about [TOPIC] in the style of @USERNAME (style DNA above). Each version should feel distinct — vary the tone, structure, or angle.\r
\r
> Based on the style DNA extracted above, write a Twitter thread (5–7 tweets) about [TOPIC]. Start with a strong hook tweet.\r
\r
> Write an X long-form post about [TOPIC] following the writing style we analyzed. Aim for ~500 words.\r
\r
#### Step 5: Save state\r
\r
Extract `thread_short_id` and `live_doc_short_id` from the JSON response fields `data.thread_short_id` and `data.live_doc_short_id`.\r
\r
---\r
\r
## Mode Decision Logic\r
\r
```\r
User input\r
│\r
├── Contains account name + "analyze / style / DNA / how does X write"\r
│ OR: アカウント名 + "分析 / スタイル / DNA / どう書いている"\r
│ → Mode 1 (Style DNA Extraction) — skip style library step\r
│\r
├── Contains account name + "write / create / imitate / in the style of"\r
│ OR: アカウント名 + "書いて / 作って / 風に / 真似て"\r
│ → Mode 1 first → then Mode 2 (follow-up, skip style library step)\r
│\r
├── Contains topic + "write / draft / tweet / thread / X post"\r
│ OR: トピック + "書いて / ツイート / スレッド / Xの投稿"\r
│ → Mode 2 directly\r
│ └── New conversation?\r
│ YES → Step 1.5: fetch TWITTER styles, present to user, wait for choice\r
│ NO → follow-up, skip style library step\r
│\r
└── Ambiguous (e.g., "help me with tweets" / "ツイートを手伝って")\r
→ Ask user: do they want to analyze an account's style, or create content?\r
```\r
\r
---\r
\r
## Complete Workflow Examples\r
\r
### Example A: Analyze an account's style\r
\r
```\r
User: "Analyze @paulg's tweet style"\r
```\r
\r
**Step 1:** Fetch tweets:\r
```bash\r
node felo-x-search/scripts/run_x_search.mjs --id "paulg" --user --tweets --limit 30\r
node felo-x-search/scripts/run_x_search.mjs --id "paulg" --user\r
```\r
\r
**Step 2:** Get `live_doc_id` (list or create)\r
\r
**Step 3:** Call SuperAgent (Mode 1 — no style library step):\r
```bash\r
node felo-superAgent/scripts/run_superagent.mjs \\r
--query "/twitter-writer Please analyze the following tweets from @paulg and extract a writing style DNA document. Cover tone, sentence structure, opening hooks, closing CTAs, frequently used words, hashtag strategy, and emoji usage.\
\
Account bio: [BIO]\
\
Tweets:\
[TWEETS]" \\r
--live-doc-id "LIVE_DOC_ID" \\r
--skill-id twitter-writer \\r
--accept-language en \\r
--json\r
```\r
\r
**Step 4:** Save `thread_short_id` and `live_doc_short_id` from JSON response fields `data.thread_short_id` and `data.live_doc_short_id`.\r
\r
---\r
\r
### Example B: Create tweets with a reference style (Mode 1 → Mode 2)\r
\r
```\r
User: "Write 3 tweets about startups in @paulg's style"\r
```\r
\r
**Step 1:** Run Mode 1 to extract style DNA (same as Example A). Style library step is skipped because Mode 1 already establishes style context in the thread.\r
\r
**Step 2:** Reuse `live_doc_id` from Mode 1.\r
\r
**Step 3:** Follow-up call (continuing the same thread — `thread_short_id` from Mode 1, no `--ext`):\r
```bash\r
node felo-superAgent/scripts/run_superagent.mjs \\r
--query "/twitter-writer Based on the @paulg style DNA extracted above, write 3 tweet variations about startups. Each should have a distinct tone and angle, within 280 characters." \\r
--thread-id "THREAD_SHORT_ID" \\r
--live-doc-id "LIVE_DOC_ID" \\r
--accept-language en \\r
--json\r
```\r
\r
---\r
\r
### Example C: Write a thread directly (Mode 2, new conversation, with style selection)\r
\r
```\r
User: "Write a Twitter thread about why most startups fail"\r
```\r
\r
**Step 1.5:** New conversation, no existing thread → fetch TWITTER styles (names only):\r
```bash\r
node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en --json | node -e "\r
const d=require('fs').readFileSync('/dev/stdin','utf8');\r
const j=JSON.parse(d);\r
const list=j.list||[];\r
const user=list.filter(s=>!s.recommended);\r
const rec=list.filter(s=>s.recommended);\r
if(user.length){console.log('[Your styles]');user.forEach((s,i)=>{const labels=(s.content?.labels?.en||[]).join(', ');console.log((i+1)+'. '+s.name+(labels?' — '+labels:''));});}\r
if(rec.length){console.log('[Recommended styles]');rec.forEach((s,i)=>{const labels=(s.content?.labels?.en||[]).join(', ');console.log((user.length+i+1)+'. '+s.name+(labels?' — '+labels:''));});}\r
if(!list.length)console.log('(No styles found)');\r
"\r
```\r
\r
Present to user:\r
```\r
Here are the available Twitter writing styles — choosing one will make the output more accurate:\r
\r
[Your styles]\r
1. My Bold Voice\r
\r
[Recommended styles]\r
2. darioamodei\r
\r
0. No preference — use default style\r
```\r
\r
User replies: `1`\r
\r
**Step 2:** Get `live_doc_id`.\r
\r
**Step 3:** New conversation with chosen style — extract full Style DNA via `--json` and pass as `--ext`:\r
```bash\r
node felo-superAgent/scripts/run_superagent.mjs \\r
--query "/twitter-writer Write a Twitter thread (6–8 tweets) about why most startups fail. Start with a strong hook tweet that grabs attention. Each tweet should stand alone but flow naturally into the next." \\r
--live-doc-id "LIVE_DOC_ID" \\r
--skill-id twitter-writer \\r
--ext "$(node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en --json | node -e "\r
const d=require('fs').readFileSync('/dev/stdin','utf8');\r
const j=JSON.parse(d);\r
const s=(j.list||[]).find(s=>s.name==='My Bold Voice');\r
const labels=(s.content?.labels?.en||[]).join(', ');\r
const block='Style name: '+s.name+'\
Style labels: '+labels+'\
Style DNA: '+s.content.styleDna;\r
console.log(JSON.stringify({brand_style_requirement:block}));\r
")" \\r
--accept-language en \\r
--json\r
```\r
\r
**Step 4:** Save `thread_short_id` and `live_doc_short_id` from JSON response fields `data.thread_short_id` and `data.live_doc_short_id`.\r
\r
---\r
\r
### Example D: Iterate on generated content (follow-up, no style step)\r
\r
```\r
User: "Make the 2nd tweet more humorous and add some emojis"\r
```\r
\r
Already have `thread_short_id` and `live_doc_id` from the previous call. This is a follow-up — do NOT fetch styles again, do NOT pass `--ext`.\r
\r
```bash\r
node felo-superAgent/scripts/run_superagent.mjs \\r
--query "/twitter-writer Please revise the 2nd tweet generated above. Make the tone more humorous and lighthearted, and add appropriate emojis. Keep the original intent intact." \\r
--thread-id "THREAD_SHORT_ID" \\r
--live-doc-id "LIVE_DOC_ID" \\r
--accept-language en \\r
--json\r
```\r
\r
**Save** updated `thread_short_id` and `live_doc_short_id` from JSON response fields `data.thread_short_id` and `data.live_doc_short_id`.\r
\r
---\r
\r
### Example E: User specifies style by name\r
\r
```\r
User: "Write a tweet about AI trends using my 'Bold Voice' style"\r
```\r
\r
**Step 1.5a:** User already named the style → extract full Style DNA via `--json`. No need to ask the user again.\r
\r
**Step 3:** New conversation with that style:\r
```bash\r
node felo-superAgent/scripts/run_superagent.mjs \\r
--query "/twitter-writer Write a tweet about AI trends" \\r
--live-doc-id "LIVE_DOC_ID" \\r
--skill-id twitter-writer \\r
--ext "$(node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en --json | node -e "\r
const d=require('fs').readFileSync('/dev/stdin','utf8');\r
const j=JSON.parse(d);\r
const s=(j.list||[]).find(s=>s.name==='My Bold Voice');\r
const labels=(s.content?.labels?.en||[]).join(', ');\r
const block='Style name: '+s.name+'\
Style labels: '+labels+'\
Style DNA: '+s.content.styleDna;\r
console.log(JSON.stringify({brand_style_requirement:block}));\r
")" \\r
--accept-language en \\r
--json\r
```\r
\r
---\r
\r
### Example F: Style library is empty\r
\r
```\r
User: "Write a tweet about the new product launch"\r
```\r
\r
**Step 1.5b:** Fetch styles (names only):\r
```bash\r
node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en --json | node -e "\r
const d=require('fs').readFileSync('/dev/stdin','utf8');\r
const j=JSON.parse(d);\r
if(!(j.list||[]).length)console.log('(No styles found)');\r
else console.log((j.list||[]).map(s=>s.name).join('\
'));\r
"\r
```\r
\r
Output: `(No styles found)`\r
\r
**Skip silently.** Proceed directly without `--ext`:\r
```bash\r
node felo-superAgent/scripts/run_superagent.mjs \\r
--query "/twitter-writer Write a tweet about the new product launch. Provide 3 versions with different tones." \\r
--live-doc-id "LIVE_DOC_ID" \\r
--skill-id twitter-writer \\r
--accept-language en \\r
--json\r
```\r
\r
---\r
\r
### Example G: User chooses no preference\r
\r
```\r
User: "Write a tweet about a new product launch"\r
```\r
\r
**Step 1.5:** Fetch styles, present list. User replies: `0` (no preference).\r
\r
Proceed without `--ext`:\r
```bash\r
node felo-superAgent/scripts/run_superagent.mjs \\r
--query "/twitter-writer Write 3 tweets about a new product launch, each with a slightly different tone." \\r
--live-doc-id "LIVE_DOC_ID" \\r
--skill-id twitter-writer \\r
--accept-language en \\r
--json\r
```\r
\r
---\r
\r
## Error Handling\r
\r
| Scenario | Action |\r
|----------|--------|\r
| Account not found or no tweets returned | Inform user, suggest trying a different username or providing tweet samples manually |\r
| `FELO_API_KEY` not set | Stop and show setup instructions (same as `felo-superAgent` SKILL.md) |\r
| SuperAgent call fails | Check `live_doc_id` validity; retry once with the same parameters |\r
| Style library fetch fails | Log warning to stderr, skip silently, proceed without `--ext` |\r
| User asks for Mode 2 with no style DNA and no account | Proceed to Step 1.5 (style library selection) |\r
| User explicitly requests a new canvas | Create a new LiveDoc: `node felo-livedoc/scripts/run_livedoc.mjs create --name "Twitter Writer" --json` |\r
| Tweet content too long for query (>2000 chars) | Trim to the 10–15 most representative tweets; prioritize high-engagement ones |\r
\r
## References\r
\r
- [felo-superAgent SKILL.md](../felo-superAgent/SKILL.md) — SuperAgent calling conventions, `--ext` format, and style library script\r
- [felo-x-search SKILL.md](../felo-x-search/SKILL.md) — X/Twitter search commands\r
- [felo-livedoc SKILL.md](../felo-livedoc/SKILL.md) — LiveDoc management commands\r
- [Felo Open Platform](https://openapi.felo.ai/docs/)\r
- [Get API Key](https://felo.ai) (Settings → API Keys)\r
- 确保已安装 OpenClaw(本地或 Docker 部署)
- 在对话框中输入安装命令:
/install felo-twitter-writer - 安装完成后,直接呼叫该 Skill 的名称或使用
/felo-twitter-writer触发 - 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
Felo Twitter Writer 是什么?
Dual-mode Twitter/X writing tool. Mode 1: input a Twitter account, auto-fetch popular tweets and extract a writing style DNA document. Mode 2: based on style... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 91 次。
如何安装 Felo Twitter Writer?
在 OpenClaw 或 Claude Code 对话框中运行命令「/install felo-twitter-writer」即可一键安装,无需额外配置。
Felo Twitter Writer 是免费的吗?
是的,Felo Twitter Writer 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。
Felo Twitter Writer 支持哪些平台?
Felo Twitter Writer 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。
谁开发了 Felo Twitter Writer?
由 wangzhiming(@wangzhiming1999)开发并维护,当前版本 v1.0.0。