mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
fix: migrate tooling to bun and accept file path targets
This commit is contained in:
22
.github/workflows/ci.yml
vendored
22
.github/workflows/ci.yml
vendored
@@ -15,38 +15,32 @@ jobs:
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
version: 9
|
||||
bun-version: latest
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: Build (TypeScript check)
|
||||
run: pnpm exec tsc --noEmit
|
||||
run: bun run tsc --noEmit
|
||||
|
||||
- name: Build (bundle)
|
||||
run: pnpm run build
|
||||
run: bun run build
|
||||
|
||||
- name: Test suite
|
||||
run: pnpm test
|
||||
run: bun run test
|
||||
|
||||
- name: Security audit
|
||||
run: pnpm audit --audit-level=high
|
||||
run: bun audit
|
||||
continue-on-error: true
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- name: Build Bun subminer wrapper
|
||||
run: make build-launcher
|
||||
|
||||
|
||||
30
.github/workflows/release.yml
vendored
30
.github/workflows/release.yml
vendored
@@ -17,28 +17,27 @@ jobs:
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
version: 9
|
||||
bun-version: latest
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: pnpm
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: Build texthooker-ui
|
||||
run: |
|
||||
cd vendor/texthooker-ui
|
||||
pnpm install
|
||||
pnpm build
|
||||
bun install
|
||||
bun run build
|
||||
|
||||
- name: Build AppImage
|
||||
run: pnpm run build:appimage
|
||||
run: bun run build:appimage
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -56,16 +55,15 @@ jobs:
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
version: 9
|
||||
bun-version: latest
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: pnpm
|
||||
|
||||
- name: Validate macOS signing/notarization secrets
|
||||
run: |
|
||||
@@ -88,16 +86,16 @@ jobs:
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: Build texthooker-ui
|
||||
run: |
|
||||
cd vendor/texthooker-ui
|
||||
pnpm install
|
||||
pnpm build
|
||||
bun install
|
||||
bun run build
|
||||
|
||||
- name: Build signed + notarized macOS artifacts
|
||||
run: pnpm run build:mac
|
||||
run: bun run build:mac
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CSC_LINK: ${{ secrets.CSC_LINK }}
|
||||
|
||||
70
Makefile
70
Makefile
@@ -1,4 +1,4 @@
|
||||
.PHONY: help deps build build-launcher install build-linux build-macos build-macos-unsigned clean install-linux install-macos install-plugin uninstall uninstall-linux uninstall-macos print-dirs pretty ensure-pnpm generate-config generate-example-config docs-dev docs docs-preview dev-start dev-start-macos dev-toggle dev-stop
|
||||
.PHONY: help deps build build-launcher install build-linux build-macos build-macos-unsigned clean install-linux install-macos install-plugin uninstall uninstall-linux uninstall-macos print-dirs pretty ensure-bun generate-config generate-example-config docs-dev docs docs-preview dev-start dev-start-macos dev-toggle dev-stop
|
||||
|
||||
APP_NAME := subminer
|
||||
THEME_FILE := subminer.rasi
|
||||
@@ -90,15 +90,15 @@ print-dirs:
|
||||
"MACOS_ZIP_SRC=$(MACOS_ZIP_SRC)"
|
||||
|
||||
deps:
|
||||
@$(MAKE) --no-print-directory ensure-pnpm
|
||||
@pnpm install
|
||||
@pnpm -C vendor/texthooker-ui install
|
||||
@$(MAKE) --no-print-directory ensure-bun
|
||||
@bun install
|
||||
@cd vendor/texthooker-ui && bun install
|
||||
|
||||
ensure-pnpm:
|
||||
@command -v pnpm >/dev/null 2>&1 || { printf '%s\n' "[ERROR] pnpm not found"; exit 1; }
|
||||
ensure-bun:
|
||||
@command -v bun >/dev/null 2>&1 || { printf '%s\n' "[ERROR] bun not found"; exit 1; }
|
||||
|
||||
pretty:
|
||||
@pnpm exec prettier --write 'src/**/*.ts'
|
||||
@bunx prettier --write 'src/**/*.ts'
|
||||
|
||||
build:
|
||||
@printf '%s\n' "[INFO] Detected platform: $(PLATFORM)"
|
||||
@@ -118,18 +118,18 @@ install:
|
||||
|
||||
build-linux: deps
|
||||
@printf '%s\n' "[INFO] Building Linux package (AppImage)"
|
||||
@pnpm -C vendor/texthooker-ui build
|
||||
@pnpm run build:appimage
|
||||
@cd vendor/texthooker-ui && bun run build
|
||||
@bun run build:appimage
|
||||
|
||||
build-macos: deps
|
||||
@printf '%s\n' "[INFO] Building macOS package (DMG + ZIP)"
|
||||
@pnpm -C vendor/texthooker-ui build
|
||||
@pnpm run build:mac
|
||||
@cd vendor/texthooker-ui && bun run build
|
||||
@bun run build:mac
|
||||
|
||||
build-macos-unsigned: deps
|
||||
@printf '%s\n' "[INFO] Building macOS package (DMG + ZIP, unsigned)"
|
||||
@pnpm -C vendor/texthooker-ui build
|
||||
@pnpm run build:mac:unsigned
|
||||
@cd vendor/texthooker-ui && bun run build
|
||||
@bun run build:mac:unsigned
|
||||
|
||||
build-launcher:
|
||||
@printf '%s\n' "[INFO] Bundling launcher script"
|
||||
@@ -144,36 +144,36 @@ clean:
|
||||
@rm -f "$(BINDIR)/subminer" "$(BINDIR)/SubMiner.AppImage"
|
||||
@rm -rf dist release
|
||||
|
||||
generate-config: ensure-pnpm
|
||||
@pnpm run build
|
||||
@pnpm exec electron . --generate-config
|
||||
generate-config: ensure-bun
|
||||
@bun run build
|
||||
@bun run electron . --generate-config
|
||||
|
||||
generate-example-config: ensure-pnpm
|
||||
@pnpm run build
|
||||
@pnpm run generate:config-example
|
||||
generate-example-config: ensure-bun
|
||||
@bun run build
|
||||
@bun run generate:config-example
|
||||
|
||||
docs-dev: ensure-pnpm
|
||||
@pnpm run docs:dev
|
||||
docs-dev: ensure-bun
|
||||
@bun run docs:dev
|
||||
|
||||
docs: ensure-pnpm
|
||||
@pnpm run docs:build
|
||||
docs: ensure-bun
|
||||
@bun run docs:build
|
||||
|
||||
docs-preview: ensure-pnpm
|
||||
@pnpm run docs:preview
|
||||
docs-preview: ensure-bun
|
||||
@bun run docs:preview
|
||||
|
||||
dev-start: ensure-pnpm
|
||||
@pnpm run build
|
||||
@pnpm exec electron . --start
|
||||
dev-start: ensure-bun
|
||||
@bun run build
|
||||
@bun run electron . --start
|
||||
|
||||
dev-start-macos: ensure-pnpm
|
||||
@pnpm run build
|
||||
@pnpm exec electron . --start --backend macos
|
||||
dev-start-macos: ensure-bun
|
||||
@bun run build
|
||||
@bun run electron . --start --backend macos
|
||||
|
||||
dev-toggle: ensure-pnpm
|
||||
@pnpm exec electron . --toggle
|
||||
dev-toggle: ensure-bun
|
||||
@bun run electron . --toggle
|
||||
|
||||
dev-stop: ensure-pnpm
|
||||
@pnpm exec electron . --stop
|
||||
dev-stop: ensure-bun
|
||||
@bun run electron . --stop
|
||||
|
||||
|
||||
install-linux: build-launcher
|
||||
|
||||
@@ -46,7 +46,10 @@ The `subminer` wrapper uses a [Bun](https://bun.sh) shebang, so `bun` must be on
|
||||
```bash
|
||||
git clone --recurse-submodules https://github.com/ksyasuda/SubMiner.git
|
||||
cd SubMiner
|
||||
make build && make install
|
||||
bun install
|
||||
cd vendor/texthooker-ui && bun install && cd ../..
|
||||
make build
|
||||
make install
|
||||
```
|
||||
|
||||
For macOS builds and platform details, see the [installation docs](docs/installation.md).
|
||||
@@ -54,6 +57,7 @@ For macOS builds and platform details, see the [installation docs](docs/installa
|
||||
## Quick Start
|
||||
|
||||
1. Copy [`config.example.jsonc`](config.example.jsonc) to `~/.config/SubMiner/config.jsonc`
|
||||
- Regenerate anytime from source: `make generate-example-config` or `bun run generate:config-example`
|
||||
2. Start mpv with IPC:
|
||||
```bash
|
||||
mpv --input-ipc-server=/tmp/subminer-socket video.mkv
|
||||
|
||||
@@ -299,7 +299,8 @@
|
||||
// ==========================================
|
||||
// Immersion Tracking
|
||||
// Enable/disable immersion tracking.
|
||||
// Set dbPath to override the default app data path.
|
||||
// Set dbPath to override the default sqlite database location.
|
||||
// Policy tuning is available for queue, flush, and retention values.
|
||||
// ==========================================
|
||||
"immersionTracking": {
|
||||
"enabled": true,
|
||||
|
||||
@@ -37,7 +37,7 @@ SubMiner.AppImage --generate-config --backup-overwrite
|
||||
- `--generate-config` writes a default JSONC config template.
|
||||
- If the target file exists, SubMiner prompts to create a timestamped backup and overwrite.
|
||||
- In non-interactive shells, use `--backup-overwrite` to explicitly back up and overwrite.
|
||||
- `pnpm run generate:config-example` regenerates both repository `config.example.jsonc` and docs-served `/config.example.jsonc` from the same centralized defaults.
|
||||
- `bun run generate:config-example` regenerates both repository `config.example.jsonc` and docs-served `/config.example.jsonc` from the same centralized defaults.
|
||||
- `make generate-config` builds and runs the same default-config generator via local Electron.
|
||||
|
||||
Invalid config values are handled with warn-and-fallback behavior: SubMiner logs the bad key/value and continues with the default for that option.
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
## Prerequisites
|
||||
|
||||
- [Node.js](https://nodejs.org/) (LTS)
|
||||
- [pnpm](https://pnpm.io/)
|
||||
- [Bun](https://bun.sh) (for the `subminer` wrapper script)
|
||||
- [Bun](https://bun.sh)
|
||||
|
||||
## Setup
|
||||
|
||||
@@ -13,15 +12,15 @@ git clone https://github.com/ksyasuda/SubMiner.git
|
||||
cd SubMiner
|
||||
make deps
|
||||
# or manually:
|
||||
pnpm install
|
||||
pnpm -C vendor/texthooker-ui install
|
||||
bun install
|
||||
bun --cwd vendor/texthooker-ui install
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
# TypeScript compile (fast, for development)
|
||||
pnpm run build
|
||||
bun run build
|
||||
|
||||
# Full platform build (includes texthooker-ui + AppImage/DMG)
|
||||
make build
|
||||
@@ -35,16 +34,16 @@ make build-macos-unsigned # macOS DMG + ZIP (unsigned)
|
||||
## Running Locally
|
||||
|
||||
```bash
|
||||
pnpm run dev # builds + launches with --start --dev
|
||||
bun run dev # builds + launches with --start --dev
|
||||
electron . --start --dev --log-level debug # equivalent Electron launch with verbose logging
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
pnpm run test:config # Config schema and validation tests (build + run)
|
||||
pnpm run test:core # Core service tests (~67 tests) (build + run)
|
||||
pnpm run test:subtitle # Subtitle pipeline tests (build + run)
|
||||
bun run test:config # Config schema and validation tests (build + run)
|
||||
bun run test:core # Core service tests (~67 tests) (build + run)
|
||||
bun run test:subtitle # Subtitle pipeline tests (build + run)
|
||||
```
|
||||
|
||||
All legacy test commands build first, then run via Node's built-in test runner (`node --test`).
|
||||
@@ -52,11 +51,11 @@ All legacy test commands build first, then run via Node's built-in test runner (
|
||||
For faster iteration while editing test code:
|
||||
|
||||
```bash
|
||||
pnpm run build # one-time compile
|
||||
pnpm run test:config:dist # no rebuild
|
||||
pnpm run test:core:dist # no rebuild
|
||||
pnpm run test:subtitle:dist # no rebuild
|
||||
pnpm run test:fast # run all tests without rebuild (assumes build is already current)
|
||||
bun run build # one-time compile
|
||||
bun run test:config:dist # no rebuild
|
||||
bun run test:core:dist # no rebuild
|
||||
bun run test:subtitle:dist # no rebuild
|
||||
bun run test:fast # run all tests without rebuild (assumes build is already current)
|
||||
```
|
||||
|
||||
## Config Generation
|
||||
@@ -67,7 +66,7 @@ make generate-config
|
||||
|
||||
# Regenerate the repo's config.example.jsonc from centralized defaults
|
||||
make generate-example-config
|
||||
# or: pnpm run generate:config-example
|
||||
# or: bun run generate:config-example
|
||||
```
|
||||
|
||||
## Documentation Site
|
||||
|
||||
@@ -82,9 +82,9 @@ brew install mpv mecab mecab-ipadic
|
||||
```bash
|
||||
git clone https://github.com/ksyasuda/SubMiner.git
|
||||
cd SubMiner
|
||||
pnpm install
|
||||
cd vendor/texthooker-ui && pnpm install && pnpm build && cd ../..
|
||||
pnpm run build:mac
|
||||
bun install
|
||||
cd vendor/texthooker-ui && bun install && bun run build && cd ../..
|
||||
bun run build:mac
|
||||
```
|
||||
|
||||
The built app will be available in the `release` directory (`.dmg` and `.zip`).
|
||||
@@ -92,7 +92,7 @@ The built app will be available in the `release` directory (`.dmg` and `.zip`).
|
||||
For unsigned local builds:
|
||||
|
||||
```bash
|
||||
pnpm run build:mac:unsigned
|
||||
bun run build:mac:unsigned
|
||||
```
|
||||
|
||||
### Accessibility Permission
|
||||
|
||||
@@ -58,4 +58,4 @@ Practical guidance:
|
||||
- Keep the JLPT bundle inside `vendor/yomitan-jlpt-vocab` to avoid network lookups.
|
||||
- Measure bundle size with:
|
||||
- `du -sh vendor/yomitan-jlpt-vocab`
|
||||
- If the JLPT source is updated, re-run `pnpm run build:appimage` / packaging and confirm startup logs do not report missing banks.
|
||||
- If the JLPT source is updated, re-run `bun run build:appimage` / packaging and confirm startup logs do not report missing banks.
|
||||
|
||||
@@ -46,26 +46,6 @@
|
||||
"level": "info"
|
||||
},
|
||||
|
||||
// Immersion Tracking
|
||||
// Persist mined subtitle/session telemetry for analytics.
|
||||
// ==========================================
|
||||
"immersionTracking": {
|
||||
"enabled": true,
|
||||
"dbPath": "",
|
||||
"batchSize": 25,
|
||||
"flushIntervalMs": 500,
|
||||
"queueCap": 1000,
|
||||
"payloadCapBytes": 256,
|
||||
"maintenanceIntervalMs": 86400000,
|
||||
"retention": {
|
||||
"eventsDays": 7,
|
||||
"telemetryDays": 30,
|
||||
"dailyRollupsDays": 365,
|
||||
"monthlyRollupsDays": 1825,
|
||||
"vacuumIntervalDays": 7
|
||||
}
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// AnkiConnect Integration
|
||||
// Automatic Anki updates and media generation options.
|
||||
@@ -314,5 +294,28 @@
|
||||
"aac"
|
||||
],
|
||||
"transcodeVideoCodec": "h264"
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// Immersion Tracking
|
||||
// Enable/disable immersion tracking.
|
||||
// Set dbPath to override the default sqlite database location.
|
||||
// Policy tuning is available for queue, flush, and retention values.
|
||||
// ==========================================
|
||||
"immersionTracking": {
|
||||
"enabled": true,
|
||||
"dbPath": "",
|
||||
"batchSize": 25,
|
||||
"flushIntervalMs": 500,
|
||||
"queueCap": 1000,
|
||||
"payloadCapBytes": 256,
|
||||
"maintenanceIntervalMs": 86400000,
|
||||
"retention": {
|
||||
"eventsDays": 7,
|
||||
"telemetryDays": 30,
|
||||
"dailyRollupsDays": 365,
|
||||
"monthlyRollupsDays": 1825,
|
||||
"vacuumIntervalDays": 7
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,6 +283,54 @@ function parseBackend(value: string): Backend {
|
||||
fail(`Invalid backend: ${value} (must be auto, hyprland, x11, or macos)`);
|
||||
}
|
||||
|
||||
function applyRootOptions(program: Command): void {
|
||||
program
|
||||
.option("-b, --backend <backend>", "Display backend")
|
||||
.option("-d, --directory <dir>", "Directory to browse")
|
||||
.option("-r, --recursive", "Search directories recursively")
|
||||
.option("-p, --profile <profile>", "MPV profile")
|
||||
.option("--start", "Explicitly start overlay")
|
||||
.option("--log-level <level>", "Log level")
|
||||
.option("-R, --rofi", "Use rofi picker")
|
||||
.option("-S, --start-overlay", "Auto-start overlay")
|
||||
.option("-T, --no-texthooker", "Disable texthooker-ui server");
|
||||
}
|
||||
|
||||
function hasTopLevelCommand(argv: string[]): boolean {
|
||||
const commandNames = new Set([
|
||||
"jellyfin",
|
||||
"jf",
|
||||
"yt",
|
||||
"youtube",
|
||||
"doctor",
|
||||
"config",
|
||||
"mpv",
|
||||
"texthooker",
|
||||
"help",
|
||||
]);
|
||||
const optionsWithValue = new Set([
|
||||
"-b",
|
||||
"--backend",
|
||||
"-d",
|
||||
"--directory",
|
||||
"-p",
|
||||
"--profile",
|
||||
"--log-level",
|
||||
]);
|
||||
for (let i = 0; i < argv.length; i += 1) {
|
||||
const token = argv[i] || "";
|
||||
if (token === "--") return false;
|
||||
if (token.startsWith("-")) {
|
||||
if (optionsWithValue.has(token)) {
|
||||
i += 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return commandNames.has(token);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function parseArgs(
|
||||
argv: string[],
|
||||
scriptName: string,
|
||||
@@ -402,27 +450,30 @@ export function parseArgs(
|
||||
let doctorLogLevel: string | null = null;
|
||||
let texthookerLogLevel: string | null = null;
|
||||
|
||||
const program = new Command();
|
||||
program
|
||||
const commandProgram = new Command();
|
||||
commandProgram
|
||||
.name(scriptName)
|
||||
.description("Launch MPV with SubMiner sentence mining overlay")
|
||||
.showHelpAfterError(true)
|
||||
.enablePositionalOptions()
|
||||
.allowExcessArguments(false)
|
||||
.allowUnknownOption(false)
|
||||
.exitOverride()
|
||||
.argument("[target]", "file, directory, or URL")
|
||||
.option("-b, --backend <backend>", "Display backend")
|
||||
.option("-d, --directory <dir>", "Directory to browse")
|
||||
.option("-r, --recursive", "Search directories recursively")
|
||||
.option("-p, --profile <profile>", "MPV profile")
|
||||
.option("--start", "Explicitly start overlay")
|
||||
.option("--log-level <level>", "Log level")
|
||||
.option("-R, --rofi", "Use rofi picker")
|
||||
.option("-S, --start-overlay", "Auto-start overlay")
|
||||
.option("-T, --no-texthooker", "Disable texthooker-ui server");
|
||||
.exitOverride();
|
||||
applyRootOptions(commandProgram);
|
||||
|
||||
program
|
||||
const rootProgram = new Command();
|
||||
rootProgram
|
||||
.name(scriptName)
|
||||
.description("Launch MPV with SubMiner sentence mining overlay")
|
||||
.usage("[options] [command] [target]")
|
||||
.showHelpAfterError(true)
|
||||
.allowExcessArguments(false)
|
||||
.allowUnknownOption(false)
|
||||
.exitOverride()
|
||||
.argument("[target]", "file, directory, or URL");
|
||||
applyRootOptions(rootProgram);
|
||||
|
||||
commandProgram
|
||||
.command("jellyfin")
|
||||
.alias("jf")
|
||||
.description("Jellyfin workflows")
|
||||
@@ -452,7 +503,7 @@ export function parseArgs(
|
||||
};
|
||||
});
|
||||
|
||||
program
|
||||
commandProgram
|
||||
.command("yt")
|
||||
.alias("youtube")
|
||||
.description("YouTube workflows")
|
||||
@@ -483,7 +534,7 @@ export function parseArgs(
|
||||
};
|
||||
});
|
||||
|
||||
program
|
||||
commandProgram
|
||||
.command("doctor")
|
||||
.description("Run dependency and environment checks")
|
||||
.option("--log-level <level>", "Log level")
|
||||
@@ -493,7 +544,7 @@ export function parseArgs(
|
||||
typeof options.logLevel === "string" ? options.logLevel : null;
|
||||
});
|
||||
|
||||
program
|
||||
commandProgram
|
||||
.command("config")
|
||||
.description("Config helpers")
|
||||
.argument("[action]", "path|show", "path")
|
||||
@@ -506,7 +557,7 @@ export function parseArgs(
|
||||
};
|
||||
});
|
||||
|
||||
program
|
||||
commandProgram
|
||||
.command("mpv")
|
||||
.description("MPV helpers")
|
||||
.argument("[action]", "status|socket|idle", "status")
|
||||
@@ -519,7 +570,7 @@ export function parseArgs(
|
||||
};
|
||||
});
|
||||
|
||||
program
|
||||
commandProgram
|
||||
.command("texthooker")
|
||||
.description("Launch texthooker-only mode")
|
||||
.option("--log-level <level>", "Log level")
|
||||
@@ -529,8 +580,9 @@ export function parseArgs(
|
||||
typeof options.logLevel === "string" ? options.logLevel : null;
|
||||
});
|
||||
|
||||
const selectedProgram = hasTopLevelCommand(argv) ? commandProgram : rootProgram;
|
||||
try {
|
||||
program.parse(["node", scriptName, ...argv]);
|
||||
selectedProgram.parse(["node", scriptName, ...argv]);
|
||||
} catch (error) {
|
||||
const commanderError = error as { code?: string; message?: string };
|
||||
if (commanderError?.code === "commander.helpDisplayed") {
|
||||
@@ -539,7 +591,7 @@ export function parseArgs(
|
||||
fail(commanderError?.message || String(error));
|
||||
}
|
||||
|
||||
const options = program.opts<Record<string, unknown>>();
|
||||
const options = selectedProgram.opts<Record<string, unknown>>();
|
||||
if (typeof options.backend === "string") {
|
||||
parsed.backend = parseBackend(options.backend);
|
||||
}
|
||||
@@ -558,7 +610,7 @@ export function parseArgs(
|
||||
if (options.startOverlay === true) parsed.autoStartOverlay = true;
|
||||
if (options.texthooker === false) parsed.useTexthooker = false;
|
||||
|
||||
const rootTarget = program.processedArgs[0];
|
||||
const rootTarget = rootProgram.processedArgs[0];
|
||||
if (typeof rootTarget === "string" && rootTarget) {
|
||||
ensureTarget(rootTarget, parsed);
|
||||
}
|
||||
|
||||
27
package.json
27
package.json
@@ -2,13 +2,14 @@
|
||||
"name": "subminer",
|
||||
"version": "0.1.0",
|
||||
"description": "All-in-one sentence mining overlay with AnkiConnect and dictionary integration",
|
||||
"packageManager": "bun@1.3.5",
|
||||
"main": "dist/main.js",
|
||||
"scripts": {
|
||||
"get-frequency": "bun run scripts/get_frequency.ts --pretty --color-top-x 10000 --yomitan-user-data ~/.config/SubMiner --colorized-line",
|
||||
"get-frequency:electron": "bun build scripts/get_frequency.ts --format=cjs --target=node --outfile dist/scripts/get_frequency.js --external electron && electron dist/scripts/get_frequency.js --pretty --color-top-x 10000 --yomitan-user-data ~/.config/SubMiner --colorized-line",
|
||||
"test-yomitan-parser": "bun run scripts/test-yomitan-parser.ts",
|
||||
"test-yomitan-parser:electron": "bun build scripts/test-yomitan-parser.ts --format=cjs --target=node --outfile dist/scripts/test-yomitan-parser.js --external electron && electron dist/scripts/test-yomitan-parser.js",
|
||||
"build": "tsc && pnpm run build:renderer && cp src/renderer/index.html src/renderer/style.css dist/renderer/ && bash scripts/build-macos-helper.sh",
|
||||
"build": "tsc && bun run build:renderer && cp src/renderer/index.html src/renderer/style.css dist/renderer/ && bash scripts/build-macos-helper.sh",
|
||||
"build:renderer": "esbuild src/renderer/renderer.ts --bundle --platform=browser --format=esm --target=es2022 --outfile=dist/renderer/renderer.js --sourcemap",
|
||||
"docs:dev": "VITE_EXTRA_EXTENSIONS=jsonc vitepress dev docs --host 0.0.0.0 --port 5173 --strictPort",
|
||||
"docs:build": "VITE_EXTRA_EXTENSIONS=jsonc vitepress build docs",
|
||||
@@ -16,20 +17,20 @@
|
||||
"test:config:dist": "node --test dist/config/config.test.js",
|
||||
"test:core:dist": "node --test dist/cli/args.test.js dist/cli/help.test.js dist/core/services/cli-command.test.js dist/core/services/ipc.test.js dist/core/services/field-grouping-overlay.test.js dist/core/services/numeric-shortcut-session.test.js dist/core/services/secondary-subtitle.test.js dist/core/services/mpv-render-metrics.test.js dist/core/services/overlay-content-measurement.test.js dist/core/services/mpv-control.test.js dist/core/services/mpv.test.js dist/core/services/runtime-options-ipc.test.js dist/core/services/runtime-config.test.js dist/core/services/tokenizer.test.js dist/core/services/subsync.test.js dist/core/services/overlay-bridge.test.js dist/core/services/overlay-manager.test.js dist/core/services/overlay-shortcut-handler.test.js dist/core/services/mining.test.js dist/core/services/anki-jimaku.test.js dist/core/services/jellyfin.test.js dist/core/services/jellyfin-remote.test.js dist/core/services/immersion-tracker-service.test.js dist/core/services/app-ready.test.js dist/core/services/startup-bootstrap.test.js dist/core/services/anilist/anilist-token-store.test.js dist/core/services/anilist/anilist-update-queue.test.js dist/subsync/utils.test.js dist/main/anilist-url-guard.test.js",
|
||||
"test:subtitle:dist": "echo \"Subtitle tests are currently not configured\"",
|
||||
"test": "pnpm run test:config && pnpm run test:core",
|
||||
"test:config": "pnpm run build && pnpm run test:config:dist",
|
||||
"test:core": "pnpm run build && pnpm run test:core:dist",
|
||||
"test:subtitle": "pnpm run build && pnpm run test:subtitle:dist",
|
||||
"test:fast": "pnpm run test:config:dist && pnpm run test:core:dist",
|
||||
"generate:config-example": "pnpm run build && node dist/generate-config-example.js",
|
||||
"start": "pnpm run build && electron . --start",
|
||||
"dev": "pnpm run build && electron . --start --dev",
|
||||
"test": "bun run test:config && bun run test:core",
|
||||
"test:config": "bun run build && bun run test:config:dist",
|
||||
"test:core": "bun run build && bun run test:core:dist",
|
||||
"test:subtitle": "bun run build && bun run test:subtitle:dist",
|
||||
"test:fast": "bun run test:config:dist && bun run test:core:dist",
|
||||
"generate:config-example": "bun run build && node dist/generate-config-example.js",
|
||||
"start": "bun run build && electron . --start",
|
||||
"dev": "bun run build && electron . --start --dev",
|
||||
"stop": "electron . --stop",
|
||||
"toggle": "electron . --toggle",
|
||||
"build:appimage": "pnpm run build && electron-builder --linux AppImage",
|
||||
"build:mac": "pnpm run build && electron-builder --mac dmg zip",
|
||||
"build:mac:unsigned": "pnpm run build && env -u APPLE_ID -u APPLE_APP_SPECIFIC_PASSWORD -u APPLE_TEAM_ID -u CSC_LINK -u CSC_KEY_PASSWORD CSC_IDENTITY_AUTO_DISCOVERY=false electron-builder --mac dmg zip",
|
||||
"build:mac:zip": "pnpm run build && electron-builder --mac zip"
|
||||
"build:appimage": "bun run build && electron-builder --linux AppImage",
|
||||
"build:mac": "bun run build && electron-builder --mac dmg zip",
|
||||
"build:mac:unsigned": "bun run build && env -u APPLE_ID -u APPLE_APP_SPECIFIC_PASSWORD -u APPLE_TEAM_ID -u CSC_LINK -u CSC_KEY_PASSWORD CSC_IDENTITY_AUTO_DISCOVERY=false electron-builder --mac dmg zip",
|
||||
"build:mac:zip": "bun run build && electron-builder --mac zip"
|
||||
},
|
||||
"keywords": [
|
||||
"anki",
|
||||
|
||||
5586
pnpm-lock.yaml
generated
5586
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@ Watch for in-flight refactors. If repo changes introduced drift, update only:
|
||||
- README.md
|
||||
- docs/**/*.md
|
||||
- config.example.jsonc
|
||||
- docs/public/config.example.jsonc <-- generated automatically with make pnpm run generate:config-example
|
||||
- docs/public/config.example.jsonc <-- generated automatically with make generate-example-config / bun run generate:config-example
|
||||
- package.json scripts/config references (only if needed)
|
||||
|
||||
Rules:
|
||||
|
||||
@@ -382,7 +382,7 @@ function parseCliArgs(argv: string[]): CliOptions {
|
||||
|
||||
function printUsage(): void {
|
||||
process.stdout.write(`Usage:
|
||||
pnpm run get-frequency [--pretty] [--diagnostics] [--dictionary <path>] [--mecab-command <path>] [--mecab-dictionary <path>] <text>
|
||||
bun run get-frequency [--pretty] [--diagnostics] [--dictionary <path>] [--mecab-command <path>] [--mecab-dictionary <path>] <text>
|
||||
|
||||
--pretty Pretty-print JSON output.
|
||||
--diagnostics Include merged-frequency lookup-term details.
|
||||
|
||||
@@ -233,4 +233,4 @@ echo " 2. socket.ts: Skip emitting empty sentences"
|
||||
echo " 3. app.css: Apply SubMiner default styling (without !important)"
|
||||
echo " 4. stores.ts: Update default settings for title/whitespace/animation/reconnect"
|
||||
echo ""
|
||||
echo "To rebuild: cd vendor/texthooker-ui && pnpm build"
|
||||
echo "To rebuild: cd vendor/texthooker-ui && bun run build"
|
||||
|
||||
@@ -258,4 +258,4 @@ echo " 1. permissions-util.js: Hardcoded permissions (Electron workaround)"
|
||||
echo " 2. options-schema.json: selectText=false, layoutAwareScan=false"
|
||||
echo " 3. popup.js: Added yomitan-popup-shown/hidden events"
|
||||
echo ""
|
||||
echo "To verify: Run 'pnpm start --dev' and check for 'Yomitan extension loaded successfully'"
|
||||
echo "To verify: Run 'bun run dev' and check for 'Yomitan extension loaded successfully'"
|
||||
|
||||
@@ -213,7 +213,7 @@ function parseCliArgs(argv: string[]): CliOptions {
|
||||
|
||||
function printUsage(): void {
|
||||
process.stdout.write(`Usage:
|
||||
pnpm run test-yomitan-parser:electron -- [--pretty] [--json] [--yomitan-extension <path>] [--yomitan-user-data <path>] [--mecab-command <path>] [--mecab-dictionary <path>] <text>
|
||||
bun run test-yomitan-parser:electron -- [--pretty] [--json] [--yomitan-extension <path>] [--yomitan-user-data <path>] [--mecab-command <path>] [--mecab-dictionary <path>] <text>
|
||||
|
||||
--pretty Pretty-print JSON output.
|
||||
--json Emit machine-readable JSON output.
|
||||
|
||||
@@ -255,7 +255,7 @@ test("JLPT CSS rules use underline-only styling in renderer stylesheet", () => {
|
||||
const cssPath = fs.existsSync(distCssPath) ? distCssPath : srcCssPath;
|
||||
if (!fs.existsSync(cssPath)) {
|
||||
assert.fail(
|
||||
"JLPT CSS file missing. Run `pnpm run build` first, or ensure src/renderer/style.css exists.",
|
||||
"JLPT CSS file missing. Run `bun run build` first, or ensure src/renderer/style.css exists.",
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user