Skip to content

Repository files navigation

Intake

Desktop preview

Everything you follow. One inbox. Decide what deserves your time.

Intake is a native Omarchy Quattro plugin for following YouTube channels, podcast RSS, article feeds and newsletter feeds. A local library brings new releases, transparent text summaries, a personal queue, saved items and notes together.

Version 0.1.0 targets Omarchy Quattro.

What works

  • Add RSS/Atom URLs or YouTube channel IDs, /channel/ URLs and resolvable handle URLs.
  • RSS podcasts with playable enclosure links; publisher-linked plain text/VTT/SRT transcripts where available (two per source per refresh).
  • Local extractive summaries and key excerpts, explicitly labeled with the text used. No model, API key, account or cloud summarization service required.
  • Create custom feeds such as Business, AI or Sports and choose their sources. A source can belong to several feeds; All feeds combines them without duplicating items. Feed tags appear on items and source listings.
  • Compact inbox, queue, saved and archive views with title, creator, format, date, duration and excerpt in each row. Quick filters, search, and Newest/Oldest/Shortest/Source sorting; the queue defaults to its manual order.
  • Mark all inbox items read, or mark only one source read, while preserving queued/saved/previously completed items. Undo the last batch restores affected items still marked done and preserves notes and subsequent state changes.
  • Direct row buttons to Queue, Save or Complete an item without opening its details. Compact icon buttons retain accessible names and tooltips when the detail pane is open.
  • Reorder the queue, open original content, mark done or dismissed, restore to inbox, save personal notes.
  • Follow/unfollow sources, connect private subscriber RSS, replace an existing feed while retaining matching items and personal history, import OPML subscriptions, manually import .eml newsletter files, export subscriptions as OPML and the library/notes as Markdown.
  • One shared background service refreshes while enabled, including when the window is closed. Optional notifications report only a count of new releases.
  • An optional fictional sample collection is clearly labeled and removable by unfollowing it.

Installation

Requires Omarchy Quattro, its existing Quickshell host, Python 3 (standard library only), and optional notify-send for digest notifications. Tested contract: installed Omarchy 4.0.0.alpha; runtime APIs inspected directly on September 5, 2026. No code or dependencies are built or downloaded at startup; configured sources are fetched on refresh. No elevated permissions are required.

Install the complete plugin with Omarchy's standard installer:

omarchy plugin add https://github.com/studioxvii/omarchy-intake

The installer clones the repository and enables Intake. Open Sources to add your subscriptions; no sources or personal library are bundled. You can also open the window through shell IPC:

omarchy-shell shell summon io.github.studioxvii.intake '{}'

The widget opens the same window as shell IPC. Escape or the close button closes it. Ctrl+F focuses search. Standard Qt Tab navigation moves through controls. Sources accepts a filesystem path for OPML or .eml imports.

Widget settings expose refreshMinutes (15–1440, default 30) and digestNotifications (default false). They are ordinary inline Omarchy widget settings. Refresh does not run while the computer or shell is off; feeds only expose their available recent history.

Coverage and deliberate limits

A summary selects sentences and chapter headings from the source's available text; it is an extractive summary, not a generative analysis. A publisher description is always labeled as a description. YouTube RSS normally has no transcript: videos remain useful queue items with description-based previews. Social links and follow/subscribe boilerplate are excluded from summaries. Existing summaries are regenerated once when the summarizer changes, without modifying item state, queue order or notes. YouTube items open their original video URL through the explicitly labeled "Watch on YouTube" action. No arbitrary YouTube transcript scraper is bundled; the official caption-download API is not a public arbitrary-video transcript source.

Article coverage is labeled Full text, Excerpt only, Subscriber access needed, or Coverage unknown, with the reason shown in the item details. A long entry or an RSS content field alone does not establish completeness. Video descriptions, publisher transcripts and imported emails retain their own labels. Podcast publisher transcripts are used only for supported text formats and bounded to 80,000 characters. No audio is automatically downloaded or transcribed. Full playback occurs in the user's default browser/player and does not imply consumption or resume tracking.

Newsletters work through publisher RSS or manual .eml imports. This release does not connect to mail accounts, import private YouTube subscriptions, build cross-source AI briefs or deduplicate across formats. These remain possible later work.

The library holds up to 1,200 items and 50 followed sources. Each source contributes up to its first 150 feed entries. On reaching capacity, only dismissed items without notes are replaced; queued/saved/noted material is preserved and refresh reports the limit. Source refreshes run oldest-checked first with an 80-second collection budget and a 100-second helper deadline. Partial refreshes report pending sources. Existing content survives failures.

Your custom feeds

Open Your feeds in the sidebar, enter a name, and choose Create feed. Select the sources to include using their Add buttons; assignments save immediately without fetching content. A source may belong to multiple feeds. Use Open feed or the selector next to search to switch between a specific feed, All feeds, and Unassigned.

