Metadata-Version: 2.4
Name: xstream-cli
Version: 0.2.1
Summary: A conversational AI agent for understanding your X feed.
Project-URL: Homepage, https://github.com/nikhil-kunapareddy/x-stream
Project-URL: Issues, https://github.com/nikhil-kunapareddy/x-stream/issues
Author: nikhil-kunapareddy
License: MIT License
        
        Copyright (c) 2026 nikhil-kunapareddy
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: agent,anthropic,claude,cli,twitter,x
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Requires-Dist: anthropic>=0.75
Requires-Dist: prompt-toolkit>=3.0.43
Requires-Dist: python-dotenv>=1.0
Requires-Dist: requests-oauthlib>=1.3
Requires-Dist: requests>=2.31
Requires-Dist: rich>=13.7
Provides-Extra: dev
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# XStream

**A conversational AI agent for understanding your X feed.**

XStream is a terminal application that reads your X (formerly Twitter) home
timeline, picks out the posts worth your attention, summarizes them with Claude,
and then lets you *talk about them*.

```text
$ x-stream

╭────────────────────────────────╮
│    XStream                     │
│    Your conversational X agent  │
╰────────────────────────────────╯

✓ Anthropic API configured
✓ X API configured (OAuth 1.0a user context)
✓ X account: @yourhandle

Model: claude-opus-5

Ask about your feed, or type /help for commands.

xstream>
```

It is a conversational agent first. Reading your feed is the tool it reaches for
when the conversation calls for it — ask it what RAG is and it just answers.

---

## Installation

```bash
pip install xstream-cli
```

Requires Python 3.10 or newer. The command it installs is `x-stream`.

Then run:

```bash
x-stream
```

---

## Configuration

There are two ways to set XStream up. Either works; pick whichever you prefer.

### Option 1 — from inside the app (easiest)

Just run it. XStream opens even with nothing configured:

```text
$ x-stream

✗ Anthropic API key not configured
✗ X API credentials not configured

Run /connect to add your credentials, or /help for commands.

xstream> /connect
```

`/connect` walks you through each credential, **hides your input as you type**,
verifies the keys against both APIs immediately, and offers to save them to
`~/.config/xstream/.env` (created with owner-only `600` permissions) so you
only do this once. Decline the save and they last for the session only.

You can re-run `/connect` any time to rotate or add a credential — entering
just one value leaves the others untouched.

### Option 2 — environment variables

XStream reads its configuration from environment variables. It will also load a
`.env` file if it finds one — first `./.env`, then `~/.config/xstream/.env`.
Real environment variables always take precedence.

Copy [`.env.example`](.env.example) to `.env` to get started.

### Anthropic API key

```bash
ANTHROPIC_API_KEY="sk-ant-..."
```

Create one at <https://console.anthropic.com/settings/keys>.

### X API credentials

