mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-09-11 05:16:27 -07:00
feat(launcher): bundle Bun runtime with launcher artifacts
- Use private Bun runtimes for installed and downloadable launchers - Package runtime licenses, source manifests, and corresponding source releases - Update launcher workflows, setup, updates, and documentation
This commit is contained in:
@@ -207,7 +207,7 @@ Run `make help` for a full list of targets. Key ones:
|
||||
| Target | Description |
|
||||
| --------------------------- | ----------------------------------------------------------------- |
|
||||
| `make build` | Build platform package for detected OS |
|
||||
| `make build-launcher` | Generate Bun launcher wrapper at `dist/launcher/subminer` |
|
||||
| `make build-launcher` | Generate launcher wrappers and CLI payload in `dist/launcher/` |
|
||||
| `make install` | Install platform artifacts (wrapper, theme, AppImage/app bundle) |
|
||||
| `make deps` | Init submodules and install root/stats/texthooker-ui deps |
|
||||
| `make pretty` | Run scoped Prettier formatting for maintained source/config files |
|
||||
|
||||
+26
-21
@@ -14,7 +14,7 @@ Three steps to get started:
|
||||
|
||||
Only **mpv** is strictly required. Everything else is optional, though you will want ffmpeg unless you are fine with cards that have no audio or screenshot.
|
||||
|
||||
Some rows below matter only for the `subminer` command-line launcher, which is Linux and macOS only. On Windows you launch playback with the **SubMiner mpv** shortcut, so skip those.
|
||||
Some rows below matter only for the `subminer` command-line launcher's picker features. On Windows, the **SubMiner mpv** shortcut remains the recommended playback entry point.
|
||||
|
||||
[Local Japanese subtitle generation](/subtitle-generation) additionally requires whisper.cpp's `whisper-cli`, FFmpeg, and `ffprobe`. Configure their executable paths in Settings if needed. SubMiner can download a speech model explicitly, or use your existing multilingual GGML model.
|
||||
|
||||
@@ -209,13 +209,13 @@ There is no equivalent setting for ffmpeg: SubMiner invokes it by bare name when
|
||||
|
||||
**Optional extras:** [MeCab for Windows](https://taku910.github.io/mecab/#download) with the UTF-8 dictionary improves annotation accuracy; it is not in any package manager, so install it from that page. `xz` is needed only for [TsukiHime](/tsukihime-integration) subtitle downloads and is not packaged by winget or Chocolatey, so use `scoop install main/xz` or download [XZ Utils](https://tukaani.org/xz/) and add its folder to `PATH`.
|
||||
|
||||
The `subminer` command-line launcher and its picker tools (`fzf`, `rofi`, `chafa`, `ffmpegthumbnailer`) are Linux/macOS only; on Windows you use the **SubMiner mpv** shortcut instead.
|
||||
The launcher's picker tools (`fzf`, `rofi`, `chafa`, `ffmpegthumbnailer`) are for Linux and macOS. On Windows, use the **SubMiner mpv** shortcut for playback or install the optional `subminer` terminal wrapper during setup.
|
||||
|
||||
## 2. Install SubMiner
|
||||
|
||||
### Arch Linux (AUR) {#arch-aur}
|
||||
|
||||
Install [`subminer-bin`](https://aur.archlinux.org/packages/subminer-bin) from the AUR. The package includes the SubMiner AppImage and the `subminer` launcher.
|
||||
Install [`subminer-bin`](https://aur.archlinux.org/packages/subminer-bin) from the AUR. The package includes the SubMiner AppImage and its launcher wrapper. Bun is included with the app, so the package has no Bun dependency. Install updates through your AUR helper or package manager.
|
||||
|
||||
```bash
|
||||
paru -S subminer-bin
|
||||
@@ -240,9 +240,7 @@ chmod +x ~/.local/bin/SubMiner.AppImage
|
||||
```
|
||||
|
||||
::: tip Launcher install is optional
|
||||
First-run setup can install [Bun](https://bun.sh) and the `subminer` command-line launcher for you automatically. You don't need to download the launcher separately.
|
||||
|
||||
If you prefer to install it manually, see [manual launcher install](#manual-launcher-install-linux).
|
||||
First-run setup can install the `subminer` command-line launcher for you. It uses Bun bundled with the AppImage, so it does not need a separate Bun installation or a Bun entry on `PATH`. The downloaded wrapper works the same way. See [manual launcher install](#manual-launcher-install-linux).
|
||||
:::
|
||||
|
||||
### macOS (DMG) {#macos-dmg}
|
||||
@@ -261,9 +259,7 @@ xattr -d com.apple.quarantine /Applications/SubMiner.app
|
||||
2. Enable SubMiner in the list (add it if it does not appear)
|
||||
|
||||
::: tip Launcher install is optional
|
||||
First-run setup can install [Bun](https://bun.sh) and the `subminer` command-line launcher for you automatically. You don't need to download the launcher separately.
|
||||
|
||||
If you prefer to install it manually, see [manual launcher install](#manual-launcher-install-macos).
|
||||
First-run setup can install the `subminer` command-line launcher for you. It uses Bun bundled inside `SubMiner.app`, so it does not need a separate Bun installation or a Bun entry on `PATH`. The downloaded wrapper works the same way. See [manual launcher install](#manual-launcher-install-macos).
|
||||
:::
|
||||
|
||||
### Windows (installer) {#windows-installer}
|
||||
@@ -272,6 +268,7 @@ Download the latest installer from [GitHub Releases](https://github.com/ksyasuda
|
||||
|
||||
- `SubMiner-<version>.exe` - installer (recommended)
|
||||
- `SubMiner-<version>-win.zip` - portable fallback
|
||||
- `subminer.cmd` - optional terminal launcher wrapper
|
||||
|
||||
Make sure `mpv.exe` is on your `PATH`, or set `mpv.executablePath` in the config during first-run setup.
|
||||
|
||||
@@ -292,6 +289,8 @@ bun run build:appimage
|
||||
|
||||
Bundled Yomitan is built during `bun run build`.
|
||||
|
||||
Source and development commands use Bun installed on your system.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
@@ -327,6 +326,10 @@ bun run build:win
|
||||
|
||||
</details>
|
||||
|
||||
### Bundled Bun runtime {#bundled-bun-runtime}
|
||||
|
||||
Every package includes an unmodified copy of Bun 1.3.5 that runs the command-line launcher. Bun is MIT licensed and statically links JavaScriptCore under LGPL 2.0 and TinyCC under LGPL 2.1. The license texts, third-party notices, and a `SOURCE.md` describing the corresponding source ship inside the app under `resources/bun/licenses` (`SubMiner.app/Contents/Resources/bun/licenses` on macOS). Each GitHub release also publishes `bun-v1.3.5-source.tar.gz` with the matching Bun, WebKit, and dependency sources and instructions for rebuilding Bun against a modified JavaScriptCore.
|
||||
|
||||
## 3. Launch and first-run setup
|
||||
|
||||
Launch SubMiner and the setup wizard opens on its own:
|
||||
@@ -348,10 +351,12 @@ The setup wizard walks you through:
|
||||
|
||||
- **Config file** - auto-created at `~/.config/SubMiner/config.jsonc` (Linux/macOS) or `%APPDATA%\SubMiner\config.jsonc` (Windows)
|
||||
- **Yomitan dictionaries** - import at least one dictionary so word lookups work
|
||||
- **Bun + `subminer` launcher** _(optional)_ - installs the command-line launcher into a writable PATH directory
|
||||
- **`subminer` launcher** _(optional)_ - installs a wrapper into a writable terminal PATH directory. The wrapper uses Bun packaged with the app, with no separate runtime setup. If the included runtime is unavailable, the launcher controls show an error asking you to reinstall SubMiner.
|
||||
- **Windows shortcut** _(Windows only)_ - create a `SubMiner mpv` Start Menu/Desktop shortcut
|
||||
|
||||
The `Finish setup` button requires a config file and at least one Yomitan dictionary. Bun and the launcher are optional and never block setup completion.
|
||||
The `Finish setup` button requires a config file and at least one Yomitan dictionary. The launcher is optional and never blocks setup completion.
|
||||
|
||||
On Linux and macOS, setup selects a writable directory already on your terminal `PATH`. If it cannot find one, it creates `~/.local/bin` and shows the `export PATH=...` command to run. Add that command to your shell configuration yourself if you want it in future terminals. Setup never edits shell configuration files. On Windows, setup adds only the wrapper directory to the user `PATH`. Setup stores a custom app location so the wrapper can find an AppImage or app bundle outside the usual install directories.
|
||||
|
||||
> [!TIP]
|
||||
> You can re-open the setup wizard at any time with `subminer app --setup` or `SubMiner.AppImage --setup`.
|
||||
@@ -400,9 +405,9 @@ subminer --update
|
||||
|
||||
SubMiner verifies AppImage, launcher, and Linux support-asset downloads against `SHA256SUMS.txt`. On Linux those support assets include the launcher-managed runtime plugin copy under `SubMiner/plugin/subminer`, the rofi theme at `SubMiner/themes/subminer.rasi`, and the scoped Matroska thumbnailer registration under `SubMiner/thumbnailers`. If the binary is in a protected path, SubMiner shows the exact command to run rather than elevating itself.
|
||||
|
||||
The tray "Check for Updates" entry installs the new app automatically on Linux, macOS, and Windows. On Linux it replaces the running `.AppImage` in place via `electron-updater` and refreshes the managed support assets from `subminer-assets.tar.gz`; AppImages managed by a system package (for example the AUR `/opt/SubMiner/SubMiner.AppImage`) are skipped so the package manager stays in charge.
|
||||
The tray "Check for Updates" entry installs the new app automatically on Linux, macOS, and Windows. Current `subminer` wrappers remain small bootstraps that locate the installed app and its private runtime. On Linux the updater replaces the running `.AppImage` in place via `electron-updater` and refreshes managed support assets from `subminer-assets.tar.gz`. The next launcher invocation detects the changed AppImage fingerprint and prepares the matching Bun and CLI cache before running the command. App startup also refreshes this payload and migrates recognized writable legacy launchers, including the launcher path an update deferred. AppImages managed by a system package, for example the AUR `/opt/SubMiner/SubMiner.AppImage`, are skipped so the package manager stays in charge.
|
||||
|
||||
`subminer -u` also performs the AppImage, launcher, and managed support-asset updates directly from the launcher process, which is useful when SubMiner is not currently running.
|
||||
On Linux, `subminer -u` updates the AppImage and managed support assets directly, even when the app is not running. The launcher cache refreshes when the app fingerprint changes. AUR installs remain under package-manager control and should be updated through the package manager.
|
||||
|
||||
## How it all fits together
|
||||
|
||||
@@ -434,14 +439,11 @@ SubMiner injects the bundled mpv plugin at runtime, so there is nothing to insta
|
||||
|
||||
## Manual launcher install
|
||||
|
||||
The `subminer` launcher uses a [Bun](https://bun.sh) shebang, so Bun must be installed. First-run setup can handle this automatically, but if you prefer to do it yourself:
|
||||
Current launcher downloads use Bun included in the SubMiner app. The wrapper searches normal install locations and honors `SUBMINER_BINARY_PATH`; Linux also honors `SUBMINER_APPIMAGE_PATH`.
|
||||
|
||||
### Linux {#manual-launcher-install-linux}
|
||||
|
||||
```bash
|
||||
# Install Bun
|
||||
curl -fsSL https://bun.sh/install | bash
|
||||
|
||||
# Download the launcher
|
||||
wget https://github.com/ksyasuda/SubMiner/releases/latest/download/subminer -O ~/.local/bin/subminer
|
||||
chmod +x ~/.local/bin/subminer
|
||||
@@ -450,19 +452,22 @@ chmod +x ~/.local/bin/subminer
|
||||
### macOS {#manual-launcher-install-macos}
|
||||
|
||||
```bash
|
||||
# Install Bun
|
||||
curl -fsSL https://bun.sh/install | bash
|
||||
|
||||
# Download the launcher
|
||||
sudo curl -fSL https://github.com/ksyasuda/SubMiner/releases/latest/download/subminer -o /usr/local/bin/subminer
|
||||
sudo chmod +x /usr/local/bin/subminer
|
||||
```
|
||||
|
||||
### Windows {#manual-launcher-install-windows}
|
||||
|
||||
Download `subminer.cmd` from GitHub Releases and place it in a directory on your user `PATH`. It finds the installed app in the normal per-user or Program Files location. Set `SUBMINER_BINARY_PATH` if you use a portable or custom install.
|
||||
|
||||
Launchers installed before the private-runtime change may still be bundled JavaScript with a Bun shebang. Those old files need system Bun until a current app startup migrates a recognized writable launcher, or until you replace one with the current release wrapper.
|
||||
|
||||
## Optional extras
|
||||
|
||||
### Linux support assets
|
||||
|
||||
SubMiner ships the Linux rofi theme, scoped Matroska thumbnailer registration, and launcher-managed runtime plugin copy in `subminer-assets.tar.gz`:
|
||||
SubMiner ships the Linux rofi theme, scoped Matroska thumbnailer registration, launcher-managed runtime plugin copy, and the bundled Bun license notices in `subminer-assets.tar.gz`:
|
||||
|
||||
```bash
|
||||
wget https://github.com/ksyasuda/SubMiner/releases/latest/download/subminer-assets.tar.gz -O /tmp/subminer-assets.tar.gz
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
# Launcher script
|
||||
|
||||
The `subminer` launcher handles video selection, mpv startup, and overlay management in one script. Use it on Linux and macOS: it is the only path that guarantees mpv comes up with the right IPC socket and SubMiner's defaults. It is a Bun script, shipped as a release asset next to the AppImage and DMG.
|
||||
The `subminer` launcher handles video selection, mpv startup, and overlay management in one script. It guarantees mpv starts with the right IPC socket and SubMiner defaults. On Windows, the **SubMiner mpv** shortcut remains the recommended playback entry point.
|
||||
|
||||
The launcher is a small wrapper around the CLI bundled in the desktop app. It locates a normal SubMiner installation, or uses `SUBMINER_BINARY_PATH` when you set a custom executable. Linux also accepts `SUBMINER_APPIMAGE_PATH`. First-run setup records the selected app location for the wrapper. You do not need Bun installed or on `PATH`; only the directory containing `subminer` needs to be on `PATH`.
|
||||
|
||||
On macOS, the wrapper runs Bun and the CLI directly from `SubMiner.app/Contents/Resources`. On Windows, `subminer.cmd` stages a versioned private Bun copy under `%LOCALAPPDATA%\SubMiner\launcher-runtime/<version>` and runs the CLI from the current app. Keeping the executable outside the app avoids locking an updater-owned file while a launcher is running. Old runtime versions are removed when no running launcher is using them.
|
||||
|
||||
On Linux, the first launch caches Bun and its matching CLI and license files under `${XDG_DATA_HOME:-~/.local/share}/SubMiner/launcher`. Later launches make one `stat` call against the AppImage and run the cache without starting Electron. A missing cache or changed app fingerprint rebuilds it. App startup also refreshes the managed payload after an update.
|
||||
|
||||
The downloaded `subminer` and `subminer.cmd` release assets use the same private runtime flow. Older launcher scripts that were installed before this change cannot update their own code retroactively and still need system Bun until the app migrates them at startup or you download a current wrapper.
|
||||
|
||||
::: tip Windows users
|
||||
On Windows, the recommended way to launch playback is the **SubMiner mpv** shortcut created during first-run setup - double-click it, drag a file onto it, or run `SubMiner.exe --launch-mpv` from a terminal. See [Windows mpv Shortcut](/usage#windows-mpv-shortcut) for details.
|
||||
@@ -101,10 +109,16 @@ subminer sync macbook --check # test SSH + remote SubMiner without sync
|
||||
subminer sync --ui # open the sync window (also in the tray menu)
|
||||
```
|
||||
|
||||
How it works: each side takes a consistent snapshot of its database (`VACUUM INTO`), the snapshots are exchanged over `scp`, and each machine merges the other's snapshot into its own database. The merge is an insert-only union keyed on stable identifiers (session UUIDs, video keys, series title keys, word/kanji identity), so it is safe to re-run at any time. Syncing twice changes nothing, and nothing is ever overwritten or summed twice. Lifetime totals and rollup charts are updated incrementally, so history older than the session retention window is preserved on both sides.
|
||||
How it works: each side takes a consistent snapshot of its database (`VACUUM INTO`), the snapshots are exchanged over SSH, and each machine merges the other's snapshot into its own database. The merge is an insert-only union keyed on stable identifiers (session UUIDs, video keys, series title keys, word/kanji identity), so it is safe to re-run at any time. Syncing twice changes nothing, and nothing is ever overwritten or summed twice. Lifetime totals and rollup charts are updated incrementally, so history older than the session retention window is preserved on both sides.
|
||||
|
||||
On macOS and Linux, sync automatically uses compressed `rsync` transfers when compatible `rsync` commands are available on both machines. The last successfully received snapshot supplies matching blocks for later transfers, so unchanged data can be reused without sending it again. Only unmatched data needs to cross the connection, with compression reducing it further. Without a cached snapshot, sync sends a full compressed snapshot. Windows endpoints and machines without compatible `rsync` use compressed `scp` automatically. No extra configuration is required, and both methods work across different networks, including Tailscale connections.
|
||||
|
||||
For a one-way transfer, `--push` snapshots the local database and merges it into the host without changing the local database. `--pull` snapshots the host and merges it into the local database without changing the host. These modes add missing data; they do not delete destination-only data or make the destination an exact mirror.
|
||||
|
||||
Each rsync transfer explicitly uses SSH and has a 30-minute time limit. A timed-out transfer stops the sync before merging the incomplete snapshot.
|
||||
|
||||
Transfers write separate temporary files and verify the reconstructed content before merging. Cached comparison snapshots are preserved throughout the transfer. After a successful rsync sync, each receiver keeps one snapshot per peer/database identity in `sync-transfer-cache/` under its SubMiner config directory. This uses roughly one database-sized file per identity; deleting that cache is safe and only makes the next sync transfer more data. Missing or unwritable caches do not prevent syncing. Older peers without the cache helper still support compressed transfers, but cannot retain the upload comparison copy.
|
||||
|
||||
Command-line sync defaults to a cold-start safety check: close SubMiner (and stop the background stats daemon with `subminer stats -s`) on both machines before running it, or pass `--force`. Syncs started from the Sync window use live mode automatically, including scheduled auto-syncs while SubMiner or playback is active. SQLite WAL provides a consistent snapshot, the transactional merge serializes with live writes, and each machine's unfinished session is excluded from the transfer; that session syncs normally after it finishes. The mpv safety check requires a live socket connection, so a stale socket file left after mpv exits does not block command-line sync. Both machines must be on the same SubMiner version; otherwise, the sync aborts on a stats schema mismatch.
|
||||
|
||||
On the remote, sync looks for the `subminer` launcher first (PATH and `~/.local/bin`), then the app binary in `--sync-cli` mode (`SubMiner` on PATH, then the standard macOS `/Applications` and `~/Applications` installs), checking standard SubMiner and Bun locations (`~/.local/bin`, `~/.bun/bin`, Homebrew, `/usr/local/bin`, `/usr/bin`, and `/bin`) even when the non-interactive SSH shell omits them from `PATH`. An AppImage in a custom location can be addressed with `--remote-cmd /path/to/SubMiner.AppImage` (or symlink it as `SubMiner` somewhere on the remote PATH).
|
||||
@@ -122,7 +136,7 @@ Unfinished sessions (a crash mid-playback) are skipped until the app finalizes t
|
||||
|
||||
`subminer sync <host> --check` verifies a host without touching any data: it probes the SSH connection, locates SubMiner on the remote (launcher or app binary), and reports its version. `--json` switches any sync mode to machine-readable NDJSON progress output (this is what the sync window consumes).
|
||||
|
||||
`sync --make-temp` creates a restricted temporary directory and prints its path; `sync --remove-temp <dir>` removes one created by that command. They are internal SSH transfer helpers, exposed for compatibility but normally invoked only by sync itself. `SubMiner --sync-cli sync ...` is the packaged app's headless compatibility entrypoint; use `SubMiner --sync-cli --help` for its sync-specific help. The `subminer sync` launcher command selects this entrypoint automatically and runs AppImages in Node-only mode, so remote sync does not require a graphical session.
|
||||
`sync --make-temp` creates a restricted temporary directory and prints its path; `sync --remove-temp <dir>` removes one created by that command. The internal `--transfer-cache <key>` option seeds the temporary directory from a previous received snapshot when creating it, or saves the received snapshot before removing it after a successful sync. Keys are 64-character lowercase hexadecimal identifiers. These are internal SSH transfer helpers, exposed for compatibility but normally invoked only by sync itself. `SubMiner --sync-cli sync ...` is the packaged app's headless compatibility entrypoint; use `SubMiner --sync-cli --help` for its sync-specific help. The `subminer sync` launcher command selects this entrypoint automatically and runs AppImages in Node-only mode, so remote sync does not require a graphical session.
|
||||
|
||||
### Sync window
|
||||
|
||||
|
||||
+6
-1
@@ -12,6 +12,8 @@ On **Windows**, use the **SubMiner mpv** shortcut created during first-run setup
|
||||
|
||||
That is the whole setup. The `subminer` launcher starts mpv, opens the IPC socket, and brings up the overlay.
|
||||
|
||||
Every current launcher wrapper uses the Bun runtime included with the SubMiner app. This includes setup installs, release downloads, `make install`, and the AUR package. You only need the wrapper directory on your terminal `PATH`. Building SubMiner from source still requires Bun on the development machine.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> SubMiner requires the bundled Yomitan instance to have at least one dictionary imported for lookups to work.
|
||||
> See [Yomitan setup](#yomitan-setup) for details.
|
||||
@@ -75,7 +77,7 @@ subminer app --setup # Re-open first-run setup
|
||||
subminer -u # Check for updates
|
||||
```
|
||||
|
||||
On **Windows** there is no `subminer` launcher. Use the **SubMiner mpv** shortcut for playback (see [Windows mpv Shortcut](#windows-mpv-shortcut)), and run `SubMiner.exe` directly for everything else.
|
||||
On **Windows**, first-run setup can install the optional `subminer` terminal wrapper. Use the **SubMiner mpv** shortcut for playback (see [Windows mpv Shortcut](#windows-mpv-shortcut)), or use `subminer` and `SubMiner.exe` from a terminal.
|
||||
|
||||
Two flags are worth knowing early:
|
||||
|
||||
@@ -226,6 +228,8 @@ The launcher groups related work under subcommands: `jellyfin` (aliased `jf`), `
|
||||
|
||||
Every subcommand has its own help page, for example `subminer jellyfin -h`. See [Launcher Script - Subcommands](/launcher-script#subcommands) for the full table, and [Sync Between Machines](/launcher-script#sync-between-machines) for the SSH stats/history sync.
|
||||
|
||||
Sync selects compressed transfers automatically and reuses cached snapshots when rsync is available. Its `--transfer-cache <key>` option belongs to the internal `--make-temp` / `--remove-temp` helpers; normal `subminer sync <host>` commands manage it for you. See [Sync Between Machines](/launcher-script#sync-between-machines) for cache storage and compatibility details.
|
||||
|
||||
A _texthooker_ is a web page that displays the current subtitle line as selectable text, so browser-based dictionary extensions and other tools can read along with playback.
|
||||
|
||||
### First-run setup
|
||||
@@ -245,6 +249,7 @@ Setup flow:
|
||||
- legacy plugin cleanup: remove detected older global SubMiner mpv plugin files if present (the bundled plugin is injected at runtime automatically)
|
||||
- Yomitan shortcut: open bundled Yomitan settings directly from the setup window
|
||||
- dictionary check: confirm at least one bundled Yomitan dictionary is present, unless an external Yomitan profile is configured
|
||||
- command line launcher: optionally install or reinstall the managed `subminer` wrapper. Reinstall it to migrate an older launcher or after moving a macOS or Windows app install.
|
||||
- Windows: optionally create or remove `SubMiner mpv` Start Menu/Desktop shortcuts (`SubMiner.exe --launch-mpv`)
|
||||
- Windows: optionally set `mpv.executablePath` if `mpv.exe` is not on `PATH`
|
||||
- refresh: re-check dictionary state without restarting
|
||||
|
||||
Reference in New Issue
Block a user