A TUI for personal knowledge management — feeds, saved articles, deep research, optional Obsidian export
Project description
wyrd
A small Linux RSS reader with AI-assisted discovery, for people tired of the feed.
The modern web is mostly other people's machines deciding what you should care about — engagement-tuned timelines, SEO-mulched listicles, ad auctions deciding which article you even see. wyrd is a terminal app built on the opposite premise: you pick the sources, you pick the keywords that matter, articles arrive as plain Markdown stripped of every banner and pop-up, and the only ranking is a transparent keyword score you control. No accounts, no recommendations from a stranger's model, no telemetry from the app itself. The name is Anglo-Saxon for the woven thread of personal fate — your reading list is yours to weave.
The reader is RSS-only on purpose. Every publisher worth following exposes a
feed (Hacker News, Reddit, Substack, blogs, news sites); the ones that don't
are usually the ones you wouldn't miss. And when you want to find pieces that
don't have a feed at all, Ctrl+D asks Claude — using web search and fetch
under the hood — for articles you'd like based on what you've already saved.
Discovered items land in the same feed table; like or dismiss them like
anything else. A deep-research helper on 3 turns Claude loose on the
peer-reviewed literature when you want to actually understand something. An
embedded terminal and optional Obsidian export round out the rest.
Requirements: Linux (x86_64 or arm64) with Python 3.12+. wyrd uses
Linux-specific behavior in the embedded terminal (pyte-backed PTY via
os.forkpty). There are no plans to support macOS or Windows — Linux is
the only target I'm interested in maintaining. If you want wyrd on another
platform, a PR is welcome and I'll review it on its merits, but I won't be
writing it myself and I won't gate Linux changes on cross-platform
compatibility. See PLAN.md for the design and roadmap.
What it does
Feeds. RSS / Atom URLs you configure flow through one scheduler. Audio /
video items are filtered out — it's a reader. Manual refresh with Ctrl+R;
auto-refresh runs quietly on a configurable interval (default hourly) and only
notifies when something new arrives or a source errors. F3 opens an
Activity modal showing recent refresh runs with per-source status and any
errors. The default config.toml ships with commented-out HN-via-RSS and
long-form-journalism examples to get you started.
Read in-app. Highlighting a feed item fetches the page and renders it as
Markdown right in the TUI (httpx → trafilatura → in-house XML→Markdown
converter that keeps code-block indentation and turns HTML tables into real
GitHub pipe tables). Each article shows a "N min read · ~W words" line plus
a 2–3 sentence Claude-generated brief at the top — what the piece is actually
about, not the publisher's SEO description. Results are cached. o falls back
to opening the URL in a real browser; y copies the URL to your clipboard
(via OSC 52 — works over SSH); Ctrl+Shift+Y copies the whole article + URL
as Markdown; Enter or F4 toggles reader-focus mode that hides the left
panel.
Like → save → loop back. l in the Feed snapshots an item into the
Saved pane (d dismisses it). Saved items get editable Tags and
Notes alongside the article, autosaved as you navigate. FTS5-backed search
(/) covers title / summary / article body / notes / tags with bm25 ranking.
And — the loop — wyrd auto-detects RSS feeds from articles you've read
(<link rel="alternate"> in the page head) and surfaces them as "Suggested
feeds" in the setup wizard. One-click subscribe.
AI-assisted discovery (Ctrl+D). Press Ctrl+D from any tab. Claude
gathers ~40 candidate articles based on your recent saved items and the
active taste profile (built-ins: default, engineer, academic, essays
— or define your own under [discover.profiles.<name>]). Each URL is
HEAD-verified before insertion; a second Claude pass re-ranks and drops weak
ones. The survivors land in the Feed table with source_kind = "discover".
Press m on a saved item to find more articles like that one specifically.
First press shows a one-time consent modal explaining exactly what data goes
to Claude. Every run is logged locally so you can see which profile produces
the highest like-rate over time.
Deep research (3). Type a topic, hit Enter, and a Claude-driven agent
reads the peer-reviewed literature on it. Each run produces a structured
review paper plus a per-source note with the agent's summary and, where an
open-access copy exists, the full text (PDF or HTML, extracted to Markdown).
Files land in a per-run folder; the left column is a tree of past runs with
live progress while the agent works.
Embedded terminal (4). A pyte-backed PTY running your $SHELL.
F12 detaches; F10 (anywhere) suspends the TUI entirely and drops into a
real shell — the always-works escape hatch.
Obsidian export. Set [obsidian] vault (in config.toml or via the
setup wizard) and every liked article lands as Markdown under
<vault>/<folder>/saved/ while every finished research run lands under
<vault>/<folder>/research/. Direct file writes — no Obsidian CLI or
desktop app required. Articles get YAML frontmatter (url, source, author,
published, saved, tags including wyrd/saved). A like before extraction
finishes defers the write until the worker lands. The wizard has an "Export
saved items to vault" button to migrate everything you'd liked before
configuring Obsidian.
Customizable. Theme picker in the setup wizard with live preview;
Ctrl+T cycles themes anywhere. Every app-level key is overridable via
[keys] in config.toml, applied live on save — no restart needed.
Install
uv tool install wyrd-tui # from PyPI (binary is `wyrd`)
uv tool install . # or from a git clone
This puts a wyrd binary on your PATH (under ~/.local/bin by default).
Develop
uv sync # create the venv, install deps
uv run wyrd # launch the TUI
uv run pytest # run the tests (parallel via pytest-xdist; ~30s)
Config lives at ~/.config/wyrd/config.toml, data (the SQLite db) at
~/.local/share/wyrd/wyrd.db. Set WYRD_HOME=/some/dir to relocate both (used by tests).
First run pops the setup wizard — add some RSS feeds (or let Claude suggest
them with verified-before-shown URLs), then Ctrl+R to fetch.
Keys
All shortcuts are configurable — F2 opens the wizard with a "Keybindings" section, or edit [keys] in config.toml directly. Defaults:
1/2/3/4— Feed / Saved / Research / Terminal tabsF12— detach from the embedded terminal (it captures every other key while focused)F10— suspend the TUI and drop into a real$SHELL(escape hatch for anything the embedded emulator mangles)F2— open the setup / preferences wizardF3— open the Activity modal (recent refresh runs; Esc to close)F4— toggle reader focus mode: hides the left panel so the article fills the screen; works in Feed, Saved, and Researchctrl+r— fetch new content from all configured feedsctrl+d— run AI-assisted content discovery (anywhere; switches to the Feed pane)ctrl+t— cycle through Textual themes (persisted to config)- In the Feed pane:
↑/↓browse (the highlighted item's article is fetched and shown as Markdown on the right);Enterenters reader focus mode (article fills the pane —EnterorF4exits);llike/save,ddismiss,oopen in a browser if the in-app reader can't parse the page;ycopy the article's URL to the clipboard (via OSC 52 — works over SSH);Ctrl+Shift+Ycopy the whole article + URL as Markdown;f5cycles the view between all / interesting only (★) / ranked by keyword score;/focuses the search box (FTS5-backed) - In the Saved pane:
↑/↓browse,Enterenters reader focus mode (EnterorF4exits), edit Tags/Notes (autosaved on navigate-away),Ctrl+Ssave now,ycopy URL,Ctrl+Shift+Ycopy article + URL as Markdown,mfind more articles like this one,/focus search ctrl+q— quit (only when the terminal doesn't have focus — detach withF12first)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wyrd_tui-1.2.0.tar.gz.
File metadata
- Download URL: wyrd_tui-1.2.0.tar.gz
- Upload date:
- Size: 88.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64c1ca7642e328edfa3d6505ee12aa2cb899977f12526800b44dfeb4d200ee5d
|
|
| MD5 |
6b1cc26e86b24a2ef475ad7c49a93924
|
|
| BLAKE2b-256 |
ccc236978a83a9641ab0b374405e8a9df47bb057f2a652165d8770e1e58a5ec8
|
File details
Details for the file wyrd_tui-1.2.0-py3-none-any.whl.
File metadata
- Download URL: wyrd_tui-1.2.0-py3-none-any.whl
- Upload date:
- Size: 115.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3aacbec5de7037e1817859bbc062819fd15bdba0691718e0faeb6b012a3a4349
|
|
| MD5 |
211302a81b4cc155c7c28e06e32c62f8
|
|
| BLAKE2b-256 |
e683fd5e05be716ad353ec8787f3c0539ac2633b2c3e7d65fec37e64e490f403
|