XStream **never** asks for your X password and never sees your X login. It
authenticates only with API credentials that you issue yourself in the
[X developer portal](https://developer.x.com/en/portal/dashboard), and it only
ever reads.

The default scheme is **OAuth 1.0a user context**, which needs four values:

```bash
X_API_KEY="..."
X_API_SECRET="..."
X_ACCESS_TOKEN="..."
X_ACCESS_TOKEN_SECRET="..."
```

To get them:

1. Create a project and an app in the developer portal.
2. Under **User authentication settings**, enable OAuth 1.0a with **Read**
   permission (Read is all XStream needs).
3. On the **Keys and tokens** tab, copy the **Consumer Keys** into `X_API_KEY`
   and `X_API_SECRET`.
4. Generate an **Access Token and Secret** and copy those into
   `X_ACCESS_TOKEN` and `X_ACCESS_TOKEN_SECRET`.

> If you change your app's permissions, regenerate the access token — the old
> one keeps the old permission level.

**Alternatively**, if you already hold a user access token from the OAuth 2.0
Authorization Code with PKCE flow (scopes `tweet.read users.read`), you can use
that instead of the four values above:

```bash
X_OAUTH2_ACCESS_TOKEN="..."
```

This must be a *user* token. An app-only bearer token cannot read a home
timeline — the endpoint requires user context.

> **A note on X API access.** Reading a home timeline is a paid capability. The
> free tier does not include timeline reads, so `x-stream` will report a
> permissions error from X until your project is on a plan that does. This is an
> X platform restriction, not an XStream one.

### Model selection

```bash
XSTREAM_MODEL=claude-opus-5
```

Available models are listed by the `/model` command, and can be switched
mid-session:

| Model | Id | Notes |
|---|---|---|
| Claude Opus 5 | `claude-opus-5` | Default. Best analysis of a busy feed. |
| Claude Sonnet 5 | `claude-sonnet-5` | Strong quality, lower cost and latency. |
| Claude Opus 4.8 | `claude-opus-4-8` | Previous-generation Opus. |
| Claude Haiku 4.5 | `claude-haiku-4-5` | Fastest and cheapest. Terser summaries. |

You can also pass `--model <id>` at launch. Reasoning effort is tunable with
`XSTREAM_EFFORT` (`low`, `medium`, `high`; default `medium`).

---

## Running

```bash
x-stream                      # start a session
x-stream --model claude-sonnet-5
x-stream --debug              # show API detail and stack traces on errors
x-stream --env-file ./prod.env
```

### Commands

| Command | Description |
|---|---|
| `/help` | Show available commands |
| `/connect` | Add or update your Anthropic and X credentials |
| `/feed` | Retrieve and summarize your feed now |
| `/model` | Show or change the model (`/model claude-sonnet-5`) |
| `/clear` | Clear the current conversation |
| `/config` | Show configuration status (never shows secrets) |
| `/exit` | Exit |

Natural language is the primary interface — the commands are shortcuts, not the
point.

Press **Ctrl+C** to interrupt a response, **Ctrl+D** to quit.

---

## Example

```text
xstream> summarize my feed

⠋ Reading your X feed…
✓ Retrieved 87 posts
⠋ Selecting posts…
✓ Selected 10 posts
⠋ Asking Claude…

## Your X Feed

### 1. @simonw

**Summary**
Walks through a failure mode he hit running an agent loop overnight: the
model kept re-reading the same three files because the harness was not
persisting tool results between turns.

**Why it matters**
A concrete, reproducible instance of a context-management bug that is easy to
introduce and hard to notice from the outside.

🔗 https://x.com/simonw/status/...

### 2. @karpathy
...

---

## Common Themes

1. Practical failures in long-running agent harnesses
2. Cost and latency tradeoffs in reasoning models
3. Two separate threads on evaluation being the bottleneck

xstream> What are the three biggest themes?

The strongest thread is agent-harness reliability — #1, #4 and #9 are all
describing variations of the same context-persistence problem...

xstream> Tell me more about #4.

#4 is @amanda's thread on eval design. Her claim is that...

xstream> Compare #2 and #7.

They reach opposite conclusions from similar evidence...

xstream> What is retrieval augmented generation?

Retrieval augmented generation is a pattern where...

xstream> summarize my feed again

⠋ Reading your X feed…
```

Numeric references (`#4`) always resolve against the most recent feed XStream
retrieved, and follow-up questions are answered from the posts already loaded —
no extra API calls.

---

## Current MVP

This version does exactly four things, and tries to do them well:

1. Reads your X home timeline.
2. Selects the 10 most relevant posts (recency, engagement, and whether the post
   carries meaningful text of its own; reposts and duplicates are collapsed).
3. Summarizes them with Claude.
4. Lets you have a conversation about them for the rest of the session.

It does **not** post, like, repost, follow, send DMs, search X, manage
bookmarks or lists, run in the background, or remember anything after you exit.
Memory is per-session by design.

---

## Security

- XStream never asks for, stores, or transmits your X password.
- Credentials are never logged, printed, included in prompts, or sent to Claude.
- `/connect` hides input as you type, and keeps it out of your shell history
  and the in-app command history.
- The only time credentials touch disk is when you explicitly agree to save
  them; the file is written atomically with owner-only (`600`) permissions.
- Only the post data required for analysis is sent to the Anthropic API.
- `/config` reports whether each credential is present, never its value.
- Error messages are sanitized; `--debug` adds API detail but never secrets.
- `.env` and friends are in `.gitignore`.

---

## Development

```bash
git clone https://github.com/nikhil-kunapareddy/x-stream
cd x-stream
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
```

The test suite mocks both the X API and the Anthropic API — running it makes no
network calls and needs no credentials.

Layout:

```text
src/xstream/
├── cli.py          # argument parsing, wiring, the session loop
├── config.py       # env loading + the model registry
├── models.py       # Post, PostMetrics, Media, FeedSummary
├── errors.py       # user-facing error types
├── agent/          # agent loop, conversation memory, tools, prompts
├── providers/      # LLMProvider interface + the Anthropic implementation
├── ranking/        # deterministic post selection
├── ui/             # everything the terminal shows
└── x/              # X API auth, client, feed retrieval
```

---

## Roadmap

Ideas for later, none of them implemented today:

- A persistent personal profile that learns what you actually find interesting
- Continuous background monitoring, with proactive "you'll want to see this"
- Topic and author following, and per-topic digests
- Threads and quote-post context resolution
- Delivery beyond the terminal (Slack, email, an API)
- Additional model providers behind the existing provider interface

---

## License

MIT — see [LICENSE](LICENSE).