The chosen feed applies across Inbox, Your queue, Saved and Archive, together with the existing format, search and sort controls. Mark feed read affects only that feed's inbox items and retains batch undo. Notes, saved states and queue order are shared when an item appears in several feeds. In Queue order, Earlier/Later moves relative to the adjacent visible item, including when search, format or feed filters hide other entries. Tags show the memberships in All feeds; item details show every tag.

Rename or delete feeds in the manager. Deleting a feed keeps its sources and items; unfollowing a source retains its existing item tags. Existing subscriptions start unassigned so you can choose the categories yourself. This release supports 30 custom feeds with names up to 40 characters.

Subscriber feeds and coverage

In Sources, choose Subscriber feed and paste the personal RSS URL supplied by your publisher. To upgrade an existing subscription, use its Edit feed button. Leave the URL blank to change its settings without replacing it. Intake validates a replacement before saving it; overlapping items match by publisher GUID or article URL and retain their IDs, notes, queue order and read state. A publisher that changes both identifiers may produce a separate item.

Keep Coverage: auto unless you have verified the feed supplies complete articles. I verified full text is a user assertion about the feed, not a subscription check; explicit paywall prompts still take precedence. Excerpts only declares the feed's limited coverage. Selecting Subscriber alone never marks an article complete or grants access. HTTP 401/403 responses report feed access denied and ask you to check the link or publisher restrictions; they do not establish that content is paywalled. Cached items and their prior coverage are preserved.

For Stratechery, copy the personalized RSS link from your account's Delivery Preferences. Access depends on your subscription. Publishers without written subscriber RSS can still be used through saved .eml imports. Mailbox synchronization, browser capture and browser-cookie login are not implemented.

Local storage and privacy

Library: ${XDG_DATA_HOME:-~/.local/share}/omarchy-intake/intake.sqlite3. Exports are written to its exports/ folder with a timestamp, using private permissions. Removing a real source retains its content, attribution and personal notes. Removing the optional sample collection deletes its sample items.

Feed URLs can contain private subscription tokens: they remain in the private database and are sent to their configured publishers. Pasted URLs are masked, and source listings hide URL paths and queries. OPML exports omit subscriber and potentially private URLs by default; an explicit checkbox includes them when needed. No telemetry, behavior monitoring, browser cookies, account passwords or external summarization endpoints are used. Original item links that contain a known feed credential are hidden from the UI snapshot. Helper requests, including notes and URLs, pass via stdin rather than process arguments. Network requests use Python's standard proxy environment behavior.

Downloads are capped at 12 MiB before XML parsing, XML entity declarations are rejected, and fields/model sizes are bounded. Only HTTP(S) sources and links without URL-embedded credentials are accepted. Initial DNS results and redirects are checked for public addresses; this is defensive filtering, not a network sandbox (DNS resolution can change). Feed markup is converted to text and remote content is rendered with plain-text QML controls. The plugin launches no persistent helper processes outside its owned service.

Disable and remove

omarchy plugin disable io.github.studioxvii.intake
omarchy plugin remove io.github.studioxvii.intake

Disabling stops the owned helper and timer; removing the plugin does not remove the user's local library. Export it before intentionally deleting the separate omarchy-intake data directory.

Development and validation

python3 -m unittest discover -s tests -v
omarchy plugin validate .
python3 ~/.codex/skills/omarchy-plugin-builder/scripts/preflight.py .

QML lint requires imports for qs.Commons and qs.Ui. The installed shell resolves qs at runtime; for standalone lint, expose those directories under a temporary qs/ import root and pass -I /that/root to /usr/lib/qt6/bin/qmllint. Dynamic shell var/QtObject properties have incomplete static type information; record unresolved metadata warnings separately from runtime failures.

Backend protocol: one bounded JSON line on stdin, one bounded JSON result on stdout. Actions: status, create-collection, rename-collection, delete-collection, set-source-collections, add, update-source, refresh, remove, state, note, move, mark-read, undo-read, demo, import-opml, import-eml, export. --data-dir supports isolated tests. UI operations are serialized; failed mutations preserve confirmed UI state. Shell summon payloads may select a section (including feeds or sources) and an existing collectionId; an empty collection ID selects All feeds.

License and attribution

MIT, Studio XVII. The FloatingWindow open/close lifecycle follows the installed Omarchy developer gallery, part of Omarchy, copyright David Heinemeier Hansson and contributors, MIT. No third-party Python package is bundled. Source content belongs to its publishers.

Local desktop verification: LOCAL-VALIDATION.md.

About

Intake: a native Omarchy inbox for videos, podcasts, newsletters, and custom content feeds.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages