| name | Scroll X |
| description | Extract posts from X.com feed via Libretto workflow, then analyze for comment-worthy and generally interesting content |
Scroll X Feed Extraction
Runs the Libretto workflow to extract posts from X.com, then analyzes the results for:
- Posts worth commenting on given your expertise
- Posts that are generally interesting to you
Always present comment-worthy posts first.
Usage
[skill:scroll-x] [target posts]
Default target: 50 posts
Step 1: Run the Libretto Workflow
Run the extraction workflow headlessly with the saved auth profile:
libretto run ./workflows/scroll-x.ts --headless --auth-profile x.com --params '{"targetPosts": 50}'
If the user specified a custom target count, pass it instead:
libretto run ./workflows/scroll-x.ts --headless --auth-profile x.com --params '{"targetPosts": 80}'
If the workflow fails with an auth error, the profile may have expired. Re-login:
libretto open https://x.com --session login-x
libretto save x.com --session login-x
libretto close --session login-x
Then re-run the workflow.
Step 2: Analyze the Output
After the workflow completes, read the output file and present a two-part analysis.
Load Summary History
Read x_summary_history.json from the project root — if it doesn't exist, start with an empty array. Filter out any posts whose IDs appear in the history.
If there are no new posts, tell the user: "No new X posts since last summary."
User profile for filtering
Read profile.md from the project root to understand what topics the user cares about, what they're trying to grow, and what their engagement style is. Use this to judge which posts are comment-worthy vs. interesting vs. skippable.
Link rules (critical)
- Never reconstruct or guess X URLs.
- Always use the exact
link field from the extracted JSON as the post link.
- If
externalLinks is non-empty, include them as supplementary links.
- If an external link is a t.co link, still include it — do not invent a resolved URL.
What belongs in Good posts to comment on
Include posts where the user has a real angle worth adding.
Be selective. Quality over quantity. 0-6 posts is normal.
For each such post, explain:
- why it is a strong commenting opportunity
- what angle would be natural/helpful to take
Do not draft the full comment unless explicitly asked.
What belongs in Interesting generally
Include posts that align with the user's broader interests even if they are not obvious commenting opportunities.
What to Skip
- low-signal memes, shitposts, vague jokes
- generic hype discourse without substance
- engagement bait
- vague teasers with no concrete product/technical substance
- commentary where the user would have no distinctive perspective
Formatting
Always present comment-worthy posts first.
Section 1: Good posts to comment on
Use this exact format:
## Good posts to comment on
**<Short title>** — <Why this is relevant to comment on>
> *"<Relevant snippet from the post>"* — **<Author>**
> **Why comment:** <1 sentence>
> **Angle:** <1 sentence describing the helpful angle to take>
> **Post:** [link](<exact link field from JSON>)
> **Supplementary:** [link 1](<url>), [link 2](<url>)
If there are no supplementary links, omit the Supplementary line.
If there are none, say:
## Good posts to comment on
No especially strong X commenting opportunities this run.
Section 2: Interesting generally
Use this exact format:
## Interesting generally
**<Short title>** — <Why this is interesting>
> *"<Relevant snippet from the post>"* — **<Author>**
> **Post:** [link](<exact link field from JSON>)
> **Supplementary:** [link 1](<url>), [link 2](<url>)
If there are no supplementary links, omit the Supplementary line.
Persist Summary History
After generating the summary, save the IDs of all newly surfaced posts back to x_summary_history.json so they are not shown again next run.
Post Structure
Each post in the output file:
{
"id": "2016927763652055300",
"author": "Display Name",
"handle": "username",
"text": "Post content (truncated to 1000 chars)",
"link": "https://x.com/username/status/2016927763652055300",
"time": "2026-01-29T17:33:46.000Z",
"externalLinks": ["https://example.com/blog-post"]
}
Troubleshooting
- Auth expired - Re-login and save profile:
libretto open https://x.com --session login && libretto save x.com --session login
- Fewer than target posts - X may throttle or recycle content. Getting close to target is the goal, not a strict guarantee.
- Want to reset history? - Delete
x_summary_history.json to start fresh