Switch known-word cache to incremental sync and doctor refresh

- Load persisted known-word cache on startup; reconcile adds/deletes/edits on timed sync
- Add `knownWords.addMinedWordsImmediately` (default `true`) for immediate mined-word updates
- Route full rebuild to explicit `subminer doctor --refresh-known-words` and expand tests/docs
This commit is contained in:
2026-03-19 19:29:58 -07:00
parent 72d78ba1ca
commit 20f53c0b70
50 changed files with 1130 additions and 119 deletions

View File

@@ -2,6 +2,7 @@ import test from 'node:test';
import assert from 'node:assert/strict';
import {
hasExplicitCommand,
isHeadlessInitialCommand,
parseArgs,
shouldRunSettingsOnlyStartup,
shouldStartApp,
@@ -101,7 +102,8 @@ test('hasExplicitCommand and shouldStartApp preserve command intent', () => {
const refreshKnownWords = parseArgs(['--refresh-known-words']);
assert.equal(refreshKnownWords.help, false);
assert.equal(hasExplicitCommand(refreshKnownWords), true);
assert.equal(shouldStartApp(refreshKnownWords), false);
assert.equal(shouldStartApp(refreshKnownWords), true);
assert.equal(isHeadlessInitialCommand(refreshKnownWords), true);
const settings = parseArgs(['--settings']);
assert.equal(settings.settings, true);

View File

@@ -376,6 +376,10 @@ export function hasExplicitCommand(args: CliArgs): boolean {
);
}
export function isHeadlessInitialCommand(args: CliArgs): boolean {
return args.refreshKnownWords;
}
export function shouldStartApp(args: CliArgs): boolean {
if (args.stop && !args.start) return false;
if (
@@ -391,6 +395,7 @@ export function shouldStartApp(args: CliArgs): boolean {
args.mineSentence ||
args.mineSentenceMultiple ||
args.updateLastCardFromClipboard ||
args.refreshKnownWords ||
args.toggleSecondarySub ||
args.triggerFieldGrouping ||
args.triggerSubsync ||

View File

@@ -19,7 +19,7 @@ test('printHelp includes configured texthooker port', () => {
assert.match(output, /default: 7777/);
assert.match(output, /--launch-mpv/);
assert.match(output, /--stats\s+Open the stats dashboard in your browser/);
assert.match(output, /--refresh-known-words/);
assert.doesNotMatch(output, /--refresh-known-words/);
assert.match(output, /--setup\s+Open first-run setup window/);
assert.match(output, /--anilist-status/);
assert.match(output, /--anilist-retry-queue/);

View File

@@ -35,7 +35,6 @@ ${B}Mining${R}
--trigger-field-grouping Run Kiku field grouping
--trigger-subsync Run subtitle sync
--toggle-secondary-sub Cycle secondary subtitle mode
--refresh-known-words Refresh known words cache
--open-runtime-options Open runtime options palette
${B}AniList${R}