Files
jackwener__opencli/docs/adapters/browser/stackoverflow.md
jakevin 55088bbb28 feat: 13 read adapters across 5 new sites + 4 extensions (round 3) (#1346)
New sites (8 commands):
- npm    : search / package / downloads (registry.npmjs.org + api.npmjs.org)
- pypi   : package / downloads (pypi.org + pypistats.org)
- crates : search / crate (crates.io)
- mdn    : search (developer.mozilla.org)
- nvd    : cve (services.nvd.nist.gov)

Extensions (5 commands; +1 dblp/author surfaced in index):
- hf            : spaces (Hugging Face Spaces by likes / created_at / last_modified)
- dblp          : venue (search dblp's venue registry by acronym/topic)
- coingecko     : derivatives (perpetual / futures markets, 24h volume)
- stackoverflow : related (related questions for a given question id)

All commands hit public unauthenticated endpoints (Strategy.PUBLIC, browser:false),
typed-fail-fast on bad inputs (no silent fallback / clamp), and round-trip listing
ids into their detail commands where applicable.

Audits (all green vs baseline):
- typed-error-lint        : 196 = 196 baseline, no new
- silent-column-drop      : 103 = 103 baseline, no new
- listing-id-pairing      : 13 advisory (was 12; +1 = dblp/venue with no
                            corresponding venue-detail command)

Doc coverage : 120/120 adapter dirs documented (+5 new doc pages, +4 updated)
Manifest     : 722 entries (was 709; +13 commands)

Live verified:
- npm search react / npm package react / npm downloads react --period last-week
- npm downloads react --period 2025-01-01:2025-01-05
- pypi package requests / pypi downloads requests --period recent / overall
- crates search tokio / crates crate serde
- mdn search fetch
- nvd cve CVE-2021-44228
- hf spaces --limit 3
- dblp venue ICLR
- coingecko derivatives --limit 3
- stackoverflow related 79935770 --limit 3
- typed-error sanity: invalid CVE id, bad npm name, bad --period
2026-05-06 13:14:41 +08:00

111 lines
4.2 KiB
Markdown

# Stack Overflow
**Mode**: 🌐 Public · **Domain**: `stackoverflow.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli stackoverflow hot` | Hot questions |
| `opencli stackoverflow search <query>` | Search questions |
| `opencli stackoverflow bounties` | Questions with active bounties |
| `opencli stackoverflow unanswered` | Unanswered questions |
| `opencli stackoverflow read <id>` | Read a question with answers and comments |
| `opencli stackoverflow user <name>` | Find users by display name (highest reputation first) |
| `opencli stackoverflow tag <tag>` | List questions tagged with a given tag (most active first) |
| `opencli stackoverflow related <id>` | List questions related to a given question id |
## Listing columns
`hot`, `search`, and `bounties` share an agent-native shape so the
`question_id` is round-trippable into `stackoverflow read`:
| Column | Source | Notes |
|--------|--------|-------|
| `rank` | local | 1-indexed position |
| `id` | `question_id` | Feed into `stackoverflow read` |
| `title` | `title` | |
| `score` | `score` | |
| `answers` | `answer_count` | |
| `views` | `view_count` | |
| `is_answered` | `is_answered` | (omitted on `unanswered` since always false) |
| `tags` | `tags` (joined) | Comma-separated |
| `author` | `owner.display_name` | |
| `creation_date` | `creation_date` | Unix epoch seconds |
| `url` | `link` | Canonical question URL |
| `bounty` | `bounty_amount` | (`bounties` only, prepended after `id`) |
## `read` columns
`stackoverflow read <id>` fetches the question, answers up to
`--answers-limit` (accepted first, then by votes — if the accepted
answer is outside the votes-sorted page it is fetched separately and
prepended), question comments up to `--comments-limit`, and answer
comments up to `--comments-limit` per answer. It mirrors the
`hackernews read` and `lobsters read` thread shape.
| Column | Description |
|--------|-------------|
| `type` | `POST` / `Q-COMMENT` / `ANSWER` / `A-COMMENT` |
| `author` | Display name (HTML entities decoded) |
| `score` | Vote count for that row |
| `accepted` | `'true'` for the accepted answer, empty string otherwise |
| `text` | Body / comment, HTML stripped, entities decoded, indented for comments |
The accepted answer (if any) is always the first `ANSWER` row. Other
answers follow in descending score order. Comments under an answer appear
immediately after that answer with `A-COMMENT` type and a `> ` indent.
## Usage Examples
```bash
# Hot questions
opencli stackoverflow hot --limit 10
# Search questions
opencli stackoverflow search "async await" --limit 20
# Active bounties
opencli stackoverflow bounties --limit 10
# Unanswered questions
opencli stackoverflow unanswered --limit 10
# Tagged questions (id feeds stackoverflow read)
opencli stackoverflow tag rust --limit 10
# Related questions for a given question id (rows feed stackoverflow read)
opencli stackoverflow related 11227809 --limit 10
opencli stackoverflow related 11227809 --sort votes --limit 5
# User profile search (returns userId/profile URL rows)
opencli stackoverflow user "Jon Skeet" --limit 5
# Read a question with answers and comments
opencli stackoverflow read 11227809
opencli stackoverflow read 11227809 --answers-limit 3 --comments-limit 5
# JSON output
opencli stackoverflow hot -f json
opencli stackoverflow read 11227809 -f json
```
## Caveats
- Stack Exchange API has a 300/day quota per IP for unauthenticated
requests. A `read` call uses up to 4 quota units (question, question
comments, answers, batched answer comments), or 5 when the accepted answer
must be fetched separately.
- `--answers-limit` and `--comments-limit` are bounded to 1-100, matching the
Stack Exchange API page size limit. If batched answer comments would be
partial, the command fails fast instead of returning an incomplete thread.
- Bodies are returned as HTML; this adapter strips tags and decodes named
/ decimal / hex HTML entities for plain-text consumption.
- `tag` returns question rows with `id`, so agents can call
`opencli stackoverflow read <id>` without parsing URLs. `user` returns
Stack Overflow profile rows (`userId` + `url`), not question rows.
## Prerequisites
- No browser required — uses the public Stack Exchange API