Skip to content

Latest commit

 

History

History
153 lines (121 loc) · 4.83 KB

File metadata and controls

153 lines (121 loc) · 4.83 KB

x-cli

x-cli is a terminal-first CLI for personal X workflows.

It separates read and write surfaces:

  • Read commands use official X API v2 endpoints with a user/app token.
  • Canonical post commands use official X API v2 create Post and media upload endpoints.
  • Live posting is gated by X_ENABLE_LIVE_POST=1 and X_CLI_LIVE_PROOF=1 because X API access is pay-per-use and posting changes the account.
  • Account-changing actions default to dry-run and require --live plus X_ENABLE_LIVE_ACTION=1.
  • Browser/session cookies can be reported for diagnostics, but token values and cookie values are never printed.

Status

Implemented and covered by focused tests:

  • x-cli auth-status --json
  • x-cli read feed --limit 5 --json
  • x-cli read profile --me --json
  • x-cli read profile --username xdevelopers --json
  • x-cli search "agent workflow" --limit 10 --json
  • x-cli post text --text "..." --dry-run --json
  • x-cli post text --text "..." --json
  • x-cli post media --text "..." --media image.png --dry-run --json
  • x-cli post media --text "..." --media image.png --json
  • x-cli like|unlike|repost|unrepost|bookmark|unbookmark <post-id> --json
  • x-cli comment <post-id> "reply text" --json
  • sns-json-v1 success/error envelopes
  • --output/-o JSON file output for contract commands
  • Live post and live action safety gates

Important Notes

  • This project is not affiliated with X Corp.
  • Official posting uses POST https://api.x.com/2/tweets.
  • Media posting uploads one image through POST https://api.x.com/2/media/upload, then references the returned media id in POST https://api.x.com/2/tweets.
  • Likes, reposts, and bookmarks use official user-context X API v2 endpoints.
  • Programmatic replies are restricted by X policy and permissions. Treat comment --live as account-risky.
  • X API access may be pay-per-use. Review billing and pricing before enabling live posts.
  • Do not use this project for spam, bulk automation, engagement loops, or anything that violates platform rules.

Auth

Official API commands resolve OAuth credentials from:

  1. X_ACCESS_TOKEN
  2. X_BEARER_TOKEN
  3. X_OAUTH_FILE
  4. ~/.config/x/oauth.json

Token file shape:

{
  "access_token": "...",
  "live_post_enabled": false,
  "live_action_enabled": false
}

Live post requires a token plus:

export X_ENABLE_LIVE_POST=1
export X_CLI_LIVE_PROOF=1

live_post_enabled can also come from the token file, but X_CLI_LIVE_PROOF=1 must stay an explicit per-run environment variable:

{
  "access_token": "...",
  "live_post_enabled": true
}

Live account actions require --live and one of:

export X_ENABLE_LIVE_ACTION=1

or:

{
  "access_token": "...",
  "live_action_enabled": true
}

Optional browser/session diagnostics:

export X_COOKIE_HEADER='auth_token=...; ct0=...'
# or write a private cookie header file:
mkdir -p ~/.config/x
chmod 700 ~/.config/x
printf '%s\n' 'auth_token=...; ct0=...' > ~/.config/x/cookies.txt
chmod 600 ~/.config/x/cookies.txt

auth-status --json reports cookie names and count only, never cookie values.

Commands

uv run x-cli auth-status --json
uv run x-cli read feed --limit 5 --json
uv run x-cli read profile --me --json
uv run x-cli read profile --username xdevelopers --json
uv run x-cli search "agent workflow" --limit 10 --json
uv run x-cli post text --text "hello" --dry-run --json
uv run x-cli post text --text "hello" --dry-run --json --output tmp/x-post-text-dry-run.json
X_ENABLE_LIVE_POST=1 X_CLI_LIVE_PROOF=1 uv run x-cli post text --text "hello" --json
uv run x-cli post media --text "hello with image" --media tests/fixtures/sample.png --dry-run --json
uv run x-cli like 1234567890 --json
uv run x-cli like 1234567890 --live --json
uv run x-cli repost 1234567890 --json
uv run x-cli bookmark 1234567890 --json
uv run x-cli comment 1234567890 "reply text" --json

Dry-run examples make no network request:

uv run x-cli post text --text "hello" --dry-run --json
uv run x-cli post media --text "hello" --media tests/fixtures/sample.png --dry-run --json
uv run x-cli like 1234567890 --json

Final live proof shape:

uv run pytest -q
uv run ruff check .
uv run python -m compileall x_cli tests
uv run x-cli auth-status --json
uv run x-cli read feed --limit 3 --json
uv run x-cli read profile --me --json
uv run x-cli post text --text "x-cli dry-run verification" --dry-run --json
uv run x-cli post text --text "x-cli dry-run verification" --dry-run --json --output tmp/x-post-text-dry-run.json
uv run x-cli post media --text "x-cli media dry-run verification" --media tests/fixtures/sample.png --dry-run --json
X_ENABLE_LIVE_POST=1 X_CLI_LIVE_PROOF=1 uv run x-cli post text --text "x-cli live verification $(date -u +%Y%m%dT%H%M%SZ)" --json

Development

uv run pytest -q
uv run ruff check .
uv run python -m compileall x_cli tests