How last30days-skill Resolves X Handles: Automatic Extraction vs. Explicit Resolution
last30days-skill resolves X (Twitter) handles through a dual-phase pipeline that automatically extracts and ranks handles from initial search results while optionally supporting explicit handle resolution via the --x-handle CLI flag.
The last30days-skill repository implements a robust X handle resolution system that combines automated entity extraction with user-specified targeting. This open-source skill analyzes social media data from the past 30 days, automatically identifying influential X accounts from search results while allowing users to force inclusion of specific handles through command-line arguments.
Automatic Handle Extraction from Search Results
The primary resolution mechanism extracts handles from the initial phase-1 X search conducted via the bundled bird-x client. After bird_x.search_handles returns raw results containing author_handle and tweet text fields, the system parses these for account identifiers and mentions.
In scripts/lib/entity_extract.py, the _extract_x_handles function (lines 50-77) processes each result to:
- Normalize
author_handleusing.strip().lstrip("@").lower() - Detect @-mentions in tweet text via the regex
@(\w{1,15}) - Increment a
Counterfor each non-generic handle - Return handles sorted by frequency of appearance
Generic handles such as elonmusk, openai, and twitter are filtered out during this process to prevent false positives from overwhelming the results.
Explicit Handle Resolution with --x-handle
When users require deterministic control over specific accounts, the CLI accepts the --x-handle (or -x) flag. Parsed in scripts/last30days.py (lines 750-860), this resolved_handle argument triggers a second, unfiltered search targeting only the specified handle.
The system checks for the has_resolved condition and submits a supplemental query via executor.submit():
if has_resolved:
resolved_future = executor.submit(
bird_x.search_handles,
[resolved_handle], # single-handle list
query, start_date, count_per=1
)
This secondary search merges its results into supplemental_x, ensuring posts from the specified account appear in the final report even if that user never appeared as an author or mention in the initial dataset.
Report Generation and Rendering
After the supplemental search completes, the resolved handle is stored on the report object. At line 1879 in scripts/last30days.py, the assignment report.resolved_x_handle = args.x_handle persists the value.
The Report data class in scripts/lib/schema.py defines the resolved_x_handle field, which is serialized into the JSON cache for reproducibility. During rendering, scripts/lib/render.py (lines 130-150) checks for this field and outputs a special "Resolved X Handle" section, annotating items with "(via @resolved_handle + keyword search)" to indicate their provenance.
Practical Code Examples
Running with an Explicit Handle
Force the skill to resolve a specific X handle using the CLI flag:
python -m scripts.last30days \
"the future of AI" \
--x-handle "samaltman" \
--emit=compact
This triggers the unfiltered secondary search for @samaltman and includes a "Resolved X Handle" line in the output.
Programmatic Handle Extraction
Extract and inspect handles from raw X search results:
from scripts.lib.entity_extract import extract_entities
# Assume x_items is returned by bird_x.search_handles(...)
entities = extract_entities(reddit_items=[], x_items=x_items, max_handles=5)
print("Top X handles found in phase-1 results:")
for h in entities["x_handles"]:
print("@", h, sep="")
Manual Resolved-Handle Search
Replicate the internal secondary search programmatically:
from scripts.lib.bird_x import search_handles
resolved = search_handles(
handles=["samaltman"],
query="the future of AI",
start_date="2026-01-01",
count_per=1
)
print(f"Fetched {len(resolved)} posts from @samaltman")
Summary
- Automatic extraction captures the most talked-about accounts from author fields and @-mentions, filtering generic handles and ranking by frequency via
_extract_x_handlesinentity_extract.py - Explicit resolution via
--x-handletriggers a dedicated unfiltered search throughbird_x.search_handles, merging results into the supplemental dataset - Report persistence stores the resolved handle in
report.resolved_x_handleaccording to the schema defined inschema.py - Visual confirmation appears in rendered output through
render.py, clearly indicating which handle provided supplemental content
Frequently Asked Questions
How does last30days-skill filter out generic X handles?
The _extract_x_handles function maintains an exclusion list that removes commonly occurring handles like elonmusk, openai, and twitter before ranking. This prevents high-volume accounts from dominating the results when they lack specific relevance to the query topic.
Can I specify multiple X handles using --x-handle?
The current implementation accepts a single resolved handle via the CLI flag. In scripts/last30days.py, the resolved_handle argument is passed as a single-element list [resolved_handle] to bird_x.search_handles. To analyze multiple specific handles, you would need to run separate queries or modify the source to accept comma-separated values.
What happens if the resolved handle search returns no results?
If the secondary unfiltered search for the specified handle returns empty results, the supplemental_x list remains empty and no items are merged. However, the report.resolved_x_handle field is still populated with the requested handle name, and the renderer will display the "Resolved X Handle" section indicating the attempt was made, preserving transparency about the search scope.
Where is the handle normalization logic located?
Handle normalization occurs in scripts/lib/entity_extract.py within the extraction pipeline. The code applies .strip().lstrip("@").lower() to ensure consistent lowercase storage without the @ prefix, while the regex @(\w{1,15}) captures mentions from tweet text using X's standard handle length constraints.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →