Files
SubMiner/docs-site/development.md
T
sudacode 8825cca642 docs: rewrite docs site pages to be shorter and easier to scan
- Pages now start with setup and usage, and reference material is in compact tables
- Configuration reference gives each config block a short explanation and a key/default table
- Internal detail removed from user pages, and docs that had drifted from current behavior fixed
- The status line shows today's date, set on the client, instead of the page's last-updated date
- Add changelog fragment
2026-09-24 16:20:42 -07:00

9.7 KiB

Building and testing

Build, run, and test SubMiner from source. Architecture and workflow rules live in the repo's internal docs, starting at docs/README.md. The lane-by-lane test guide is docs/workflow/verification.md.

Prerequisites

  • Bun, at the version pinned in package.json
  • A system lua interpreter for the mpv plugin tests (bun run test:launcher, bun run test:env)
  • macOS only: bun run build compiles a Swift window helper. Set SUBMINER_SKIP_MACOS_HELPER_BUILD=1 to skip it.

Setup

git clone --recurse-submodules https://github.com/ksyasuda/SubMiner.git
cd SubMiner
make deps

make deps initializes submodules and installs dependencies for the root, stats/, and vendor/texthooker-ui. The Yomitan submodule installs its own dependencies during bun run build.

Build

bun run build               # app build, including bundled Yomitan from vendor/subminer-yomitan
bun run build:appimage      # Linux AppImage
bun run build:mac           # macOS DMG + ZIP (signed)
bun run build:mac:unsigned  # macOS DMG + ZIP (unsigned)
bun run build:win           # Windows NSIS installer + ZIP
make build-launcher         # launcher only, output: dist/launcher/subminer

The launcher source is launcher/*.ts. dist/launcher/subminer is generated, so never edit it by hand. The repo-root ./subminer is a stale path and verification rejects it. make install-linux and make install-macos copy from dist/launcher/subminer. To check the launcher build:

make build-launcher
dist/launcher/subminer --help >/dev/null
bash scripts/verify-generated-launcher.sh

Run locally

bun run dev                                  # build, then launch with --start --dev
make dev-watch                               # watch TS + renderer and relaunch Electron
make dev-watch-macos                         # same, forcing --backend macos
electron . --start --dev --log-level debug   # verbose launch of an existing build
electron . --background                      # tray/background mode

To test through the mpv plugin without exporting SUBMINER_BINARY_PATH each time, point mpv.subminerBinaryPath in your config at the dev script. The launcher passes it to the plugin at runtime:

{
  "mpv": {
    "subminerBinaryPath": "/absolute/path/to/SubMiner/scripts/subminer-dev.sh"
  }
}

Test

Run the handoff gate before submitting substantial changes:

bun run typecheck
bun run test:fast
bun run test:env
bun run build
bun run test:smoke:dist

For smaller changes, start with the cheapest lane that covers what you touched:

Command Covers
bun run test / test:fast All src/** tests, launcher unit tests, and scripts/** tests
bun run test:config Config schema, defaults, and config.example.jsonc generation
bun run test:launcher Launcher tests plus the Lua plugin tests
bun run test:env Launcher e2e smoke, Lua plugin tests, SQLite immersion tests from source
bun run test:scripts Build and release scripts under scripts/**
bun run test:stats Stats dashboard UI under stats/src/**
bun run test:runtime:compat Compiled-runtime smoke against dist/ (run bun run build first)
bun run test:immersion:sqlite Compiles, then runs the SQLite-backed immersion tracker tests
bun run test:subtitle alass/ffsubsync subtitle sync
bun run test:docs:kb Internal docs, AGENTS.md, and repo skills

Lane membership is defined in scripts/test-lanes.ts and discovered by directory, so a new test file joins its lane automatically. Do not hand-list test files in package.json. scripts/run-test-lane.mjs runs each file in its own bun test process, so a hanging test cannot take down the rest of the lane. Pass --jobs N to parallelize or --single-process to share one process while debugging.

Launcher smoke artifacts go to .tmp/launcher-smoke. CI uploads them when the smoke step fails.

Format

make pretty               # format the maintained source and stats files
bun run format:check:src  # check the same set without writing

bun run format runs Prettier over the whole repo. Use it only when you mean to.

Config generation

bun run electron . --generate-config   # write a default config to ~/.config/SubMiner/config.jsonc (%APPDATA%\SubMiner\config.jsonc on Windows)
bun run generate:config-example        # regenerate config.example.jsonc from the defaults

make generate-config and make generate-example-config wrap the same commands.

Config definitions are split by domain under src/config/definitions/:

  • defaults: defaults-*.ts
  • option metadata: options-*.ts
  • generated template sections and comments: template-sections.ts

src/config/definitions.ts composes them into the public API (DEFAULT_CONFIG, registries, template export). A new key also needs a resolver entry under src/config/resolve/, or the resolved config keeps the default.

Documentation site

The user docs live in docs-site/ (VitePress).

bun --cwd docs-site install
bun run docs:dev      # dev server at http://localhost:5173
bun run docs:test     # docs regression tests (links, pinned strings)
bun run docs:build    # production build into docs-site/.vitepress/dist
bun run docs:preview  # preview the build at http://localhost:4173

Run bun run docs:test and bun run docs:build whenever you change docs-site/.

Production uses the versioned build:

bun run docs:build:versioned

It writes .tmp/docs-versioned-site: the latest stable docs at / with a generated /versions page, and development docs at /main/. Prerelease tags are skipped. Stable archives under /v/<version>/ are built once and stored in R2. Without R2 credentials the build skips archive sync, so a local run only produces / and /main/.

The docs-pages GitHub Actions workflow uploads that output to Cloudflare Pages with Wrangler. Cloudflare's Git-integration builds are disabled on purpose, so do not re-enable them in the dashboard. docs-site/README.md has the full deployment setup.

Makefile targets

Run make help for the full list.

Target Description
make deps Init submodules and install root, stats, and texthooker deps
make build Build the platform package for the current OS
make build-linux Build the Linux package
make build-macos Build the signed macOS package
make build-macos-unsigned Build the unsigned macOS package
make build-launcher Generate the launcher in dist/launcher/
make install Install platform artifacts (wrapper, theme, AppImage or app)
make pretty Run scoped Prettier formatting
make generate-config Generate a default config

Contributor notes

  • See Architecture for module boundaries and IPC + runtime contracts before adding IPC channels.
  • src/core/services/overlay-manager.ts owns overlay window and visibility state.
  • In src/main/ modules, pass simple dependencies as inline objects. Add a helper or adapter only when it adapts, validates, or gets reused.
  • Packaged Linux desktop launches pass --background through build.linux.executableArgs in package.json.

Environment variables

Variable Description
SUBMINER_APPIMAGE_PATH SubMiner app binary the launcher uses for playback
SUBMINER_BINARY_PATH Alias for SUBMINER_APPIMAGE_PATH
SUBMINER_ROFI_THEME rofi theme for the launcher picker
SUBMINER_MPV_PLUGIN_PATH mpv plugin directory the launcher injects
SUBMINER_LOG_LEVEL App log level (debug, info, warn, error)
SUBMINER_MPV_LOG Shared mpv/app log file path
SUBMINER_JIMAKU_API_KEY Jimaku API key for launcher subtitle downloads
SUBMINER_JIMAKU_API_KEY_COMMAND Command that prints the Jimaku API key
SUBMINER_JIMAKU_API_BASE_URL Jimaku API base URL
SUBMINER_JELLYFIN_ACCESS_TOKEN Jellyfin access token, used before the stored encrypted session
SUBMINER_JELLYFIN_USER_ID Jellyfin user ID
SUBMINER_SKIP_MACOS_HELPER_BUILD Set to 1 to skip the macOS helper build during bun run build