this repo has no description
1# CLAUDE.md
2
3This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
5## Project Overview
6
7"Thought" is a Rust CLI application for real-time streaming and posting to the ATProto network using `stream.thought.blip` records. It functions like an IRC client for Bluesky, featuring a terminal UI (TUI) for live message streaming.
8
9**Key Technology Stack:**
10- Rust with async/await (Tokio runtime)
11- ATProto API for authentication and posting
12- Jetstream WebSocket for real-time firehose
13- Ratatui for terminal UI
14- Custom record type: `stream.thought.blip`
15
16## Building and Running
17
18```bash
19# Build (development)
20cargo build
21
22# Build (release)
23cargo build --release
24
25# Run tests
26cargo test
27
28# Lint
29cargo clippy
30
31# Run the CLI
32./target/release/thought
33
34# Login first-time use
35./target/release/thought login
36
37# Main TUI mode (recommended)
38./target/release/thought stream
39```
40
41## Architecture
42
43### Module Structure
44
45- **main.rs**: CLI entry point, command routing, and authentication setup
46- **client.rs**: ATProto HTTP client for authentication and posting blips
47- **credentials.rs**: Secure credential and session storage (platform-specific config directories)
48- **jetstream.rs**: WebSocket client for Jetstream firehose, DID resolution, and message filtering
49- **tui.rs**: Ratatui-based terminal UI with scrollable message feed
50- **interactive.rs**: Coordinator for TUI and simple REPL modes
51
52### Authentication Flow
53
541. User provides handle/email and app password via `thought login`
552. Credentials stored in platform config directory (macOS: `~/Library/Application Support/com.thoughtstream.think/`)
563. Session tokens (accessJwt/refreshJwt) cached separately in `session.json`
574. Token refresh handled transparently by `create_authenticated_client()` in main.rs:133
585. Failed refresh triggers re-login with stored credentials
59
60**Important**: Session management uses both `credentials.json` (username/password/PDS URI) and `session.json` (JWT tokens). The client automatically refreshes tokens before operations.
61
62### Real-time Message Flow
63
641. TUI spawns Jetstream listener in background task
652. Listener connects to `wss://jetstream2.us-west.bsky.network/subscribe` with collection filter
663. Incoming commits filtered for `stream.thought.blip` collection and "create" operations
674. DIDs resolved to handles via `app.bsky.actor.getProfile` (with caching)
685. Messages sent through mpsc channel to TUI for rendering
696. User's own messages filtered out using stored DID
70
71### TUI Rendering
72
73- Messages displayed in **reverse chronological order** (newest first)
74- Scrollable with arrow keys/PageUp/PageDown
75- Auto-scrolls to bottom when at offset 0
76- User's own posts styled in bold green
77- Connection status tracked via channel activity
78- Maximum 1000 messages buffered
79
80## Development Notes
81
82### Credential Storage Paths
83- macOS: `~/Library/Application Support/com.thoughtstream.think/`
84- Linux: `~/.config/thoughtstream/think/`
85- Windows: `%APPDATA%\thoughtstream\think\`
86
87### Token Refresh Logic
88The client implements automatic token refresh (client.rs:106-137):
891. Attempt operation with current access token
902. On 401/ExpiredToken error, call `refresh_session()`
913. Retry operation with new token
924. If refresh fails, clear session and prompt re-login
93
94### Jetstream Connection
95- Attempts simple connection first, then falls back to collection-filtered URL
96- Reconnects with 5-second delay on failure
97- Uses User-Agent: `think-cli/0.1.0`
98- Filters messages on client side even with server-side collection filter
99
100### Publishing Blips
101Records posted with structure:
102```json
103{
104 "$type": "stream.thought.blip",
105 "content": "<message>",
106 "createdAt": "<ISO8601 timestamp>"
107}
108```
109Posted to `com.atproto.repo.createRecord` with user's DID as repo.
110
111## Note on Julia Dependencies
112
113The `Project.toml` and `Manifest.toml` files are unrelated to the Rust project—likely leftover artifacts or separate experiments (Franklin static site generator). The actual Rust dependencies are in `Cargo.toml`.