Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# AGENTS.md

This file provides guidance to WARP (warp.dev) when working with code in this repository.

## Project Overview

SuperFlux is a desktop RSS reader built with **Tauri v2** (Rust backend) + **React 19** / TypeScript / Vite 7 frontend. It features a 3-panel layout, AI summaries, TTS, podcast player, and cloud sync via Supabase. The app runs as a native desktop app; the Rust backend handles all HTTP requests (bypassing CORS), window effects, native TTS, and system info.

## Commands

### Development
```
npm run dev # Full Tauri dev mode (Vite + Rust backend)
npm run dev:app # Frontend only (Vite on port 5173, no Tauri)
npm run dev:proxy # CORS proxy server on port 3001 (for browser-only dev)
```

When developing UI-only changes without Rust, run `dev:app` + `dev:proxy` together. The `tauriFetch.ts` abstraction auto-detects whether Tauri runtime is available and falls back to the proxy.

### Build & Lint
```
npm run build # Full Tauri build (frontend + Rust → installer)
npm run build:frontend # TypeScript check + Vite build only
npm run lint # ESLint on all .ts/.tsx files
```

No test framework is configured.

## Architecture

### Dual Runtime: Tauri vs Browser

The critical abstraction is `src/lib/tauriFetch.ts`. It exposes `fetchViaBackend()` and `httpRequest()` that:
- In Tauri: invoke Rust commands (`fetch_url`, `http_request`) which use a shared reqwest client with proper User-Agent headers per domain (Reddit/YouTube need specific handling)
- In browser: proxy through `localhost:3001` (proxy-server.js)

All network-dependent services **must** use these helpers, never raw `fetch()` for external URLs.

### State Management

No state library — state lives in custom hooks and React context:
- `useFeedStore` (hooks/) — all feed/item CRUD, stored in localStorage. Exposes `FeedStoreCallbacks` for sync integration.
- `useHighlightStore` (hooks/) — text highlight persistence
- `useResizablePanels` (hooks/) — 3-panel layout geometry
- `useCommands` (hooks/) — command palette registration
- `AuthContext` — Supabase auth (email, OAuth via separate Tauri window with PKCE)
- `ProContext` — license/Pro status with 24h cache

State is persisted to **localStorage** under `superflux_*` keys. `fullContent` is stripped before saving items to avoid blowing the quota.

### Sync Architecture (3 layers)

1. **SyncService** (`services/syncService.ts`) — Supabase cloud sync. Debounces item updates, ensures parent feeds exist before upserting items (FK constraint). Uses `superflux-sync-update` custom event to notify UI of remote changes.
2. **ProviderSync** (`services/providerSync.ts`) — bidirectional sync with external RSS providers (Miniflux, FreshRSS, Feedbin, BazQux). Manages `remoteId` mapping between local and provider IDs.
3. **Provider implementations** (`services/providers/`) — implement the `RSSProvider` interface from `types.ts`. Factory pattern via `createProvider()` in `index.ts`.

`App.tsx` wires these together through `FeedStoreCallbacks`: feed/item changes trigger both SyncService and ProviderSync pushes.

### Rust Backend (`src-tauri/src/lib.rs`)

Key Tauri commands:
- `fetch_url` / `http_request` — HTTP with domain-specific headers, shared connection pool
- `collapse_window` / `expand_window` — bar mode with saved geometry
- `set_window_effect` — Windows Mica/Acrylic/Blur with DWM repaint workaround
- `tts_speak` / `tts_stop` — native OS TTS via the `tts` crate
- `tts_speak_elevenlabs` — cloud TTS, returns base64 MP3
- `open_auth_window` — separate Tauri window for OAuth flow, communicates back via `auth-callback` event
- `get_cpu_usage` / `get_memory_usage` / `get_net_speed` — system info via sysinfo

Android builds compile but stub out window/TTS commands (`#[cfg(not(target_os = "android"))]`).

### Supabase Schema

Migrations in `supabase/migrations/`. Core tables: `profiles`, `feeds` (composite PK: `id, user_id`), `feed_items` (FK to feeds with composite key), `user_settings`, `bookmarks`, `editor_documents`, `notes`. All tables have RLS policies scoped to `auth.uid()`.

### Services Layer

- `rssService.ts` — parses RSS/Atom/Reddit JSON/YouTube feeds, resolves YouTube @handles to channel IDs
- `llmService.ts` — AI summaries via Ollama (local) or Groq (cloud), prompts in French
- `ttsService.ts` — TTS abstraction (browser Web Speech / native Tauri / ElevenLabs)
- `articleExtractor.ts` — full-text extraction via @mozilla/readability
- `licenseService.ts` — LemonSqueezy license activation
- `bookmarkService.ts` / `noteService.ts` / `editorDocService.ts` — Supabase CRUD for additional features

### App Modes

The app has 5 brand modes (controlled by `brandMode` state in `App.tsx`): `flux` (RSS reader), `note` (notes), `bookmark` (web bookmarks), `editor` (rich text editor with TipTap), `draw` (drawing canvas). Each mode swaps the 3-panel content.

## Environment Variables

Required in `.env` for full functionality:
- `VITE_SUPABASE_URL` / `VITE_SUPABASE_ANON_KEY` — Supabase project
- `VITE_GROQ_API_KEY` — Groq API (optional, for cloud AI summaries)

## Conventions

- UI text and LLM prompts are in **French**
- Path alias: `@/*` → `./src/*`
- Styling: Tailwind CSS v4 with `color-mix()`, themes via CSS classes (`dark`, `sepia`, `amoled`)
- UI components: mix of Radix UI primitives and custom shadcn/ui components in `src/components/ui/`
- Icons: Lucide React
- Animations: Framer Motion
- Feed sources are typed as `FeedSource`: `article | reddit | youtube | twitter | mastodon | podcast`
- Each source has default icon/color in `sourceDefaults` (defined in both `useFeedStore` and `providerSync` — intentionally duplicated to avoid circular deps)
85 changes: 74 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
![Shot](https://github.com/devohmycode/SuperFlux/blob/master/src-tauri/icons/shot-01.png)
# SuperFlux

A fast, native desktop RSS reader with a resizable 3-panel layout, built-in Reddit comments, AI summaries, text-to-speech, and a collapsible bar mode. Built with Tauri 2 and React 19.
A fast, native desktop RSS reader and productivity suite with a resizable 3-panel layout, built-in Reddit comments, AI summaries, text-to-speech, bookmarks, notes, a document editor, a drawing canvas, and a collapsible bar mode. Built with Tauri 2 and React 19.

![Shot2](https://github.com/devohmycode/SuperFlux/blob/master/src-tauri/icons/shot-02.png)

Expand All @@ -13,9 +13,9 @@ The interface is split into three independently resizable columns with drag hand

| Panel | Default Width | Content |
|-------|--------------|---------|
| **Sources** (left) | 18% | Feed tree organized by type, folders with drag-and-drop, unread counts, favorites, read later |
| **Sources** (left) | 18% | Feed tree, folders, unread counts, favorites, read later, mode tabs |
| **Feed** (center) | 32% | Article list with pagination, time grouping, 3 view modes (normal, compact, cards) |
| **Reader** (right) | 50% | Full article reader, AI summary, TTS, highlights, web view toggle, Reddit comments |
| **Reader** (right) | 50% | Full article reader, AI summary, TTS, highlights, web view, Reddit comments, or contextual module (notes editor, document editor, bookmark reader, drawing canvas) |

Each panel can be **closed individually** -- it collapses into a thin clickable strip. Toggle panels with keyboard shortcuts `1`, `2`, `3`. Panels resize freely by dragging the handles between them.

Expand Down Expand Up @@ -80,6 +80,48 @@ Built-in audio player for podcast feeds with:
- Seekable progress bar, volume slider
- Album artwork display

### 5 Integrated Modes

Switch between modes using the icon tab bar in the sources panel or keyboard shortcuts `Ctrl+1` through `Ctrl+5`. A command palette (`Ctrl+K`) provides quick access to all commands and navigation.

| Mode | Shortcut | Description |
|------|----------|-------------|
| **SuperFlux** | `Ctrl+1` | RSS reader -- the default 3-panel feed experience |
| **SuperBookmark** | `Ctrl+2` | Web bookmark manager with full-page reader and metadata extraction |
| **SuperNote** | `Ctrl+3` | Sticky notes with folders, color-coded cards, and cloud sync |
| **SuperEditor** | `Ctrl+4` | Document editor with Pandoc export (PDF, DOCX, HTML, Markdown) |
| **SuperDraw** | `Ctrl+5` | Canvas drawing tool with shapes, freehand, text, arrows, dark/light mode, and PNG export |

### SuperBookmark

Save and organize web bookmarks with automatic metadata extraction (title, excerpt, favicon, author). Features a built-in reader view for saved pages.

### SuperNote

Quick note-taking with folder organization, sticky-note style cards, and Supabase cloud sync. Notes support positioning, colors, and resizing.

### SuperEditor

A full document editor with:

- Folder organization and document management
- **Pandoc integration** for exporting to PDF, DOCX, HTML, Markdown, and more
- Cloud sync via Supabase

### SuperDraw

A custom canvas drawing tool inspired by Excalidraw:

- **10 tools**: select, hand (pan), rectangle, ellipse, diamond, line, arrow, freehand, text, eraser
- **Color picker** for stroke and fill with 7 preset colors + transparent
- **Stroke width** selector (1--8px)
- **Font size** selector for text tool (12--64px)
- **Dark / light mode** toggle (independent of app theme, auto-adapts element colors)
- **Zoom & pan** with mouse wheel (Ctrl+wheel to zoom, wheel to pan)
- **Selection** with resize handles, multi-select box, duplicate (`Ctrl+D`), delete
- **Undo / redo** history (`Ctrl+Z` / `Ctrl+Y`)
- **PNG export** and persistent local storage

### Full Article Extraction

When RSS content is truncated, SuperFlux automatically fetches the full article from the original site using [Readability](https://github.com/mozilla/readability). A manual "Fetch from original site" button is also available.
Expand All @@ -103,20 +145,28 @@ Sign in with a Supabase account to sync feeds, read/star/bookmark status across

### Appearance

- **3 themes**: Light, Sepia, Dark with animated circular transition effect
- **3 themes**: Light, Sepia, Dark (+ AMOLED) with animated circular transition effect
- **Window effects** (Windows): Mica, Acrylic, Blur, Tabbed with adjustable opacity
- **Custom frameless title bar** with minimize, maximize, collapse controls
![Shot4](https://github.com/devohmycode/SuperFlux/blob/master/src-tauri/icons/shot-04.png)
### Keyboard Shortcuts

| Key | Action |
|-----|--------|
| `1` | Toggle Sources panel |
| `2` | Toggle Feed panel |
| `3` | Toggle Reader panel |
| `↑` `↓` | Navigate articles |
| `Enter` | Open selected article |
| `S` | Toggle star/favorite |
| `Ctrl+K` | Open command palette |
| `Ctrl+1`--`5` | Switch mode (Flux, Bookmark, Note, Editor, Draw) |
| `Alt+1` | Toggle Sources panel |
| `Alt+2` | Toggle Feed panel |
| `Alt+3` | Toggle Reader panel |
| `J` / `K` | Next / previous article |
| `O` | Open article in browser |
| `R` | Toggle read / unread |
| `S` | Toggle star / favorite |
| `B` | Toggle read later |
| `Shift+R` | Mark all as read |
| `Ctrl+D` | Duplicate selection (Draw mode) |
| `Ctrl+Z` / `Ctrl+Y` | Undo / Redo |
| `?` | Show shortcuts help |

## Pro Plan

Expand Down Expand Up @@ -181,9 +231,17 @@ src/
types.ts # Feed, FeedItem, FeedCategory, TextHighlight types
index.css # Full theme + window effect CSS
components/
SourcePanel.tsx # Panel 1 -- feed tree, folders, sources
SourcePanel.tsx # Panel 1 -- feed tree, folders, sources, mode tabs
FeedPanel.tsx # Panel 2 -- article list, view modes, pagination
ReaderPanel.tsx # Panel 3 -- reader, web view, comments, TTS
NotePanel.tsx # Note list panel (SuperNote mode)
NoteEditor.tsx # Note editor (SuperNote mode)
BookmarkPanel.tsx # Bookmark list panel (SuperBookmark mode)
BookmarkReader.tsx # Bookmark reader view (SuperBookmark mode)
SuperEditor.tsx # Document editor with Pandoc export (SuperEditor mode)
SuperDraw.tsx # Canvas drawing tool (SuperDraw mode)
CommandPalette.tsx # Ctrl+K command palette
ShortcutsOverlay.tsx # Keyboard shortcuts help overlay
TitleBar.tsx # Custom title bar with bar/collapse mode
AudioPlayer.tsx # Embedded podcast player
SettingsModal.tsx # Settings (account, provider, AI, TTS, appearance)
Expand All @@ -202,6 +260,10 @@ src/
syncService.ts # Supabase cloud sync logic
feedSearchService.ts # Feed discovery (Feedly, iTunes, Reddit)
providerSync.ts # External provider sync orchestration
bookmarkService.ts # Bookmark CRUD and metadata extraction
noteService.ts # Notes cloud sync with Supabase
editorDocService.ts # Editor documents cloud sync
pandocService.ts # Pandoc export integration
providers/
miniflux.ts # Miniflux API client
googleReader.ts # Google Reader API (FreshRSS, BazQux)
Expand All @@ -210,6 +272,7 @@ src/
useFeedStore.ts # Feed & article state management
useHighlightStore.ts # Highlight persistence
useResizablePanels.ts # Panel resize logic
useCommands.ts # Command palette & keyboard shortcuts
contexts/
AuthContext.tsx # Supabase auth context
ProContext.tsx # Pro status management & caching
Expand Down
6 changes: 5 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@
<script>
(function() {
var t = localStorage.getItem('theme');
if (t === 'dark' || (!t && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
if (t === 'amoled') {
document.documentElement.classList.add('amoled');
} else if (t === 'dark' || (!t && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
} else if (t === 'sepia') {
document.documentElement.classList.add('sepia');
}
var p = localStorage.getItem('superflux_palette');
if (p) document.documentElement.setAttribute('data-palette', p);
})();
</script>
</head>
Expand Down
Loading