Add TWITTER_BROWSER environment variable to allow users to control
which browser's cookies are prioritized during extraction.
Example: TWITTER_BROWSER=chrome twitter feed
Supported values: arc, chrome, edge, firefox, brave.
The specified browser is moved to the front of the extraction order.
Also adds AGENTS.md developer guide for AI coding assistants.
Co-authored-by: Agassi <413855+agassiyzh@users.noreply.github.com>
- Fix auth.py subprocess script Windows Edge cookie path inconsistency
- Add timeutil.py for UTC→local time and relative time conversion
- Integrate time localization into formatter.py and serialization.py
- Add --output/-o option to show command for saving tweet detail as JSON
- Remove constants.py legacy aliases (USER_AGENT, SEC_CH_UA)
- Remove client.py backward-compat delegation methods and re-exports
- Update test imports to use parser module directly
Auto-iterates all Chrome/Arc/Edge/Brave profiles (Default, Profile 1,
Profile 2, ...) to find Twitter cookies. Falls back to the default
browser_cookie3 behavior when no profile dirs are found.
Set TWITTER_CHROME_PROFILE env var to specify a profile explicitly:
TWITTER_CHROME_PROFILE='Profile 2' twitter feed
Closes#6
CLI-level smoke tests using --yaml output against real Twitter API.
Default skipped via @pytest.mark.smoke marker + pyproject.toml addopts.
Run locally with: uv run pytest -m smoke -v
- Cookie cache: save to ~/.cache/twitter-cli/cookies.json (24h TTL)
- On 401/403 auth failure: auto-invalidate cache, re-extract from browser
- Cache uses 0600 permissions for security
- Add --json option to twitter user command for scripting
- Priority: env vars → cache file → browser extraction
- _get_client: remove useless try/except that re-raised same error
- verify_cookies: increase timeout from 3s to 5s
- fetch_user: use _deep_get for URL extraction (consistent with
_parse_user_result)
- formatter: remove no-op tweets_to_json wrapper and unused import
- _as_int/_as_float: filter.py now imports from config.py (dedup)
- CLI read commands: extract _fetch_and_display() to dedup
favorite/search/likes/list_timeline
- _write_action: move load_config inside try block
- auth.py: add PEP 8 blank line after logger
Bug fixes:
- _extract_cursor: only extract Bottom cursors, preventing Top cursor
from corrupting pagination state
- _api_request: merge _api_get/_api_post into unified method — POST
now has rate-limit code 88 retry (was missing)
- fetch_user_likes: add override_base_variables=True
Code quality:
- Extract BEARER_TOKEN and USER_AGENT into constants.py (was duped
in auth.py and client.py)
- Add user_profile_to_dict/users_to_json for proper UserProfile
serialization (followers/following JSON output was ad-hoc)
- Refactor 6 CLI write commands via _write_action helper
- Extract _extract_media and _extract_author from _parse_tweet_result
- Update CLI module docstring with all 18 commands