X

search-tweets

x.com · Cowork
Download for Coworkthe skill folder, zipped
How to use it in Coworkonce per skill
Download the skill (.zip)

One .zip per skill. Inside: SKILL.md with the intent and the frontmatter, and the code that runs in the page.

Open Skills in Cowork

Settings → Personalize → Skills. This is Cowork's own skill library, shared across every chat.

Add → pick the .zip

Click Add and choose the file you just downloaded. Cowork installs it once; no CLAUDE.md, no per-project setup.

Ask in plain language

The skill stays available in every session. Cowork runs it in your own Chrome, riding the session you are already signed into.

Side effectread
Authsession
Needsnavigate · evaluate
Summary

Search tweets on X/Twitter by keyword/topic (Latest tab), to find intent signals (people asking for a solution, complaining about a competitor, describing a problem).

Params
{"query":"string (search text)"}
Returns
{"count":"int","query":"string","results":"array of { displayName, handle, text, id, url, time }"}
SKILL.md45 lines

Intent

Search tweets on X/Twitter by keyword/topic (Latest tab), to find intent signals (people asking for a solution, complaining about a competitor, describing a problem). PARAM: query (search text, e.g. 'looking for a CRM' or 'alternative to notion'). X's internal API (SearchTimeline GraphQL) is blocked by the anti-bot header x-client-transaction-id, so it navigates to /search?q=...&f=live and parses the DOM (stable data-testid selectors) with scrolling to gather ~30-50 tweets. Returns { count, query, results:[{ displayName, handle, text, id, url, time }] }; if there are no results it returns count:0 / results:[] (not an error). handle = the @ without the at-sign (feeds x-get-profile / replying). NOTE: X virtualizes the timeline (only what's visible is in the DOM); the tool scrolls and dedupes by id, but still brings a subset. Image/video-only tweets may come with empty text. Requires an active X session. If X changes the data-testid, recapture.

Preconditions

  • Logged-in session in the browser you drive (X/Twitter session started (x.com cookies)).
  • If not logged in: navigate to https://x.com and let the user log in, then retry.

Execute

  1. navigate → https://x.com/search?q={{query|encode}}&src=typed_query&f=live
  2. evaluate the Extractor below with params. It does the in-page work and returns the JSON in returns.

Extractor

( async (root, params) => { const sleep = ms => new Promise(r=>setTimeout(r,ms)); const parse1 = a => { const nameEl=a.querySelector('[data-testid="User-Name"]'); const nl = nameEl ? nameEl.innerText.split('\n').filter(Boolean) : []; const handle=(nl.find(s=>s.startsWith('@'))||'').replace('@',''); const displayName=nl[0]||null; const statusLink=Array.from(a.querySelectorAll('a[href*="/status/"]')).map(x=>x.getAttribute('href')).find(h=>//status/\d+/.test(h)); const id=statusLink?(statusLink.match(/status/(\d+)/)||[])[1]:null; const timeEl=a.querySelector('time'); const time=timeEl?timeEl.getAttribute('datetime'):null; let full=a.textContent||''; const grp=a.querySelector('[role="group"]'); if(grp) full=full.split(grp.textContent)[0]; if(timeEl){ const t=timeEl.textContent; const i=full.indexOf(t); if(i>=0) full=full.slice(i+t.length); } const text=full.replace(/^[\s·]+/,'').replace(/^Article/,'').trim(); return { displayName, handle, text: text||null, id, url: statusLink?'https://x.com'+statusLink:null, time }; }; const seen=new Map(); const collect=()=>{ document.querySelectorAll('article[data-testid="tweet"]').forEach(a=>{ const r=parse1(a); if(r.id && !seen.has(r.id)) seen.set(r.id,r); }); }; for(let i=0;i<20 && document.querySelectorAll('article[data-testid="tweet"]').length===0;i++) await sleep(300); collect(); for(let s=0;s<6;s++){ window.scrollTo(0, document.body.scrollHeight); await sleep(900); collect(); } const results=Array.from(seen.values()); return { count: results.length, query: (params&&params.query)||null, results }; } )

Success assertion

{
  "expr": "[data-testid=\"primaryColumn\"]",
  "type": "dom"
}
search-tweets: the X skill in Cowork · browser-memory