Files
PodTui/README.md
Michael Freno 69e12cf5b9 fix: podtui binary crashed with 'preload not found' when launched from repo root
The embedded runtime reads the CWD bunfig.toml at startup; the repo's
top-level 'preload = ["@opentui/solid/preload"]' made the standalone die
because that module isn't bundled. Removed the ambient preload from
bunfig.toml and moved the solid transform registration to explicit
--preload flags in the start/dev scripts ([test] preload untouched).

Verified: binary boots from repo root, from a clean dir, and dev/start
still work; bun test 54 pass. No new release needed — the binaries were
never config-dependent; this was purely the repo's bunfig trap.
2026-08-07 17:36:11 -04:00

222 lines
7.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PodTui
A keyboard-first, yazi-style terminal podcast client written in TypeScript and
built on [OpenTUI](https://github.com/opentui/opentui). Subscribe to RSS feeds,
browse episodes in a three-pane file-manager layout, and play audio through an
external player with full transport control — all from your terminal.
## Features
- **Vim/yazi-style navigation** — `j/k` to move, `h/l` to swipe between panes,
`Enter` to open, `16` / `[` `]` to switch tabs. The tab list is the app root:
at launch it fills the current pane, and drilling into a tab's contents slides
it into the parent pane.
- **Three-pane view** — parent / current / preview (Up | Current | Preview),
mirroring yazi's pane model.
- **Podcast feeds** — add feeds, browse episodes, and manage your library
(My Shows, Discover, Feed tabs).
- **Search** across your subscribed shows.
- **Audio playback** through an external player with full transport control:
play/pause, next/previous, seek, speed, and per-episode resume progress.
- **Themeable** and **remappable keybindings**.
- Ships as a **standalone compiled binary** — no runtime or install step beyond
a system audio player.
## Requirements
- A terminal with UTF-8 and modern color support (kitty, iTerm2, WezTerm,
tmux, GNOME Terminal, etc.).
- An **audio player** on `PATH`. PodTui auto-detects in priority order:
| Player | Platforms | Seek | Speed | Position tracking |
|----------|----------------|:----:|:-----:|:------------------|
| `mpv` | any | ✔ | ✔ | ✔ (recommended) |
| `ffplay` | any | ✔ | ✘ | ✘ |
| `afplay` | macOS built-in | ✔ | ✔ | ✘ |
| `open`/`xdg-open` | any | ✘ | ✘ | ✘ |
Install `mpv` for the best experience (`brew install mpv`,
`sudo apt install mpv`, `pacman -S mpv`). You can force a specific backend
with `PODTUI_AUDIO_BACKEND=mpv|ffplay|afplay|system|none`.
## Installation
PodTui distributes as a **self-contained binary** for macOS (arm64/x64) and
Linux (arm64/x64). Pick whichever fits your platform.
### 1. Homebrew (macOS)
```sh
brew install mikefreno/podtui/podtui # requires mpv: brew install mpv
```
> The formula installs the standalone binary plus its two native libraries
> side by side (see [Packaging model](#packaging-model)). It does **not**
> depend on Bun.
### 2. Standalone tarball (all platforms)
Grab `podtui-<platform>-<arch>.tar.gz` from the latest
[GitHub Release](https://github.com/mikefreno/podtui/releases), unpack it, and
put `podtui` on your `PATH`:
```bash
curl -sSL -o podtui.tar.gz \
https://github.com/mikefreno/podtui/releases/latest/download/podtui-linux-x64.tar.gz
tar -xzf podtui.tar.gz
sudo install -m755 podtui /usr/local/bin/podtui
```
> The tarball contains `podtui` plus `libopentui.<ext>` and
> `libcavacore.<ext>` **beside it** — keep them together (don't move just the
> binary alone), or the native FFI libraries won't load.
>
> One caveat: the embedded runtime reads a `bunfig.toml` from the directory
> you launch from. If that file has a `preload` entry (as Bun project
> directories often do), startup fails with `preload not found`. Launching
> from a normal directory (home, `~/bin`, …) works fine.
### 3. Arch Linux (AUR)
```bash
yay -S podtui
```
or build from the PKGBUILD (`podtui-bin`). The package installs the released
binary and its sibling libraries.
### 4. From source
Requires [Bun](https://bun.sh) ≥ 1.2.
```bash
git clone https://github.com/mikefreno/podtui.git
cd podtui
bun install
bun run build:native # build the cavacore FFI lib from C source
bun run dev # run with hot reload, or: bun start
```
## Linux distribution notes
PodTUI deliberately does **not** ship `.deb`, `.rpm`, Flatpak, or Snap
packages. For a terminal application that's overwhelmingly installed through
repositories or archives, those formats add desktop-sandboxing overhead and a
packaging tax with little benefit. Instead:
- **GitHub Release tarballs** are the universal path — one upload, works on
any distro with `curl` + `tar`.
- **AUR (`podtui-bin`)** covers Arch. Anyone on Arch/Manjaro gets the same
binary through their native package manager.
- **Nix / cross-distro** users can build from source (or a Nix flake can be
added later).
This keeps maintenance to a single build per OS/arch and still reaches the
vast majority of desktop Linux users through their preferred path.
## Usage
Launch `podtui` (or `bun src/index.tsx` from the source tree). Press `~`
for the in-app help.
### Command-line flags
| Flag | Description |
|------|-------------|
| `-v`, `--version` | Print the version and exit |
| `-q`, `--query <term>` | Query feeds for a show title and print matching shows, without launching the TUI |
| `-p`, `--play <term>` | Play the matching show, without launching the TUI |
### Keybindings
All keys are remappable — edit `~/.config/podtui/keybinds.jsonc`.
| Keys | Action |
|------|--------|
| `j` / `k` | Move cursor down / up |
| `J` / `K` | Jump 5 lines |
| `ctrl-d` / `ctrl-u` | Page down / up |
| `gg` / `G` | Go to top / bottom |
| `h` / `l` | Swipe to parent pane / preview pane |
| `Enter` | Open the item under the cursor (a tab, episode, show…) |
| `Space` | Select / toggle selection |
| `v` | Visual mode (multi-select) |
| `1``6` | Jump to tab 16 (Feed, My Shows, Discover, Search, Player, Settings) |
| `[` / `]` | Previous / next tab |
| `P` (shift) | Play / pause |
| `N` / `B` | Next / previous episode |
| `shift-.` / `shift-,` | Seek forward / backward |
| `s` | Search (in a list) |
| `f` | Filter |
| `r` | Refresh |
| `:` | Command bar |
| `~`, `f1` | Help |
| `q`, `ctrl-c` | Quit |
| `Esc` | Escape / cancel |
## Configuration
Configuration lives under the XDG config directory — `~/.config/podtui` by
default (`$XDG_CONFIG_HOME/podtui` if set).
| File | Purpose |
|------|---------|
| `feeds.json` | Your subscribed feeds (RSS/podcast sources) |
| `sources.json` | Custom feed sources |
| `downloads.json` | Downloaded episode metadata |
| `keybinds.jsonc` | Keybinding remaps (see above) |
| `themes/` | Optional custom theme files |
Env overrides: `PODTUI_AUDIO_BACKEND`, `XDG_CONFIG_HOME`. Startup also reads
the same OpenTUI environment variables.
## Development
```bash
bun install # install dependencies
bun run dev # run with hot reload
bun test # run the test suite
bun run build # bundle JS + copy native libs into dist/
make native # rebuild cavacore from C source
make lint # type-check (tsc)
```
### Releasing
Tag a release (e.g. `v0.1.0`); CI builds and uploads the per-platform tarballs
to your GitHub Release automatically:
```bash
make dist # build the standalone binary + tarball for THIS platform
make dist-mac # (run on macOS) → podtui-darwin-<arch>.tar.gz
make dist-linux # (run on Linux) → podtui-linux-<arch>.tar.gz
```
`make dist` emits a config-independent binary: Bun does not bake bunfig
settings into `--compile` output, and the solid JSX transform is registered in
`build.ts` itself. The binary then embeds the `preload`-free runtime, so launch
it from any normal directory.
## Packaging model
A release tarball is three files sitting side by side:
```
podtui # standalone compiled binary (embeds the Bun runtime)
libopentui.<dylib|so> # OpenTUI native renderer FFI library
libcavacore.<dylib|so> # cavacore spectrum FFI library (built from C)
```
PodTui loads its native libraries relative to the binary, so **keep them in
the same directory**. The compiled binary embeds the Bun runtime, so it runs
with no Bun installed. Each release builds one tarball per OS/arch in CI; there
is no cross-compilation.
## License
TBD — choose and document a license before first release.
## Related
- [OpenTUI](https://github.com/opentui/opentui) — the TUI framework driving the interface