Build standalone binary with bunfig autoload disabled

Set autoloadBunfig: false in build.ts so the compiled runtime ignores any
bunfig.toml in the launching directory, preventing startup failures from a
CWD preload the standalone cannot resolve. Update release.yml, Makefile,
bunfig.toml, CONTRIBUTING.md, and README.md to match.
This commit is contained in:
2026-08-10 09:00:30 -04:00
parent 491a736c32
commit 2e69868ffc
6 changed files with 161 additions and 137 deletions

208
README.md
View File

@@ -1,7 +1,6 @@
# 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,
A keyboard-first, terminal podcast client 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.
@@ -11,8 +10,7 @@ external player with full transport control — all from your terminal.
`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.
- **Three-pane view** — parent / current / preview (Up | Current | Preview).
- **Podcast feeds** — add feeds, browse episodes, and manage your library
(My Shows, Discover, Feed tabs).
- **Search** across your subscribed shows.
@@ -22,13 +20,28 @@ external player with full transport control — all from your terminal.
- Ships as a **standalone compiled binary** — no runtime or install step beyond
a system audio player.
## Quick start
1. Install PodTui ([Installation](#installation)) and make sure **mpv** is in
your `PATH`.
2. Run `podtui` in your terminal.
3. Press `3` to open **Discover** (or `4` to open **Search**, then `s`), drill
in with `Enter`, and press `Enter` on a show to subscribe.
4. Press `1` (**Feed**) or `2` (**My Shows**), open an episode with `Enter`,
and use `P` to play/pause, `N`/`B` for next/previous, and `shift-.` /
`shift-,` to seek.
Press `~` any time for in-app help. All keys are remappable — see
[Keybindings](#keybindings).
## Requirements
- A terminal with UTF-8 and modern color support (kitty, iTerm2, WezTerm,
tmux, GNOME Terminal, etc.).
Ghostty, tmux etc.).
- **mpv** on `PATH` for audio playback. PodTui drives mpv over JSON IPC, so
seek, speed, and position tracking all work. Without `mpv` on `PATH`,
playback is a silent no-op (the `none` backend).
playback is a silent no-op (the `none` backend) — see
[Troubleshooting](#troubleshooting).
## Installation
@@ -41,10 +54,6 @@ Linux (arm64/x64). Pick whichever fits your platform.
brew install mikefreno/tap/podtui
```
> 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
@@ -62,68 +71,29 @@ sudo ln -sf /opt/podtui/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
# Status: PKGBUILD ready, not yet on the AUR (see note below)
yay -S podtui-bin # once published
```
Requires an AUR helper ([paru](https://github.com/morgan/paru)). The AUR
package (PKGBUILD lives in `packaging/aur/`) installs the released binary and
its two FFI sibling libraries into `/usr/lib/podtui/` with a `/usr/bin/podtui`
symlink, and pulls in `mpv` (the sole audio backend) as a dependency.
Requires an AUR helper ([paru](https://github.com/morgan/paru)); the package
pulls in `mpv` as a dependency.
> **Not yet on the AUR.** The `podtui-bin` PKGBUILD and `.SRCINFO` are ready
> in `packaging/aur/` and can be built locally today:
>
> ```bash
> cd packaging/aur && makepkg -si
> ```
>
> Publishing is on hold until [AUR account registrations](https://aur.archlinux.org)
> reopen (suspended while the AUR team works on suspicious-package
> moderation).
> **Not yet on the AUR.** The `podtui-bin` package is staged and awaiting
> publication (AUR account registrations are currently suspended). Until it
> lands, use the standalone tarball above.
### 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.
PodTui is written in TypeScript and runs on [Bun](https://bun.sh). To build
from source (development, distro packaging, unreleased versions), see
[CONTRIBUTING.md](CONTRIBUTING.md).
## Usage
Launch `podtui` (or `bun src/index.tsx` from the source tree). Press `~`
for the in-app help.
Launch `podtui`. Press `~` for the in-app help.
### Command-line flags
@@ -135,30 +105,70 @@ for the in-app help.
### Keybindings
All keys are remappable — edit `~/.config/podtui/keybinds.jsonc`.
All keys are remappable — edit `keybinds.jsonc` in your config directory
(see [Configuration](#configuration)).
**Movement**
| Keys | Action |
|------|--------|
| `j` / `k` | Move cursor down / up |
| `J` / `K` | Jump 5 lines |
| `j` / `k` (or `down` / `up`) | Move down / up |
| `J` / `K` | Jump 5 lines down / up |
| `ctrl-d` / `ctrl-u` | Page down / up |
| `ctrl-f` / `ctrl-b` | Full page down / up |
| `gg` / `G` | Go to top / bottom |
| `h` / `l` | Swipe to parent pane / preview pane |
**Panes**
| Keys | Action |
|------|--------|
| `h` / `l` (or `left` / `right`) | Focus parent pane / preview pane |
| `Enter` | Open the item under the cursor (a tab, episode, show…) |
| `Space` | Select / toggle selection |
| `shift-enter` | Open with the interactive variant |
**Selection**
| Keys | Action |
|------|--------|
| `Space` | Toggle selection |
| `v` | Visual mode (multi-select) |
| `ctrl-a` | Select / deselect all |
| `ctrl-r` | Invert selection |
| `Esc` | Cancel / escape |
**Tabs**
| Keys | Action |
|------|--------|
| `1``6` | Jump to tab 16 (Feed, My Shows, Discover, Search, Player, Settings) |
| `[` / `]` | Previous / next tab |
| `P` (shift) | Play / pause |
**Commands, help, quit**
| Keys | Action |
|------|--------|
| `:` or `q` | Open the command palette (type `q` + `Enter` there to quit) |
| `Q` or `ctrl-c` | Quit |
| `~` or `f1` | In-app help |
**Lists**
| Keys | Action |
|------|--------|
| `s` | Search |
| `f` | Filter |
| `,` | Sort |
| `.` | Toggle hidden |
| `r` | Refresh |
| `x` | Unsubscribe the focused show (My Shows) |
**Audio**
| Keys | Action |
|------|--------|
| `P` | 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
@@ -175,50 +185,32 @@ default (`$XDG_CONFIG_HOME/podtui` if set).
Legacy `feeds.json`, `sources.json`, and `app-state.json` are auto-migrated
into `config.json` on first run.
Env overrides: `PODTUI_AUDIO_BACKEND`, `XDG_CONFIG_HOME`. Startup also reads
the same OpenTUI environment variables.
Env overrides: `PODTUI_AUDIO_BACKEND`, `XDG_CONFIG_HOME`.
## Development
## Troubleshooting
```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)
```
**`preload not found` at startup** — this used to happen when the binary was
launched from a Bun project directory whose `bunfig.toml` had a `preload`
entry. Releases are compiled with bunfig autoload disabled
(`autoloadBunfig: false`), so current binaries ignore the CWD's `bunfig.toml`
entirely. If you still hit it, you're on an old release — upgrade.
### Releasing
**No audio — playback is a silent no-op** — PodTui needs **mpv** on your
`PATH`. Install it (`brew install mpv`, `pacman -S mpv`, …) and relaunch.
Tag a release (e.g. `v0.1.0`); CI builds and uploads the per-platform tarballs
to your GitHub Release automatically:
**Homebrew prints a dylib warning** — “load commands do not fit in the header
… needs `-headerpad`” is benign: the app loads its libraries by path, the
install completes, and the app boots normally.
```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
```
**The app won't start / no spectrum after moving files**`podtui` loads its
two native libraries relative to the binary, so keep `podtui`,
`libopentui.*`, and `libcavacore.*` together in the same directory (the
tarball unpacks them side by side).
`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.
## Building from source / contributing
## 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.
Development setup, the test suite, packaging, and the release process are
documented in [CONTRIBUTING.md](CONTRIBUTING.md).
## License