Help us shape the future of Go! Take the 2026 Go Developer Survey

pine

command module
v0.8.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 13, 2026 License: MIT Imports: 13 Imported by: 0

README

pine

A terminal user interface for Audiobookshelf — listen to audiobooks and podcasts from your self-hosted server without leaving the terminal.

Built with bubbletea and mpv.

Two programs

This repository contains two programs. One Go module builds them, and one release tag covers them. They share the player, MPRIS, logger, and UI packages.

Program Server Install
pine Audiobookshelf: audiobooks and podcasts go install github.com/Thelost77/pine@latest
spruce Jellyfin: music go install github.com/Thelost77/pine/cmd/spruce@latest

The remaining sections describe pine. For spruce, see docs/spruce/README.md.

Features

  • Browse your audiobook and podcast libraries
  • Play audiobooks with chapter navigation and multi-track support
  • Play podcast episodes with progress tracking
  • Captions from VTT sidecar files
  • Playback queue
  • Series browsing, with marks for finished books
  • Persistent local API cache for instant startup and near-instant library switching
  • Fuzzy command-palette search (Ctrl+P) across books, podcasts, episodes, and series
  • In-place filtering (/) on home, library, and series lists
  • Metadata editor for books and episodes
  • MPRIS media-key support on Linux
  • Bookmarks — create, edit, navigate to, and delete
  • Sleep timer
  • Automatic progress sync every 30 seconds
  • Multiple library support with tab switching
  • Delete books and podcast episodes from the server
  • Keyboard-driven navigation
  • Configurable colors and keys, with the Everforest dark theme as the default
  • Session restore — pick up where you left off
  • In-process playback through libmpv — no mpv subprocess

Requirements

  • Go 1.26.4+ for an installation from source
  • libmpv, the library of mpv 0.34 or later. The mpv program is not necessary.
    • Debian and Ubuntu: sudo apt install libmpv2. On Ubuntu 22.04 the package is libmpv1.
    • Arch: sudo pacman -S mpv
    • macOS: brew install mpv
  • An Audiobookshelf server

pine does not load the mpv config files. The options in mpv.conf do not apply.

Linux is the primary platform. macOS works with mpv from Homebrew. MPRIS needs a D-Bus session, so the media keys work on Linux only. On Windows, the tests pass with libmpv-2.dll in the directory of the program, but pine has not run on a Windows machine.

Installation

go install github.com/Thelost77/pine@latest

Each release from v0.8.0 also has archives with a binary for Linux, macOS, and Windows. Download an archive from the release page. The binary needs libmpv. See "Requirements".

Usage

pine                # start the TUI
pine --clear-cache  # clear local cache and exit

On first run, you'll be prompted to log in to your Audiobookshelf server.

pine keeps its files in the user config directory. On Linux this is ~/.config/pine.

File Content
pine.db The server URL, the username, the auth token, the last session, and the API cache
config.toml The optional configuration
pine.log The log. It shows why a stream did not load.

Common keybindings

Some keys are context-specific.

Key Action
q Quit
esc / ← Go back
enter / → Open / select
j / k Navigate down / up
/ Filter current list
h / l Seek backward / forward
space / p Play / pause
a / A Add to queue / play next
> Play next queued item
+ / - Speed up / down
] / [ Volume up / down
c Toggle captions during playback
C Open chapter list
s Browse series (library)
S Cycle sleep timer during playback
b Add bookmark
d / e Delete / edit bookmark
f Mark finished
m Edit metadata (detail view)
tab Switch focus / library
ctrl+p Command palette
o Open library
? Help overlay

Configuration

Optional config file: config.toml in the config directory. Each key is optional. This example shows the defaults:

[player]
speed = 1.0
seek_seconds = 10

[keybinds]
quit = "q"
back = "esc"
play_pause = " "
seek_forward = "l"
seek_backward = "h"
next_in_queue = ">"
speed_up = "+"
speed_down = "-"
volume_up = "]"
volume_down = "["
sleep_timer = "S"

[theme]
background = "#2b3339"
foreground = "#d3c6aa"
accent = "#a7c080"
error = "#e67e80"
muted = "#859289"
selected = "#475258"
border = "#4f585e"
warning = "#dbbc7f"
info = "#7fbbb3"

Pine creates a stable playback identity on first run:

device_name = "my-host (Pine)"
device_id = "pine-my-host-a41c29ef"

Audiobookshelf uses device_id to distinguish playback devices. Keep it stable for one Pine installation. If you copy config.toml to another machine, delete or replace its device_id there so Pine generates a new one. device_name is display-only and can be changed without changing device_id. Audiobookshelf displays this as Pine <device_name> (without Pine's default (Pine) suffix), for example Pine my-host.

Pine sends its Go module build version as clientVersion to Audiobookshelf. Local development builds report dev.

Releases

Create SemVer tags with a leading v so Go can resolve @latest and versioned installs correctly. Keep release notes in docs/releases/ and publish the tag plus the GitHub Release together.

One tag releases pine and spruce together. Write the release notes for the two programs in one file. Commit the notes and push them to main. Then use the release script.

${EDITOR:-vi} docs/releases/v0.8.3.md
./scripts/release.sh v0.8.3

When the script publishes the GitHub Release, the Release workflow builds the two programs for Linux, macOS, and Windows. It attaches one archive for each program and each system to the release.

Architecture

main.go         pine entry point
cmd/spruce/     spruce entry point
internal/
  abs/          Audiobookshelf API client
  app/          Root model, screen routing, playback lifecycle
  cache/        Persistent API cache store and cached client wrapper
  captions/     VTT caption parser
  config/       TOML configuration
  db/           SQLite persistence (accounts, last session)
  screens/      Screen models (login, home, library, detail, metadataedit, series, serieslist)
  spruce/       spruce packages (app, buildinfo, config, jellyfin, screens)
  logger/       Shared: file-based structured logging
  mpris/        Shared: MPRIS D-Bus adapter for media-key integration
  player/       Shared: libmpv player
  ui/           Shared: styles, formatting, components

Development

go build -o pine .
go build -o spruce ./cmd/spruce
gofmt -l .
go vet ./...
golangci-lint run
go test ./... -count=1

A GitHub Actions workflow runs go vet, golangci-lint, and the tests on Linux, macOS, and Windows for each pull request. The player tests need libmpv. See AGENTS.md for the package map and the rules.

Status

Active development. Core functionality is stable — audiobooks, podcasts, bookmarks, chapters, search, persistent cache, metadata editing, server-side deletion, and progress sync are all functional.

Acknowledgements

Inspired by Toutui.

License

MIT

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
cmd
spruce command
internal
abs
app
captions
Package captions parses timed transcript sidecars and selects the active cue.
Package captions parses timed transcript sidecars and selects the active cue.
db
logger
Package logger provides file-based structured logging.
Package logger provides file-based structured logging.
player
Package player plays audio through libmpv and provides the player model.
Package player plays audio through libmpv and provides the player model.
ui

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL