Markdown · llms.txt

LLM providers

tf generate and the generate screen inside tf onboard call one backend. The default is the Claude Code CLI. No API key.

Set the backend in .env or pass --provider / --model for a single run.

TF_LLM_PROVIDERKeyDefault model
claude-code (default)none; uses your claude loginthe CLI’s own default. TF_LLM_MODEL is passed as claude --model
anthropicANTHROPIC_API_KEYclaude-sonnet-4-6
openrouterOPENROUTER_API_KEYanthropic/claude-sonnet-4.6
openaiOPENAI_API_KEYgpt-4o
bash
# one-off, without editing .env
tf generate --provider anthropic --model claude-sonnet-4-6

Direct API calls use temperature 0.8 and a token cap (8,000 for a full bundle, so four ideas with two or three variants fit). Claude Code gets a 240 second timeout.

Claude Code subprocess

tf runs:

claude -p <prompt> --output-format json --permission-mode dontAsk --tools "" --disallowedTools "*,mcp__*" --strict-mcp-config --max-turns 1 --no-session-persistence

--tools "" removes built-in tools. --allowedTools only pre-approves tools, so it is not used as the control. Scraped tweets, articles, and Notion pages sit inside <reference_data>, and a closing fence typed inside that text is stripped. The subprocess cannot run shell commands or edit files.

If claude is not on PATH, the error tells you to install Claude Code or set TF_LLM_PROVIDER and a key.

Claude Code has to be logged in on that machine, including a server you cron from. tf does not ship a Claude credential.

Output shape

The model must return one JSON object. Zod checks persona (handle, identity, lane, voice rules, hottest take, building), contentPillars, replyTargets, cadence, strategy, and either ideas[] (each with variants[] of text, optional aim and note) or a legacy drafts[]. A flat drafts array is always written back after scoring, with text, score, signal, and optional note. Prose or a broken object throws. Re-run, or switch model.

Scores are computed in-process after the model returns text. tweet-factory does not execute the X ranking code. It multiplies editorial strengths by the published weights in src/rank/weights.ts (x-algorithm cb45b55). The same module builds the system prompt, so the prompt and the scorer share one table. The narrative write-up is X_ALGORITHM_BOOST_PLAYBOOK.md. When your own posts have enough impressions, src/rank/calibrate.ts scales reply, quote, repost, and like strengths from tweets.db. Bookmarks stay diagnostic. The formula is on how drafts are scored.

An optional org skill at ~/.claude/skills/twitter-algorithm-optimizer/ can replace that playbook when a person runs the /tweet-factory Claude Code skill. tf generate always uses the weights compiled into the binary.

Verify. tf generate --n 1 --json prints a JSON object with a drafts array, or fails with a clear provider error (missing claude, missing API key). Fix that error before treating generation as set up.