jackwener
4afc4fc246
refactor: add exceptions.py module with structured exception hierarchy
...
- Create exceptions.py with 7 exception types: TwitterError, AuthenticationError,
RateLimitError, NotFoundError, NetworkError, QueryIdError, TwitterAPIError
- Remove inline TwitterAPIError from client.py, import from exceptions module
- Replace RuntimeError('Cannot resolve queryId') with QueryIdError
- Replace RuntimeError('User not found') with NotFoundError
- Update test assertion for new TwitterAPIError message format
2026-03-10 23:05:05 +08:00
jackwener
9cf74abd56
feat: add integration smoke tests
...
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
2026-03-10 22:26:46 +08:00
jackwener
4c2c02efd5
feat: unify structured error output
2026-03-10 21:18:38 +08:00
jackwener
642ffe84a8
feat: unify agent status schema
2026-03-10 21:02:08 +08:00
jackwener
32d074dc9f
feat: anti-detection hardening, transaction cache, article parsing, structured write output
...
Anti-detection:
- Add 6 sec-ch-ua-* Client Hints headers (arch, bitness, full-version, etc.)
- POST requests now send Referer: x.com/compose/post + Priority: u=1, i
- follow/unfollow REST adds include_profile_interstitial_type param
Performance:
- Transaction ID cache with 1h TTL (~/.twitter-cli/transaction_cache.json)
- resolve_user_id: auto-detect screen_name vs numeric user_id
Features:
- Twitter Article parsing: extract long-form content as Markdown
- Write operations emit structured JSON/YAML when piped or OUTPUT env set
ActionResult: {success, action, id, url, ...}
84 tests passing
2026-03-10 20:48:42 +08:00
jackwener
49d3e237c4
feat: add whoami, reply, quote, follow/unfollow commands and --compact mode
...
- whoami: fetch current authenticated user profile
- reply <id> <text>: standalone reply command
- quote <id> <text>: quote-tweet command
- follow/unfollow <handle>: follow/unfollow users
- --compact/-c: global flag for LLM-friendly minimal JSON output
- client.py: add fetch_me, quote_tweet, follow_user, unfollow_user
- serialization.py: add tweet_to_compact_dict, tweets_to_compact_json
- 7 new tests (82 total, all passing)
2026-03-10 20:09:08 +08:00
jackwener
d71ad45a0a
fix: harden pagination auth and runtime headers
2026-03-10 12:33:04 +08:00
jackwener
4f144d1591
test: track parser fixture files
2026-03-10 12:08:47 +08:00
jackwener
19ab11d6a4
fix: harden auth flow and sync browser support docs
2026-03-10 11:02:34 +08:00
jackwener
fda9b1c3dc
fix: 431 Request Too Large — reduce FEATURES to 15 essential keys, dynamic update only updates existing keys
2026-03-09 20:59:16 +08:00
jackwener
d20c5699fd
fix: 414 URI Too Long — omit False-valued features from GET URL, add regression tests
2026-03-09 20:50:45 +08:00
jackwener
12f425abea
feat: write operation delays, dynamic FEATURES update, 30+ client.py tests, fix README proxy wording
2026-03-09 20:45:51 +08:00
jackwener
27d73efee5
feat: anti-detection hardening with curl_cffi TLS impersonation and request jitter
2026-03-09 17:11:59 +08:00
jackwener
55c48b077b
feat: add rate limiting, retry with backoff, and max count cap
...
- Add configurable request delay between paginated API calls (default 1.5s)
- Add retry with exponential backoff on HTTP 429 and Twitter error code 88
- Add hard max count cap (default 200, absolute ceiling 500)
- Add rateLimit config section with requestDelay, maxRetries, retryBaseDelay, maxCount
- Add normalization tests for rateLimit config
2026-03-07 19:02:49 +08:00
jackwener
6f322ff2d6
test+ci: add regression tests and GitHub Actions workflow
2026-03-05 16:14:05 +08:00