rdt-cli 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rdt_cli-0.2.0/.github/workflows/ci.yml +57 -0
- rdt_cli-0.2.0/.github/workflows/publish.yml +30 -0
- rdt_cli-0.2.0/.gitignore +8 -0
- rdt_cli-0.2.0/PKG-INFO +398 -0
- rdt_cli-0.2.0/README.md +375 -0
- rdt_cli-0.2.0/SCHEMA.md +31 -0
- rdt_cli-0.2.0/SKILL.md +222 -0
- rdt_cli-0.2.0/pyproject.toml +59 -0
- rdt_cli-0.2.0/rdt_cli/__init__.py +3 -0
- rdt_cli-0.2.0/rdt_cli/__main__.py +5 -0
- rdt_cli-0.2.0/rdt_cli/auth.py +174 -0
- rdt_cli-0.2.0/rdt_cli/cli.py +72 -0
- rdt_cli-0.2.0/rdt_cli/client.py +356 -0
- rdt_cli-0.2.0/rdt_cli/commands/__init__.py +0 -0
- rdt_cli-0.2.0/rdt_cli/commands/_common.py +353 -0
- rdt_cli-0.2.0/rdt_cli/commands/auth.py +105 -0
- rdt_cli-0.2.0/rdt_cli/commands/browse.py +386 -0
- rdt_cli-0.2.0/rdt_cli/commands/post.py +183 -0
- rdt_cli-0.2.0/rdt_cli/commands/search.py +227 -0
- rdt_cli-0.2.0/rdt_cli/commands/social.py +163 -0
- rdt_cli-0.2.0/rdt_cli/constants.py +83 -0
- rdt_cli-0.2.0/rdt_cli/exceptions.py +69 -0
- rdt_cli-0.2.0/rdt_cli/index_cache.py +77 -0
- rdt_cli-0.2.0/tests/__init__.py +0 -0
- rdt_cli-0.2.0/tests/test_cli.py +673 -0
- rdt_cli-0.2.0/tests/test_smoke.py +312 -0
- rdt_cli-0.2.0/uv.lock +539 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_call:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
lint-and-test:
|
|
12
|
+
name: Lint and test (Python ${{ matrix.python-version }})
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
strategy:
|
|
15
|
+
fail-fast: false
|
|
16
|
+
matrix:
|
|
17
|
+
python-version: ["3.10", "3.12", "3.13"]
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Set up Python
|
|
22
|
+
uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: ${{ matrix.python-version }}
|
|
25
|
+
|
|
26
|
+
- name: Install uv
|
|
27
|
+
uses: astral-sh/setup-uv@v6
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: uv sync --group dev
|
|
31
|
+
|
|
32
|
+
- name: Run ruff
|
|
33
|
+
run: uv run ruff check .
|
|
34
|
+
|
|
35
|
+
- name: Run tests
|
|
36
|
+
run: uv run python -m pytest -q
|
|
37
|
+
|
|
38
|
+
build:
|
|
39
|
+
name: Build package
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
needs: lint-and-test
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v4
|
|
44
|
+
|
|
45
|
+
- name: Set up Python
|
|
46
|
+
uses: actions/setup-python@v5
|
|
47
|
+
with:
|
|
48
|
+
python-version: "3.12"
|
|
49
|
+
|
|
50
|
+
- name: Install uv
|
|
51
|
+
uses: astral-sh/setup-uv@v6
|
|
52
|
+
|
|
53
|
+
- name: Install dependencies
|
|
54
|
+
run: uv sync --group dev
|
|
55
|
+
|
|
56
|
+
- name: Build distribution
|
|
57
|
+
run: uv build
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
publish:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
environment: pypi
|
|
13
|
+
permissions:
|
|
14
|
+
id-token: write
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.12"
|
|
22
|
+
|
|
23
|
+
- name: Setup uv
|
|
24
|
+
uses: astral-sh/setup-uv@v6
|
|
25
|
+
|
|
26
|
+
- name: Build package
|
|
27
|
+
run: uv build
|
|
28
|
+
|
|
29
|
+
- name: Publish to PyPI
|
|
30
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
rdt_cli-0.2.0/.gitignore
ADDED
rdt_cli-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rdt-cli
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A CLI for Reddit — browse feeds, read posts, search, and interact via terminal 📖
|
|
5
|
+
Project-URL: Homepage, https://github.com/jackwener/rdt-cli
|
|
6
|
+
Project-URL: Repository, https://github.com/jackwener/rdt-cli
|
|
7
|
+
Project-URL: Issues, https://github.com/jackwener/rdt-cli/issues
|
|
8
|
+
Author-email: jackwener <jakevingoo@gmail.com>
|
|
9
|
+
License-Expression: Apache-2.0
|
|
10
|
+
Keywords: api,cli,rdt,reddit,terminal
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Utilities
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: browser-cookie3>=0.19
|
|
18
|
+
Requires-Dist: click>=8.0
|
|
19
|
+
Requires-Dist: httpx>=0.27
|
|
20
|
+
Requires-Dist: pyyaml>=6.0
|
|
21
|
+
Requires-Dist: rich>=13.0
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# rdt-cli
|
|
25
|
+
|
|
26
|
+
[](https://github.com/jackwener/rdt-cli/actions/workflows/ci.yml)
|
|
27
|
+
[](https://pypi.org/project/rdt-cli/)
|
|
28
|
+
[](https://pypi.org/project/rdt-cli/)
|
|
29
|
+
|
|
30
|
+
A CLI for Reddit — browse feeds, read posts, search, and interact via reverse-engineered API 📖
|
|
31
|
+
|
|
32
|
+
[English](#features) | [中文](#功能特性)
|
|
33
|
+
|
|
34
|
+
## More Tools
|
|
35
|
+
|
|
36
|
+
- [xiaohongshu-cli](https://github.com/jackwener/xiaohongshu-cli) — Xiaohongshu CLI for search, reading, and posting
|
|
37
|
+
- [twitter-cli](https://github.com/jackwener/twitter-cli) — Twitter/X CLI for timelines, bookmarks, and posting
|
|
38
|
+
- [bilibili-cli](https://github.com/jackwener/bilibili-cli) — Bilibili CLI for videos, users, search, and feeds
|
|
39
|
+
- [discord-cli](https://github.com/jackwener/discord-cli) — Discord CLI for local-first sync, search, and export
|
|
40
|
+
- [tg-cli](https://github.com/jackwener/tg-cli) — Telegram CLI for local-first sync, search, and export
|
|
41
|
+
|
|
42
|
+
## Features
|
|
43
|
+
|
|
44
|
+
- 🔐 **Auth** — auto-extract browser cookies, status check, whoami
|
|
45
|
+
- 🏠 **Feed** — browse home feed, popular, and /r/all
|
|
46
|
+
- 📋 **Subreddits** — browse any subreddit with sort/time filters, view subreddit info
|
|
47
|
+
- 📰 **Posts** — read posts and comment trees with syntax highlighting
|
|
48
|
+
- 🔢 **Short-index navigation** — `rdt show 3` to read, `rdt open 3` to browser
|
|
49
|
+
- 🔍 **Search** — full-text search with subreddit, sort, and time filters
|
|
50
|
+
- 📤 **Export** — export search results to CSV or JSON; `-o file.json` on any listing
|
|
51
|
+
- 👤 **Users** — view user profiles and post history
|
|
52
|
+
- ⬆️ **Interactions** — upvote/downvote, save/unsave, subscribe/unsubscribe, comment (with 1.5-4s rate-limit delay)
|
|
53
|
+
- 🛡️ **Anti-detection** — consistent Chrome 133 fingerprint, `sec-ch-ua` alignment, Gaussian jitter, exponential backoff
|
|
54
|
+
- 📊 **Structured output** — `--yaml`, `--json`, `--output FILE`, `--compact`, `--full-text`
|
|
55
|
+
- 📦 **Stable envelope** — see [SCHEMA.md](./SCHEMA.md) for `ok/schema_version/data/error`
|
|
56
|
+
- 🤖 **Agent-friendly** — Rich output on stderr, `--compact` for token-efficient output
|
|
57
|
+
|
|
58
|
+
> **AI Agent Tip:** Prefer `--yaml` for structured output unless strict JSON is required. Non-TTY stdout defaults to YAML automatically. Use `--compact` to reduce token usage.
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Recommended: uv tool (fast, isolated)
|
|
64
|
+
uv tool install rdt-cli
|
|
65
|
+
|
|
66
|
+
# Or: pipx
|
|
67
|
+
pipx install rdt-cli
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Upgrade to the latest version:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
uv tool upgrade rdt-cli
|
|
74
|
+
# Or: pipx upgrade rdt-cli
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
From source:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
git clone git@github.com:jackwener/rdt-cli.git
|
|
81
|
+
cd rdt-cli
|
|
82
|
+
uv sync
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Usage
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# ─── Auth ─────────────────────────────────────────
|
|
89
|
+
rdt login # Extract cookies from browser
|
|
90
|
+
rdt status # Check login status
|
|
91
|
+
rdt status --json # Structured JSON envelope
|
|
92
|
+
rdt whoami # Detailed profile (karma, account age)
|
|
93
|
+
rdt logout # Clear saved cookies
|
|
94
|
+
|
|
95
|
+
# ─── Browse ───────────────────────────────────────
|
|
96
|
+
rdt feed # Home feed (requires login)
|
|
97
|
+
rdt popular # Popular posts
|
|
98
|
+
rdt popular --full-text # Show full titles
|
|
99
|
+
rdt all # /r/all
|
|
100
|
+
rdt sub python # Browse subreddit
|
|
101
|
+
rdt sub programming -s top -t week # Sort + time filter
|
|
102
|
+
rdt sub-info python # Subreddit info (subscribers, etc.)
|
|
103
|
+
rdt user spez # User profile
|
|
104
|
+
rdt user-posts spez # User's submitted posts
|
|
105
|
+
|
|
106
|
+
# Short index works after list commands (feed/popular/sub/search)
|
|
107
|
+
rdt sub python
|
|
108
|
+
rdt show 1 # Read post #1 from listing
|
|
109
|
+
rdt open 1 # Open post #1 in browser
|
|
110
|
+
rdt upvote 1 # Upvote post #1
|
|
111
|
+
|
|
112
|
+
# ─── Reading ──────────────────────────────────────
|
|
113
|
+
rdt read 1abc123 # Read post by ID
|
|
114
|
+
rdt show 3 # Read result #3 from last listing
|
|
115
|
+
rdt show 1 -s top # Sort comments by top
|
|
116
|
+
rdt open 3 # Open in browser
|
|
117
|
+
|
|
118
|
+
# ─── Search ───────────────────────────────────────
|
|
119
|
+
rdt search "python async" # Global search
|
|
120
|
+
rdt search "rust vs go" -r programming # Within subreddit
|
|
121
|
+
rdt search "ML" -s top -t year # Sort by top, last year
|
|
122
|
+
rdt search "AI" -o results.json # Save to file
|
|
123
|
+
rdt search "rust" --compact --json # Compact agent output
|
|
124
|
+
|
|
125
|
+
# ─── Export ───────────────────────────────────────
|
|
126
|
+
rdt export "python tips" -n 100 -o tips.csv
|
|
127
|
+
rdt export "rust" --format json -o results.json
|
|
128
|
+
|
|
129
|
+
# ─── Interactions (require login) ─────────────────
|
|
130
|
+
rdt upvote 3 # Upvote result #3
|
|
131
|
+
rdt upvote 3 --down # Downvote
|
|
132
|
+
rdt upvote 3 --undo # Remove vote
|
|
133
|
+
rdt save 3 # Save result #3
|
|
134
|
+
rdt save 3 --undo # Unsave
|
|
135
|
+
rdt subscribe python # Subscribe to r/python
|
|
136
|
+
rdt subscribe python --undo # Unsubscribe
|
|
137
|
+
rdt comment 3 "Great post!" # Comment on result #3
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Authentication
|
|
141
|
+
|
|
142
|
+
rdt-cli supports browser cookie extraction to authenticate with Reddit:
|
|
143
|
+
|
|
144
|
+
1. **Saved cookies** — loads from `~/.config/rdt-cli/credential.json`
|
|
145
|
+
2. **Browser cookies** — auto-detects installed browsers and extracts cookies (supports Chrome, Firefox, Edge, Brave)
|
|
146
|
+
|
|
147
|
+
`rdt login` automatically tries all installed browsers and uses the first one with valid cookies.
|
|
148
|
+
|
|
149
|
+
### Cookie TTL
|
|
150
|
+
|
|
151
|
+
Saved cookies are valid for **7 days** by default. After that, the client automatically attempts to refresh from the browser. If browser extraction fails, the existing cookies are used with a warning.
|
|
152
|
+
|
|
153
|
+
### Short-Index Navigation
|
|
154
|
+
|
|
155
|
+
After any listing command such as `feed`, `popular`, `all`, `sub`, or `search`, the CLI stores the latest ordered post list in `~/.config/rdt-cli/index_cache.json`.
|
|
156
|
+
|
|
157
|
+
- `rdt show <N>` reads the Nth post from the latest listing
|
|
158
|
+
- `rdt open <N>` opens the Nth post in the browser
|
|
159
|
+
- `rdt upvote <N>`, `rdt save <N>`, `rdt comment <N>` reuse the same short index
|
|
160
|
+
- Empty listings clear the index cache, so old results are not reused by accident
|
|
161
|
+
|
|
162
|
+
## Environment Variables
|
|
163
|
+
|
|
164
|
+
| Variable | Default | Description |
|
|
165
|
+
|----------|---------|-------------|
|
|
166
|
+
| `OUTPUT` | `auto` | Output format: `json`, `yaml`, `rich`, or `auto` (→ YAML when non-TTY) |
|
|
167
|
+
|
|
168
|
+
## Rate Limiting & Anti-Detection
|
|
169
|
+
|
|
170
|
+
rdt-cli includes anti-detection measures designed to minimize risk:
|
|
171
|
+
|
|
172
|
+
### Request Timing
|
|
173
|
+
- **Gaussian jitter**: Delays between requests use a truncated Gaussian distribution (~1s mean, σ=0.3)
|
|
174
|
+
- **Random long pauses**: ~5% of requests include an additional 2-5 second delay simulating reading behavior
|
|
175
|
+
- **Auto-retry**: Exponential backoff on HTTP 429/5xx and network errors (up to 3 retries)
|
|
176
|
+
|
|
177
|
+
### Browser Fingerprint Consistency
|
|
178
|
+
- **UA/Platform alignment**: User-Agent, `sec-ch-ua`, `sec-ch-ua-platform`, `sec-ch-ua-mobile` are all consistent (Chrome 133)
|
|
179
|
+
- **Cookie merge**: Set-Cookie headers from Reddit responses are merged back into the session
|
|
180
|
+
|
|
181
|
+
## Structured Output
|
|
182
|
+
|
|
183
|
+
All `--json` / `--yaml` output uses the shared envelope from [SCHEMA.md](./SCHEMA.md):
|
|
184
|
+
```yaml
|
|
185
|
+
ok: true
|
|
186
|
+
schema_version: "1"
|
|
187
|
+
data: { ... }
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
When stdout is not a TTY (e.g., piped or invoked by an AI agent), output defaults to YAML.
|
|
191
|
+
Use `OUTPUT=yaml|json|rich|auto` to override.
|
|
192
|
+
|
|
193
|
+
## Use as AI Agent Skill
|
|
194
|
+
|
|
195
|
+
rdt-cli ships with a [`SKILL.md`](./SKILL.md) that teaches AI agents how to use it.
|
|
196
|
+
|
|
197
|
+
### Claude Code / Antigravity
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
mkdir -p .agents/skills
|
|
201
|
+
git clone git@github.com:jackwener/rdt-cli.git .agents/skills/rdt-cli
|
|
202
|
+
|
|
203
|
+
# Or just copy the SKILL.md
|
|
204
|
+
curl -o .agents/skills/rdt-cli/SKILL.md \
|
|
205
|
+
https://raw.githubusercontent.com/jackwener/rdt-cli/main/SKILL.md
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### OpenClaw / ClawHub
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
clawhub install rdt-cli
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Project Structure
|
|
215
|
+
|
|
216
|
+
```text
|
|
217
|
+
rdt_cli/
|
|
218
|
+
├── __init__.py # Version
|
|
219
|
+
├── __main__.py # python -m rdt_cli entry point
|
|
220
|
+
├── cli.py # Click entry point & command registration
|
|
221
|
+
├── client.py # Reddit API client (rate-limit, retry, anti-detection)
|
|
222
|
+
├── auth.py # Cookie authentication + TTL refresh
|
|
223
|
+
├── constants.py # URLs, headers, sort options
|
|
224
|
+
├── exceptions.py # Error hierarchy (6 exception types)
|
|
225
|
+
├── index_cache.py # Short-index cache for show/open commands
|
|
226
|
+
└── commands/
|
|
227
|
+
├── _common.py # Shared helpers (envelope, output routing, formatters)
|
|
228
|
+
├── auth.py # login, logout, status, whoami
|
|
229
|
+
├── browse.py # feed, popular, all, sub, sub-info, user, user-posts, open
|
|
230
|
+
├── post.py # read, show
|
|
231
|
+
├── search.py # search, export
|
|
232
|
+
└── social.py # upvote, save, subscribe, comment
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Development
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
# Install dependencies
|
|
239
|
+
uv sync
|
|
240
|
+
|
|
241
|
+
# Run tests
|
|
242
|
+
uv run pytest tests/ -v
|
|
243
|
+
|
|
244
|
+
# Unit tests only (no network)
|
|
245
|
+
uv run pytest tests/ -v -m "not smoke"
|
|
246
|
+
|
|
247
|
+
# Smoke tests (need cookies)
|
|
248
|
+
uv run pytest tests/ -v -m smoke
|
|
249
|
+
|
|
250
|
+
# Lint
|
|
251
|
+
uv run ruff check .
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Troubleshooting
|
|
255
|
+
|
|
256
|
+
**Q: `No Reddit cookies found`**
|
|
257
|
+
|
|
258
|
+
1. Open any browser and visit https://www.reddit.com/
|
|
259
|
+
2. Log in with your account
|
|
260
|
+
3. Run `rdt login` (auto-detects browser)
|
|
261
|
+
|
|
262
|
+
**Q: `database is locked`**
|
|
263
|
+
|
|
264
|
+
Close the browser Cookie database lock — close browser, then retry `rdt login`.
|
|
265
|
+
|
|
266
|
+
**Q: `Session expired`**
|
|
267
|
+
|
|
268
|
+
Your cookies have expired. Run `rdt logout && rdt login` to refresh.
|
|
269
|
+
|
|
270
|
+
**Q: `Rate limited`**
|
|
271
|
+
|
|
272
|
+
Wait and retry; the built-in exponential backoff handles this automatically.
|
|
273
|
+
|
|
274
|
+
**Q: Requests are slow**
|
|
275
|
+
|
|
276
|
+
The built-in Gaussian jitter delay (~1s between requests) is intentional to mimic natural browsing and avoid triggering Reddit's rate limiting.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## 推荐项目
|
|
281
|
+
|
|
282
|
+
- [xiaohongshu-cli](https://github.com/jackwener/xiaohongshu-cli) — 小红书搜索、阅读和发帖 CLI
|
|
283
|
+
- [twitter-cli](https://github.com/jackwener/twitter-cli) — Twitter/X 时间线、书签和发推 CLI
|
|
284
|
+
- [bilibili-cli](https://github.com/jackwener/bilibili-cli) — Bilibili 视频、用户、搜索与动态 CLI
|
|
285
|
+
- [discord-cli](https://github.com/jackwener/discord-cli) — Discord 本地优先同步、检索与导出 CLI
|
|
286
|
+
- [tg-cli](https://github.com/jackwener/tg-cli) — Telegram 本地优先同步、检索与导出 CLI
|
|
287
|
+
|
|
288
|
+
## 功能特性
|
|
289
|
+
|
|
290
|
+
- 🔐 **认证** — 自动提取浏览器 Cookie,状态检查,用户信息
|
|
291
|
+
- 🏠 **浏览** — 首页 Feed、Popular、/r/all
|
|
292
|
+
- 📋 **子版块** — 浏览任意 subreddit(排序/时间过滤),查看子版块信息
|
|
293
|
+
- 📰 **帖子** — 阅读帖子和评论树
|
|
294
|
+
- 🔢 **短索引导航** — `rdt show 3` 阅读、`rdt open 3` 浏览器打开
|
|
295
|
+
- 🔍 **搜索** — 全文搜索,支持子版块、排序、时间过滤
|
|
296
|
+
- 📤 **导出** — 搜索结果导出为 CSV 或 JSON
|
|
297
|
+
- 👤 **用户** — 查看用户资料和发帖历史
|
|
298
|
+
- ⬆️ **互动** — 点赞/踩、收藏、订阅、评论
|
|
299
|
+
- 🛡️ **反风控** — Chrome 133 指纹一致性、高斯抖动延迟、指数退避重试
|
|
300
|
+
- 📊 **结构化输出** — `--yaml` / `--json`,非 TTY 默认输出 YAML
|
|
301
|
+
- 📦 **稳定 envelope** — 参见 [SCHEMA.md](./SCHEMA.md)
|
|
302
|
+
|
|
303
|
+
## 安装
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
# 推荐:uv tool(快速、隔离环境)
|
|
307
|
+
uv tool install rdt-cli
|
|
308
|
+
|
|
309
|
+
# 或者:pipx
|
|
310
|
+
pipx install rdt-cli
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
升级到最新版本:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
uv tool upgrade rdt-cli
|
|
317
|
+
# 或:pipx upgrade rdt-cli
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
从源码安装:
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
git clone git@github.com:jackwener/rdt-cli.git
|
|
324
|
+
cd rdt-cli
|
|
325
|
+
uv sync
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## 使用示例
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
# 认证
|
|
332
|
+
rdt login # 从浏览器提取 Cookie
|
|
333
|
+
rdt status # 检查登录状态
|
|
334
|
+
rdt whoami # 查看用户资料
|
|
335
|
+
rdt logout # 清除缓存的 Cookie
|
|
336
|
+
|
|
337
|
+
# 浏览
|
|
338
|
+
rdt feed # 首页 Feed(需要登录)
|
|
339
|
+
rdt popular # 热门帖子
|
|
340
|
+
rdt all # /r/all
|
|
341
|
+
rdt sub python # 浏览子版块
|
|
342
|
+
rdt sub programming -s top -t week # 排序 + 时间过滤
|
|
343
|
+
rdt sub-info python # 子版块信息
|
|
344
|
+
|
|
345
|
+
# 阅读
|
|
346
|
+
rdt read 1abc123 # 按 ID 阅读帖子
|
|
347
|
+
rdt show 3 # 阅读最近一次列表里的第 3 条
|
|
348
|
+
rdt open 3 # 在浏览器打开
|
|
349
|
+
|
|
350
|
+
# 搜索
|
|
351
|
+
rdt search "python async" # 全局搜索
|
|
352
|
+
rdt search "rust vs go" -r programming # 在子版块内搜索
|
|
353
|
+
rdt export "python tips" -n 100 -o tips.csv # 导出
|
|
354
|
+
|
|
355
|
+
# 互动(需要登录)
|
|
356
|
+
rdt upvote 3 # 点赞
|
|
357
|
+
rdt save 3 # 收藏
|
|
358
|
+
rdt subscribe python # 订阅
|
|
359
|
+
rdt comment 3 "Great post!" # 评论
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## 认证策略
|
|
363
|
+
|
|
364
|
+
rdt-cli 支持浏览器 Cookie 提取来认证 Reddit:
|
|
365
|
+
|
|
366
|
+
1. **已保存 Cookie** — 从 `~/.config/rdt-cli/credential.json` 加载
|
|
367
|
+
2. **浏览器 Cookie** — 自动检测已安装浏览器并提取(支持 Chrome、Firefox、Edge、Brave)
|
|
368
|
+
|
|
369
|
+
Cookie 保存后有效期 **7 天**,超时后自动尝试从浏览器刷新。
|
|
370
|
+
|
|
371
|
+
## 常见问题
|
|
372
|
+
|
|
373
|
+
- `No Reddit cookies found` — 请先在任意浏览器打开 https://www.reddit.com/ 并登录,然后执行 `rdt login`
|
|
374
|
+
- `database is locked` — 关闭浏览器后重试
|
|
375
|
+
- `Session expired` — Cookie 过期,执行 `rdt logout && rdt login` 刷新
|
|
376
|
+
- `Rate limited` — 等待重试,内置指数退避会自动处理
|
|
377
|
+
- 请求较慢是正常的 — 内置高斯随机延迟(~1s)是为了模拟人类浏览行为,避免触发限速
|
|
378
|
+
|
|
379
|
+
## 作为 AI Agent Skill 使用
|
|
380
|
+
|
|
381
|
+
rdt-cli 自带 [`SKILL.md`](./SKILL.md),让 AI Agent 能自动学习并使用本工具。
|
|
382
|
+
|
|
383
|
+
### Claude Code / Antigravity
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
mkdir -p .agents/skills
|
|
387
|
+
git clone git@github.com:jackwener/rdt-cli.git .agents/skills/rdt-cli
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### OpenClaw / ClawHub
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
clawhub install rdt-cli
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
## License
|
|
397
|
+
|
|
398
|
+
Apache-2.0
|